]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/PciCfg2OnPciCfgThunk/PciCfg2OnPciCfgThunk.c
Free the buffer allocated by GetSectionFromAnyFv() when exit, and add Error Status...
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / PciCfg2OnPciCfgThunk / PciCfg2OnPciCfgThunk.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
584d5652
HT
61Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
62This program and the accompanying materials\r
4259256b 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
26a76fbc 142 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
c98d6f47 143\r
26a76fbc 144 @param This Pointer to local data for the interface.\r
c98d6f47 145\r
26a76fbc
LG
146 @param Width The width of the access. Enumerated in bytes.\r
147 See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
c98d6f47 148\r
26a76fbc
LG
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
c98d6f47 151\r
26a76fbc 152 @param Buffer A pointer to the buffer of data..\r
c98d6f47 153\r
154\r
26a76fbc 155 @retval EFI_SUCCESS The function completed successfully.\r
c98d6f47 156\r
26a76fbc 157 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
c98d6f47 158\r
26a76fbc 159 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this time.\r
c98d6f47 160\r
161**/\r
4259256b 162EFI_STATUS\r
163EFIAPI\r
164PciCfg2Write (\r
165 IN CONST EFI_PEI_SERVICES **PeiServices,\r
166 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
167 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
168 IN UINT64 Address,\r
169 IN OUT VOID *Buffer\r
170 );\r
171\r
c98d6f47 172/**\r
173 PCI read-modify-write operation.\r
174\r
175 @param PeiServices An indirect pointer to the PEI Services Table\r
176 published by the PEI Foundation.\r
177\r
178 @param This Pointer to local data for the interface.\r
179\r
180 @param Width The width of the access. Enumerated in bytes. Type\r
181 EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().\r
182\r
183 @param Address The physical address of the access.\r
184\r
185 @param SetBits Points to value to bitwise-OR with the read configuration value.\r
186 The size of the value is determined by Width.\r
187\r
188 @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value.\r
189 The size of the value is determined by Width.\r
190\r
191\r
192 @retval EFI_SUCCESS The function completed successfully.\r
193\r
194 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
195\r
196 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting\r
197 the operation at this time.\r
198\r
199**/\r
4259256b 200EFI_STATUS\r
201EFIAPI\r
202PciCfg2Modify (\r
203 IN CONST EFI_PEI_SERVICES **PeiServices,\r
204 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
205 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
206 IN UINT64 Address,\r
4bf85832 207 IN VOID *SetBits,\r
208 IN VOID *ClearBits\r
4259256b 209 );\r
210\r
211//\r
212// Module globals\r
213//\r
214EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnEcpPciCfgList = {\r
215 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
216 &gEcpPeiPciCfgPpiGuid,\r
217 EcpPciCfgPpiNotifyCallback \r
218};\r
219\r
220EFI_PEI_PCI_CFG2_PPI mPciCfg2Ppi = {\r
221 PciCfg2Read,\r
222 PciCfg2Write,\r
223 PciCfg2Modify,\r
224 0\r
225};\r
226\r
227EFI_PEI_PPI_DESCRIPTOR mPpiListPciCfg2 = {\r
228 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
229 &gEfiPciCfg2PpiGuid,\r
230 &mPciCfg2Ppi\r
231};\r
232\r
233\r
c98d6f47 234/**\r
4259256b 235\r
c98d6f47 236 Standard PEIM entry point.\r
4259256b 237\r
26a76fbc
LG
238 @param FileHandle Handle of the file being invoked.\r
239 @param PeiServices General purpose services available to every PEIM.\r
4259256b 240\r
26a76fbc 241 @retval EFI_SUCCESS The interface could be successfully installed.\r
4259256b 242\r
26a76fbc 243**/\r
c98d6f47 244EFI_STATUS\r
245EFIAPI\r
246PeimInitializePciCfg2 (\r
26a76fbc 247 IN EFI_PEI_FILE_HANDLE FileHandle,\r
c98d6f47 248 IN CONST EFI_PEI_SERVICES **PeiServices\r
249 )\r
4259256b 250{\r
251 EFI_STATUS Status;\r
c98d6f47 252 VOID *Ppi;\r
253\r
254 //\r
255 // Make sure no other module has install the first instance of gEfiPciCfg2PpiGuid.\r
256 //\r
257 Status = (*PeiServices)->LocatePpi (PeiServices, &gEfiPciCfg2PpiGuid, 0, NULL, &Ppi);\r
258 ASSERT (Status == EFI_NOT_FOUND);\r
4259256b 259\r
260 //\r
261 // Register a notification for ECP PCI CFG PPI\r
262 //\r
263 Status = (*PeiServices)->NotifyPpi (PeiServices, &mNotifyOnEcpPciCfgList);\r
264 ASSERT_EFI_ERROR (Status);\r
265 return Status;\r
266}\r
267\r
c98d6f47 268\r
269/**\r
270 Notification service to be called when gEcpPeiPciCfgPpiGuid is installed.\r
271\r
272 @param PeiServices Indirect reference to the PEI Services Table.\r
273 @param NotifyDescriptor Address of the notification descriptor data structure. Type\r
274 EFI_PEI_NOTIFY_DESCRIPTOR is defined above.\r
275 @param Ppi Address of the PPI that was installed.\r
276\r
277 @retval EFI_STATUS This function will install a PPI to PPI database. The status\r
278 code will be the code for (*PeiServices)->InstallPpi.\r
279\r
280**/\r
4259256b 281EFI_STATUS\r
282EFIAPI\r
283EcpPciCfgPpiNotifyCallback (\r
284 IN EFI_PEI_SERVICES **PeiServices,\r
285 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
286 IN VOID *Ppi\r
287 )\r
288{\r
289 //\r
290 // When ECP PCI CFG PPI is installed, publish the PCI CFG2 PPI in the \r
291 // PEI Services Table and the PPI database\r
292 //\r
293 (*PeiServices)->PciCfg = &mPciCfg2Ppi;\r
294 return (*PeiServices)->InstallPpi ((CONST EFI_PEI_SERVICES **)PeiServices, &mPpiListPciCfg2);\r
295}\r
296\r
c98d6f47 297/**\r
298 Reads from a given location in the PCI configuration space.\r
299\r
300 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
301\r
302 @param This Pointer to local data for the interface.\r
303\r
304 @param Width The width of the access. Enumerated in bytes.\r
305 See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
306\r
307 @param Address The physical address of the access. The format of\r
308 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
309\r
310 @param Buffer A pointer to the buffer of data..\r
311\r
312\r
313 @retval EFI_SUCCESS The function completed successfully.\r
314\r
315 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
316\r
317 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this\r
318 time.\r
319\r
320**/\r
4259256b 321EFI_STATUS\r
322EFIAPI\r
323PciCfg2Read (\r
324 IN CONST EFI_PEI_SERVICES **PeiServices,\r
325 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
326 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
327 IN UINT64 Address,\r
328 IN OUT VOID *Buffer\r
329 )\r
330{\r
331 EFI_STATUS Status;\r
332 EFI_PEI_PCI_CFG_PPI *PciCfg;\r
333\r
334 Status = (*PeiServices)->LocatePpi (\r
335 PeiServices,\r
336 &gEcpPeiPciCfgPpiGuid,\r
337 0,\r
338 NULL,\r
339 (VOID **)&PciCfg\r
340 );\r
341 ASSERT_EFI_ERROR (Status);\r
342\r
343 return PciCfg->Read ((EFI_PEI_SERVICES **)PeiServices, PciCfg, Width, Address, Buffer);\r
344}\r
345\r
c98d6f47 346/**\r
347 Write to a given location in the PCI configuration space.\r
348\r
349 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
350\r
351 @param This Pointer to local data for the interface.\r
352\r
353 @param Width The width of the access. Enumerated in bytes.\r
354 See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
355\r
356 @param Address The physical address of the access. The format of\r
357 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
358\r
359 @param Buffer A pointer to the buffer of data..\r
360\r
361\r
362 @retval EFI_SUCCESS The function completed successfully.\r
363\r
364 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
365\r
366 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this\r
367 time.\r
368\r
369**/\r
4259256b 370EFI_STATUS\r
371EFIAPI\r
372PciCfg2Write (\r
373 IN CONST EFI_PEI_SERVICES **PeiServices,\r
374 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
375 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
376 IN UINT64 Address,\r
377 IN OUT VOID *Buffer\r
378 )\r
379{\r
380 EFI_STATUS Status;\r
381 EFI_PEI_PCI_CFG_PPI *PciCfg;\r
382\r
383 Status = (*PeiServices)->LocatePpi (\r
384 PeiServices,\r
385 &gEcpPeiPciCfgPpiGuid,\r
386 0,\r
387 NULL,\r
388 (VOID **)&PciCfg\r
389 );\r
390 ASSERT_EFI_ERROR (Status);\r
391\r
392 return PciCfg->Write ((EFI_PEI_SERVICES **)PeiServices, PciCfg, Width, Address, Buffer);\r
393}\r
394\r
c98d6f47 395/**\r
396 PCI read-modify-write operation.\r
397\r
398 @param PeiServices An indirect pointer to the PEI Services Table\r
399 published by the PEI Foundation.\r
400\r
401 @param This Pointer to local data for the interface.\r
402\r
403 @param Width The width of the access. Enumerated in bytes. Type\r
404 EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().\r
405\r
406 @param Address The physical address of the access.\r
407\r
408 @param SetBits Points to value to bitwise-OR with the read configuration value.\r
409 The size of the value is determined by Width.\r
410\r
411 @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value.\r
412 The size of the value is determined by Width.\r
413\r
414\r
415 @retval EFI_SUCCESS The function completed successfully.\r
416\r
417 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
418\r
419 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting\r
420 the operation at this time.\r
421\r
422**/\r
4259256b 423EFI_STATUS\r
424EFIAPI\r
425PciCfg2Modify (\r
426 IN CONST EFI_PEI_SERVICES **PeiServices,\r
427 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
428 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
429 IN UINT64 Address,\r
0e667e82 430 IN VOID *SetBits,\r
431 IN VOID *ClearBits\r
4259256b 432 )\r
433{\r
434 EFI_STATUS Status;\r
435 EFI_PEI_PCI_CFG_PPI *PciCfg;\r
436\r
437 Status = (*PeiServices)->LocatePpi (\r
438 PeiServices,\r
c30050f5 439 &gEfiPciCfgPpiInServiceTableGuid,\r
4259256b 440 0,\r
441 NULL,\r
442 (VOID **)&PciCfg\r
443 );\r
444 ASSERT_EFI_ERROR (Status);\r
445\r
446 return PciCfg->Modify ((EFI_PEI_SERVICES **)PeiServices, PciCfg, Width, Address, *(UINTN *)SetBits, *(UINTN *)ClearBits);\r
447}\r