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
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.
16 #include <Ppi/PciCfg2.h>
18 #include <Library/BaseLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/PciLib.h>
21 #include <Library/PeimEntryPoint.h>
23 #include <IndustryStandard\Pci.h>
25 #define COMMON_TO_PCILIB_ADDRESS(A) (UINTN)PCI_LIB_ADDRESS( \
26 ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &A)->Bus, \
27 ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &A)->Device, \
28 ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &A)->Function, \
29 ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &A)->Register \
34 Reads from a given location in the PCI configuration space.
36 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.
38 @param This Pointer to local data for the interface.
40 @param Width The width of the access. Enumerated in bytes.
41 See EFI_PEI_PCI_CFG_PPI_WIDTH above.
43 @param Address The physical address of the access. The format of
44 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.
46 @param Buffer A pointer to the buffer of data..
49 @retval EFI_SUCCESS The function completed successfully.
51 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
53 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this
60 IN CONST EFI_PEI_SERVICES
**PeiServices
,
61 IN CONST EFI_PEI_PCI_CFG2_PPI
*This
,
62 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
68 Write to a given location in the PCI configuration space.
70 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.
72 @param This Pointer to local data for the interface.
74 @param Width The width of the access. Enumerated in bytes.
75 See EFI_PEI_PCI_CFG_PPI_WIDTH above.
77 @param Address The physical address of the access. The format of
78 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.
80 @param Buffer A pointer to the buffer of data..
83 @retval EFI_SUCCESS The function completed successfully.
85 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
87 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this
94 IN CONST EFI_PEI_SERVICES
**PeiServices
,
95 IN CONST EFI_PEI_PCI_CFG2_PPI
*This
,
96 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
103 PCI read-modify-write operation.
105 @param PeiServices An indirect pointer to the PEI Services Table
106 published by the PEI Foundation.
108 @param This Pointer to local data for the interface.
110 @param Width The width of the access. Enumerated in bytes. Type
111 EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().
113 @param Address The physical address of the access.
115 @param SetBits Points to value to bitwise-OR with the read configuration value.
117 The size of the value is determined by Width.
119 @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value.
120 The size of the value is determined by Width.
123 @retval EFI_SUCCESS The function completed successfully.
125 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
127 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting
128 the operation at this time.
134 IN CONST EFI_PEI_SERVICES
**PeiServices
,
135 IN CONST EFI_PEI_PCI_CFG2_PPI
*This
,
136 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
138 IN CONST VOID
*SetBits
,
139 IN CONST VOID
*ClearBits
145 @par Ppi Description:
146 The EFI_PEI_PCI_CFG2_PPI interfaces are used to abstract
147 accesses to PCI controllers behind a PCI root bridge
150 @param Read PCI read services. See the Read() function description.
152 @param Write PCI write services. See the Write() function description.
154 @param Modify PCI read-modify-write services. See the Modify() function description.
156 @param Segment The PCI bus segment which the specified functions will access.
159 GLOBAL_REMOVE_IF_UNREFERENCED
160 EFI_PEI_PCI_CFG2_PPI gPciCfg2Ppi
= {
166 GLOBAL_REMOVE_IF_UNREFERENCED
167 EFI_PEI_PPI_DESCRIPTOR gPciCfg2PpiList
= {
168 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
174 Reads from a given location in the PCI configuration space.
176 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.
178 @param This Pointer to local data for the interface.
180 @param Width The width of the access. Enumerated in bytes.
181 See EFI_PEI_PCI_CFG_PPI_WIDTH above.
183 @param Address The physical address of the access. The format of
184 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.
186 @param Buffer A pointer to the buffer of data..
189 @retval EFI_SUCCESS The function completed successfully.
191 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
193 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this
200 IN CONST EFI_PEI_SERVICES
**PeiServices
,
201 IN CONST EFI_PEI_PCI_CFG2_PPI
*This
,
202 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
209 PciLibAddress
= COMMON_TO_PCILIB_ADDRESS (Address
);
211 if (Width
== EfiPeiPciCfgWidthUint8
) {
212 *((UINT8
*) Buffer
) = PciRead8 (PciLibAddress
);
213 } else if (Width
== EfiPeiPciCfgWidthUint16
) {
214 *((UINT16
*) Buffer
) = PciRead16 (PciLibAddress
);
215 } else if (Width
== EfiPeiPciCfgWidthUint32
) {
216 *((UINT32
*) Buffer
) = PciRead32 (PciLibAddress
);
218 return EFI_INVALID_PARAMETER
;
225 Write to a given location in the PCI configuration space.
227 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.
229 @param This Pointer to local data for the interface.
231 @param Width The width of the access. Enumerated in bytes.
232 See EFI_PEI_PCI_CFG_PPI_WIDTH above.
234 @param Address The physical address of the access. The format of
235 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.
237 @param Buffer A pointer to the buffer of data..
240 @retval EFI_SUCCESS The function completed successfully.
242 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
244 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this
251 IN CONST EFI_PEI_SERVICES
**PeiServices
,
252 IN CONST EFI_PEI_PCI_CFG2_PPI
*This
,
253 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
260 PciLibAddress
= COMMON_TO_PCILIB_ADDRESS (Address
);
262 if (Width
== EfiPeiPciCfgWidthUint8
) {
263 PciWrite8 (PciLibAddress
, *((UINT8
*) Buffer
));
264 } else if (Width
== EfiPeiPciCfgWidthUint16
) {
265 PciWrite16 (PciLibAddress
, *((UINT16
*) Buffer
));
266 } else if (Width
== EfiPeiPciCfgWidthUint32
) {
267 PciWrite32 (PciLibAddress
, *((UINT32
*) Buffer
));
269 return EFI_INVALID_PARAMETER
;
277 PCI read-modify-write operation.
279 @param PeiServices An indirect pointer to the PEI Services Table
280 published by the PEI Foundation.
282 @param This Pointer to local data for the interface.
284 @param Width The width of the access. Enumerated in bytes. Type
285 EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().
287 @param Address The physical address of the access.
289 @param SetBits Points to value to bitwise-OR with the read configuration value.
291 The size of the value is determined by Width.
293 @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value.
294 The size of the value is determined by Width.
297 @retval EFI_SUCCESS The function completed successfully.
299 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
301 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting
302 the operation at this time.
308 IN CONST EFI_PEI_SERVICES
**PeiServices
,
309 IN CONST EFI_PEI_PCI_CFG2_PPI
*This
,
310 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
312 IN CONST VOID
*SetBits
,
313 IN CONST VOID
*ClearBits
318 PciLibAddress
= COMMON_TO_PCILIB_ADDRESS (Address
);
320 if (Width
== EfiPeiPciCfgWidthUint8
) {
321 PciAndThenOr8 (PciLibAddress
, ~(*(UINT8
*)ClearBits
), *((UINT8
*) SetBits
));
322 } else if (Width
== EfiPeiPciCfgWidthUint16
) {
323 PciAndThenOr16 (PciLibAddress
, ~ReadUnaligned16 ((UINT16
*) ClearBits
), ReadUnaligned16 ((UINT16
*) SetBits
));
324 } else if (Width
== EfiPeiPciCfgWidthUint32
) {
325 PciAndThenOr32 (PciLibAddress
, ~ReadUnaligned32 ((UINT32
*) ClearBits
), ReadUnaligned32 ((UINT32
*) SetBits
));
327 return EFI_INVALID_PARAMETER
;
335 PeimInitializePciCfg (
336 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
337 IN EFI_PEI_SERVICES
**PeiServices
342 ASSERT ((**PeiServices
).Hdr
.Revision
>= PEI_SERVICES_REVISION
);
344 (**PeiServices
).PciCfg
= &gPciCfg2Ppi
;
345 Status
= (**PeiServices
).InstallPpi (PeiServices
, &gPciCfg2PpiList
);