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