]> git.proxmox.com Git - mirror_edk2.git/blame - DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / DynamicTablesPkg / Library / Acpi / Arm / AcpiSsdtPcieLibArm / SsdtPcieGenerator.c
CommitLineData
e35a746c
PG
1/** @file\r
2 SSDT Pcie Table Generator.\r
3\r
5816bd3e 4 Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>\r
e35a746c
PG
5\r
6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
7\r
8 @par Reference(s):\r
9 - PCI Firmware Specification - Revision 3.0\r
10 - ACPI 6.4 specification:\r
11 - s6.2.13 "_PRT (PCI Routing Table)"\r
12 - s6.1.1 "_ADR (Address)"\r
13 - linux kernel code\r
14 - Arm Base Boot Requirements v1.0\r
5816bd3e 15 - Arm Base System Architecture v1.0\r
e35a746c
PG
16**/\r
17\r
18#include <Library/AcpiLib.h>\r
19#include <Library/BaseLib.h>\r
20#include <Library/BaseMemoryLib.h>\r
21#include <Library/DebugLib.h>\r
22#include <Library/MemoryAllocationLib.h>\r
23#include <Protocol/AcpiTable.h>\r
24\r
25// Module specific include files.\r
26#include <AcpiTableGenerator.h>\r
27#include <ConfigurationManagerObject.h>\r
28#include <ConfigurationManagerHelper.h>\r
29#include <Library/AcpiHelperLib.h>\r
30#include <Library/TableHelperLib.h>\r
31#include <Library/AmlLib/AmlLib.h>\r
19a87683 32#include <Library/SsdtPcieSupportLib.h>\r
e35a746c
PG
33#include <Protocol/ConfigurationManagerProtocol.h>\r
34\r
35#include "SsdtPcieGenerator.h"\r
36\r
033ba8bb
KQ
37#define PCI_MAX_DEVICE_COUNT_PER_BUS 32\r
38#define PCI_MAX_FUNCTION_COUNT_PER_DEVICE 8\r
39\r
e35a746c
PG
40/** ARM standard SSDT Pcie Table Generator.\r
41\r
42Requirements:\r
43 The following Configuration Manager Object(s) are required by\r
44 this Generator:\r
45 - EArmObjCmRef\r
46 - EArmObjPciConfigSpaceInfo\r
47 - EArmObjPciAddressMapInfo\r
48 - EArmObjPciInterruptMapInfo\r
49*/\r
50\r
51/** This macro expands to a function that retrieves the cross-CM-object-\r
52 reference information from the Configuration Manager.\r
53*/\r
54GET_OBJECT_LIST (\r
55 EObjNameSpaceArm,\r
56 EArmObjCmRef,\r
57 CM_ARM_OBJ_REF\r
58 );\r
59\r
60/** This macro expands to a function that retrieves the Pci\r
61 Configuration Space Information from the Configuration Manager.\r
62*/\r
63GET_OBJECT_LIST (\r
64 EObjNameSpaceArm,\r
65 EArmObjPciConfigSpaceInfo,\r
66 CM_ARM_PCI_CONFIG_SPACE_INFO\r
67 );\r
68\r
69/** This macro expands to a function that retrieves the Pci\r
70 Address Mapping Information from the Configuration Manager.\r
71*/\r
72GET_OBJECT_LIST (\r
73 EObjNameSpaceArm,\r
74 EArmObjPciAddressMapInfo,\r
75 CM_ARM_PCI_ADDRESS_MAP_INFO\r
76 );\r
77\r
78/** This macro expands to a function that retrieves the Pci\r
79 Interrupt Mapping Information from the Configuration Manager.\r
80*/\r
81GET_OBJECT_LIST (\r
82 EObjNameSpaceArm,\r
83 EArmObjPciInterruptMapInfo,\r
84 CM_ARM_PCI_INTERRUPT_MAP_INFO\r
85 );\r
86\r
87/** Initialize the MappingTable.\r
88\r
89 @param [in] MappingTable The mapping table structure.\r
90 @param [in] Count Number of entries to allocate in the\r
91 MappingTable.\r
92\r
93 @retval EFI_SUCCESS Success.\r
94 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
95 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
96**/\r
97STATIC\r
98EFI_STATUS\r
99EFIAPI\r
100MappingTableInitialize (\r
101 IN MAPPING_TABLE *MappingTable,\r
102 IN UINT32 Count\r
103 )\r
104{\r
105 UINT32 *Table;\r
106\r
107 if ((MappingTable == NULL) ||\r
108 (Count == 0))\r
109 {\r
110 ASSERT (0);\r
111 return EFI_INVALID_PARAMETER;\r
112 }\r
113\r
114 Table = AllocateZeroPool (sizeof (*Table) * Count);\r
115 if (Table == NULL) {\r
116 ASSERT (0);\r
117 return EFI_OUT_OF_RESOURCES;\r
118 }\r
119\r
120 MappingTable->Table = Table;\r
121 MappingTable->LastIndex = 0;\r
122 MappingTable->MaxIndex = Count;\r
123\r
124 return EFI_SUCCESS;\r
125}\r
126\r
127/** Free the MappingTable.\r
128\r
129 @param [in, out] MappingTable The mapping table structure.\r
130**/\r
131STATIC\r
132VOID\r
133EFIAPI\r
134MappingTableFree (\r
135 IN OUT MAPPING_TABLE *MappingTable\r
136 )\r
137{\r
138 ASSERT (MappingTable != NULL);\r
139 ASSERT (MappingTable->Table != NULL);\r
140\r
141 if (MappingTable->Table != NULL) {\r
142 FreePool (MappingTable->Table);\r
143 }\r
144}\r
145\r
146/** Add a new entry to the MappingTable and return its index.\r
147\r
148 If an entry with [Integer] is already available in the table,\r
149 return its index without adding a new entry.\r
150\r
151 @param [in] MappingTable The mapping table structure.\r
152 @param [in] Integer New Integer entry to add.\r
153\r
154 @retval The index of the Integer entry in the MappingTable.\r
155**/\r
156STATIC\r
157UINT32\r
158EFIAPI\r
159MappingTableAdd (\r
160 IN MAPPING_TABLE *MappingTable,\r
161 IN UINT32 Integer\r
162 )\r
163{\r
164 UINT32 *Table;\r
165 UINT32 Index;\r
166 UINT32 LastIndex;\r
167\r
168 ASSERT (MappingTable != NULL);\r
169 ASSERT (MappingTable->Table != NULL);\r
170\r
171 Table = MappingTable->Table;\r
172 LastIndex = MappingTable->LastIndex;\r
173\r
174 // Search if there is already an entry with this Integer.\r
175 for (Index = 0; Index < LastIndex; Index++) {\r
176 if (Table[Index] == Integer) {\r
177 return Index;\r
178 }\r
179 }\r
180\r
181 ASSERT (LastIndex < MappingTable->MaxIndex);\r
182\r
183 // If no, create a new entry.\r
184 Table[LastIndex] = Integer;\r
185\r
186 return MappingTable->LastIndex++;\r
187}\r
188\r
189/** Generate required Pci device information.\r
190\r
191 ASL code:\r
192 Name (_UID, <Uid>) // Uid of the Pci device\r
193 Name (_HID, EISAID ("PNP0A08")) // PCI Express Root Bridge\r
194 Name (_CID, EISAID ("PNP0A03")) // Compatible PCI Root Bridge\r
195 Name (_SEG, <Pci segment group>) // PCI Segment Group number\r
196 Name (_BBN, <Bus number>) // PCI Base Bus Number\r
197 Name (_CCA, 1) // Initially mark the PCI coherent\r
198\r
199 @param [in] PciInfo Pci device information.\r
200 @param [in] Uid Unique Id of the Pci device.\r
201 @param [in, out] PciNode Pci node to amend.\r
202\r
203 @retval EFI_SUCCESS Success.\r
204 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
205 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
206**/\r
207STATIC\r
208EFI_STATUS\r
209EFIAPI\r
210GeneratePciDeviceInfo (\r
211 IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,\r
212 IN UINT32 Uid,\r
213 IN OUT AML_OBJECT_NODE_HANDLE PciNode\r
214 )\r
215{\r
216 EFI_STATUS Status;\r
217 UINT32 EisaId;\r
218\r
219 ASSERT (PciInfo != NULL);\r
220 ASSERT (PciNode != NULL);\r
221\r
222 // ASL: Name (_UID, <Uid>)\r
223 Status = AmlCodeGenNameInteger ("_UID", Uid, PciNode, NULL);\r
224 if (EFI_ERROR (Status)) {\r
225 ASSERT (0);\r
226 return Status;\r
227 }\r
228\r
229 // ASL: Name (_HID, EISAID ("PNP0A08"))\r
230 Status = AmlGetEisaIdFromString ("PNP0A08", &EisaId);\r
231 if (EFI_ERROR (Status)) {\r
232 ASSERT (0);\r
233 return Status;\r
234 }\r
235\r
236 Status = AmlCodeGenNameInteger ("_HID", EisaId, PciNode, NULL);\r
237 if (EFI_ERROR (Status)) {\r
238 ASSERT (0);\r
239 return Status;\r
240 }\r
241\r
242 // ASL: Name (_CID, EISAID ("PNP0A03"))\r
243 Status = AmlGetEisaIdFromString ("PNP0A03", &EisaId);\r
244 if (EFI_ERROR (Status)) {\r
245 ASSERT (0);\r
246 return Status;\r
247 }\r
248\r
249 Status = AmlCodeGenNameInteger ("_CID", EisaId, PciNode, NULL);\r
250 if (EFI_ERROR (Status)) {\r
251 ASSERT (0);\r
252 return Status;\r
253 }\r
254\r
255 // ASL: Name (_SEG, <Pci segment group>)\r
256 Status = AmlCodeGenNameInteger (\r
257 "_SEG",\r
258 PciInfo->PciSegmentGroupNumber,\r
259 PciNode,\r
260 NULL\r
261 );\r
262 if (EFI_ERROR (Status)) {\r
263 ASSERT (0);\r
264 return Status;\r
265 }\r
266\r
267 // ASL: Name (_BBN, <Bus number>)\r
268 Status = AmlCodeGenNameInteger (\r
269 "_BBN",\r
270 PciInfo->StartBusNumber,\r
271 PciNode,\r
272 NULL\r
273 );\r
274 if (EFI_ERROR (Status)) {\r
275 ASSERT (0);\r
276 return Status;\r
277 }\r
278\r
279 // ASL: Name (_CCA, 1)\r
280 // Must be aligned with the IORT CCA property in\r
281 // "Table 14 Memory access properties"\r
282 Status = AmlCodeGenNameInteger ("_CCA", 1, PciNode, NULL);\r
283 ASSERT_EFI_ERROR (Status);\r
284 return Status;\r
285}\r
286\r
e35a746c
PG
287/** Generate a _PRT object (Pci Routing Table) for the Pci device.\r
288\r
289 Cf. ACPI 6.4 specification, s6.2.13 "_PRT (PCI Routing Table)"\r
290\r
e35a746c
PG
291 @param [in] Generator The SSDT Pci generator.\r
292 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
293 Protocol interface.\r
294 @param [in] PciInfo Pci device information.\r
0a4079ad 295 @param [in] Uid Unique Id of the Pci device.\r
e35a746c
PG
296 @param [in, out] PciNode Pci node to amend.\r
297\r
298 @retval EFI_SUCCESS The function completed successfully.\r
299 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
300 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.\r
301**/\r
302STATIC\r
303EFI_STATUS\r
304EFIAPI\r
305GeneratePrt (\r
306 IN ACPI_PCI_GENERATOR *Generator,\r
307 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
308 IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,\r
0a4079ad 309 IN UINT32 Uid,\r
e35a746c
PG
310 IN OUT AML_OBJECT_NODE_HANDLE PciNode\r
311 )\r
312{\r
313 EFI_STATUS Status;\r
314 INT32 Index;\r
e35a746c 315 AML_OBJECT_NODE_HANDLE PrtNode;\r
e35a746c
PG
316 CM_ARM_OBJ_REF *RefInfo;\r
317 UINT32 RefCount;\r
318 CM_ARM_PCI_INTERRUPT_MAP_INFO *IrqMapInfo;\r
e35a746c
PG
319\r
320 ASSERT (Generator != NULL);\r
321 ASSERT (CfgMgrProtocol != NULL);\r
322 ASSERT (PciInfo != NULL);\r
323 ASSERT (PciNode != NULL);\r
324\r
325 PrtNode = NULL;\r
326\r
327 // Get the array of CM_ARM_OBJ_REF referencing the\r
328 // CM_ARM_PCI_INTERRUPT_MAP_INFO objects.\r
329 Status = GetEArmObjCmRef (\r
330 CfgMgrProtocol,\r
331 PciInfo->InterruptMapToken,\r
332 &RefInfo,\r
333 &RefCount\r
334 );\r
335 if (EFI_ERROR (Status)) {\r
336 ASSERT (0);\r
337 return Status;\r
338 }\r
339\r
e35a746c
PG
340 // Initialized DeviceTable.\r
341 Status = MappingTableInitialize (&Generator->DeviceTable, RefCount);\r
342 if (EFI_ERROR (Status)) {\r
343 ASSERT (0);\r
344 goto exit_handler0;\r
345 }\r
346\r
347 // ASL: Name (_PRT, Package () {})\r
348 Status = AmlCodeGenNamePackage ("_PRT", NULL, &PrtNode);\r
349 if (EFI_ERROR (Status)) {\r
350 ASSERT (0);\r
351 goto exit_handler;\r
352 }\r
353\r
e35a746c
PG
354 for (Index = 0; Index < RefCount; Index++) {\r
355 // Get CM_ARM_PCI_INTERRUPT_MAP_INFO structures one by one.\r
356 Status = GetEArmObjPciInterruptMapInfo (\r
357 CfgMgrProtocol,\r
358 RefInfo[Index].ReferenceToken,\r
359 &IrqMapInfo,\r
360 NULL\r
361 );\r
362 if (EFI_ERROR (Status)) {\r
363 ASSERT (0);\r
364 goto exit_handler;\r
365 }\r
366\r
5816bd3e
PG
367 // Check that the interrupts flags are SPIs, level high.\r
368 // Cf. Arm BSA v1.0, sE.6 "Legacy interrupts"\r
369 if ((Index > 0) &&\r
370 (IrqMapInfo->IntcInterrupt.Interrupt >= 32) &&\r
371 (IrqMapInfo->IntcInterrupt.Interrupt < 1020) &&\r
fc4a132c 372 ((IrqMapInfo->IntcInterrupt.Flags & 0xB) != 0))\r
5816bd3e 373 {\r
e35a746c 374 Status = EFI_INVALID_PARAMETER;\r
5816bd3e 375 ASSERT_EFI_ERROR (Status);\r
e35a746c
PG
376 goto exit_handler;\r
377 }\r
378\r
379 // Add the device to the DeviceTable.\r
380 MappingTableAdd (&Generator->DeviceTable, IrqMapInfo->PciDevice);\r
381\r
382 /* Add a _PRT entry.\r
383 ASL\r
384 Name (_PRT, Package () {\r
385 <OldPrtEntries>,\r
386 <NewPrtEntry>\r
387 })\r
388\r
389 Address is set as:\r
390 ACPI 6.4 specification, Table 6.2: "ADR Object Address Encodings"\r
391 High word-Device #, Low word-Function #. (for example, device 3,\r
392 function 2 is 0x00030002). To refer to all the functions on a device #,\r
393 use a function number of FFFF).\r
a5672d43
PG
394\r
395 Use the second model for _PRT object and describe a hardwired interrupt.\r
e35a746c
PG
396 */\r
397 Status = AmlAddPrtEntry (\r
398 (IrqMapInfo->PciDevice << 16) | 0xFFFF,\r
399 IrqMapInfo->PciInterrupt,\r
5816bd3e
PG
400 NULL,\r
401 IrqMapInfo->IntcInterrupt.Interrupt,\r
e35a746c
PG
402 PrtNode\r
403 );\r
404 if (EFI_ERROR (Status)) {\r
405 ASSERT (0);\r
406 goto exit_handler;\r
407 }\r
408 } // for\r
409\r
5816bd3e 410 // Attach the _PRT entry.\r
e35a746c
PG
411 Status = AmlAttachNode (PciNode, PrtNode);\r
412 if (EFI_ERROR (Status)) {\r
5816bd3e 413 ASSERT_EFI_ERROR (Status);\r
e35a746c
PG
414 goto exit_handler;\r
415 }\r
416\r
417 PrtNode = NULL;\r
418\r
419 // Generate the Pci slots once all the device have been added.\r
0a4079ad 420 Status = GeneratePciSlots (PciInfo, &Generator->DeviceTable, Uid, PciNode);\r
e35a746c
PG
421 if (EFI_ERROR (Status)) {\r
422 ASSERT (0);\r
423 goto exit_handler;\r
424 }\r
425\r
426exit_handler:\r
427 MappingTableFree (&Generator->DeviceTable);\r
428exit_handler0:\r
e35a746c
PG
429 if (PrtNode != NULL) {\r
430 AmlDeleteTree (PrtNode);\r
431 }\r
432\r
433 return Status;\r
434}\r
435\r
436/** Generate a _CRS method for the Pci device.\r
437\r
438 @param [in] Generator The SSDT Pci generator.\r
439 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
440 Protocol interface.\r
441 @param [in] PciInfo Pci device information.\r
442 @param [in, out] PciNode Pci node to amend.\r
443\r
444 @retval EFI_SUCCESS The function completed successfully.\r
445 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
446 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.\r
447**/\r
448STATIC\r
449EFI_STATUS\r
450EFIAPI\r
451GeneratePciCrs (\r
452 IN ACPI_PCI_GENERATOR *Generator,\r
453 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
454 IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,\r
455 IN OUT AML_OBJECT_NODE_HANDLE PciNode\r
456 )\r
457{\r
458 EFI_STATUS Status;\r
459 BOOLEAN Translation;\r
460 UINT32 Index;\r
461 CM_ARM_OBJ_REF *RefInfo;\r
462 UINT32 RefCount;\r
463 CM_ARM_PCI_ADDRESS_MAP_INFO *AddrMapInfo;\r
464 AML_OBJECT_NODE_HANDLE CrsNode;\r
6cda306d 465 BOOLEAN IsPosDecode;\r
e35a746c
PG
466\r
467 ASSERT (Generator != NULL);\r
468 ASSERT (CfgMgrProtocol != NULL);\r
469 ASSERT (PciInfo != NULL);\r
470 ASSERT (PciNode != NULL);\r
471\r
472 // ASL: Name (_CRS, ResourceTemplate () {})\r
473 Status = AmlCodeGenNameResourceTemplate ("_CRS", PciNode, &CrsNode);\r
474 if (EFI_ERROR (Status)) {\r
475 ASSERT (0);\r
476 return Status;\r
477 }\r
478\r
479 // ASL:\r
480 // WordBusNumber ( // Bus numbers assigned to this root\r
481 // ResourceProducer, MinFixed, MaxFixed, PosDecode,\r
482 // 0, // AddressGranularity\r
483 // <Start>, // AddressMinimum - Minimum Bus Number\r
484 // <End>, // AddressMaximum - Maximum Bus Number\r
485 // 0, // AddressTranslation - Set to 0\r
486 // <End> - <Start> + 1 // RangeLength - Number of Busses\r
487 // )\r
488 Status = AmlCodeGenRdWordBusNumber (\r
489 FALSE,\r
490 TRUE,\r
491 TRUE,\r
492 TRUE,\r
493 0,\r
494 PciInfo->StartBusNumber,\r
495 PciInfo->EndBusNumber,\r
496 0,\r
497 PciInfo->EndBusNumber - PciInfo->StartBusNumber + 1,\r
498 0,\r
499 NULL,\r
500 CrsNode,\r
501 NULL\r
502 );\r
503 if (EFI_ERROR (Status)) {\r
504 ASSERT (0);\r
505 return Status;\r
506 }\r
507\r
508 // Get the array of CM_ARM_OBJ_REF referencing the\r
509 // CM_ARM_PCI_ADDRESS_MAP_INFO objects.\r
510 Status = GetEArmObjCmRef (\r
511 CfgMgrProtocol,\r
512 PciInfo->AddressMapToken,\r
513 &RefInfo,\r
514 &RefCount\r
515 );\r
516 if (EFI_ERROR (Status)) {\r
517 ASSERT (0);\r
518 return Status;\r
519 }\r
520\r
521 for (Index = 0; Index < RefCount; Index++) {\r
522 // Get CM_ARM_PCI_ADDRESS_MAP_INFO structures one by one.\r
523 Status = GetEArmObjPciAddressMapInfo (\r
524 CfgMgrProtocol,\r
525 RefInfo[Index].ReferenceToken,\r
526 &AddrMapInfo,\r
527 NULL\r
528 );\r
529 if (EFI_ERROR (Status)) {\r
530 ASSERT (0);\r
531 return Status;\r
532 }\r
533\r
534 Translation = (AddrMapInfo->CpuAddress != AddrMapInfo->PciAddress);\r
6cda306d
JB
535 if (AddrMapInfo->CpuAddress >= AddrMapInfo->PciAddress) {\r
536 IsPosDecode = TRUE;\r
537 } else {\r
538 IsPosDecode = FALSE;\r
539 }\r
e35a746c
PG
540\r
541 switch (AddrMapInfo->SpaceCode) {\r
542 case PCI_SS_IO:\r
543 Status = AmlCodeGenRdDWordIo (\r
544 FALSE,\r
545 TRUE,\r
546 TRUE,\r
6cda306d 547 IsPosDecode,\r
e35a746c
PG
548 3,\r
549 0,\r
550 AddrMapInfo->PciAddress,\r
551 AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1,\r
6cda306d 552 Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0,\r
e35a746c
PG
553 AddrMapInfo->AddressSize,\r
554 0,\r
555 NULL,\r
556 TRUE,\r
557 FALSE,\r
558 CrsNode,\r
559 NULL\r
560 );\r
561 break;\r
562\r
563 case PCI_SS_M32:\r
564 Status = AmlCodeGenRdDWordMemory (\r
565 FALSE,\r
6cda306d 566 IsPosDecode,\r
e35a746c
PG
567 TRUE,\r
568 TRUE,\r
569 TRUE,\r
570 TRUE,\r
571 0,\r
572 AddrMapInfo->PciAddress,\r
573 AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1,\r
6cda306d 574 Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0,\r
e35a746c
PG
575 AddrMapInfo->AddressSize,\r
576 0,\r
577 NULL,\r
578 0,\r
579 TRUE,\r
580 CrsNode,\r
581 NULL\r
582 );\r
583 break;\r
584\r
585 case PCI_SS_M64:\r
586 Status = AmlCodeGenRdQWordMemory (\r
587 FALSE,\r
6cda306d 588 IsPosDecode,\r
e35a746c
PG
589 TRUE,\r
590 TRUE,\r
591 TRUE,\r
592 TRUE,\r
593 0,\r
594 AddrMapInfo->PciAddress,\r
595 AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1,\r
6cda306d 596 Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0,\r
e35a746c
PG
597 AddrMapInfo->AddressSize,\r
598 0,\r
599 NULL,\r
600 0,\r
601 TRUE,\r
602 CrsNode,\r
603 NULL\r
604 );\r
605 break;\r
606\r
607 default:\r
608 Status = EFI_INVALID_PARAMETER;\r
609 } // switch\r
610\r
611 if (EFI_ERROR (Status)) {\r
612 ASSERT (0);\r
613 return Status;\r
614 }\r
615 } // for\r
616\r
617 return Status;\r
618}\r
619\r
033ba8bb
KQ
620/** Generate a RES0 device node to reserve PNP motherboard resources\r
621 for a given PCI node.\r
622\r
623 @param [in] PciNode Parent PCI node handle of the generated\r
624 resource object.\r
625 @param [out] CrsNode CRS node of the AML tree to populate.\r
626\r
627 @retval EFI_SUCCESS The function completed successfully.\r
628 @retval EFI_INVALID_PARAMETER Invalid input parameter.\r
629 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.\r
630**/\r
631STATIC\r
632EFI_STATUS\r
633EFIAPI\r
634GenerateMotherboardDevice (\r
635 IN AML_OBJECT_NODE_HANDLE PciNode,\r
636 OUT AML_OBJECT_NODE_HANDLE *CrsNode\r
637 )\r
638{\r
639 EFI_STATUS Status;\r
640 UINT32 EisaId;\r
641 AML_OBJECT_NODE_HANDLE ResNode;\r
642\r
643 if (CrsNode == NULL) {\r
644 ASSERT (0);\r
645 return EFI_INVALID_PARAMETER;\r
646 }\r
647\r
648 // ASL: Device (RES0) {}\r
649 Status = AmlCodeGenDevice ("RES0", PciNode, &ResNode);\r
650 if (EFI_ERROR (Status)) {\r
651 ASSERT (0);\r
652 return Status;\r
653 }\r
654\r
655 // ASL: Name (_HID, EISAID ("PNP0C02"))\r
656 Status = AmlGetEisaIdFromString ("PNP0C02", &EisaId); /* PNP Motherboard Resources */\r
657 if (EFI_ERROR (Status)) {\r
658 ASSERT (0);\r
659 return Status;\r
660 }\r
661\r
662 Status = AmlCodeGenNameInteger ("_HID", EisaId, ResNode, NULL);\r
663 if (EFI_ERROR (Status)) {\r
664 ASSERT (0);\r
665 return Status;\r
666 }\r
667\r
668 // ASL: Name (_CRS, ResourceTemplate () {})\r
669 Status = AmlCodeGenNameResourceTemplate ("_CRS", ResNode, CrsNode);\r
670 if (EFI_ERROR (Status)) {\r
671 ASSERT (0);\r
672 return Status;\r
673 }\r
674\r
675 return Status;\r
676}\r
677\r
678/** Reserves ECAM space for PCI config space\r
679\r
680 @param [in] Generator The SSDT Pci generator.\r
681 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
682 Protocol interface.\r
683 @param [in] PciInfo Pci device information.\r
684 @param [in, out] PciNode RootNode of the AML tree to populate.\r
685\r
686 @retval EFI_SUCCESS The function completed successfully.\r
687 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
688 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.\r
689**/\r
690STATIC\r
691EFI_STATUS\r
692EFIAPI\r
693ReserveEcamSpace (\r
694 IN ACPI_PCI_GENERATOR *Generator,\r
695 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
696 IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,\r
697 IN OUT AML_OBJECT_NODE_HANDLE PciNode\r
698 )\r
699{\r
700 EFI_STATUS Status;\r
701 AML_OBJECT_NODE_HANDLE CrsNode;\r
702 UINT64 AddressMinimum;\r
703 UINT64 AddressMaximum;\r
704\r
705 Status = GenerateMotherboardDevice (PciNode, &CrsNode);\r
706 if (EFI_ERROR (Status)) {\r
707 ASSERT (0);\r
708 return Status;\r
709 }\r
710\r
711 AddressMinimum = PciInfo->BaseAddress + (PciInfo->StartBusNumber *\r
712 PCI_MAX_DEVICE_COUNT_PER_BUS * PCI_MAX_FUNCTION_COUNT_PER_DEVICE * SIZE_4KB);\r
713 AddressMaximum = PciInfo->BaseAddress + ((PciInfo->EndBusNumber + 1) *\r
714 PCI_MAX_DEVICE_COUNT_PER_BUS * PCI_MAX_FUNCTION_COUNT_PER_DEVICE * SIZE_4KB) - 1;\r
715\r
716 Status = AmlCodeGenRdQWordMemory (\r
717 FALSE,\r
718 TRUE,\r
719 TRUE,\r
720 TRUE,\r
721 FALSE, // non-cacheable\r
722 TRUE,\r
723 0,\r
724 AddressMinimum,\r
725 AddressMaximum,\r
726 0, // no translation\r
727 AddressMaximum - AddressMinimum + 1,\r
728 0,\r
729 NULL,\r
730 0,\r
731 TRUE,\r
732 CrsNode,\r
733 NULL\r
734 );\r
735\r
736 if (EFI_ERROR (Status)) {\r
737 ASSERT (0);\r
738 return Status;\r
739 }\r
740\r
741 return Status;\r
742}\r
743\r
e35a746c
PG
744/** Generate a Pci device.\r
745\r
746 @param [in] Generator The SSDT Pci generator.\r
747 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
748 Protocol interface.\r
749 @param [in] PciInfo Pci device information.\r
750 @param [in] Uid Unique Id of the Pci device.\r
751 @param [in, out] RootNode RootNode of the AML tree to populate.\r
752\r
753 @retval EFI_SUCCESS The function completed successfully.\r
754 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
755 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.\r
756**/\r
757STATIC\r
758EFI_STATUS\r
759EFIAPI\r
760GeneratePciDevice (\r
761 IN ACPI_PCI_GENERATOR *Generator,\r
762 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
763 IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,\r
764 IN UINT32 Uid,\r
765 IN OUT AML_ROOT_NODE_HANDLE *RootNode\r
766 )\r
767{\r
768 EFI_STATUS Status;\r
769\r
770 CHAR8 AslName[AML_NAME_SEG_SIZE + 1];\r
771 AML_OBJECT_NODE_HANDLE ScopeNode;\r
772 AML_OBJECT_NODE_HANDLE PciNode;\r
773\r
774 ASSERT (Generator != NULL);\r
775 ASSERT (CfgMgrProtocol != NULL);\r
776 ASSERT (PciInfo != NULL);\r
777 ASSERT (RootNode != NULL);\r
778\r
779 PciNode = NULL;\r
780\r
781 // ASL: Scope (\_SB) {}\r
782 Status = AmlCodeGenScope (SB_SCOPE, RootNode, &ScopeNode);\r
783 if (EFI_ERROR (Status)) {\r
784 ASSERT (0);\r
785 return Status;\r
786 }\r
787\r
788 // Write the name of the PCI device.\r
789 CopyMem (AslName, "PCIx", AML_NAME_SEG_SIZE + 1);\r
9ac155bf
JB
790 AslName[AML_NAME_SEG_SIZE - 1] = AsciiFromHex (Uid & 0xF);\r
791 if (Uid > 0xF) {\r
792 AslName[AML_NAME_SEG_SIZE - 2] = AsciiFromHex ((Uid >> 4) & 0xF);\r
793 }\r
e35a746c
PG
794\r
795 // ASL: Device (PCIx) {}\r
796 Status = AmlCodeGenDevice (AslName, ScopeNode, &PciNode);\r
797 if (EFI_ERROR (Status)) {\r
798 ASSERT (0);\r
799 return Status;\r
800 }\r
801\r
802 // Populate the PCIx node with some Id values.\r
803 Status = GeneratePciDeviceInfo (PciInfo, Uid, PciNode);\r
804 if (EFI_ERROR (Status)) {\r
805 ASSERT (0);\r
806 return Status;\r
807 }\r
808\r
809 // Generate the Pci Routing Table (_PRT).\r
810 if (PciInfo->InterruptMapToken != CM_NULL_TOKEN) {\r
811 Status = GeneratePrt (\r
812 Generator,\r
813 CfgMgrProtocol,\r
814 PciInfo,\r
0a4079ad 815 Uid,\r
e35a746c
PG
816 PciNode\r
817 );\r
818 if (EFI_ERROR (Status)) {\r
819 ASSERT (0);\r
820 return Status;\r
821 }\r
822 }\r
823\r
824 // Generate the _CRS method.\r
825 Status = GeneratePciCrs (Generator, CfgMgrProtocol, PciInfo, PciNode);\r
826 if (EFI_ERROR (Status)) {\r
827 ASSERT (0);\r
828 return Status;\r
829 }\r
830\r
033ba8bb
KQ
831 // Add the PNP Motherboard Resources Device to reserve ECAM space\r
832 Status = ReserveEcamSpace (Generator, CfgMgrProtocol, PciInfo, PciNode);\r
833 if (EFI_ERROR (Status)) {\r
834 ASSERT (0);\r
835 return Status;\r
836 }\r
837\r
e35a746c 838 // Add the template _OSC method.\r
19a87683 839 Status = AddOscMethod (PciInfo, PciNode);\r
e35a746c 840 ASSERT_EFI_ERROR (Status);\r
033ba8bb 841\r
e35a746c
PG
842 return Status;\r
843}\r
844\r
845/** Build an Ssdt table describing a Pci device.\r
846\r
847 @param [in] Generator The SSDT Pci generator.\r
848 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
849 Protocol interface.\r
850 @param [in] AcpiTableInfo Pointer to the ACPI table information.\r
851 @param [in] PciInfo Pci device information.\r
852 @param [in] Uid Unique Id of the Pci device.\r
853 @param [out] Table If success, contains the created SSDT table.\r
854\r
855 @retval EFI_SUCCESS The function completed successfully.\r
856 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
857 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.\r
858**/\r
859STATIC\r
860EFI_STATUS\r
861EFIAPI\r
862BuildSsdtPciTable (\r
863 IN ACPI_PCI_GENERATOR *Generator,\r
864 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
865 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,\r
866 IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,\r
867 IN UINT32 Uid,\r
868 OUT EFI_ACPI_DESCRIPTION_HEADER **Table\r
869 )\r
870{\r
871 EFI_STATUS Status;\r
872 EFI_STATUS Status1;\r
873 AML_ROOT_NODE_HANDLE RootNode;\r
874\r
875 ASSERT (Generator != NULL);\r
876 ASSERT (CfgMgrProtocol != NULL);\r
877 ASSERT (PciInfo != NULL);\r
878 ASSERT (Table != NULL);\r
879\r
880 // Create a new Ssdt table.\r
881 Status = AddSsdtAcpiHeader (\r
882 CfgMgrProtocol,\r
883 &Generator->Header,\r
884 AcpiTableInfo,\r
885 &RootNode\r
886 );\r
887 if (EFI_ERROR (Status)) {\r
888 ASSERT (0);\r
889 return Status;\r
890 }\r
891\r
892 Status = GeneratePciDevice (\r
893 Generator,\r
894 CfgMgrProtocol,\r
895 PciInfo,\r
896 Uid,\r
897 RootNode\r
898 );\r
899 if (EFI_ERROR (Status)) {\r
900 ASSERT (0);\r
901 goto exit_handler;\r
902 }\r
903\r
904 // Serialize the tree.\r
905 Status = AmlSerializeDefinitionBlock (\r
906 RootNode,\r
907 Table\r
908 );\r
909 if (EFI_ERROR (Status)) {\r
910 DEBUG ((\r
911 DEBUG_ERROR,\r
912 "ERROR: SSDT-PCI: Failed to Serialize SSDT Table Data."\r
913 " Status = %r\n",\r
914 Status\r
915 ));\r
916 }\r
917\r
918exit_handler:\r
919 // Cleanup\r
920 Status1 = AmlDeleteTree (RootNode);\r
921 if (EFI_ERROR (Status1)) {\r
922 DEBUG ((\r
923 DEBUG_ERROR,\r
924 "ERROR: SSDT-PCI: Failed to cleanup AML tree."\r
925 " Status = %r\n",\r
926 Status1\r
927 ));\r
928 // If Status was success but we failed to delete the AML Tree\r
929 // return Status1 else return the original error code, i.e. Status.\r
930 if (!EFI_ERROR (Status)) {\r
931 return Status1;\r
932 }\r
933 }\r
934\r
935 return Status;\r
936}\r
937\r
938/** Construct SSDT tables describing Pci root complexes.\r
939\r
940 This function invokes the Configuration Manager protocol interface\r
941 to get the required hardware information for generating the ACPI\r
942 table.\r
943\r
944 If this function allocates any resources then they must be freed\r
945 in the FreeXXXXTableResourcesEx function.\r
946\r
947 @param [in] This Pointer to the ACPI table generator.\r
948 @param [in] AcpiTableInfo Pointer to the ACPI table information.\r
949 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
950 Protocol interface.\r
951 @param [out] Table Pointer to a list of generated ACPI table(s).\r
952 @param [out] TableCount Number of generated ACPI table(s).\r
953\r
954 @retval EFI_SUCCESS Table generated successfully.\r
955 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration\r
956 Manager is less than the Object size for\r
957 the requested object.\r
958 @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
959 @retval EFI_NOT_FOUND Could not find information.\r
960 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.\r
961 @retval EFI_UNSUPPORTED Unsupported configuration.\r
962**/\r
963STATIC\r
964EFI_STATUS\r
965EFIAPI\r
966BuildSsdtPciTableEx (\r
967 IN CONST ACPI_TABLE_GENERATOR *This,\r
968 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,\r
969 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
970 OUT EFI_ACPI_DESCRIPTION_HEADER ***Table,\r
971 OUT UINTN *CONST TableCount\r
972 )\r
973{\r
974 EFI_STATUS Status;\r
975 CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo;\r
976 UINT32 PciCount;\r
977 UINTN Index;\r
978 EFI_ACPI_DESCRIPTION_HEADER **TableList;\r
979 ACPI_PCI_GENERATOR *Generator;\r
8c92a950 980 UINT32 Uid;\r
e35a746c
PG
981\r
982 ASSERT (This != NULL);\r
983 ASSERT (AcpiTableInfo != NULL);\r
984 ASSERT (CfgMgrProtocol != NULL);\r
985 ASSERT (Table != NULL);\r
986 ASSERT (TableCount != NULL);\r
987 ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);\r
988 ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);\r
989\r
990 *TableCount = 0;\r
991 Generator = (ACPI_PCI_GENERATOR *)This;\r
992\r
993 Status = GetEArmObjPciConfigSpaceInfo (\r
994 CfgMgrProtocol,\r
995 CM_NULL_TOKEN,\r
996 &PciInfo,\r
997 &PciCount\r
998 );\r
999 if (EFI_ERROR (Status)) {\r
1000 ASSERT (0);\r
1001 return Status;\r
1002 }\r
1003\r
1004 if (PciCount > MAX_PCI_ROOT_COMPLEXES_SUPPORTED) {\r
1005 DEBUG ((\r
1006 DEBUG_ERROR,\r
1007 "ERROR: SSDT-PCI: Too many Pci root complexes: %d."\r
1008 " Maximum Pci root complexes supported = %d.\n",\r
1009 PciCount,\r
1010 MAX_PCI_ROOT_COMPLEXES_SUPPORTED\r
1011 ));\r
1012 return EFI_INVALID_PARAMETER;\r
1013 }\r
1014\r
1015 // Allocate a table to store pointers to the SSDT tables.\r
1016 TableList = (EFI_ACPI_DESCRIPTION_HEADER **)\r
1017 AllocateZeroPool (\r
1018 (sizeof (EFI_ACPI_DESCRIPTION_HEADER *) * PciCount)\r
1019 );\r
1020 if (TableList == NULL) {\r
1021 Status = EFI_OUT_OF_RESOURCES;\r
1022 DEBUG ((\r
1023 DEBUG_ERROR,\r
1024 "ERROR: SSDT-PCI: Failed to allocate memory for Table List."\r
1025 " Status = %r\n",\r
1026 Status\r
1027 ));\r
1028 return Status;\r
1029 }\r
1030\r
1031 // Setup the table list early so that appropriate cleanup\r
1032 // can be done in case of failure.\r
1033 *Table = TableList;\r
1034\r
1035 for (Index = 0; Index < PciCount; Index++) {\r
8c92a950
JB
1036 if (PcdGetBool (PcdPciUseSegmentAsUid)) {\r
1037 Uid = PciInfo[Index].PciSegmentGroupNumber;\r
1038 if (Uid > MAX_PCI_ROOT_COMPLEXES_SUPPORTED) {\r
1039 DEBUG ((\r
1040 DEBUG_ERROR,\r
1041 "ERROR: SSDT-PCI: Pci root complexes segment number: %d."\r
1042 " Greater than maximum number of Pci root complexes supported = %d.\n",\r
1043 Uid,\r
1044 MAX_PCI_ROOT_COMPLEXES_SUPPORTED\r
1045 ));\r
1046 return EFI_INVALID_PARAMETER;\r
1047 }\r
1048 } else {\r
1049 Uid = Index;\r
1050 }\r
1051\r
e35a746c
PG
1052 // Build a SSDT table describing the Pci devices.\r
1053 Status = BuildSsdtPciTable (\r
1054 Generator,\r
1055 CfgMgrProtocol,\r
1056 AcpiTableInfo,\r
1057 &PciInfo[Index],\r
8c92a950 1058 Uid,\r
e35a746c
PG
1059 &TableList[Index]\r
1060 );\r
1061 if (EFI_ERROR (Status)) {\r
1062 DEBUG ((\r
1063 DEBUG_ERROR,\r
1064 "ERROR: SSDT-PCI: Failed to build associated SSDT table."\r
1065 " Status = %r\n",\r
1066 Status\r
1067 ));\r
1068 goto error_handler;\r
1069 }\r
1070\r
1071 *TableCount += 1;\r
1072 } // for\r
1073\r
1074error_handler:\r
1075 // Note: Table list and Table count have been setup. The\r
1076 // error handler does nothing here as the framework will invoke\r
1077 // FreeSsdtPciTableEx () even on failure.\r
1078 return Status;\r
1079}\r
1080\r
1081/** Free any resources allocated for constructing the tables.\r
1082\r
1083 @param [in] This Pointer to the ACPI table generator.\r
1084 @param [in] AcpiTableInfo Pointer to the ACPI Table Info.\r
1085 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
1086 Protocol Interface.\r
1087 @param [in, out] Table Pointer to an array of pointers\r
1088 to ACPI Table(s).\r
1089 @param [in] TableCount Number of ACPI table(s).\r
1090\r
1091 @retval EFI_SUCCESS The resources were freed successfully.\r
1092 @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.\r
1093**/\r
1094STATIC\r
1095EFI_STATUS\r
1096EFIAPI\r
1097FreeSsdtPciTableEx (\r
1098 IN CONST ACPI_TABLE_GENERATOR *CONST This,\r
1099 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,\r
1100 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
1101 IN OUT EFI_ACPI_DESCRIPTION_HEADER ***CONST Table,\r
1102 IN CONST UINTN TableCount\r
1103 )\r
1104{\r
1105 EFI_ACPI_DESCRIPTION_HEADER **TableList;\r
1106 UINTN Index;\r
1107\r
1108 ASSERT (This != NULL);\r
1109 ASSERT (AcpiTableInfo != NULL);\r
1110 ASSERT (CfgMgrProtocol != NULL);\r
1111 ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);\r
1112 ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);\r
1113\r
1114 if ((Table == NULL) ||\r
1115 (*Table == NULL) ||\r
1116 (TableCount == 0))\r
1117 {\r
1118 DEBUG ((DEBUG_ERROR, "ERROR: SSDT-PCI: Invalid Table Pointer\n"));\r
1119 return EFI_INVALID_PARAMETER;\r
1120 }\r
1121\r
1122 TableList = *Table;\r
1123 for (Index = 0; Index < TableCount; Index++) {\r
1124 if ((TableList[Index] != NULL) &&\r
1125 (TableList[Index]->Signature ==\r
1126 EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE))\r
1127 {\r
1128 FreePool (TableList[Index]);\r
1129 } else {\r
1130 DEBUG ((\r
1131 DEBUG_ERROR,\r
1132 "ERROR: SSDT-PCI: Could not free SSDT table at index %d.",\r
1133 Index\r
1134 ));\r
1135 return EFI_INVALID_PARAMETER;\r
1136 }\r
1137 } // for\r
1138\r
1139 // Free the table list.\r
1140 FreePool (*Table);\r
1141\r
1142 return EFI_SUCCESS;\r
1143}\r
1144\r
1145/** This macro defines the SSDT Pci Table Generator revision.\r
1146*/\r
1147#define SSDT_PCI_GENERATOR_REVISION CREATE_REVISION (1, 0)\r
1148\r
1149/** The interface for the SSDT Pci Table Generator.\r
1150*/\r
1151STATIC\r
1152ACPI_PCI_GENERATOR SsdtPcieGenerator = {\r
1153 // ACPI table generator header\r
1154 {\r
1155 // Generator ID\r
1156 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtPciExpress),\r
1157 // Generator Description\r
1158 L"ACPI.STD.SSDT.PCI.GENERATOR",\r
1159 // ACPI Table Signature\r
1160 EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,\r
1161 // ACPI Table Revision - Unused\r
1162 0,\r
1163 // Minimum ACPI Table Revision - Unused\r
1164 0,\r
1165 // Creator ID\r
1166 TABLE_GENERATOR_CREATOR_ID_ARM,\r
1167 // Creator Revision\r
1168 SSDT_PCI_GENERATOR_REVISION,\r
1169 // Build table function. Use the extended version instead.\r
1170 NULL,\r
1171 // Free table function. Use the extended version instead.\r
1172 NULL,\r
1173 // Extended Build table function.\r
1174 BuildSsdtPciTableEx,\r
1175 // Extended free function.\r
1176 FreeSsdtPciTableEx\r
1177 },\r
1178\r
1179 // Private fields are defined from here.\r
1180\r
e35a746c
PG
1181 // DeviceTable\r
1182 {\r
1183 // Table\r
1184 NULL,\r
1185 // LastIndex\r
1186 0,\r
1187 // MaxIndex\r
1188 0\r
1189 },\r
1190};\r
1191\r
1192/** Register the Generator with the ACPI Table Factory.\r
1193\r
1194 @param [in] ImageHandle The handle to the image.\r
1195 @param [in] SystemTable Pointer to the System Table.\r
1196\r
1197 @retval EFI_SUCCESS The Generator is registered.\r
1198 @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
1199 @retval EFI_ALREADY_STARTED The Generator for the Table ID\r
1200 is already registered.\r
1201**/\r
1202EFI_STATUS\r
1203EFIAPI\r
1204AcpiSsdtPcieLibConstructor (\r
1205 IN EFI_HANDLE ImageHandle,\r
1206 IN EFI_SYSTEM_TABLE *SystemTable\r
1207 )\r
1208{\r
1209 EFI_STATUS Status;\r
1210\r
1211 Status = RegisterAcpiTableGenerator (&SsdtPcieGenerator.Header);\r
1212 DEBUG ((\r
1213 DEBUG_INFO,\r
1214 "SSDT-PCI: Register Generator. Status = %r\n",\r
1215 Status\r
1216 ));\r
1217 ASSERT_EFI_ERROR (Status);\r
1218 return Status;\r
1219}\r
1220\r
1221/** Deregister the Generator from the ACPI Table Factory.\r
1222\r
1223 @param [in] ImageHandle The handle to the image.\r
1224 @param [in] SystemTable Pointer to the System Table.\r
1225\r
1226 @retval EFI_SUCCESS The Generator is deregistered.\r
1227 @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
1228 @retval EFI_NOT_FOUND The Generator is not registered.\r
1229**/\r
1230EFI_STATUS\r
1231EFIAPI\r
1232AcpiSsdtPcieLibDestructor (\r
1233 IN EFI_HANDLE ImageHandle,\r
1234 IN EFI_SYSTEM_TABLE *SystemTable\r
1235 )\r
1236{\r
1237 EFI_STATUS Status;\r
1238\r
1239 Status = DeregisterAcpiTableGenerator (&SsdtPcieGenerator.Header);\r
1240 DEBUG ((\r
1241 DEBUG_INFO,\r
1242 "SSDT-PCI: Deregister Generator. Status = %r\n",\r
1243 Status\r
1244 ));\r
1245 ASSERT_EFI_ERROR (Status);\r
1246 return Status;\r
1247}\r