]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PciCfg2.c
1. EDK_RELEASE_VERSION removed;
[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
8191cd5e
LG
137 if ((PciLibAddress & 0x01) == 0) {\r
138 //\r
139 // Aligned Pci address access\r
140 //\r
141 WriteUnaligned16 (((UINT16 *) Buffer), PciRead16 (PciLibAddress));\r
142 } else {\r
143 //\r
144 // Unaligned Pci address access, break up the request into byte by byte.\r
145 //\r
146 *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);\r
147 *((UINT8 *) Buffer + 1) = PciRead8 (PciLibAddress + 1);\r
148 }\r
12232778 149 } else if (Width == EfiPeiPciCfgWidthUint32) {\r
8191cd5e
LG
150 if ((PciLibAddress & 0x03) == 0) {\r
151 //\r
152 // Aligned Pci address access\r
153 //\r
154 WriteUnaligned32 (((UINT32 *) Buffer), PciRead32 (PciLibAddress));\r
155 } else if ((PciLibAddress & 0x01) == 0) {\r
156 //\r
157 // Unaligned Pci address access, break up the request into word by word.\r
158 //\r
159 WriteUnaligned16 (((UINT16 *) Buffer), PciRead16 (PciLibAddress));\r
160 WriteUnaligned16 (((UINT16 *) Buffer + 1), PciRead16 (PciLibAddress + 2));\r
161 } else {\r
162 //\r
163 // Unaligned Pci address access, break up the request into byte by byte.\r
164 //\r
165 *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);\r
166 *((UINT8 *) Buffer + 1) = PciRead8 (PciLibAddress + 1);\r
167 *((UINT8 *) Buffer + 2) = PciRead8 (PciLibAddress + 2);\r
168 *((UINT8 *) Buffer + 3) = PciRead8 (PciLibAddress + 3);\r
169 }\r
12232778 170 } else {\r
171 return EFI_INVALID_PARAMETER;\r
172 }\r
173\r
174 return EFI_SUCCESS;\r
175}\r
176\r
177/**\r
178 Write to a given location in the PCI configuration space.\r
179\r
180 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
181\r
182 @param This Pointer to local data for the interface.\r
183\r
184 @param Width The width of the access. Enumerated in bytes.\r
185 See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
186\r
187 @param Address The physical address of the access. The format of\r
188 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
189\r
190 @param Buffer A pointer to the buffer of data..\r
191\r
192\r
193 @retval EFI_SUCCESS The function completed successfully.\r
194\r
195 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
196\r
197 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this\r
198 time.\r
199\r
200**/\r
201EFI_STATUS\r
202EFIAPI \r
203PciCfg2Write (\r
204 IN CONST EFI_PEI_SERVICES **PeiServices,\r
205 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
206 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
207 IN UINT64 Address,\r
208 IN OUT VOID *Buffer\r
209)\r
210{\r
211 UINTN PciLibAddress;\r
212\r
d8b61daa 213 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);\r
12232778 214\r
215 if (Width == EfiPeiPciCfgWidthUint8) {\r
216 PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));\r
217 } else if (Width == EfiPeiPciCfgWidthUint16) {\r
8191cd5e
LG
218 if ((PciLibAddress & 0x01) == 0) {\r
219 //\r
220 // Aligned Pci address access\r
221 //\r
222 PciWrite16 (PciLibAddress, ReadUnaligned16 ((UINT16 *) Buffer));\r
223 } else {\r
224 //\r
225 // Unaligned Pci address access, break up the request into byte by byte.\r
226 //\r
227 PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));\r
228 PciWrite8 (PciLibAddress + 1, *((UINT8 *) Buffer + 1)); \r
229 }\r
12232778 230 } else if (Width == EfiPeiPciCfgWidthUint32) {\r
8191cd5e
LG
231 if ((PciLibAddress & 0x03) == 0) {\r
232 //\r
233 // Aligned Pci address access\r
234 //\r
235 PciWrite32 (PciLibAddress, ReadUnaligned32 ((UINT32 *) Buffer));\r
236 } else if ((PciLibAddress & 0x01) == 0) {\r
237 //\r
238 // Unaligned Pci address access, break up the request into word by word.\r
239 //\r
240 PciWrite16 (PciLibAddress, ReadUnaligned16 ((UINT16 *) Buffer));\r
241 PciWrite16 (PciLibAddress + 2, ReadUnaligned16 ((UINT16 *) Buffer + 1));\r
242 } else {\r
243 //\r
244 // Unaligned Pci address access, break up the request into byte by byte.\r
245 //\r
246 PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));\r
247 PciWrite8 (PciLibAddress + 1, *((UINT8 *) Buffer + 1)); \r
248 PciWrite8 (PciLibAddress + 2, *((UINT8 *) Buffer + 2)); \r
249 PciWrite8 (PciLibAddress + 3, *((UINT8 *) Buffer + 3)); \r
250 }\r
12232778 251 } else {\r
252 return EFI_INVALID_PARAMETER;\r
253 }\r
254\r
255 return EFI_SUCCESS;\r
256}\r
257\r
258\r
259/**\r
260 PCI read-modify-write operation.\r
261\r
262 @param PeiServices An indirect pointer to the PEI Services Table\r
263 published by the PEI Foundation.\r
264\r
265 @param This Pointer to local data for the interface.\r
266\r
267 @param Width The width of the access. Enumerated in bytes. Type\r
268 EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().\r
269\r
270 @param Address The physical address of the access.\r
271\r
272 @param SetBits Points to value to bitwise-OR with the read configuration value.\r
273\r
274 The size of the value is determined by Width.\r
275\r
276 @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value.\r
277 The size of the value is determined by Width.\r
278\r
279\r
280 @retval EFI_SUCCESS The function completed successfully.\r
281\r
282 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
283\r
284 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting\r
285 the operation at this time.\r
286\r
287**/\r
288EFI_STATUS\r
289EFIAPI \r
290PciCfg2Modify (\r
291 IN CONST EFI_PEI_SERVICES **PeiServices,\r
292 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
293 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
294 IN UINT64 Address,\r
01edaf2a 295 IN VOID *SetBits,\r
296 IN VOID *ClearBits\r
12232778 297)\r
298{\r
702887db 299 UINTN PciLibAddress;\r
300 UINT16 ClearValue16;\r
301 UINT16 SetValue16;\r
302 UINT32 ClearValue32;\r
303 UINT32 SetValue32;\r
12232778 304\r
d8b61daa 305 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);\r
12232778 306\r
307 if (Width == EfiPeiPciCfgWidthUint8) {\r
702887db 308 PciAndThenOr8 (PciLibAddress, (UINT8) (~(*(UINT8 *) ClearBits)), *((UINT8 *) SetBits));\r
12232778 309 } else if (Width == EfiPeiPciCfgWidthUint16) {\r
8191cd5e
LG
310 if ((PciLibAddress & 0x01) == 0) {\r
311 //\r
312 // Aligned Pci address access\r
313 //\r
314 ClearValue16 = (UINT16) (~ReadUnaligned16 ((UINT16 *) ClearBits));\r
315 SetValue16 = ReadUnaligned16 ((UINT16 *) SetBits);\r
316 PciAndThenOr16 (PciLibAddress, ClearValue16, SetValue16);\r
317 } else {\r
318 //\r
319 // Unaligned Pci address access, break up the request into byte by byte.\r
320 //\r
321 PciAndThenOr8 (PciLibAddress, (UINT8) (~(*(UINT8 *) ClearBits)), *((UINT8 *) SetBits));\r
322 PciAndThenOr8 (PciLibAddress + 1, (UINT8) (~(*((UINT8 *) ClearBits + 1))), *((UINT8 *) SetBits + 1));\r
323 }\r
12232778 324 } else if (Width == EfiPeiPciCfgWidthUint32) {\r
8191cd5e
LG
325 if ((PciLibAddress & 0x03) == 0) {\r
326 //\r
327 // Aligned Pci address access\r
328 //\r
329 ClearValue32 = (UINT32) (~ReadUnaligned32 ((UINT32 *) ClearBits));\r
330 SetValue32 = ReadUnaligned32 ((UINT32 *) SetBits);\r
331 PciAndThenOr32 (PciLibAddress, ClearValue32, SetValue32);\r
332 } else if ((PciLibAddress & 0x01) == 0) {\r
333 //\r
334 // Unaligned Pci address access, break up the request into word by word.\r
335 //\r
336 ClearValue16 = (UINT16) (~ReadUnaligned16 ((UINT16 *) ClearBits));\r
337 SetValue16 = ReadUnaligned16 ((UINT16 *) SetBits);\r
338 PciAndThenOr16 (PciLibAddress, ClearValue16, SetValue16);\r
339\r
340 ClearValue16 = (UINT16) (~ReadUnaligned16 ((UINT16 *) ClearBits + 1));\r
341 SetValue16 = ReadUnaligned16 ((UINT16 *) SetBits + 1);\r
342 PciAndThenOr16 (PciLibAddress + 2, ClearValue16, SetValue16);\r
343 } else {\r
344 //\r
345 // Unaligned Pci address access, break up the request into byte by byte.\r
346 //\r
347 PciAndThenOr8 (PciLibAddress, (UINT8) (~(*(UINT8 *) ClearBits)), *((UINT8 *) SetBits));\r
348 PciAndThenOr8 (PciLibAddress + 1, (UINT8) (~(*((UINT8 *) ClearBits + 1))), *((UINT8 *) SetBits + 1));\r
349 PciAndThenOr8 (PciLibAddress + 2, (UINT8) (~(*((UINT8 *) ClearBits + 2))), *((UINT8 *) SetBits + 2));\r
350 PciAndThenOr8 (PciLibAddress + 3, (UINT8) (~(*((UINT8 *) ClearBits + 3))), *((UINT8 *) SetBits + 3));\r
351 }\r
12232778 352 } else {\r
353 return EFI_INVALID_PARAMETER;\r
354 }\r
355 return EFI_SUCCESS;\r
356}\r
357\r
bcd70414 358/**\r
359 Module's entry function. \r
360 This routine will install EFI_PEI_PCI_CFG2_PPI or EFI_PEI_PCI_CFG_PPI\r
361 according to PeiServices's version.\r
362 \r
8bd22b8a
LG
363 @param FileHandle Handle of the file being invoked.\r
364 @param PeiServices Describes the list of possible PEI Services.\r
365\r
bcd70414 366 @return Whether success to install service\r
367**/\r
12232778 368EFI_STATUS\r
369EFIAPI\r
370PeimInitializePciCfg (\r
8bd22b8a
LG
371 IN EFI_PEI_FILE_HANDLE FileHandle,\r
372 IN CONST EFI_PEI_SERVICES **PeiServices\r
12232778 373 )\r
374{\r
375 EFI_STATUS Status;\r
376\r
377 Status = EFI_SUCCESS;\r
378\r
379 if ((**PeiServices).Hdr.Revision < PEI_SERVICES_REVISION) {\r
380 //\r
381 // BugBug: Curently, the FrameworkPkg does not define\r
382 // FRAMEWORK_PEI_SERVICES. So, In order to install \r
383 // the PeiServices.PciCfg(), we casttype \r
384 // EFI_PEI_PCI_CFG_PPI to EFI_PEI_PCI_CFG2_PPI.\r
385 // After defining the FRAMEWORK_PEI_SERVICES. this should\r
386 // be updated as:\r
387 // \r
388 // FrameworkPeiServices = (FRAMEWORK_PEI_SERVICES **) PeiServices;\r
389 // (**FrameworkPeiServices).PciCfg = &mPciCfgPpi;\r
390 // \r
8bd22b8a 391 (**(EFI_PEI_SERVICES**)PeiServices).PciCfg = (EFI_PEI_PCI_CFG2_PPI *) &gPciCfgPpi;\r
12232778 392 } else {\r
8bd22b8a 393 (**(EFI_PEI_SERVICES**)PeiServices).PciCfg = &gPciCfg2Ppi;\r
12232778 394 }\r
395 \r
396 if (!FeaturePcdGet (PcdPciCfgDisable)) {\r
8bd22b8a 397 Status = (**PeiServices).InstallPpi (PeiServices, &gPciCfgPpiList);\r
12232778 398 } \r
399 if (!FeaturePcdGet (PcdPciCfg2Disable)) {\r
8bd22b8a 400 Status = (**PeiServices).InstallPpi (PeiServices, &gPciCfg2PpiList);\r
12232778 401 }\r
402\r
403 return Status;\r
404}\r
bcd70414 405\r