--- /dev/null
+/** @file\r
+ FADT Table Generator\r
+\r
+ Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ @par Reference(s):\r
+ - ACPI 6.2 Specification - Errata A, September 2017\r
+\r
+**/\r
+\r
+#include <Library/AcpiLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Protocol/AcpiTable.h>\r
+\r
+// Module specific include files.\r
+#include <AcpiTableGenerator.h>\r
+#include <ConfigurationManagerObject.h>\r
+#include <ConfigurationManagerHelper.h>\r
+#include <Library/TableHelperLib.h>\r
+#include <Protocol/ConfigurationManagerProtocol.h>\r
+\r
+/** ARM standard FADT Generator\r
+\r
+Requirements:\r
+ The following Configuration Manager Object(s) are required by\r
+ this Generator:\r
+ - EArmObjPowerManagementProfileInfo\r
+ - EArmObjBootArchInfo\r
+ - EArmObjHypervisorVendorIdentity (OPTIONAL)\r
+*/\r
+\r
+/** This macro defines the FADT flag options for ARM Platforms.\r
+*/\r
+#define FADT_FLAGS (EFI_ACPI_6_2_HW_REDUCED_ACPI | \\r
+ EFI_ACPI_6_2_LOW_POWER_S0_IDLE_CAPABLE)\r
+\r
+/** This macro defines the valid mask for the FADT flag option\r
+ if HW_REDUCED_ACPI flag in the table is set.\r
+\r
+ Invalid bits are: 1, 2, 3,7, 8, 13, 14,16, 17 and\r
+ 22-31 (reserved).\r
+\r
+ Valid bits are:\r
+ EFI_ACPI_6_2_WBINVD BIT0\r
+ EFI_ACPI_6_2_PWR_BUTTON BIT4\r
+ EFI_ACPI_6_2_SLP_BUTTON BIT5\r
+ EFI_ACPI_6_2_FIX_RTC BIT6\r
+ EFI_ACPI_6_2_DCK_CAP BIT9\r
+ EFI_ACPI_6_2_RESET_REG_SUP BIT10\r
+ EFI_ACPI_6_2_SEALED_CASE BIT11\r
+ EFI_ACPI_6_2_HEADLESS BIT12\r
+ EFI_ACPI_6_2_USE_PLATFORM_CLOCK BIT15\r
+ EFI_ACPI_6_2_FORCE_APIC_CLUSTER_MODEL BIT18\r
+ EFI_ACPI_6_2_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19\r
+ EFI_ACPI_6_2_HW_REDUCED_ACPI BIT20\r
+ EFI_ACPI_6_2_LOW_POWER_S0_IDLE_CAPABLE BIT21\r
+*/\r
+#define VALID_HARDWARE_REDUCED_FLAG_MASK ( \\r
+ EFI_ACPI_6_2_WBINVD | \\r
+ EFI_ACPI_6_2_PWR_BUTTON | \\r
+ EFI_ACPI_6_2_SLP_BUTTON | \\r
+ EFI_ACPI_6_2_FIX_RTC | \\r
+ EFI_ACPI_6_2_DCK_CAP | \\r
+ EFI_ACPI_6_2_RESET_REG_SUP | \\r
+ EFI_ACPI_6_2_SEALED_CASE | \\r
+ EFI_ACPI_6_2_HEADLESS | \\r
+ EFI_ACPI_6_2_USE_PLATFORM_CLOCK | \\r
+ EFI_ACPI_6_2_FORCE_APIC_CLUSTER_MODEL | \\r
+ EFI_ACPI_6_2_FORCE_APIC_PHYSICAL_DESTINATION_MODE | \\r
+ EFI_ACPI_6_2_HW_REDUCED_ACPI | \\r
+ EFI_ACPI_6_2_LOW_POWER_S0_IDLE_CAPABLE)\r
+\r
+#pragma pack(1)\r
+\r
+/** The AcpiFadt is a template EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE\r
+ structure used for generating the FADT Table.\r
+ Note: fields marked with "{Template}" will be updated dynamically.\r
+*/\r
+STATIC\r
+EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE AcpiFadt = {\r
+ ACPI_HEADER (\r
+ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,\r
+ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE,\r
+ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_REVISION\r
+ ),\r
+ // UINT32 FirmwareCtrl\r
+ 0,\r
+ // UINT32 Dsdt\r
+ 0,\r
+ // UINT8 Reserved0\r
+ EFI_ACPI_RESERVED_BYTE,\r
+ // UINT8 PreferredPmProfile\r
+ EFI_ACPI_6_2_PM_PROFILE_UNSPECIFIED, // {Template}: Power Management Profile\r
+ // UINT16 SciInt\r
+ 0,\r
+ // UINT32 SmiCmd\r
+ 0,\r
+ // UINT8 AcpiEnable\r
+ 0,\r
+ // UINT8 AcpiDisable\r
+ 0,\r
+ // UINT8 S4BiosReq\r
+ 0,\r
+ // UINT8 PstateCnt\r
+ 0,\r
+ // UINT32 Pm1aEvtBlk\r
+ 0,\r
+ // UINT32 Pm1bEvtBlk\r
+ 0,\r
+ // UINT32 Pm1aCntBlk\r
+ 0,\r
+ // UINT32 Pm1bCntBlk\r
+ 0,\r
+ // UINT32 Pm2CntBlk\r
+ 0,\r
+ // UINT32 PmTmrBlk\r
+ 0,\r
+ // UINT32 Gpe0Blk\r
+ 0,\r
+ // UINT32 Gpe1Blk\r
+ 0,\r
+ // UINT8 Pm1EvtLen\r
+ 0,\r
+ // UINT8 Pm1CntLen\r
+ 0,\r
+ // UINT8 Pm2CntLen\r
+ 0,\r
+ // UINT8 PmTmrLen\r
+ 0,\r
+ // UINT8 Gpe0BlkLen\r
+ 0,\r
+ // UINT8 Gpe1BlkLen\r
+ 0,\r
+ // UINT8 Gpe1Base\r
+ 0,\r
+ // UINT8 CstCnt\r
+ 0,\r
+ // UINT16 PLvl2Lat\r
+ 0,\r
+ // UINT16 PLvl3Lat\r
+ 0,\r
+ // UINT16 FlushSize\r
+ 0,\r
+ // UINT16 FlushStride\r
+ 0,\r
+ // UINT8 DutyOffset\r
+ 0,\r
+ // UINT8 DutyWidth\r
+ 0,\r
+ // UINT8 DayAlrm\r
+ 0,\r
+ // UINT8 MonAlrm\r
+ 0,\r
+ // UINT8 Century\r
+ 0,\r
+ // UINT16 IaPcBootArch\r
+ 0,\r
+ // UINT8 Reserved1\r
+ 0,\r
+ // UINT32 Flags\r
+ FADT_FLAGS,\r
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE ResetReg\r
+ NULL_GAS,\r
+ // UINT8 ResetValue\r
+ 0,\r
+ // UINT16 ArmBootArch\r
+ EFI_ACPI_6_2_ARM_PSCI_COMPLIANT, // {Template}: ARM Boot Architecture Flags\r
+ // UINT8 MinorRevision\r
+ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION,\r
+ // UINT64 XFirmwareCtrl\r
+ 0,\r
+ // UINT64 XDsdt\r
+ 0,\r
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk\r
+ NULL_GAS,\r
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk\r
+ NULL_GAS,\r
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk\r
+ NULL_GAS,\r
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk\r
+ NULL_GAS,\r
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk\r
+ NULL_GAS,\r
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk\r
+ NULL_GAS,\r
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XGpe0Blk\r
+ NULL_GAS,\r
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XGpe1Blk\r
+ NULL_GAS,\r
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE SleepControlReg\r
+ NULL_GAS,\r
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE SleepStatusReg\r
+ NULL_GAS,\r
+ // UINT64 HypervisorVendorIdentity\r
+ EFI_ACPI_RESERVED_QWORD // {Template}: Hypervisor Vendor ID\r
+};\r
+\r
+#pragma pack()\r
+\r
+/** This macro expands to a function that retrieves the Power\r
+ Management Profile Information from the Configuration Manager.\r
+*/\r
+GET_OBJECT_LIST (\r
+ EObjNameSpaceArm,\r
+ EArmObjPowerManagementProfileInfo,\r
+ CM_ARM_POWER_MANAGEMENT_PROFILE_INFO\r
+ );\r
+\r
+/** This macro expands to a function that retrieves the Boot\r
+ Architecture Information from the Configuration Manager.\r
+*/\r
+GET_OBJECT_LIST (\r
+ EObjNameSpaceArm,\r
+ EArmObjBootArchInfo,\r
+ CM_ARM_BOOT_ARCH_INFO\r
+ );\r
+\r
+/** This macro expands to a function that retrieves the Hypervisor\r
+ Vendor ID from the Configuration Manager.\r
+*/\r
+GET_OBJECT_LIST (\r
+ EObjNameSpaceArm,\r
+ EArmObjHypervisorVendorIdentity,\r
+ CM_ARM_HYPERVISOR_VENDOR_ID\r
+ );\r
+\r
+/** This macro expands to a function that retrieves the Fixed\r
+ feature flags for the platform from the Configuration Manager.\r
+*/\r
+GET_OBJECT_LIST (\r
+ EObjNameSpaceArm,\r
+ EArmObjFixedFeatureFlags,\r
+ CM_ARM_FIXED_FEATURE_FLAGS\r
+ );\r
+\r
+/** Update the Power Management Profile information in the FADT Table.\r
+\r
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
+ Protocol Interface.\r
+\r
+ @retval EFI_SUCCESS Success.\r
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+ @retval EFI_NOT_FOUND The required object was not found.\r
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration\r
+ Manager is less than the Object size for the\r
+ requested object.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+FadtAddPmProfileInfo (\r
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol\r
+)\r
+{\r
+ EFI_STATUS Status;\r
+ CM_ARM_POWER_MANAGEMENT_PROFILE_INFO * PmProfile;\r
+\r
+ ASSERT (CfgMgrProtocol != NULL);\r
+\r
+ // Get the Power Management Profile from the Platform Configuration Manager\r
+ Status = GetEArmObjPowerManagementProfileInfo (\r
+ CfgMgrProtocol,\r
+ CM_NULL_TOKEN,\r
+ &PmProfile,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "ERROR: FADT: Failed to get Power Management Profile information." \\r
+ " Status = %r\n",\r
+ Status\r
+ ));\r
+ goto error_handler;\r
+ }\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "FADT: PreferredPmProfile = 0x%x\n",\r
+ PmProfile->PowerManagementProfile\r
+ ));\r
+\r
+ AcpiFadt.PreferredPmProfile = PmProfile->PowerManagementProfile;\r
+\r
+error_handler:\r
+ return Status;\r
+}\r
+\r
+/** Updates the Boot Architecture information in the FADT Table.\r
+\r
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
+ Protocol Interface.\r
+\r
+ @retval EFI_SUCCESS Success.\r
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+ @retval EFI_NOT_FOUND The required object was not found.\r
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration\r
+ Manager is less than the Object size for the\r
+ requested object.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+FadtAddBootArchInfo (\r
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol\r
+)\r
+{\r
+ EFI_STATUS Status;\r
+ CM_ARM_BOOT_ARCH_INFO * BootArchInfo;\r
+\r
+ ASSERT (CfgMgrProtocol != NULL);\r
+\r
+ // Get the Boot Architecture flags from the Platform Configuration Manager\r
+ Status = GetEArmObjBootArchInfo (\r
+ CfgMgrProtocol,\r
+ CM_NULL_TOKEN,\r
+ &BootArchInfo,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "ERROR: FADT: Failed to get Boot Architecture flags. Status = %r\n",\r
+ Status\r
+ ));\r
+ goto error_handler;\r
+ }\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "FADT BootArchFlag = 0x%x\n",\r
+ BootArchInfo->BootArchFlags\r
+ ));\r
+\r
+ AcpiFadt.ArmBootArch = BootArchInfo->BootArchFlags;\r
+\r
+error_handler:\r
+ return Status;\r
+}\r
+\r
+/** Update the Hypervisor Vendor ID in the FADT Table.\r
+\r
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
+ Protocol Interface.\r
+\r
+ @retval EFI_SUCCESS Success.\r
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+ @retval EFI_NOT_FOUND The required object was not found.\r
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration\r
+ Manager is less than the Object size for the\r
+ requested object.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+FadtAddHypervisorVendorId (\r
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol\r
+)\r
+{\r
+ EFI_STATUS Status;\r
+ CM_ARM_HYPERVISOR_VENDOR_ID * HypervisorVendorInfo;\r
+\r
+ ASSERT (CfgMgrProtocol != NULL);\r
+\r
+ // Get the Hypervisor Vendor ID from the Platform Configuration Manager\r
+ Status = GetEArmObjHypervisorVendorIdentity (\r
+ CfgMgrProtocol,\r
+ CM_NULL_TOKEN,\r
+ &HypervisorVendorInfo,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "INFO: FADT: Platform does not have a Hypervisor Vendor ID."\r
+ "Status = %r\n",\r
+ Status\r
+ ));\r
+ } else {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "ERROR: FADT: Failed to get Hypervisor Vendor ID. Status = %r\n",\r
+ Status\r
+ ));\r
+ }\r
+ goto error_handler;\r
+ }\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "FADT: EArmObjHypervisorVendorIdentity = 0x%lx\n",\r
+ HypervisorVendorInfo->HypervisorVendorId\r
+ ));\r
+\r
+ AcpiFadt.HypervisorVendorIdentity = HypervisorVendorInfo->HypervisorVendorId;\r
+\r
+error_handler:\r
+ return Status;\r
+}\r
+\r
+/** Update the Fixed Feature Flags in the FADT Table.\r
+\r
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
+ Protocol Interface.\r
+\r
+ @retval EFI_SUCCESS Success.\r
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+ @retval EFI_NOT_FOUND The required object was not found.\r
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration\r
+ Manager is less than the Object size for the\r
+ requested object.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+FadtAddFixedFeatureFlags (\r
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol\r
+)\r
+{\r
+ EFI_STATUS Status;\r
+ CM_ARM_FIXED_FEATURE_FLAGS * FixedFeatureFlags;\r
+\r
+ ASSERT (CfgMgrProtocol != NULL);\r
+\r
+ // Get the Fixed feature flags from the Platform Configuration Manager\r
+ Status = GetEArmObjFixedFeatureFlags (\r
+ CfgMgrProtocol,\r
+ CM_NULL_TOKEN,\r
+ &FixedFeatureFlags,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "INFO: FADT: Platform does not define additional Fixed feature flags."\r
+ "Status = %r\n",\r
+ Status\r
+ ));\r
+ } else {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "ERROR: FADT: Failed to get Fixed feature flags. Status = %r\n",\r
+ Status\r
+ ));\r
+ }\r
+ goto error_handler;\r
+ }\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "FADT: EArmObjFixedFeatureFlags = 0x%x\n",\r
+ FixedFeatureFlags->Flags\r
+ ));\r
+\r
+ if ((FixedFeatureFlags->Flags & ~(VALID_HARDWARE_REDUCED_FLAG_MASK)) != 0) {\r
+ DEBUG ((\r
+ DEBUG_WARN,\r
+ "FADT: Invalid Fixed feature flags defined by platform,"\r
+ "Invalid Flags bits are = 0x%x\n",\r
+ (FixedFeatureFlags->Flags & ~(VALID_HARDWARE_REDUCED_FLAG_MASK))\r
+ ));\r
+ }\r
+\r
+ AcpiFadt.Flags |= (FixedFeatureFlags->Flags &\r
+ VALID_HARDWARE_REDUCED_FLAG_MASK);\r
+\r
+error_handler:\r
+ return Status;\r
+}\r
+\r
+/** Construct the FADT table.\r
+\r
+ This function invokes the Configuration Manager protocol interface\r
+ to get the required hardware information for generating the ACPI\r
+ table.\r
+\r
+ If this function allocates any resources then they must be freed\r
+ in the FreeXXXXTableResources function.\r
+\r
+ @param [in] This Pointer to the table generator.\r
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.\r
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
+ Protocol Interface.\r
+ @param [out] Table Pointer to the constructed ACPI Table.\r
+\r
+ @retval EFI_SUCCESS Table generated successfully.\r
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+ @retval EFI_NOT_FOUND The required object was not found.\r
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration\r
+ Manager is less than the Object size for the\r
+ requested object.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+BuildFadtTable (\r
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,\r
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,\r
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,\r
+ OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ ASSERT (This != NULL);\r
+ ASSERT (AcpiTableInfo != NULL);\r
+ ASSERT (CfgMgrProtocol != NULL);\r
+ ASSERT (Table != NULL);\r
+ ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);\r
+ ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);\r
+\r
+ if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) ||\r
+ (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "ERROR: FADT: Requested table revision = %d, is not supported."\r
+ "Supported table revision: Minimum = %d, Maximum = %d\n",\r
+ AcpiTableInfo->AcpiTableRevision,\r
+ This->MinAcpiTableRevision,\r
+ This->AcpiTableRevision\r
+ ));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *Table = NULL;\r
+\r
+ Status = AddAcpiHeader (\r
+ CfgMgrProtocol,\r
+ This,\r
+ (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiFadt,\r
+ AcpiTableInfo->AcpiTableRevision,\r
+ sizeof (EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE)\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "ERROR: FADT: Failed to add ACPI header. Status = %r\n",\r
+ Status\r
+ ));\r
+ goto error_handler;\r
+ }\r
+\r
+ // Update PmProfile Info\r
+ Status = FadtAddPmProfileInfo (CfgMgrProtocol);\r
+ if (EFI_ERROR (Status)) {\r
+ goto error_handler;\r
+ }\r
+\r
+ // Update BootArch Info\r
+ Status = FadtAddBootArchInfo (CfgMgrProtocol);\r
+ if (EFI_ERROR (Status)) {\r
+ goto error_handler;\r
+ }\r
+\r
+ // Add the Hypervisor Vendor Id if present\r
+ // Note if no hypervisor is present the zero bytes\r
+ // will be placed in this field.\r
+ Status = FadtAddHypervisorVendorId (CfgMgrProtocol);\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "INFO: FADT: No Hypervisor Vendor ID found," \\r
+ " assuming no Hypervisor is present in the firmware.\n"\r
+ ));\r
+ } else {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "ERROR: FADT: Error reading Hypervisor Vendor ID, Status = %r",\r
+ Status\r
+ ));\r
+ goto error_handler;\r
+ }\r
+ }\r
+\r
+ Status = FadtAddFixedFeatureFlags (CfgMgrProtocol);\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "INFO: FADT: No Fixed feature flags found," \\r
+ " assuming no additional flags are defined for the platform.\n"\r
+ ));\r
+ Status = EFI_SUCCESS;\r
+ } else {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "ERROR: FADT: Error reading Fixed feature flags, Status = %r",\r
+ Status\r
+ ));\r
+ goto error_handler;\r
+ }\r
+ }\r
+\r
+ *Table = (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiFadt;\r
+error_handler:\r
+ return Status;\r
+}\r
+\r
+/** This macro defines the FADT Table Generator revision.\r
+*/\r
+#define FADT_GENERATOR_REVISION CREATE_REVISION (1, 0)\r
+\r
+/** The interface for the FADT Table Generator.\r
+*/\r
+STATIC\r
+CONST\r
+ACPI_TABLE_GENERATOR FadtGenerator = {\r
+ // Generator ID\r
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt),\r
+ // Generator Description\r
+ L"ACPI.STD.FADT.GENERATOR",\r
+ // ACPI Table Signature\r
+ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,\r
+ // ACPI Table Revision supported by this Generator\r
+ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,\r
+ // Minimum supported ACPI Table Revision\r
+ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,\r
+ // Creator ID\r
+ TABLE_GENERATOR_CREATOR_ID_ARM,\r
+ // Creator Revision\r
+ FADT_GENERATOR_REVISION,\r
+ // Build Table function\r
+ BuildFadtTable,\r
+ // No additional resources are allocated by the generator.\r
+ // Hence the Free Resource function is not required.\r
+ NULL,\r
+ // Extended build function not needed\r
+ NULL,\r
+ // Extended build function not implemented by the generator.\r
+ // Hence extended free resource function is not required.\r
+ NULL\r
+};\r
+\r
+/** Register the Generator with the ACPI Table Factory.\r
+\r
+ @param [in] ImageHandle The handle to the image.\r
+ @param [in] SystemTable Pointer to the System Table.\r
+\r
+ @retval EFI_SUCCESS The Generator is registered.\r
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID\r
+ is already registered.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AcpiFadtLibConstructor (\r
+ IN CONST EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE * CONST SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ Status = RegisterAcpiTableGenerator (&FadtGenerator);\r
+ DEBUG ((DEBUG_INFO, "FADT: Register Generator. Status = %r\n", Status));\r
+ ASSERT_EFI_ERROR (Status);\r
+ return Status;\r
+}\r
+\r
+/** Deregister the Generator from the ACPI Table Factory.\r
+\r
+ @param [in] ImageHandle The handle to the image.\r
+ @param [in] SystemTable Pointer to the System Table.\r
+\r
+ @retval EFI_SUCCESS The Generator is deregistered.\r
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+ @retval EFI_NOT_FOUND The Generator is not registered.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AcpiFadtLibDestructor (\r
+ IN CONST EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE * CONST SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ Status = DeregisterAcpiTableGenerator (&FadtGenerator);\r
+ DEBUG ((DEBUG_INFO, "FADT: Deregister Generator. Status = %r\n", Status));\r
+ ASSERT_EFI_ERROR (Status);\r
+ return Status;\r
+}\r