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.
14 #include "PciCfgInternal.h"
18 The EFI_PEI_PCI_CFG2_PPI interfaces are used to abstract
19 accesses to PCI controllers behind a PCI root bridge
22 @param Read PCI read services. See the Read() function description.
24 @param Write PCI write services. See the Write() function description.
26 @param Modify PCI read-modify-write services. See the Modify() function description.
28 @param Segment The PCI bus segment which the specified functions will access.
31 GLOBAL_REMOVE_IF_UNREFERENCED
32 EFI_PEI_PCI_CFG2_PPI gPciCfg2Ppi
= {
38 GLOBAL_REMOVE_IF_UNREFERENCED
39 EFI_PEI_PPI_DESCRIPTOR gPciCfg2PpiList
= {
40 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
48 The EFI_PEI_PCI_CFG_PPI interfaces are used to abstract accesses to PCI
49 controllers behind a PCI root bridge controller.
51 @param Read PCI read services. See the Read() function description.
53 @param Write PCI write services. See the Write() function description.
55 @param Modify PCI read-modify-write services. See the Modify() function description.
57 @param Segment The PCI bus segment which the specified functions will access.
60 GLOBAL_REMOVE_IF_UNREFERENCED
61 EFI_PEI_PCI_CFG_PPI gPciCfgPpi
= {
67 GLOBAL_REMOVE_IF_UNREFERENCED
68 EFI_PEI_PPI_DESCRIPTOR gPciCfgPpiList
= {
69 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
70 &gEfiPciCfgPpiInServiceTableGuid
,
76 Convert EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS to PCI_LIB_ADDRESS.
78 @param Address PCI address with
79 EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS format.
81 @return The PCI address with PCI_LIB_ADDRESS format.
85 PciCfgAddressConvert (
86 EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS
*Address
89 if (Address
->ExtendedRegister
== 0) {
90 return PCI_LIB_ADDRESS (Address
->Bus
, Address
->Device
, Address
->Function
, Address
->Register
);
93 return PCI_LIB_ADDRESS (Address
->Bus
, Address
->Device
, Address
->Function
, Address
->ExtendedRegister
);
97 Reads from a given location in the PCI configuration space.
99 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.
101 @param This Pointer to local data for the interface.
103 @param Width The width of the access. Enumerated in bytes.
104 See EFI_PEI_PCI_CFG_PPI_WIDTH above.
106 @param Address The physical address of the access. The format of
107 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.
109 @param Buffer A pointer to the buffer of data..
112 @retval EFI_SUCCESS The function completed successfully.
114 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
116 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this
123 IN CONST EFI_PEI_SERVICES
**PeiServices
,
124 IN CONST EFI_PEI_PCI_CFG2_PPI
*This
,
125 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
132 PciLibAddress
= PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS
*) &Address
);
134 if (Width
== EfiPeiPciCfgWidthUint8
) {
135 *((UINT8
*) Buffer
) = PciRead8 (PciLibAddress
);
136 } else if (Width
== EfiPeiPciCfgWidthUint16
) {
137 *((UINT16
*) Buffer
) = PciRead16 (PciLibAddress
);
138 } else if (Width
== EfiPeiPciCfgWidthUint32
) {
139 *((UINT32
*) Buffer
) = PciRead32 (PciLibAddress
);
141 return EFI_INVALID_PARAMETER
;
148 Write to a given location in the PCI configuration space.
150 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.
152 @param This Pointer to local data for the interface.
154 @param Width The width of the access. Enumerated in bytes.
155 See EFI_PEI_PCI_CFG_PPI_WIDTH above.
157 @param Address The physical address of the access. The format of
158 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.
160 @param Buffer A pointer to the buffer of data..
163 @retval EFI_SUCCESS The function completed successfully.
165 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
167 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this
174 IN CONST EFI_PEI_SERVICES
**PeiServices
,
175 IN CONST EFI_PEI_PCI_CFG2_PPI
*This
,
176 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
183 PciLibAddress
= PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS
*) &Address
);
185 if (Width
== EfiPeiPciCfgWidthUint8
) {
186 PciWrite8 (PciLibAddress
, *((UINT8
*) Buffer
));
187 } else if (Width
== EfiPeiPciCfgWidthUint16
) {
188 PciWrite16 (PciLibAddress
, *((UINT16
*) Buffer
));
189 } else if (Width
== EfiPeiPciCfgWidthUint32
) {
190 PciWrite32 (PciLibAddress
, *((UINT32
*) Buffer
));
192 return EFI_INVALID_PARAMETER
;
200 PCI read-modify-write operation.
202 @param PeiServices An indirect pointer to the PEI Services Table
203 published by the PEI Foundation.
205 @param This Pointer to local data for the interface.
207 @param Width The width of the access. Enumerated in bytes. Type
208 EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().
210 @param Address The physical address of the access.
212 @param SetBits Points to value to bitwise-OR with the read configuration value.
214 The size of the value is determined by Width.
216 @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value.
217 The size of the value is determined by Width.
220 @retval EFI_SUCCESS The function completed successfully.
222 @retval EFI_DEVICE_ERROR There was a problem with the transaction.
224 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting
225 the operation at this time.
231 IN CONST EFI_PEI_SERVICES
**PeiServices
,
232 IN CONST EFI_PEI_PCI_CFG2_PPI
*This
,
233 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
235 IN CONST VOID
*SetBits
,
236 IN CONST VOID
*ClearBits
241 PciLibAddress
= PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS
*) &Address
);
243 if (Width
== EfiPeiPciCfgWidthUint8
) {
244 PciAndThenOr8 (PciLibAddress
, ~(*(UINT8
*)ClearBits
), *((UINT8
*) SetBits
));
245 } else if (Width
== EfiPeiPciCfgWidthUint16
) {
246 PciAndThenOr16 (PciLibAddress
, ~ReadUnaligned16 ((UINT16
*) ClearBits
), ReadUnaligned16 ((UINT16
*) SetBits
));
247 } else if (Width
== EfiPeiPciCfgWidthUint32
) {
248 PciAndThenOr32 (PciLibAddress
, ~ReadUnaligned32 ((UINT32
*) ClearBits
), ReadUnaligned32 ((UINT32
*) SetBits
));
250 return EFI_INVALID_PARAMETER
;
258 PeimInitializePciCfg (
259 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
260 IN EFI_PEI_SERVICES
**PeiServices
265 Status
= EFI_SUCCESS
;
267 if ((**PeiServices
).Hdr
.Revision
< PEI_SERVICES_REVISION
) {
269 // BugBug: Curently, the FrameworkPkg does not define
270 // FRAMEWORK_PEI_SERVICES. So, In order to install
271 // the PeiServices.PciCfg(), we casttype
272 // EFI_PEI_PCI_CFG_PPI to EFI_PEI_PCI_CFG2_PPI.
273 // After defining the FRAMEWORK_PEI_SERVICES. this should
276 // FrameworkPeiServices = (FRAMEWORK_PEI_SERVICES **) PeiServices;
277 // (**FrameworkPeiServices).PciCfg = &mPciCfgPpi;
279 (**PeiServices
).PciCfg
= (EFI_PEI_PCI_CFG2_PPI
*) &gPciCfgPpi
;
281 (**PeiServices
).PciCfg
= &gPciCfg2Ppi
;
284 if (!FeaturePcdGet (PcdPciCfgDisable
)) {
285 Status
= (**PeiServices
).InstallPpi (PeiServices
, &gPciCfgPpiList
);
287 if (!FeaturePcdGet (PcdPciCfg2Disable
)) {
288 Status
= (**PeiServices
).InstallPpi (PeiServices
, &gPciCfg2PpiList
);