]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PciCfg2.c
Update PciCfg2.c to follow strict ANSI C spec.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / PcatSingleSegmentPciCfgPei / PciCfg2.c
CommitLineData
12232778 1/**\r
2\r
3 Copyright (c) 2006 - 2007, Intel Corporation\r
4 All rights reserved. This program and the accompanying materials\r
5 are licensed and made available under the terms and conditions of the BSD License\r
6 which accompanies this distribution. The full text of the license may be found at\r
7 http://opensource.org/licenses/bsd-license.php\r
8\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12**/\r
13\r
14#include "PciCfgInternal.h"\r
15\r
16/**\r
17 @par Ppi Description:\r
18 The EFI_PEI_PCI_CFG2_PPI interfaces are used to abstract\r
19 accesses to PCI controllers behind a PCI root bridge\r
20 controller.\r
21\r
22 @param Read PCI read services. See the Read() function description.\r
23\r
24 @param Write PCI write services. See the Write() function description.\r
25\r
26 @param Modify PCI read-modify-write services. See the Modify() function description.\r
27\r
28 @param Segment The PCI bus segment which the specified functions will access.\r
29\r
30**/\r
31GLOBAL_REMOVE_IF_UNREFERENCED\r
32EFI_PEI_PCI_CFG2_PPI gPciCfg2Ppi = {\r
33 PciCfg2Read,\r
34 PciCfg2Write,\r
35 PciCfg2Modify\r
36};\r
37\r
38GLOBAL_REMOVE_IF_UNREFERENCED\r
39EFI_PEI_PPI_DESCRIPTOR gPciCfg2PpiList = {\r
40 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
41 &gEfiPciCfg2PpiGuid,\r
42 &gPciCfg2Ppi\r
43};\r
44\r
45\r
46/**\r
47 @par Ppi Description:\r
48 The EFI_PEI_PCI_CFG_PPI interfaces are used to abstract accesses to PCI\r
49 controllers behind a PCI root bridge controller.\r
50\r
51 @param Read PCI read services. See the Read() function description.\r
52\r
53 @param Write PCI write services. See the Write() function description.\r
54\r
55 @param Modify PCI read-modify-write services. See the Modify() function description.\r
56\r
57 @param Segment The PCI bus segment which the specified functions will access.\r
58\r
59**/\r
60GLOBAL_REMOVE_IF_UNREFERENCED\r
61EFI_PEI_PCI_CFG_PPI gPciCfgPpi = {\r
62 PciCfgRead,\r
63 PciCfgWrite,\r
64 PciCfgModify\r
65};\r
66\r
67GLOBAL_REMOVE_IF_UNREFERENCED\r
68EFI_PEI_PPI_DESCRIPTOR gPciCfgPpiList = {\r
69 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
70 &gEfiPciCfgPpiInServiceTableGuid,\r
71 &gPciCfgPpi\r
72};\r
73\r
d8b61daa 74\r
75/**\r
76 Convert EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS to PCI_LIB_ADDRESS.\r
77\r
78 @param Address PCI address with\r
79 EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS format.\r
80 \r
81 @return The PCI address with PCI_LIB_ADDRESS format.\r
82 \r
83**/\r
84UINTN\r
85PciCfgAddressConvert (\r
86 EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *Address\r
87 )\r
88{\r
89 if (Address->ExtendedRegister == 0) {\r
90 return PCI_LIB_ADDRESS (Address->Bus, Address->Device, Address->Function, Address->Register);\r
91 }\r
92\r
93 return PCI_LIB_ADDRESS (Address->Bus, Address->Device, Address->Function, Address->ExtendedRegister);\r
94}\r
95\r
12232778 96/**\r
97 Reads from a given location in the PCI configuration space.\r
98\r
99 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
100\r
101 @param This Pointer to local data for the interface.\r
102\r
103 @param Width The width of the access. Enumerated in bytes.\r
104 See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
105\r
106 @param Address The physical address of the access. The format of\r
107 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
108\r
109 @param Buffer A pointer to the buffer of data..\r
110\r
111\r
112 @retval EFI_SUCCESS The function completed successfully.\r
113\r
114 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
115\r
116 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this\r
117 time.\r
118\r
119**/\r
120EFI_STATUS\r
121EFIAPI \r
122PciCfg2Read (\r
123 IN CONST EFI_PEI_SERVICES **PeiServices,\r
124 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
125 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
126 IN UINT64 Address,\r
127 IN OUT VOID *Buffer\r
128)\r
129{\r
130 UINTN PciLibAddress;\r
131\r
d8b61daa 132 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);\r
12232778 133\r
134 if (Width == EfiPeiPciCfgWidthUint8) {\r
135 *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);\r
136 } else if (Width == EfiPeiPciCfgWidthUint16) {\r
137 *((UINT16 *) Buffer) = PciRead16 (PciLibAddress);\r
138 } else if (Width == EfiPeiPciCfgWidthUint32) {\r
139 *((UINT32 *) Buffer) = PciRead32 (PciLibAddress);\r
140 } else {\r
141 return EFI_INVALID_PARAMETER;\r
142 }\r
143\r
144 return EFI_SUCCESS;\r
145}\r
146\r
147/**\r
148 Write to a given location in the PCI configuration space.\r
149\r
150 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
151\r
152 @param This Pointer to local data for the interface.\r
153\r
154 @param Width The width of the access. Enumerated in bytes.\r
155 See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
156\r
157 @param Address The physical address of the access. The format of\r
158 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
159\r
160 @param Buffer A pointer to the buffer of data..\r
161\r
162\r
163 @retval EFI_SUCCESS The function completed successfully.\r
164\r
165 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
166\r
167 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this\r
168 time.\r
169\r
170**/\r
171EFI_STATUS\r
172EFIAPI \r
173PciCfg2Write (\r
174 IN CONST EFI_PEI_SERVICES **PeiServices,\r
175 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
176 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
177 IN UINT64 Address,\r
178 IN OUT VOID *Buffer\r
179)\r
180{\r
181 UINTN PciLibAddress;\r
182\r
d8b61daa 183 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);\r
12232778 184\r
185 if (Width == EfiPeiPciCfgWidthUint8) {\r
186 PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));\r
187 } else if (Width == EfiPeiPciCfgWidthUint16) {\r
188 PciWrite16 (PciLibAddress, *((UINT16 *) Buffer));\r
189 } else if (Width == EfiPeiPciCfgWidthUint32) {\r
190 PciWrite32 (PciLibAddress, *((UINT32 *) Buffer));\r
191 } else {\r
192 return EFI_INVALID_PARAMETER;\r
193 }\r
194\r
195 return EFI_SUCCESS;\r
196}\r
197\r
198\r
199/**\r
200 PCI read-modify-write operation.\r
201\r
202 @param PeiServices An indirect pointer to the PEI Services Table\r
203 published by the PEI Foundation.\r
204\r
205 @param This Pointer to local data for the interface.\r
206\r
207 @param Width The width of the access. Enumerated in bytes. Type\r
208 EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().\r
209\r
210 @param Address The physical address of the access.\r
211\r
212 @param SetBits Points to value to bitwise-OR with the read configuration value.\r
213\r
214 The size of the value is determined by Width.\r
215\r
216 @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value.\r
217 The size of the value is determined by Width.\r
218\r
219\r
220 @retval EFI_SUCCESS The function completed successfully.\r
221\r
222 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
223\r
224 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting\r
225 the operation at this time.\r
226\r
227**/\r
228EFI_STATUS\r
229EFIAPI \r
230PciCfg2Modify (\r
231 IN CONST EFI_PEI_SERVICES **PeiServices,\r
232 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
233 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
234 IN UINT64 Address,\r
235 IN CONST VOID *SetBits,\r
236 IN CONST VOID *ClearBits\r
237)\r
238{\r
702887db 239 UINTN PciLibAddress;\r
240 UINT16 ClearValue16;\r
241 UINT16 SetValue16;\r
242 UINT32 ClearValue32;\r
243 UINT32 SetValue32;\r
12232778 244\r
d8b61daa 245 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);\r
12232778 246\r
247 if (Width == EfiPeiPciCfgWidthUint8) {\r
702887db 248 PciAndThenOr8 (PciLibAddress, (UINT8) (~(*(UINT8 *) ClearBits)), *((UINT8 *) SetBits));\r
12232778 249 } else if (Width == EfiPeiPciCfgWidthUint16) {\r
702887db 250 ClearValue16 = (UINT16) (~ReadUnaligned16 ((UINT16 *) ClearBits));\r
251 SetValue16 = ReadUnaligned16 ((UINT16 *) SetBits);\r
252 PciAndThenOr16 (PciLibAddress, ClearValue16, SetValue16);\r
12232778 253 } else if (Width == EfiPeiPciCfgWidthUint32) {\r
702887db 254 ClearValue32 = (UINT32) (~ReadUnaligned32 ((UINT32 *) ClearBits));\r
255 SetValue32 = ReadUnaligned32 ((UINT32 *) SetBits);\r
256 PciAndThenOr32 (PciLibAddress, ClearValue32, SetValue32);\r
12232778 257 } else {\r
258 return EFI_INVALID_PARAMETER;\r
259 }\r
260 return EFI_SUCCESS;\r
261}\r
262\r
263\r
264EFI_STATUS\r
265EFIAPI\r
266PeimInitializePciCfg (\r
267 IN EFI_FFS_FILE_HEADER *FfsHeader,\r
268 IN EFI_PEI_SERVICES **PeiServices\r
269 )\r
270{\r
271 EFI_STATUS Status;\r
272\r
273 Status = EFI_SUCCESS;\r
274\r
275 if ((**PeiServices).Hdr.Revision < PEI_SERVICES_REVISION) {\r
276 //\r
277 // BugBug: Curently, the FrameworkPkg does not define\r
278 // FRAMEWORK_PEI_SERVICES. So, In order to install \r
279 // the PeiServices.PciCfg(), we casttype \r
280 // EFI_PEI_PCI_CFG_PPI to EFI_PEI_PCI_CFG2_PPI.\r
281 // After defining the FRAMEWORK_PEI_SERVICES. this should\r
282 // be updated as:\r
283 // \r
284 // FrameworkPeiServices = (FRAMEWORK_PEI_SERVICES **) PeiServices;\r
285 // (**FrameworkPeiServices).PciCfg = &mPciCfgPpi;\r
286 // \r
287 (**PeiServices).PciCfg = (EFI_PEI_PCI_CFG2_PPI *) &gPciCfgPpi;\r
288 } else {\r
289 (**PeiServices).PciCfg = &gPciCfg2Ppi;\r
290 }\r
291 \r
292 if (!FeaturePcdGet (PcdPciCfgDisable)) {\r
293 Status = (**PeiServices).InstallPpi (PeiServices, &gPciCfgPpiList);\r
294 } \r
295 if (!FeaturePcdGet (PcdPciCfg2Disable)) {\r
296 Status = (**PeiServices).InstallPpi (PeiServices, &gPciCfg2PpiList);\r
297 }\r
298\r
299 return Status;\r
300}\r