4 Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
8 - ACPI 6.2 Specification - Errata A, September 2017
12 #include <Library/AcpiLib.h>
13 #include <Library/DebugLib.h>
14 #include <Library/MemoryAllocationLib.h>
15 #include <Protocol/AcpiTable.h>
17 // Module specific include files.
18 #include <AcpiTableGenerator.h>
19 #include <ConfigurationManagerObject.h>
20 #include <ConfigurationManagerHelper.h>
21 #include <Library/TableHelperLib.h>
22 #include <Protocol/ConfigurationManagerProtocol.h>
24 /** ARM standard MADT Generator
27 The following Configuration Manager Object(s) are required by
31 - EArmObjGicMsiFrameInfo (OPTIONAL)
32 - EArmObjGicRedistributorInfo (OPTIONAL)
33 - EArmObjGicItsInfo (OPTIONAL)
36 /** This macro expands to a function that retrieves the GIC
37 CPU interface Information from the Configuration Manager.
45 /** This macro expands to a function that retrieves the GIC
46 Distributor Information from the Configuration Manager.
55 /** This macro expands to a function that retrieves the GIC
56 MSI Frame Information from the Configuration Manager.
60 EArmObjGicMsiFrameInfo
,
61 CM_ARM_GIC_MSI_FRAME_INFO
64 /** This macro expands to a function that retrieves the GIC
65 Redistributor Information from the Configuration Manager.
70 EArmObjGicRedistributorInfo
,
71 CM_ARM_GIC_REDIST_INFO
74 /** This macro expands to a function that retrieves the GIC
75 Interrupt Translation Service Information from the
76 Configuration Manager.
84 /** This function updates the GIC CPU Interface Information in the
85 EFI_ACPI_6_2_GIC_STRUCTURE structure.
87 @param [in] Gicc Pointer to GIC CPU Interface structure.
88 @param [in] GicCInfo Pointer to the GIC CPU Interface Information.
93 IN EFI_ACPI_6_2_GIC_STRUCTURE
* CONST Gicc
,
94 IN CONST CM_ARM_GICC_INFO
* CONST GicCInfo
97 ASSERT (Gicc
!= NULL
);
98 ASSERT (GicCInfo
!= NULL
);
101 Gicc
->Type
= EFI_ACPI_6_2_GIC
;
103 Gicc
->Length
= sizeof (EFI_ACPI_6_2_GIC_STRUCTURE
);
105 Gicc
->Reserved
= EFI_ACPI_RESERVED_WORD
;
107 // UINT32 CPUInterfaceNumber
108 Gicc
->CPUInterfaceNumber
= GicCInfo
->CPUInterfaceNumber
;
109 // UINT32 AcpiProcessorUid
110 Gicc
->AcpiProcessorUid
= GicCInfo
->AcpiProcessorUid
;
112 Gicc
->Flags
= GicCInfo
->Flags
;
113 // UINT32 ParkingProtocolVersion
114 Gicc
->ParkingProtocolVersion
= GicCInfo
->ParkingProtocolVersion
;
115 // UINT32 PerformanceInterruptGsiv
116 Gicc
->PerformanceInterruptGsiv
= GicCInfo
->PerformanceInterruptGsiv
;
117 // UINT64 ParkedAddress
118 Gicc
->ParkedAddress
= GicCInfo
->ParkedAddress
;
120 // UINT64 PhysicalBaseAddress
121 Gicc
->PhysicalBaseAddress
= GicCInfo
->PhysicalBaseAddress
;
123 Gicc
->GICV
= GicCInfo
->GICV
;
125 Gicc
->GICH
= GicCInfo
->GICH
;
127 // UINT32 VGICMaintenanceInterrupt
128 Gicc
->VGICMaintenanceInterrupt
= GicCInfo
->VGICMaintenanceInterrupt
;
129 // UINT64 GICRBaseAddress
130 Gicc
->GICRBaseAddress
= GicCInfo
->GICRBaseAddress
;
133 Gicc
->MPIDR
= GicCInfo
->MPIDR
;
134 // UINT8 ProcessorPowerEfficiencyClass
135 Gicc
->ProcessorPowerEfficiencyClass
=
136 GicCInfo
->ProcessorPowerEfficiencyClass
;
137 // UINT8 Reserved2[3]
138 Gicc
->Reserved2
[0] = EFI_ACPI_RESERVED_BYTE
;
139 Gicc
->Reserved2
[1] = EFI_ACPI_RESERVED_BYTE
;
140 Gicc
->Reserved2
[2] = EFI_ACPI_RESERVED_BYTE
;
144 Function to test if two GIC CPU Interface information structures have the
145 same ACPI Processor UID.
147 @param [in] GicCInfo1 Pointer to the first GICC info structure.
148 @param [in] GicCInfo2 Pointer to the second GICC info structure.
149 @param [in] Index1 Index of GicCInfo1 in the shared list of GIC
150 CPU Interface Info structures.
151 @param [in] Index2 Index of GicCInfo2 in the shared list of GIC
152 CPU Interface Info structures.
154 @retval TRUE GicCInfo1 and GicCInfo2 have the same UID.
155 @retval FALSE GicCInfo1 and GicCInfo2 have different UIDs.
160 IN CONST VOID
* GicCInfo1
,
161 IN CONST VOID
* GicCInfo2
,
169 ASSERT ((GicCInfo1
!= NULL
) && (GicCInfo2
!= NULL
));
171 Uid1
= ((CM_ARM_GICC_INFO
*)GicCInfo1
)->AcpiProcessorUid
;
172 Uid2
= ((CM_ARM_GICC_INFO
*)GicCInfo2
)->AcpiProcessorUid
;
177 "ERROR: MADT: GICC Info Structures %d and %d have the same ACPI " \
178 "Processor UID: 0x%x.\n",
189 /** Add the GIC CPU Interface Information to the MADT Table.
191 This function also checks for duplicate ACPI Processor UIDs.
193 @param [in] Gicc Pointer to GIC CPU Interface structure list.
194 @param [in] GicCInfo Pointer to the GIC CPU Information list.
195 @param [in] GicCCount Count of GIC CPU Interfaces.
197 @retval EFI_SUCCESS GIC CPU Interface Information was added
199 @retval EFI_INVALID_PARAMETER One or more invalid GIC CPU Info values were
200 provided and the generator failed to add the
201 information to the table.
206 IN EFI_ACPI_6_2_GIC_STRUCTURE
* Gicc
,
207 IN CONST CM_ARM_GICC_INFO
* GicCInfo
,
211 BOOLEAN IsAcpiProcUidDuplicated
;
213 ASSERT (Gicc
!= NULL
);
214 ASSERT (GicCInfo
!= NULL
);
216 IsAcpiProcUidDuplicated
= FindDuplicateValue (
219 sizeof (CM_ARM_GICC_INFO
),
222 // Duplicate ACPI Processor UID was found so the GICC info provided
224 if (IsAcpiProcUidDuplicated
) {
225 return EFI_INVALID_PARAMETER
;
228 while (GicCCount
-- != 0) {
229 AddGICC (Gicc
++, GicCInfo
++);
235 /** Update the GIC Distributor Information in the MADT Table.
237 @param [in] Gicd Pointer to GIC Distributor structure.
238 @param [in] GicDInfo Pointer to the GIC Distributor Information.
243 EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE
* CONST Gicd
,
244 CONST CM_ARM_GICD_INFO
* CONST GicDInfo
247 ASSERT (Gicd
!= NULL
);
248 ASSERT (GicDInfo
!= NULL
);
251 Gicd
->Type
= EFI_ACPI_6_2_GICD
;
253 Gicd
->Length
= sizeof (EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE
);
255 Gicd
->Reserved1
= EFI_ACPI_RESERVED_WORD
;
257 // One, and only one, GIC distributor structure must be present
258 // in the MADT for an ARM based system
260 // UINT64 PhysicalBaseAddress
261 Gicd
->PhysicalBaseAddress
= GicDInfo
->PhysicalBaseAddress
;
263 Gicd
->SystemVectorBase
= EFI_ACPI_RESERVED_DWORD
;
265 Gicd
->GicVersion
= GicDInfo
->GicVersion
;
266 // UINT8 Reserved2[3]
267 Gicd
->Reserved2
[0] = EFI_ACPI_RESERVED_BYTE
;
268 Gicd
->Reserved2
[1] = EFI_ACPI_RESERVED_BYTE
;
269 Gicd
->Reserved2
[2] = EFI_ACPI_RESERVED_BYTE
;
272 /** Update the GIC MSI Frame Information.
274 @param [in] GicMsiFrame Pointer to GIC MSI Frame structure.
275 @param [in] GicMsiFrameInfo Pointer to the GIC MSI Frame Information.
280 IN EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE
* CONST GicMsiFrame
,
281 IN CONST CM_ARM_GIC_MSI_FRAME_INFO
* CONST GicMsiFrameInfo
284 ASSERT (GicMsiFrame
!= NULL
);
285 ASSERT (GicMsiFrameInfo
!= NULL
);
287 GicMsiFrame
->Type
= EFI_ACPI_6_2_GIC_MSI_FRAME
;
288 GicMsiFrame
->Length
= sizeof (EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE
);
289 GicMsiFrame
->Reserved1
= EFI_ACPI_RESERVED_WORD
;
290 GicMsiFrame
->GicMsiFrameId
= GicMsiFrameInfo
->GicMsiFrameId
;
291 GicMsiFrame
->PhysicalBaseAddress
= GicMsiFrameInfo
->PhysicalBaseAddress
;
293 GicMsiFrame
->Flags
= GicMsiFrameInfo
->Flags
;
294 GicMsiFrame
->SPICount
= GicMsiFrameInfo
->SPICount
;
295 GicMsiFrame
->SPIBase
= GicMsiFrameInfo
->SPIBase
;
298 /** Add the GIC MSI Frame Information to the MADT Table.
300 @param [in] GicMsiFrame Pointer to GIC MSI Frame structure list.
301 @param [in] GicMsiFrameInfo Pointer to the GIC MSI Frame info list.
302 @param [in] GicMsiFrameCount Count of GIC MSI Frames.
306 AddGICMsiFrameInfoList (
307 IN EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE
* GicMsiFrame
,
308 IN CONST CM_ARM_GIC_MSI_FRAME_INFO
* GicMsiFrameInfo
,
309 IN UINT32 GicMsiFrameCount
312 ASSERT (GicMsiFrame
!= NULL
);
313 ASSERT (GicMsiFrameInfo
!= NULL
);
315 while (GicMsiFrameCount
-- != 0) {
316 AddGICMsiFrame (GicMsiFrame
++, GicMsiFrameInfo
++);
320 /** Update the GIC Redistributor Information.
322 @param [in] Gicr Pointer to GIC Redistributor structure.
323 @param [in] GicRedisributorInfo Pointer to the GIC Redistributor Info.
327 AddGICRedistributor (
328 IN EFI_ACPI_6_2_GICR_STRUCTURE
* CONST Gicr
,
329 IN CONST CM_ARM_GIC_REDIST_INFO
* CONST GicRedisributorInfo
332 ASSERT (Gicr
!= NULL
);
333 ASSERT (GicRedisributorInfo
!= NULL
);
335 Gicr
->Type
= EFI_ACPI_6_2_GICR
;
336 Gicr
->Length
= sizeof (EFI_ACPI_6_2_GICR_STRUCTURE
);
337 Gicr
->Reserved
= EFI_ACPI_RESERVED_WORD
;
338 Gicr
->DiscoveryRangeBaseAddress
=
339 GicRedisributorInfo
->DiscoveryRangeBaseAddress
;
340 Gicr
->DiscoveryRangeLength
= GicRedisributorInfo
->DiscoveryRangeLength
;
343 /** Add the GIC Redistributor Information to the MADT Table.
345 @param [in] Gicr Pointer to GIC Redistributor structure list.
346 @param [in] GicRInfo Pointer to the GIC Distributor info list.
347 @param [in] GicRCount Count of GIC Distributors.
351 AddGICRedistributorList (
352 IN EFI_ACPI_6_2_GICR_STRUCTURE
* Gicr
,
353 IN CONST CM_ARM_GIC_REDIST_INFO
* GicRInfo
,
357 ASSERT (Gicr
!= NULL
);
358 ASSERT (GicRInfo
!= NULL
);
360 while (GicRCount
-- != 0) {
361 AddGICRedistributor (Gicr
++, GicRInfo
++);
365 /** Update the GIC Interrupt Translation Service Information
367 @param [in] GicIts Pointer to GIC ITS structure.
368 @param [in] GicItsInfo Pointer to the GIC ITS Information.
372 AddGICInterruptTranslationService (
373 IN EFI_ACPI_6_2_GIC_ITS_STRUCTURE
* CONST GicIts
,
374 IN CONST CM_ARM_GIC_ITS_INFO
* CONST GicItsInfo
377 ASSERT (GicIts
!= NULL
);
378 ASSERT (GicItsInfo
!= NULL
);
380 GicIts
->Type
= EFI_ACPI_6_2_GIC_ITS
;
381 GicIts
->Length
= sizeof (EFI_ACPI_6_2_GIC_ITS_STRUCTURE
);
382 GicIts
->Reserved
= EFI_ACPI_RESERVED_WORD
;
383 GicIts
->GicItsId
= GicItsInfo
->GicItsId
;
384 GicIts
->PhysicalBaseAddress
= GicItsInfo
->PhysicalBaseAddress
;
385 GicIts
->Reserved2
= EFI_ACPI_RESERVED_DWORD
;
388 /** Add the GIC Interrupt Translation Service Information
391 @param [in] GicIts Pointer to GIC ITS structure list.
392 @param [in] GicItsInfo Pointer to the GIC ITS list.
393 @param [in] GicItsCount Count of GIC ITS.
398 IN EFI_ACPI_6_2_GIC_ITS_STRUCTURE
* GicIts
,
399 IN CONST CM_ARM_GIC_ITS_INFO
* GicItsInfo
,
400 IN UINT32 GicItsCount
403 ASSERT (GicIts
!= NULL
);
404 ASSERT (GicItsInfo
!= NULL
);
406 while (GicItsCount
-- != 0) {
407 AddGICInterruptTranslationService (GicIts
++, GicItsInfo
++);
411 /** Construct the MADT ACPI table.
413 This function invokes the Configuration Manager protocol interface
414 to get the required hardware information for generating the ACPI
417 If this function allocates any resources then they must be freed
418 in the FreeXXXXTableResources function.
420 @param [in] This Pointer to the table generator.
421 @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
422 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
424 @param [out] Table Pointer to the constructed ACPI Table.
426 @retval EFI_SUCCESS Table generated successfully.
427 @retval EFI_INVALID_PARAMETER A parameter is invalid.
428 @retval EFI_NOT_FOUND The required object was not found.
429 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
430 Manager is less than the Object size for the
437 IN CONST ACPI_TABLE_GENERATOR
* CONST This
,
438 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO
* CONST AcpiTableInfo
,
439 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL
* CONST CfgMgrProtocol
,
440 OUT EFI_ACPI_DESCRIPTION_HEADER
** CONST Table
448 UINT32 GicRedistCount
;
450 CM_ARM_GICC_INFO
* GicCInfo
;
451 CM_ARM_GICD_INFO
* GicDInfo
;
452 CM_ARM_GIC_MSI_FRAME_INFO
* GicMSIInfo
;
453 CM_ARM_GIC_REDIST_INFO
* GicRedistInfo
;
454 CM_ARM_GIC_ITS_INFO
* GicItsInfo
;
458 UINT32 GicRedistOffset
;
461 EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER
* Madt
;
463 ASSERT (This
!= NULL
);
464 ASSERT (AcpiTableInfo
!= NULL
);
465 ASSERT (CfgMgrProtocol
!= NULL
);
466 ASSERT (Table
!= NULL
);
467 ASSERT (AcpiTableInfo
->TableGeneratorId
== This
->GeneratorID
);
468 ASSERT (AcpiTableInfo
->AcpiTableSignature
== This
->AcpiTableSignature
);
470 if ((AcpiTableInfo
->AcpiTableRevision
< This
->MinAcpiTableRevision
) ||
471 (AcpiTableInfo
->AcpiTableRevision
> This
->AcpiTableRevision
)) {
474 "ERROR: MADT: Requested table revision = %d, is not supported."
475 "Supported table revision: Minimum = %d, Maximum = %d\n",
476 AcpiTableInfo
->AcpiTableRevision
,
477 This
->MinAcpiTableRevision
,
478 This
->AcpiTableRevision
480 return EFI_INVALID_PARAMETER
;
485 Status
= GetEArmObjGicCInfo (
491 if (EFI_ERROR (Status
)) {
494 "ERROR: MADT: Failed to get GICC Info. Status = %r\n",
500 if (GicCCount
== 0) {
503 "ERROR: MADT: GIC CPU Interface information not provided.\n"
505 ASSERT (GicCCount
!= 0);
506 Status
= EFI_INVALID_PARAMETER
;
510 Status
= GetEArmObjGicDInfo (
516 if (EFI_ERROR (Status
)) {
519 "ERROR: MADT: Failed to get GICD Info. Status = %r\n",
525 if (GicDCount
== 0) {
528 "ERROR: MADT: GIC Distributor information not provided.\n"
530 ASSERT (GicDCount
!= 0);
531 Status
= EFI_INVALID_PARAMETER
;
538 "ERROR: MADT: One, and only one, GIC distributor must be present."
542 ASSERT (GicDCount
<= 1);
543 Status
= EFI_INVALID_PARAMETER
;
547 Status
= GetEArmObjGicMsiFrameInfo (
553 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
556 "ERROR: MADT: Failed to get GIC MSI Info. Status = %r\n",
562 Status
= GetEArmObjGicRedistributorInfo (
568 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
571 "ERROR: MADT: Failed to get GIC Redistributor Info. Status = %r\n",
577 Status
= GetEArmObjGicItsInfo (
583 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
586 "ERROR: MADT: Failed to get GIC ITS Info. Status = %r\n",
592 TableSize
= sizeof (EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER
);
594 GicCOffset
= TableSize
;
595 TableSize
+= (sizeof (EFI_ACPI_6_2_GIC_STRUCTURE
) * GicCCount
);
597 GicDOffset
= TableSize
;
598 TableSize
+= (sizeof (EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE
) * GicDCount
);
600 GicMSIOffset
= TableSize
;
601 TableSize
+= (sizeof (EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE
) * GicMSICount
);
603 GicRedistOffset
= TableSize
;
604 TableSize
+= (sizeof (EFI_ACPI_6_2_GICR_STRUCTURE
) * GicRedistCount
);
606 GicItsOffset
= TableSize
;
607 TableSize
+= (sizeof (EFI_ACPI_6_2_GIC_ITS_STRUCTURE
) * GicItsCount
);
609 // Allocate the Buffer for MADT table
610 *Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)AllocateZeroPool (TableSize
);
611 if (*Table
== NULL
) {
612 Status
= EFI_OUT_OF_RESOURCES
;
615 "ERROR: MADT: Failed to allocate memory for MADT Table, Size = %d," \
623 Madt
= (EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER
*)*Table
;
627 "MADT: Madt = 0x%p TableSize = 0x%x\n",
632 Status
= AddAcpiHeader (
639 if (EFI_ERROR (Status
)) {
642 "ERROR: MADT: Failed to add ACPI header. Status = %r\n",
648 Status
= AddGICCList (
649 (EFI_ACPI_6_2_GIC_STRUCTURE
*)((UINT8
*)Madt
+ GicCOffset
),
653 if (EFI_ERROR (Status
)) {
656 "ERROR: MADT: Failed to add GICC structures. Status = %r\n",
663 (EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE
*)((UINT8
*)Madt
+ GicDOffset
),
667 if (GicMSICount
!= 0) {
668 AddGICMsiFrameInfoList (
669 (EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE
*)((UINT8
*)Madt
+ GicMSIOffset
),
675 if (GicRedistCount
!= 0) {
676 AddGICRedistributorList (
677 (EFI_ACPI_6_2_GICR_STRUCTURE
*)((UINT8
*)Madt
+ GicRedistOffset
),
683 if (GicItsCount
!= 0) {
685 (EFI_ACPI_6_2_GIC_ITS_STRUCTURE
*)((UINT8
*)Madt
+ GicItsOffset
),
694 if (*Table
!= NULL
) {
701 /** Free any resources allocated for constructing the MADT
703 @param [in] This Pointer to the table generator.
704 @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
705 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
707 @param [in, out] Table Pointer to the ACPI Table.
709 @retval EFI_SUCCESS The resources were freed successfully.
710 @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
714 FreeMadtTableResources (
715 IN CONST ACPI_TABLE_GENERATOR
* CONST This
,
716 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO
* CONST AcpiTableInfo
,
717 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL
* CONST CfgMgrProtocol
,
718 IN OUT EFI_ACPI_DESCRIPTION_HEADER
** CONST Table
721 ASSERT (This
!= NULL
);
722 ASSERT (AcpiTableInfo
!= NULL
);
723 ASSERT (CfgMgrProtocol
!= NULL
);
724 ASSERT (AcpiTableInfo
->TableGeneratorId
== This
->GeneratorID
);
725 ASSERT (AcpiTableInfo
->AcpiTableSignature
== This
->AcpiTableSignature
);
727 if ((Table
== NULL
) || (*Table
== NULL
)) {
728 DEBUG ((DEBUG_ERROR
, "ERROR: MADT: Invalid Table Pointer\n"));
729 ASSERT ((Table
!= NULL
) && (*Table
!= NULL
));
730 return EFI_INVALID_PARAMETER
;
738 /** The MADT Table Generator revision.
740 #define MADT_GENERATOR_REVISION CREATE_REVISION (1, 0)
742 /** The interface for the MADT Table Generator.
746 ACPI_TABLE_GENERATOR MadtGenerator
= {
748 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMadt
),
749 // Generator Description
750 L
"ACPI.STD.MADT.GENERATOR",
751 // ACPI Table Signature
752 EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE
,
753 // ACPI Table Revision supported by this Generator
754 EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION
,
755 // Minimum supported ACPI Table Revision
756 EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION
,
758 TABLE_GENERATOR_CREATOR_ID_ARM
,
760 MADT_GENERATOR_REVISION
,
761 // Build Table function
763 // Free Resource function
764 FreeMadtTableResources
,
765 // Extended build function not needed
767 // Extended build function not implemented by the generator.
768 // Hence extended free resource function is not required.
772 /** Register the Generator with the ACPI Table Factory.
774 @param [in] ImageHandle The handle to the image.
775 @param [in] SystemTable Pointer to the System Table.
777 @retval EFI_SUCCESS The Generator is registered.
778 @retval EFI_INVALID_PARAMETER A parameter is invalid.
779 @retval EFI_ALREADY_STARTED The Generator for the Table ID
780 is already registered.
784 AcpiMadtLibConstructor (
785 IN CONST EFI_HANDLE ImageHandle
,
786 IN EFI_SYSTEM_TABLE
* CONST SystemTable
790 Status
= RegisterAcpiTableGenerator (&MadtGenerator
);
791 DEBUG ((DEBUG_INFO
, "MADT: Register Generator. Status = %r\n", Status
));
792 ASSERT_EFI_ERROR (Status
);
796 /** Deregister the Generator from the ACPI Table Factory.
798 @param [in] ImageHandle The handle to the image.
799 @param [in] SystemTable Pointer to the System Table.
801 @retval EFI_SUCCESS The Generator is deregistered.
802 @retval EFI_INVALID_PARAMETER A parameter is invalid.
803 @retval EFI_NOT_FOUND The Generator is not registered.
807 AcpiMadtLibDestructor (
808 IN CONST EFI_HANDLE ImageHandle
,
809 IN EFI_SYSTEM_TABLE
* CONST SystemTable
813 Status
= DeregisterAcpiTableGenerator (&MadtGenerator
);
814 DEBUG ((DEBUG_INFO
, "MADT: Deregister Generator. Status = %r\n", Status
));
815 ASSERT_EFI_ERROR (Status
);