1. Sync the latest network stack. Add NetLibCreateIPv4DPathNode () in netlib library.
[mirror_edk2.git] / MdeModulePkg / Universal / PcatSingleSegmentPciCfg2Pei / PciCfg2.c
1 /**
2
3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 **/
13
14 #include <PiPei.h>
15
16 #include <Ppi/PciCfg2.h>
17
18 #include <Library/BaseLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/PciLib.h>
21 #include <Library/PeimEntryPoint.h>
22
23 #include <IndustryStandard/Pci.h>
24
25 /**
26 Convert EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS to PCI_LIB_ADDRESS.
27
28 @param Address PCI address with
29 EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS format.
30
31 @return The PCI address with PCI_LIB_ADDRESS format.
32
33 **/
34 STATIC
35 UINTN
36 PciCfgAddressConvert (
37 EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *Address
38 )
39 {
40 if (Address->ExtendedRegister == 0) {
41 return PCI_LIB_ADDRESS (Address->Bus, Address->Device, Address->Function, Address->Register);
42 }
43
44 return PCI_LIB_ADDRESS (Address->Bus, Address->Device, Address->Function, Address->ExtendedRegister);
45 }
46
47 /**
48 Reads from a given location in the PCI configuration space.
49
50 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.
51
52 @param This Pointer to local data for the interface.
53
54 @param Width The width of the access. Enumerated in bytes.
55 See EFI_PEI_PCI_CFG_PPI_WIDTH above.
56
57 @param Address The physical address of the access. The format of
58 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.
59
60 @param Buffer A pointer to the buffer of data..
61
62
63 @retval EFI_SUCCESS The function completed successfully.
64
65 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
66
67 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this
68 time.
69
70 **/
71 EFI_STATUS
72 EFIAPI
73 PciCfg2Read (
74 IN CONST EFI_PEI_SERVICES **PeiServices,
75 IN CONST EFI_PEI_PCI_CFG2_PPI *This,
76 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
77 IN UINT64 Address,
78 IN OUT VOID *Buffer
79 );
80
81 /**
82 Write to a given location in the PCI configuration space.
83
84 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.
85
86 @param This Pointer to local data for the interface.
87
88 @param Width The width of the access. Enumerated in bytes.
89 See EFI_PEI_PCI_CFG_PPI_WIDTH above.
90
91 @param Address The physical address of the access. The format of
92 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.
93
94 @param Buffer A pointer to the buffer of data..
95
96
97 @retval EFI_SUCCESS The function completed successfully.
98
99 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
100
101 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this
102 time.
103
104 **/
105 EFI_STATUS
106 EFIAPI
107 PciCfg2Write (
108 IN CONST EFI_PEI_SERVICES **PeiServices,
109 IN CONST EFI_PEI_PCI_CFG2_PPI *This,
110 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
111 IN UINT64 Address,
112 IN OUT VOID *Buffer
113 );
114
115
116 /**
117 PCI read-modify-write operation.
118
119 @param PeiServices An indirect pointer to the PEI Services Table
120 published by the PEI Foundation.
121
122 @param This Pointer to local data for the interface.
123
124 @param Width The width of the access. Enumerated in bytes. Type
125 EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().
126
127 @param Address The physical address of the access.
128
129 @param SetBits Points to value to bitwise-OR with the read configuration value.
130
131 The size of the value is determined by Width.
132
133 @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value.
134 The size of the value is determined by Width.
135
136
137 @retval EFI_SUCCESS The function completed successfully.
138
139 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
140
141 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting
142 the operation at this time.
143
144 **/
145 EFI_STATUS
146 EFIAPI
147 PciCfg2Modify (
148 IN CONST EFI_PEI_SERVICES **PeiServices,
149 IN CONST EFI_PEI_PCI_CFG2_PPI *This,
150 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
151 IN UINT64 Address,
152 IN CONST VOID *SetBits,
153 IN CONST VOID *ClearBits
154 );
155
156
157
158 /**
159 @par Ppi Description:
160 The EFI_PEI_PCI_CFG2_PPI interfaces are used to abstract
161 accesses to PCI controllers behind a PCI root bridge
162 controller.
163
164 @param Read PCI read services. See the Read() function description.
165
166 @param Write PCI write services. See the Write() function description.
167
168 @param Modify PCI read-modify-write services. See the Modify() function description.
169
170 @param Segment The PCI bus segment which the specified functions will access.
171
172 **/
173 GLOBAL_REMOVE_IF_UNREFERENCED
174 EFI_PEI_PCI_CFG2_PPI gPciCfg2Ppi = {
175 PciCfg2Read,
176 PciCfg2Write,
177 PciCfg2Modify
178 };
179
180 GLOBAL_REMOVE_IF_UNREFERENCED
181 EFI_PEI_PPI_DESCRIPTOR gPciCfg2PpiList = {
182 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
183 &gEfiPciCfg2PpiGuid,
184 &gPciCfg2Ppi
185 };
186
187 /**
188 Reads from a given location in the PCI configuration space.
189
190 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.
191
192 @param This Pointer to local data for the interface.
193
194 @param Width The width of the access. Enumerated in bytes.
195 See EFI_PEI_PCI_CFG_PPI_WIDTH above.
196
197 @param Address The physical address of the access. The format of
198 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.
199
200 @param Buffer A pointer to the buffer of data..
201
202
203 @retval EFI_SUCCESS The function completed successfully.
204
205 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
206
207 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this
208 time.
209
210 **/
211 EFI_STATUS
212 EFIAPI
213 PciCfg2Read (
214 IN CONST EFI_PEI_SERVICES **PeiServices,
215 IN CONST EFI_PEI_PCI_CFG2_PPI *This,
216 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
217 IN UINT64 Address,
218 IN OUT VOID *Buffer
219 )
220 {
221 UINTN PciLibAddress;
222
223 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);
224
225 if (Width == EfiPeiPciCfgWidthUint8) {
226 *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);
227 } else if (Width == EfiPeiPciCfgWidthUint16) {
228 *((UINT16 *) Buffer) = PciRead16 (PciLibAddress);
229 } else if (Width == EfiPeiPciCfgWidthUint32) {
230 *((UINT32 *) Buffer) = PciRead32 (PciLibAddress);
231 } else {
232 return EFI_INVALID_PARAMETER;
233 }
234
235 return EFI_SUCCESS;
236 }
237
238 /**
239 Write to a given location in the PCI configuration space.
240
241 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.
242
243 @param This Pointer to local data for the interface.
244
245 @param Width The width of the access. Enumerated in bytes.
246 See EFI_PEI_PCI_CFG_PPI_WIDTH above.
247
248 @param Address The physical address of the access. The format of
249 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.
250
251 @param Buffer A pointer to the buffer of data..
252
253
254 @retval EFI_SUCCESS The function completed successfully.
255
256 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
257
258 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this
259 time.
260
261 **/
262 EFI_STATUS
263 EFIAPI
264 PciCfg2Write (
265 IN CONST EFI_PEI_SERVICES **PeiServices,
266 IN CONST EFI_PEI_PCI_CFG2_PPI *This,
267 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
268 IN UINT64 Address,
269 IN OUT VOID *Buffer
270 )
271 {
272 UINTN PciLibAddress;
273
274 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);
275
276 if (Width == EfiPeiPciCfgWidthUint8) {
277 PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));
278 } else if (Width == EfiPeiPciCfgWidthUint16) {
279 PciWrite16 (PciLibAddress, *((UINT16 *) Buffer));
280 } else if (Width == EfiPeiPciCfgWidthUint32) {
281 PciWrite32 (PciLibAddress, *((UINT32 *) Buffer));
282 } else {
283 return EFI_INVALID_PARAMETER;
284 }
285
286 return EFI_SUCCESS;
287 }
288
289
290 /**
291 PCI read-modify-write operation.
292
293 @param PeiServices An indirect pointer to the PEI Services Table
294 published by the PEI Foundation.
295
296 @param This Pointer to local data for the interface.
297
298 @param Width The width of the access. Enumerated in bytes. Type
299 EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().
300
301 @param Address The physical address of the access.
302
303 @param SetBits Points to value to bitwise-OR with the read configuration value.
304
305 The size of the value is determined by Width.
306
307 @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value.
308 The size of the value is determined by Width.
309
310
311 @retval EFI_SUCCESS The function completed successfully.
312
313 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
314
315 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting
316 the operation at this time.
317
318 **/
319 EFI_STATUS
320 EFIAPI
321 PciCfg2Modify (
322 IN CONST EFI_PEI_SERVICES **PeiServices,
323 IN CONST EFI_PEI_PCI_CFG2_PPI *This,
324 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
325 IN UINT64 Address,
326 IN CONST VOID *SetBits,
327 IN CONST VOID *ClearBits
328 )
329 {
330 UINTN PciLibAddress;
331 UINT16 ClearValue16;
332 UINT16 SetValue16;
333 UINT32 ClearValue32;
334 UINT32 SetValue32;
335
336 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);
337
338 if (Width == EfiPeiPciCfgWidthUint8) {
339 PciAndThenOr8 (PciLibAddress, (UINT8) (~(*(UINT8 *) ClearBits)), *((UINT8 *) SetBits));
340 } else if (Width == EfiPeiPciCfgWidthUint16) {
341 ClearValue16 = (UINT16) (~ReadUnaligned16 ((UINT16 *) ClearBits));
342 SetValue16 = ReadUnaligned16 ((UINT16 *) SetBits);
343 PciAndThenOr16 (PciLibAddress, ClearValue16, SetValue16);
344 } else if (Width == EfiPeiPciCfgWidthUint32) {
345 ClearValue32 = (UINT32) (~ReadUnaligned32 ((UINT32 *) ClearBits));
346 SetValue32 = ReadUnaligned32 ((UINT32 *) SetBits);
347 PciAndThenOr32 (PciLibAddress, ClearValue32, SetValue32);
348 } else {
349 return EFI_INVALID_PARAMETER;
350 }
351 return EFI_SUCCESS;
352 }
353
354
355 EFI_STATUS
356 EFIAPI
357 PeimInitializePciCfg (
358 IN EFI_FFS_FILE_HEADER *FfsHeader,
359 IN EFI_PEI_SERVICES **PeiServices
360 )
361 {
362 EFI_STATUS Status;
363
364 ASSERT ((**PeiServices).Hdr.Revision >= PEI_SERVICES_REVISION);
365
366 (**PeiServices).PciCfg = &gPciCfg2Ppi;
367 Status = (**PeiServices).InstallPpi (PeiServices, &gPciCfg2PpiList);
368
369 return Status;
370 }