]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/PciCfg2ToPciCfgThunk/PciCfg2ToPciCfgThunk.c
Fix a bug to locate the correct PPI.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / PciCfg2ToPciCfgThunk / PciCfg2ToPciCfgThunk.c
CommitLineData
c98d6f47 1/** @file\r
0004d140 2 Module produces PciCfgPpi2 on top of PciCfgPpi. It also updates the \r
3 PciCfg2Ppi pointer in the EFI_PEI_SERVICES upon a installation of\r
4 EcpPeiPciCfgPpi. \r
5\r
6 EcpPeiPciCfgPpi is installed by a framework module which\r
7 produce PciCfgPpi originally. Such framework module is updated based on the \r
8 following rule to install EcpPeiPciCfgPpi instead of updating the PciCfg pointer\r
9 in the Framework PeiServicesTable: \r
10 \r
11 Search pattern:\r
12 PeiServices->PciCfg = <*>;\r
13 Replace pattern:\r
14 {\r
15 static EFI_PEI_PPI_DESCRIPTOR gEcpPeiPciCfgPpiList = {\r
16 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
17 &gEcpPeiPciCfgPpiGuid,\r
18 <*>\r
19 };\r
20 (**PeiServices).InstallPpi (PeiServices, gEcpPeiPciCfgPpiList);\r
21 }\r
22 \r
23 In addition, the PeiServicesTable definition in PeiApi.h is updated to\r
24 \r
25 struct _EFI_PEI_SERVICES {\r
26 EFI_TABLE_HEADER Hdr;\r
27 ...\r
28 \r
29 //\r
30 // Pointer to PPI interface\r
31 //\r
32 if (PI_SPECIFICATION_VERSION < 0x00010000)\r
33 \r
34 PEI_CPU_IO_PPI *CpuIo;\r
35 ECP_PEI_PCI_CFG_PPI *PciCfg; //Changed.\r
36 else\r
37 ...\r
38 endif\r
39 \r
40 };\r
41 \r
42 This change enable the detection of code segment which invokes PeiServices->PciCfg->Modify.\r
43 Such code causes a build break as ECP_PEI_PCI_CFG_PPI does not has "Modify" field. \r
44 This should be updated to a call to PeiLibPciCfgModify as shown below:\r
45 \r
46 Search pattern:\r
47 *->Modify(<*>); \r
48 Replace pattern:\r
49 PeiLibPciCfgModify(<*>);\r
50\r
51\r
c98d6f47 52\r
53PIWG's PI specification replaces Inte's EFI Specification 1.10.\r
54EFI_PEI_PCI_CFG_PPI defined in Inte's EFI Specification 1.10 is replaced by\r
55EFI_PEI_PCI_CFG2_PPI in PI 1.0.\r
56This module produces PciCfgPpi on top of PciCfgPpi2. This module is used on platform when both of\r
57these two conditions are true:\r
581) Framework module present that produces PCI CFG PPI AND\r
592) PI module that produces PCI CFG2 is not present\r
4259256b 60\r
61Copyright (c) 2006 - 2008 Intel Corporation. <BR>\r
62All rights reserved. This program and the accompanying materials\r
63are licensed and made available under the terms and conditions of the BSD License\r
64which accompanies this distribution. The full text of the license may be found at\r
65http://opensource.org/licenses/bsd-license.php\r
66\r
67THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
68WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
4259256b 69\r
c98d6f47 70**/\r
4259256b 71\r
72#include <PiPei.h>\r
73#include <Ppi/PciCfg.h>\r
74#include <Ppi/PciCfg2.h>\r
75#include <Ppi/EcpPciCfg.h>\r
76#include <Library/DebugLib.h>\r
77\r
78//\r
c98d6f47 79// Function Prototypes \r
4259256b 80//\r
c98d6f47 81\r
82/**\r
83 Notification service to be called when gEcpPeiPciCfgPpiGuid is installed.\r
84\r
85 @param PeiServices Indirect reference to the PEI Services Table.\r
86 @param NotifyDescriptor Address of the notification descriptor data structure. Type\r
87 EFI_PEI_NOTIFY_DESCRIPTOR is defined above.\r
88 @param Ppi Address of the PPI that was installed.\r
89\r
90 @retval EFI_STATUS This function will install a PPI to PPI database. The status\r
91 code will be the code for (*PeiServices)->InstallPpi.\r
92\r
93**/\r
4259256b 94EFI_STATUS\r
95EFIAPI\r
96EcpPciCfgPpiNotifyCallback (\r
97 IN EFI_PEI_SERVICES **PeiServices,\r
98 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
99 IN VOID *Ppi\r
100 );\r
101\r
102//\r
103// Function Prototypes\r
104//\r
c98d6f47 105/**\r
106 Reads from a given location in the PCI configuration space.\r
107\r
108 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
109\r
110 @param This Pointer to local data for the interface.\r
111\r
112 @param Width The width of the access. Enumerated in bytes.\r
113 See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
114\r
115 @param Address The physical address of the access. The format of\r
116 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
117\r
118 @param Buffer A pointer to the buffer of data..\r
119\r
120\r
121 @retval EFI_SUCCESS The function completed successfully.\r
122\r
123 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
124\r
125 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this\r
126 time.\r
127\r
128**/\r
4259256b 129EFI_STATUS\r
130EFIAPI\r
131PciCfg2Read (\r
132 IN CONST EFI_PEI_SERVICES **PeiServices,\r
133 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
134 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
135 IN UINT64 Address,\r
136 IN OUT VOID *Buffer\r
137 );\r
138\r
c98d6f47 139/**\r
140 Write to a given location in the PCI configuration space.\r
141\r
142 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
143\r
144 @param This Pointer to local data for the interface.\r
145\r
146 @param Width The width of the access. Enumerated in bytes.\r
147 See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
148\r
149 @param Address The physical address of the access. The format of\r
150 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
151\r
152 @param Buffer A pointer to the buffer of data..\r
153\r
154\r
155 @retval EFI_SUCCESS The function completed successfully.\r
156\r
157 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
158\r
159 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this\r
160 time.\r
161\r
162**/\r
4259256b 163EFI_STATUS\r
164EFIAPI\r
165PciCfg2Write (\r
166 IN CONST EFI_PEI_SERVICES **PeiServices,\r
167 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
168 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
169 IN UINT64 Address,\r
170 IN OUT VOID *Buffer\r
171 );\r
172\r
c98d6f47 173/**\r
174 PCI read-modify-write operation.\r
175\r
176 @param PeiServices An indirect pointer to the PEI Services Table\r
177 published by the PEI Foundation.\r
178\r
179 @param This Pointer to local data for the interface.\r
180\r
181 @param Width The width of the access. Enumerated in bytes. Type\r
182 EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().\r
183\r
184 @param Address The physical address of the access.\r
185\r
186 @param SetBits Points to value to bitwise-OR with the read configuration value.\r
187 The size of the value is determined by Width.\r
188\r
189 @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value.\r
190 The size of the value is determined by Width.\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\r
198 the operation at this time.\r
199\r
200**/\r
4259256b 201EFI_STATUS\r
202EFIAPI\r
203PciCfg2Modify (\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 CONST VOID *SetBits,\r
209 IN CONST VOID *ClearBits\r
210 );\r
211\r
212//\r
213// Module globals\r
214//\r
215EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnEcpPciCfgList = {\r
216 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
217 &gEcpPeiPciCfgPpiGuid,\r
218 EcpPciCfgPpiNotifyCallback \r
219};\r
220\r
221EFI_PEI_PCI_CFG2_PPI mPciCfg2Ppi = {\r
222 PciCfg2Read,\r
223 PciCfg2Write,\r
224 PciCfg2Modify,\r
225 0\r
226};\r
227\r
228EFI_PEI_PPI_DESCRIPTOR mPpiListPciCfg2 = {\r
229 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
230 &gEfiPciCfg2PpiGuid,\r
231 &mPciCfg2Ppi\r
232};\r
233\r
234\r
c98d6f47 235/**\r
4259256b 236\r
c98d6f47 237 Standard PEIM entry point.\r
4259256b 238\r
c98d6f47 239 @param FfsHeadher The FFS file header\r
240 @param PeiServices General purpose services available to every PEIM.\r
4259256b 241\r
4259256b 242\r
c98d6f47 243 @retval EFI_SUCCESS if the interface could be successfully\r
244 installed\r
4259256b 245\r
246--*/\r
c98d6f47 247EFI_STATUS\r
248EFIAPI\r
249PeimInitializePciCfg2 (\r
250 IN EFI_FFS_FILE_HEADER *FfsHeader,\r
251 IN CONST EFI_PEI_SERVICES **PeiServices\r
252 )\r
4259256b 253{\r
254 EFI_STATUS Status;\r
c98d6f47 255 VOID *Ppi;\r
256\r
257 //\r
258 // Make sure no other module has install the first instance of gEfiPciCfg2PpiGuid.\r
259 //\r
260 Status = (*PeiServices)->LocatePpi (PeiServices, &gEfiPciCfg2PpiGuid, 0, NULL, &Ppi);\r
261 ASSERT (Status == EFI_NOT_FOUND);\r
4259256b 262\r
263 //\r
264 // Register a notification for ECP PCI CFG PPI\r
265 //\r
266 Status = (*PeiServices)->NotifyPpi (PeiServices, &mNotifyOnEcpPciCfgList);\r
267 ASSERT_EFI_ERROR (Status);\r
268 return Status;\r
269}\r
270\r
c98d6f47 271\r
272/**\r
273 Notification service to be called when gEcpPeiPciCfgPpiGuid is installed.\r
274\r
275 @param PeiServices Indirect reference to the PEI Services Table.\r
276 @param NotifyDescriptor Address of the notification descriptor data structure. Type\r
277 EFI_PEI_NOTIFY_DESCRIPTOR is defined above.\r
278 @param Ppi Address of the PPI that was installed.\r
279\r
280 @retval EFI_STATUS This function will install a PPI to PPI database. The status\r
281 code will be the code for (*PeiServices)->InstallPpi.\r
282\r
283**/\r
4259256b 284EFI_STATUS\r
285EFIAPI\r
286EcpPciCfgPpiNotifyCallback (\r
287 IN EFI_PEI_SERVICES **PeiServices,\r
288 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
289 IN VOID *Ppi\r
290 )\r
291{\r
292 //\r
293 // When ECP PCI CFG PPI is installed, publish the PCI CFG2 PPI in the \r
294 // PEI Services Table and the PPI database\r
295 //\r
296 (*PeiServices)->PciCfg = &mPciCfg2Ppi;\r
297 return (*PeiServices)->InstallPpi ((CONST EFI_PEI_SERVICES **)PeiServices, &mPpiListPciCfg2);\r
298}\r
299\r
c98d6f47 300/**\r
301 Reads from a given location in the PCI configuration space.\r
302\r
303 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
304\r
305 @param This Pointer to local data for the interface.\r
306\r
307 @param Width The width of the access. Enumerated in bytes.\r
308 See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
309\r
310 @param Address The physical address of the access. The format of\r
311 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
312\r
313 @param Buffer A pointer to the buffer of data..\r
314\r
315\r
316 @retval EFI_SUCCESS The function completed successfully.\r
317\r
318 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
319\r
320 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this\r
321 time.\r
322\r
323**/\r
4259256b 324EFI_STATUS\r
325EFIAPI\r
326PciCfg2Read (\r
327 IN CONST EFI_PEI_SERVICES **PeiServices,\r
328 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
329 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
330 IN UINT64 Address,\r
331 IN OUT VOID *Buffer\r
332 )\r
333{\r
334 EFI_STATUS Status;\r
335 EFI_PEI_PCI_CFG_PPI *PciCfg;\r
336\r
337 Status = (*PeiServices)->LocatePpi (\r
338 PeiServices,\r
339 &gEcpPeiPciCfgPpiGuid,\r
340 0,\r
341 NULL,\r
342 (VOID **)&PciCfg\r
343 );\r
344 ASSERT_EFI_ERROR (Status);\r
345\r
346 return PciCfg->Read ((EFI_PEI_SERVICES **)PeiServices, PciCfg, Width, Address, Buffer);\r
347}\r
348\r
c98d6f47 349/**\r
350 Write to a given location in the PCI configuration space.\r
351\r
352 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
353\r
354 @param This Pointer to local data for the interface.\r
355\r
356 @param Width The width of the access. Enumerated in bytes.\r
357 See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
358\r
359 @param Address The physical address of the access. The format of\r
360 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
361\r
362 @param Buffer A pointer to the buffer of data..\r
363\r
364\r
365 @retval EFI_SUCCESS The function completed successfully.\r
366\r
367 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
368\r
369 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this\r
370 time.\r
371\r
372**/\r
4259256b 373EFI_STATUS\r
374EFIAPI\r
375PciCfg2Write (\r
376 IN CONST EFI_PEI_SERVICES **PeiServices,\r
377 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
378 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
379 IN UINT64 Address,\r
380 IN OUT VOID *Buffer\r
381 )\r
382{\r
383 EFI_STATUS Status;\r
384 EFI_PEI_PCI_CFG_PPI *PciCfg;\r
385\r
386 Status = (*PeiServices)->LocatePpi (\r
387 PeiServices,\r
388 &gEcpPeiPciCfgPpiGuid,\r
389 0,\r
390 NULL,\r
391 (VOID **)&PciCfg\r
392 );\r
393 ASSERT_EFI_ERROR (Status);\r
394\r
395 return PciCfg->Write ((EFI_PEI_SERVICES **)PeiServices, PciCfg, Width, Address, Buffer);\r
396}\r
397\r
c98d6f47 398/**\r
399 PCI read-modify-write operation.\r
400\r
401 @param PeiServices An indirect pointer to the PEI Services Table\r
402 published by the PEI Foundation.\r
403\r
404 @param This Pointer to local data for the interface.\r
405\r
406 @param Width The width of the access. Enumerated in bytes. Type\r
407 EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().\r
408\r
409 @param Address The physical address of the access.\r
410\r
411 @param SetBits Points to value to bitwise-OR with the read configuration value.\r
412 The size of the value is determined by Width.\r
413\r
414 @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value.\r
415 The size of the value is determined by Width.\r
416\r
417\r
418 @retval EFI_SUCCESS The function completed successfully.\r
419\r
420 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
421\r
422 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting\r
423 the operation at this time.\r
424\r
425**/\r
4259256b 426EFI_STATUS\r
427EFIAPI\r
428PciCfg2Modify (\r
429 IN CONST EFI_PEI_SERVICES **PeiServices,\r
430 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
431 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
432 IN UINT64 Address,\r
0e667e82 433 IN VOID *SetBits,\r
434 IN VOID *ClearBits\r
4259256b 435 )\r
436{\r
437 EFI_STATUS Status;\r
438 EFI_PEI_PCI_CFG_PPI *PciCfg;\r
439\r
440 Status = (*PeiServices)->LocatePpi (\r
441 PeiServices,\r
c30050f5 442 &gEfiPciCfgPpiInServiceTableGuid,\r
4259256b 443 0,\r
444 NULL,\r
445 (VOID **)&PciCfg\r
446 );\r
447 ASSERT_EFI_ERROR (Status);\r
448\r
449 return PciCfg->Modify ((EFI_PEI_SERVICES **)PeiServices, PciCfg, Width, Address, *(UINTN *)SetBits, *(UINTN *)ClearBits);\r
450}\r