4 Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
8 - ACPI 6.3 Specification - January 2019
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 GTDT Generator
27 The following Configuration Manager Object(s) are required by
29 - EArmObjGenericTimerInfo
30 - EArmObjPlatformGenericWatchdogInfo (OPTIONAL)
31 - EArmObjPlatformGTBlockInfo (OPTIONAL)
32 - EArmObjGTBlockTimerFrameInfo (OPTIONAL)
35 /** This macro expands to a function that retrieves the Generic
36 Timer Information from the Configuration Manager.
40 EArmObjGenericTimerInfo
,
41 CM_ARM_GENERIC_TIMER_INFO
44 /** This macro expands to a function that retrieves the SBSA Generic
45 Watchdog Timer Information from the Configuration Manager.
49 EArmObjPlatformGenericWatchdogInfo
,
50 CM_ARM_GENERIC_WATCHDOG_INFO
53 /** This macro expands to a function that retrieves the Platform Generic
54 Timer Block Information from the Configuration Manager.
58 EArmObjPlatformGTBlockInfo
,
62 /** This macro expands to a function that retrieves the Generic
63 Timer Block Timer Frame Information from the Configuration Manager.
67 EArmObjGTBlockTimerFrameInfo
,
68 CM_ARM_GTBLOCK_TIMER_FRAME_INFO
71 /** Add the Generic Timer Information to the GTDT table.
73 Also update the Platform Timer offset information if the platform
74 implements platform timers.
76 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
78 @param [in] Gtdt Pointer to the GTDT Table.
79 @param [in] PlatformTimerCount Platform timer count.
80 @param [in] AcpiTableRevision Acpi Revision targeted by the platform.
82 @retval EFI_SUCCESS Success.
83 @retval EFI_INVALID_PARAMETER A parameter is invalid.
84 @retval EFI_NOT_FOUND The required object was not found.
85 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
86 Manager is less than the Object size for the
93 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL
* CONST CfgMgrProtocol
,
94 IN EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE
* CONST Gtdt
,
95 IN CONST UINT32 PlatformTimerCount
,
96 IN CONST UINT32 AcpiTableRevision
100 CM_ARM_GENERIC_TIMER_INFO
* GenericTimerInfo
;
102 ASSERT (CfgMgrProtocol
!= NULL
);
103 ASSERT (Gtdt
!= NULL
);
105 Status
= GetEArmObjGenericTimerInfo (
112 if (EFI_ERROR (Status
)) {
115 "ERROR: GTDT: Failed to get GenericTimerInfo. Status = %r\n",
121 Gtdt
->CntControlBasePhysicalAddress
=
122 GenericTimerInfo
->CounterControlBaseAddress
;
123 Gtdt
->Reserved
= EFI_ACPI_RESERVED_DWORD
;
124 Gtdt
->SecurePL1TimerGSIV
= GenericTimerInfo
->SecurePL1TimerGSIV
;
125 Gtdt
->SecurePL1TimerFlags
= GenericTimerInfo
->SecurePL1TimerFlags
;
126 Gtdt
->NonSecurePL1TimerGSIV
= GenericTimerInfo
->NonSecurePL1TimerGSIV
;
127 Gtdt
->NonSecurePL1TimerFlags
= GenericTimerInfo
->NonSecurePL1TimerFlags
;
128 Gtdt
->VirtualTimerGSIV
= GenericTimerInfo
->VirtualTimerGSIV
;
129 Gtdt
->VirtualTimerFlags
= GenericTimerInfo
->VirtualTimerFlags
;
130 Gtdt
->NonSecurePL2TimerGSIV
= GenericTimerInfo
->NonSecurePL2TimerGSIV
;
131 Gtdt
->NonSecurePL2TimerFlags
= GenericTimerInfo
->NonSecurePL2TimerFlags
;
132 Gtdt
->CntReadBasePhysicalAddress
=
133 GenericTimerInfo
->CounterReadBaseAddress
;
134 Gtdt
->PlatformTimerCount
= PlatformTimerCount
;
135 Gtdt
->PlatformTimerOffset
= (PlatformTimerCount
== 0) ? 0 :
136 sizeof (EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE
);
138 if (AcpiTableRevision
> EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION
) {
139 Gtdt
->VirtualPL2TimerGSIV
= GenericTimerInfo
->VirtualPL2TimerGSIV
;
140 Gtdt
->VirtualPL2TimerFlags
= GenericTimerInfo
->VirtualPL2TimerFlags
;
146 /** Add the SBSA Generic Watchdog Timers to the GTDT table.
148 @param [in] Gtdt Pointer to the GTDT Table.
149 @param [in] WatchdogOffset Offset to the watchdog information in the
151 @param [in] WatchdogInfoList Pointer to the watchdog information list.
152 @param [in] WatchdogCount Platform timer count.
156 AddGenericWatchdogList (
157 IN EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE
* CONST Gtdt
,
158 IN CONST UINT32 WatchdogOffset
,
159 IN CONST CM_ARM_GENERIC_WATCHDOG_INFO
* WatchdogInfoList
,
160 IN UINT32 WatchdogCount
163 EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE
* Watchdog
;
165 ASSERT (Gtdt
!= NULL
);
166 ASSERT (WatchdogInfoList
!= NULL
);
168 Watchdog
= (EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE
*)
169 ((UINT8
*)Gtdt
+ WatchdogOffset
);
171 while (WatchdogCount
-- != 0) {
172 // Add watchdog entry
173 DEBUG ((DEBUG_INFO
, "GTDT: Watchdog = 0x%p\n", Watchdog
));
174 Watchdog
->Type
= EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG
;
176 sizeof (EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE
);
177 Watchdog
->Reserved
= EFI_ACPI_RESERVED_BYTE
;
178 Watchdog
->RefreshFramePhysicalAddress
=
179 WatchdogInfoList
->RefreshFrameAddress
;
180 Watchdog
->WatchdogControlFramePhysicalAddress
=
181 WatchdogInfoList
->ControlFrameAddress
;
182 Watchdog
->WatchdogTimerGSIV
= WatchdogInfoList
->TimerGSIV
;
183 Watchdog
->WatchdogTimerFlags
= WatchdogInfoList
->Flags
;
190 Function to test if two Generic Timer Block Frame Info structures have the
193 @param [in] Frame1 Pointer to the first GT Block Frame Info
195 @param [in] Frame2 Pointer to the second GT Block Frame Info
197 @param [in] Index1 Index of Frame1 in the shared GT Block Frame
199 @param [in] Index2 Index of Frame2 in the shared GT Block Frame
202 @retval TRUE Frame1 and Frame2 have the same frame number.
203 @return FALSE Frame1 and Frame2 have different frame numbers.
208 IsGtFrameNumberEqual (
209 IN CONST VOID
* Frame1
,
210 IN CONST VOID
* Frame2
,
218 ASSERT ((Frame1
!= NULL
) && (Frame2
!= NULL
));
220 FrameNumber1
= ((CM_ARM_GTBLOCK_TIMER_FRAME_INFO
*)Frame1
)->FrameNumber
;
221 FrameNumber2
= ((CM_ARM_GTBLOCK_TIMER_FRAME_INFO
*)Frame2
)->FrameNumber
;
223 if (FrameNumber1
== FrameNumber2
) {
226 "ERROR: GTDT: GT Block Frame Info Structures %d and %d have the same " \
227 "frame number: 0x%x.\n",
238 /** Update the GT Block Timer Frame lists in the GTDT Table.
240 @param [in] GtBlockFrame Pointer to the GT Block Frames
242 @param [in] GTBlockTimerFrameList Pointer to the GT Block Frame
244 @param [in] GTBlockFrameCount Number of GT Block Frames.
246 @retval EFI_SUCCESS Table generated successfully.
247 @retval EFI_INVALID_PARAMETER A parameter is invalid.
251 AddGTBlockTimerFrames (
252 IN EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_STRUCTURE
* GtBlockFrame
,
253 IN CONST CM_ARM_GTBLOCK_TIMER_FRAME_INFO
* GTBlockTimerFrameList
,
254 IN UINT32 GTBlockFrameCount
257 BOOLEAN IsFrameNumberDuplicated
;
259 ASSERT (GtBlockFrame
!= NULL
);
260 ASSERT (GTBlockTimerFrameList
!= NULL
);
262 if (GTBlockFrameCount
> 8) {
265 "ERROR: GTDT: GT Block Frame Count %d is greater than 8\n",
268 ASSERT (GTBlockFrameCount
<= 8);
269 return EFI_INVALID_PARAMETER
;
272 IsFrameNumberDuplicated
= FindDuplicateValue (
273 GTBlockTimerFrameList
,
275 sizeof (CM_ARM_GTBLOCK_TIMER_FRAME_INFO
),
278 // Duplicate entry was found so timer frame numbers provided are invalid
279 if (IsFrameNumberDuplicated
) {
280 return EFI_INVALID_PARAMETER
;
283 while (GTBlockFrameCount
-- != 0) {
286 "GTDT: GtBlockFrame = 0x%p\n",
290 if (GTBlockTimerFrameList
->FrameNumber
>= 8) {
293 "ERROR: GTDT: Frame number %d is not in the range 0-7\n",
294 GTBlockTimerFrameList
->FrameNumber
296 return EFI_INVALID_PARAMETER
;
299 GtBlockFrame
->GTFrameNumber
= GTBlockTimerFrameList
->FrameNumber
;
300 GtBlockFrame
->Reserved
[0] = EFI_ACPI_RESERVED_BYTE
;
301 GtBlockFrame
->Reserved
[1] = EFI_ACPI_RESERVED_BYTE
;
302 GtBlockFrame
->Reserved
[2] = EFI_ACPI_RESERVED_BYTE
;
304 GtBlockFrame
->CntBaseX
= GTBlockTimerFrameList
->PhysicalAddressCntBase
;
305 GtBlockFrame
->CntEL0BaseX
=
306 GTBlockTimerFrameList
->PhysicalAddressCntEL0Base
;
308 GtBlockFrame
->GTxPhysicalTimerGSIV
=
309 GTBlockTimerFrameList
->PhysicalTimerGSIV
;
310 GtBlockFrame
->GTxPhysicalTimerFlags
=
311 GTBlockTimerFrameList
->PhysicalTimerFlags
;
313 GtBlockFrame
->GTxVirtualTimerGSIV
= GTBlockTimerFrameList
->VirtualTimerGSIV
;
314 GtBlockFrame
->GTxVirtualTimerFlags
=
315 GTBlockTimerFrameList
->VirtualTimerFlags
;
317 GtBlockFrame
->GTxCommonFlags
= GTBlockTimerFrameList
->CommonFlags
;
319 GTBlockTimerFrameList
++;
324 /** Add the GT Block Timers in the GTDT Table.
326 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
328 @param [in] Gtdt Pointer to the GTDT Table.
329 @param [in] GTBlockOffset Offset of the GT Block
330 information in the GTDT Table.
331 @param [in] GTBlockInfo Pointer to the GT Block
333 @param [in] BlockTimerCount Number of GT Block Timers.
335 @retval EFI_SUCCESS Table generated successfully.
336 @retval EFI_INVALID_PARAMETER A parameter is invalid.
341 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL
* CONST CfgMgrProtocol
,
342 IN EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE
* CONST Gtdt
,
343 IN CONST UINT32 GTBlockOffset
,
344 IN CONST CM_ARM_GTBLOCK_INFO
* GTBlockInfo
,
345 IN UINT32 BlockTimerCount
349 EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE
* GTBlock
;
350 EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_STRUCTURE
* GtBlockFrame
;
351 CM_ARM_GTBLOCK_TIMER_FRAME_INFO
* GTBlockTimerFrameList
;
352 UINT32 GTBlockTimerFrameCount
;
354 ASSERT (Gtdt
!= NULL
);
355 ASSERT (GTBlockInfo
!= NULL
);
357 GTBlock
= (EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE
*)((UINT8
*)Gtdt
+
360 while (BlockTimerCount
-- != 0) {
361 DEBUG ((DEBUG_INFO
, "GTDT: GTBlock = 0x%p\n", GTBlock
));
363 Status
= GetEArmObjGTBlockTimerFrameInfo (
365 GTBlockInfo
->GTBlockTimerFrameToken
,
366 >BlockTimerFrameList
,
367 >BlockTimerFrameCount
369 if (EFI_ERROR (Status
) ||
370 (GTBlockTimerFrameCount
!= GTBlockInfo
->GTBlockTimerFrameCount
)) {
373 "ERROR: GTDT: Failed to get Generic Timer Frames. Status = %r\n",
379 GTBlock
->Type
= EFI_ACPI_6_3_GTDT_GT_BLOCK
;
380 GTBlock
->Length
= sizeof (EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE
) +
381 (sizeof (EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_STRUCTURE
) *
382 GTBlockInfo
->GTBlockTimerFrameCount
);
384 GTBlock
->Reserved
= EFI_ACPI_RESERVED_BYTE
;
385 GTBlock
->CntCtlBase
= GTBlockInfo
->GTBlockPhysicalAddress
;
386 GTBlock
->GTBlockTimerCount
= GTBlockInfo
->GTBlockTimerFrameCount
;
387 GTBlock
->GTBlockTimerOffset
=
388 sizeof (EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE
);
390 GtBlockFrame
= (EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_STRUCTURE
*)
391 ((UINT8
*)GTBlock
+ GTBlock
->GTBlockTimerOffset
);
393 // Add GT Block Timer frames
394 Status
= AddGTBlockTimerFrames (
396 GTBlockTimerFrameList
,
397 GTBlockTimerFrameCount
399 if (EFI_ERROR (Status
)) {
402 "ERROR: GTDT: Failed to add Generic Timer Frames. Status = %r\n",
409 GTBlock
= (EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE
*)((UINT8
*)GTBlock
+
416 /** Construct the GTDT ACPI table.
418 Called by the Dynamic Table Manager, this function invokes the
419 Configuration Manager protocol interface to get the required hardware
420 information for generating the ACPI table.
422 If this function allocates any resources then they must be freed
423 in the FreeXXXXTableResources function.
425 @param [in] This Pointer to the table generator.
426 @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
427 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
429 @param [out] Table Pointer to the constructed ACPI Table.
431 @retval EFI_SUCCESS Table generated successfully.
432 @retval EFI_INVALID_PARAMETER A parameter is invalid.
433 @retval EFI_NOT_FOUND The required object was not found.
434 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
435 Manager is less than the Object size for the
437 @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
443 IN CONST ACPI_TABLE_GENERATOR
* CONST This
,
444 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO
* CONST AcpiTableInfo
,
445 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL
* CONST CfgMgrProtocol
,
446 OUT EFI_ACPI_DESCRIPTION_HEADER
** CONST Table
451 UINT32 PlatformTimerCount
;
452 UINT32 WatchdogCount
;
453 UINT32 BlockTimerCount
;
454 CM_ARM_GENERIC_WATCHDOG_INFO
* WatchdogInfoList
;
455 CM_ARM_GTBLOCK_INFO
* GTBlockInfo
;
456 EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE
* Gtdt
;
458 UINT32 GTBlockOffset
;
459 UINT32 WatchdogOffset
;
461 ASSERT (This
!= NULL
);
462 ASSERT (AcpiTableInfo
!= NULL
);
463 ASSERT (CfgMgrProtocol
!= NULL
);
464 ASSERT (Table
!= NULL
);
465 ASSERT (AcpiTableInfo
->TableGeneratorId
== This
->GeneratorID
);
466 ASSERT (AcpiTableInfo
->AcpiTableSignature
== This
->AcpiTableSignature
);
468 if ((AcpiTableInfo
->AcpiTableRevision
< This
->MinAcpiTableRevision
) ||
469 (AcpiTableInfo
->AcpiTableRevision
> This
->AcpiTableRevision
)) {
472 "ERROR: GTDT: Requested table revision = %d, is not supported."
473 "Supported table revision: Minimum = %d, Maximum = %d\n",
474 AcpiTableInfo
->AcpiTableRevision
,
475 This
->MinAcpiTableRevision
,
476 This
->AcpiTableRevision
478 return EFI_INVALID_PARAMETER
;
482 Status
= GetEArmObjPlatformGTBlockInfo (
488 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
491 "ERROR: GTDT: Failed to Get Platform GT Block Information." \
498 Status
= GetEArmObjPlatformGenericWatchdogInfo (
504 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
507 "ERROR: GTDT: Failed to Get Platform Generic Watchdog Information." \
516 "GTDT: BlockTimerCount = %d, WatchdogCount = %d\n",
521 // Calculate the GTDT Table Size
522 PlatformTimerCount
= 0;
523 TableSize
= sizeof (EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE
);
524 if (BlockTimerCount
!= 0) {
525 GTBlockOffset
= TableSize
;
526 PlatformTimerCount
+= BlockTimerCount
;
527 TableSize
+= (sizeof (EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE
) *
530 for (Idx
= 0; Idx
< BlockTimerCount
; Idx
++) {
531 if (GTBlockInfo
[Idx
].GTBlockTimerFrameCount
> 8) {
532 Status
= EFI_INVALID_PARAMETER
;
535 "GTDT: GTBockFrameCount cannot be more than 8." \
536 " GTBockFrameCount = %d, Status = %r\n",
537 GTBlockInfo
[Idx
].GTBlockTimerFrameCount
,
542 TableSize
+= (sizeof (EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_STRUCTURE
) *
543 GTBlockInfo
[Idx
].GTBlockTimerFrameCount
);
548 "GTDT: GTBockOffset = 0x%x, PLATFORM_TIMER_COUNT = %d\n",
555 if (WatchdogCount
!= 0) {
556 WatchdogOffset
= TableSize
;
557 PlatformTimerCount
+= WatchdogCount
;
558 TableSize
+= (sizeof (EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE
) *
562 "GTDT: WatchdogOffset = 0x%x, PLATFORM_TIMER_COUNT = %d\n",
568 *Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)AllocateZeroPool (TableSize
);
569 if (*Table
== NULL
) {
570 Status
= EFI_OUT_OF_RESOURCES
;
573 "ERROR: GTDT: Failed to allocate memory for GTDT Table, Size = %d," \
581 Gtdt
= (EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE
*)*Table
;
584 "GTDT: Gtdt = 0x%p TableSize = 0x%x\n",
589 Status
= AddAcpiHeader (
596 if (EFI_ERROR (Status
)) {
599 "ERROR: GTDT: Failed to add ACPI header. Status = %r\n",
605 Status
= AddGenericTimerInfo (
609 AcpiTableInfo
->AcpiTableRevision
611 if (EFI_ERROR (Status
)) {
614 "ERROR: GTDT: Failed to add Generic Timer Info. Status = %r\n",
620 if (BlockTimerCount
!= 0) {
621 Status
= AddGTBlockList (
628 if (EFI_ERROR (Status
)) {
631 "ERROR: GTDT: Failed to add GT Block timers. Status = %r\n",
638 if (WatchdogCount
!= 0) {
639 AddGenericWatchdogList (
650 if (*Table
!= NULL
) {
657 /** Free any resources allocated for constructing the GTDT.
659 @param [in] This Pointer to the table generator.
660 @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
661 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
663 @param [in, out] Table Pointer to the ACPI Table.
665 @retval EFI_SUCCESS The resources were freed successfully.
666 @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
670 FreeGtdtTableResources (
671 IN CONST ACPI_TABLE_GENERATOR
* CONST This
,
672 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO
* CONST AcpiTableInfo
,
673 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL
* CONST CfgMgrProtocol
,
674 IN OUT EFI_ACPI_DESCRIPTION_HEADER
** CONST Table
677 ASSERT (This
!= NULL
);
678 ASSERT (AcpiTableInfo
!= NULL
);
679 ASSERT (CfgMgrProtocol
!= NULL
);
680 ASSERT (AcpiTableInfo
->TableGeneratorId
== This
->GeneratorID
);
681 ASSERT (AcpiTableInfo
->AcpiTableSignature
== This
->AcpiTableSignature
);
683 if ((Table
== NULL
) || (*Table
== NULL
)) {
684 DEBUG ((DEBUG_ERROR
, "ERROR: GTDT: Invalid Table Pointer\n"));
685 ASSERT ((Table
!= NULL
) && (*Table
!= NULL
));
686 return EFI_INVALID_PARAMETER
;
694 /** This macro defines the GTDT Table Generator revision.
696 #define GTDT_GENERATOR_REVISION CREATE_REVISION (1, 0)
698 /** The interface for the GTDT Table Generator.
702 ACPI_TABLE_GENERATOR GtdtGenerator
= {
704 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdGtdt
),
705 // Generator Description
706 L
"ACPI.STD.GTDT.GENERATOR",
707 // ACPI Table Signature
708 EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE
,
709 // ACPI Table Revision supported by this Generator
710 EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION
,
711 // Minimum ACPI Table Revision supported by this Generator
712 EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION
,
714 TABLE_GENERATOR_CREATOR_ID_ARM
,
716 GTDT_GENERATOR_REVISION
,
717 // Build Table function
719 // Free Resource function
720 FreeGtdtTableResources
,
721 // Extended build function not needed
723 // Extended build function not implemented by the generator.
724 // Hence extended free resource function is not required.
728 /** Register the Generator with the ACPI Table Factory.
730 @param [in] ImageHandle The handle to the image.
731 @param [in] SystemTable Pointer to the System Table.
733 @retval EFI_SUCCESS The Generator is registered.
734 @retval EFI_INVALID_PARAMETER A parameter is invalid.
735 @retval EFI_ALREADY_STARTED The Generator for the Table ID
736 is already registered.
740 AcpiGtdtLibConstructor (
741 IN CONST EFI_HANDLE ImageHandle
,
742 IN EFI_SYSTEM_TABLE
* CONST SystemTable
746 Status
= RegisterAcpiTableGenerator (&GtdtGenerator
);
747 DEBUG ((DEBUG_INFO
, "GTDT: Register Generator. Status = %r\n", Status
));
748 ASSERT_EFI_ERROR (Status
);
752 /** Deregister the Generator from the ACPI Table Factory.
754 @param [in] ImageHandle The handle to the image.
755 @param [in] SystemTable Pointer to the System Table.
757 @retval EFI_SUCCESS The Generator is deregistered.
758 @retval EFI_INVALID_PARAMETER A parameter is invalid.
759 @retval EFI_NOT_FOUND The Generator is not registered.
763 AcpiGtdtLibDestructor (
764 IN CONST EFI_HANDLE ImageHandle
,
765 IN EFI_SYSTEM_TABLE
* CONST SystemTable
769 Status
= DeregisterAcpiTableGenerator (&GtdtGenerator
);
770 DEBUG ((DEBUG_INFO
, "GTDT: Deregister Generator. Status = %r\n", Status
));
771 ASSERT_EFI_ERROR (Status
);