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
;
355 ASSERT (Gtdt
!= NULL
);
356 ASSERT (GTBlockInfo
!= NULL
);
358 GTBlock
= (EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE
*)((UINT8
*)Gtdt
+
361 while (BlockTimerCount
-- != 0) {
362 DEBUG ((DEBUG_INFO
, "GTDT: GTBlock = 0x%p\n", GTBlock
));
364 Status
= GetEArmObjGTBlockTimerFrameInfo (
366 GTBlockInfo
->GTBlockTimerFrameToken
,
367 >BlockTimerFrameList
,
368 >BlockTimerFrameCount
370 if (EFI_ERROR (Status
) ||
371 (GTBlockTimerFrameCount
!= GTBlockInfo
->GTBlockTimerFrameCount
)) {
374 "ERROR: GTDT: Failed to get Generic Timer Frames. Status = %r\n",
380 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 // Check that the length of the GT block does not
386 if (Length
> MAX_UINT16
) {
387 Status
= EFI_INVALID_PARAMETER
;
390 "ERROR: GTDT: Too many GT Frames. Count = %d. " \
391 "Maximum supported GT Block size exceeded. " \
393 GTBlockInfo
->GTBlockTimerFrameCount
,
399 GTBlock
->Type
= EFI_ACPI_6_3_GTDT_GT_BLOCK
;
400 GTBlock
->Length
= (UINT16
)Length
;
401 GTBlock
->Reserved
= EFI_ACPI_RESERVED_BYTE
;
402 GTBlock
->CntCtlBase
= GTBlockInfo
->GTBlockPhysicalAddress
;
403 GTBlock
->GTBlockTimerCount
= GTBlockInfo
->GTBlockTimerFrameCount
;
404 GTBlock
->GTBlockTimerOffset
=
405 sizeof (EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE
);
407 GtBlockFrame
= (EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_STRUCTURE
*)
408 ((UINT8
*)GTBlock
+ GTBlock
->GTBlockTimerOffset
);
410 // Add GT Block Timer frames
411 Status
= AddGTBlockTimerFrames (
413 GTBlockTimerFrameList
,
414 GTBlockTimerFrameCount
416 if (EFI_ERROR (Status
)) {
419 "ERROR: GTDT: Failed to add Generic Timer Frames. Status = %r\n",
426 GTBlock
= (EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE
*)((UINT8
*)GTBlock
+
433 /** Construct the GTDT ACPI table.
435 Called by the Dynamic Table Manager, this function invokes the
436 Configuration Manager protocol interface to get the required hardware
437 information for generating the ACPI table.
439 If this function allocates any resources then they must be freed
440 in the FreeXXXXTableResources function.
442 @param [in] This Pointer to the table generator.
443 @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
444 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
446 @param [out] Table Pointer to the constructed ACPI Table.
448 @retval EFI_SUCCESS Table generated successfully.
449 @retval EFI_INVALID_PARAMETER A parameter is invalid.
450 @retval EFI_NOT_FOUND The required object was not found.
451 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
452 Manager is less than the Object size for the
454 @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
460 IN CONST ACPI_TABLE_GENERATOR
* CONST This
,
461 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO
* CONST AcpiTableInfo
,
462 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL
* CONST CfgMgrProtocol
,
463 OUT EFI_ACPI_DESCRIPTION_HEADER
** CONST Table
468 UINT32 PlatformTimerCount
;
469 UINT32 WatchdogCount
;
470 UINT32 BlockTimerCount
;
471 CM_ARM_GENERIC_WATCHDOG_INFO
* WatchdogInfoList
;
472 CM_ARM_GTBLOCK_INFO
* GTBlockInfo
;
473 EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE
* Gtdt
;
475 UINT32 GTBlockOffset
;
476 UINT32 WatchdogOffset
;
478 ASSERT (This
!= NULL
);
479 ASSERT (AcpiTableInfo
!= NULL
);
480 ASSERT (CfgMgrProtocol
!= NULL
);
481 ASSERT (Table
!= NULL
);
482 ASSERT (AcpiTableInfo
->TableGeneratorId
== This
->GeneratorID
);
483 ASSERT (AcpiTableInfo
->AcpiTableSignature
== This
->AcpiTableSignature
);
485 if ((AcpiTableInfo
->AcpiTableRevision
< This
->MinAcpiTableRevision
) ||
486 (AcpiTableInfo
->AcpiTableRevision
> This
->AcpiTableRevision
)) {
489 "ERROR: GTDT: Requested table revision = %d, is not supported."
490 "Supported table revision: Minimum = %d, Maximum = %d\n",
491 AcpiTableInfo
->AcpiTableRevision
,
492 This
->MinAcpiTableRevision
,
493 This
->AcpiTableRevision
495 return EFI_INVALID_PARAMETER
;
499 Status
= GetEArmObjPlatformGTBlockInfo (
505 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
508 "ERROR: GTDT: Failed to Get Platform GT Block Information." \
515 Status
= GetEArmObjPlatformGenericWatchdogInfo (
521 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
524 "ERROR: GTDT: Failed to Get Platform Generic Watchdog Information." \
533 "GTDT: BlockTimerCount = %d, WatchdogCount = %d\n",
538 // Calculate the GTDT Table Size
539 PlatformTimerCount
= 0;
540 TableSize
= sizeof (EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE
);
541 if (BlockTimerCount
!= 0) {
542 GTBlockOffset
= TableSize
;
543 PlatformTimerCount
+= BlockTimerCount
;
544 TableSize
+= (sizeof (EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE
) *
547 for (Idx
= 0; Idx
< BlockTimerCount
; Idx
++) {
548 if (GTBlockInfo
[Idx
].GTBlockTimerFrameCount
> 8) {
549 Status
= EFI_INVALID_PARAMETER
;
552 "GTDT: GTBockFrameCount cannot be more than 8." \
553 " GTBockFrameCount = %d, Status = %r\n",
554 GTBlockInfo
[Idx
].GTBlockTimerFrameCount
,
559 TableSize
+= (sizeof (EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_STRUCTURE
) *
560 GTBlockInfo
[Idx
].GTBlockTimerFrameCount
);
565 "GTDT: GTBockOffset = 0x%x, PLATFORM_TIMER_COUNT = %d\n",
572 if (WatchdogCount
!= 0) {
573 WatchdogOffset
= TableSize
;
574 PlatformTimerCount
+= WatchdogCount
;
575 TableSize
+= (sizeof (EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE
) *
579 "GTDT: WatchdogOffset = 0x%x, PLATFORM_TIMER_COUNT = %d\n",
585 *Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)AllocateZeroPool (TableSize
);
586 if (*Table
== NULL
) {
587 Status
= EFI_OUT_OF_RESOURCES
;
590 "ERROR: GTDT: Failed to allocate memory for GTDT Table, Size = %d," \
598 Gtdt
= (EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE
*)*Table
;
601 "GTDT: Gtdt = 0x%p TableSize = 0x%x\n",
606 Status
= AddAcpiHeader (
613 if (EFI_ERROR (Status
)) {
616 "ERROR: GTDT: Failed to add ACPI header. Status = %r\n",
622 Status
= AddGenericTimerInfo (
626 AcpiTableInfo
->AcpiTableRevision
628 if (EFI_ERROR (Status
)) {
631 "ERROR: GTDT: Failed to add Generic Timer Info. Status = %r\n",
637 if (BlockTimerCount
!= 0) {
638 Status
= AddGTBlockList (
645 if (EFI_ERROR (Status
)) {
648 "ERROR: GTDT: Failed to add GT Block timers. Status = %r\n",
655 if (WatchdogCount
!= 0) {
656 AddGenericWatchdogList (
667 if (*Table
!= NULL
) {
674 /** Free any resources allocated for constructing the GTDT.
676 @param [in] This Pointer to the table generator.
677 @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
678 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
680 @param [in, out] Table Pointer to the ACPI Table.
682 @retval EFI_SUCCESS The resources were freed successfully.
683 @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
687 FreeGtdtTableResources (
688 IN CONST ACPI_TABLE_GENERATOR
* CONST This
,
689 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO
* CONST AcpiTableInfo
,
690 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL
* CONST CfgMgrProtocol
,
691 IN OUT EFI_ACPI_DESCRIPTION_HEADER
** CONST Table
694 ASSERT (This
!= NULL
);
695 ASSERT (AcpiTableInfo
!= NULL
);
696 ASSERT (CfgMgrProtocol
!= NULL
);
697 ASSERT (AcpiTableInfo
->TableGeneratorId
== This
->GeneratorID
);
698 ASSERT (AcpiTableInfo
->AcpiTableSignature
== This
->AcpiTableSignature
);
700 if ((Table
== NULL
) || (*Table
== NULL
)) {
701 DEBUG ((DEBUG_ERROR
, "ERROR: GTDT: Invalid Table Pointer\n"));
702 ASSERT ((Table
!= NULL
) && (*Table
!= NULL
));
703 return EFI_INVALID_PARAMETER
;
711 /** This macro defines the GTDT Table Generator revision.
713 #define GTDT_GENERATOR_REVISION CREATE_REVISION (1, 0)
715 /** The interface for the GTDT Table Generator.
719 ACPI_TABLE_GENERATOR GtdtGenerator
= {
721 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdGtdt
),
722 // Generator Description
723 L
"ACPI.STD.GTDT.GENERATOR",
724 // ACPI Table Signature
725 EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE
,
726 // ACPI Table Revision supported by this Generator
727 EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION
,
728 // Minimum ACPI Table Revision supported by this Generator
729 EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION
,
731 TABLE_GENERATOR_CREATOR_ID_ARM
,
733 GTDT_GENERATOR_REVISION
,
734 // Build Table function
736 // Free Resource function
737 FreeGtdtTableResources
,
738 // Extended build function not needed
740 // Extended build function not implemented by the generator.
741 // Hence extended free resource function is not required.
745 /** Register the Generator with the ACPI Table Factory.
747 @param [in] ImageHandle The handle to the image.
748 @param [in] SystemTable Pointer to the System Table.
750 @retval EFI_SUCCESS The Generator is registered.
751 @retval EFI_INVALID_PARAMETER A parameter is invalid.
752 @retval EFI_ALREADY_STARTED The Generator for the Table ID
753 is already registered.
757 AcpiGtdtLibConstructor (
758 IN EFI_HANDLE ImageHandle
,
759 IN EFI_SYSTEM_TABLE
* SystemTable
763 Status
= RegisterAcpiTableGenerator (&GtdtGenerator
);
764 DEBUG ((DEBUG_INFO
, "GTDT: Register Generator. Status = %r\n", Status
));
765 ASSERT_EFI_ERROR (Status
);
769 /** Deregister the Generator from the ACPI Table Factory.
771 @param [in] ImageHandle The handle to the image.
772 @param [in] SystemTable Pointer to the System Table.
774 @retval EFI_SUCCESS The Generator is deregistered.
775 @retval EFI_INVALID_PARAMETER A parameter is invalid.
776 @retval EFI_NOT_FOUND The Generator is not registered.
780 AcpiGtdtLibDestructor (
781 IN EFI_HANDLE ImageHandle
,
782 IN EFI_SYSTEM_TABLE
* SystemTable
786 Status
= DeregisterAcpiTableGenerator (&GtdtGenerator
);
787 DEBUG ((DEBUG_INFO
, "GTDT: Deregister Generator. Status = %r\n", Status
));
788 ASSERT_EFI_ERROR (Status
);