+
+ @retval SMBIOS_HANDLE_MAP if the CmObjectToken is found.
+ @retval NULL if not found.
+**/
+SMBIOS_HANDLE_MAP *
+EFIAPI
+FindSmbiosHandle (
+ CM_OBJECT_TOKEN CmObjectToken
+ )
+{
+ UINTN Index;
+ SMBIOS_HANDLE_MAP *SmbiosHandleMap;
+
+ SmbiosHandleMap = NULL;
+ for (Index = 0; Index < MAX_SMBIOS_HANDLES; Index++) {
+ if (TableFactoryInfo.SmbiosHandleMap[Index].SmbiosCmToken ==
CmObjectToken) {
+ SmbiosHandleMap = &TableFactoryInfo.SmbiosHandleMap[Index];
+ break;
+ }
+ }
+
+ return SmbiosHandleMap;
+}
+
/** Return a pointer to the SMBIOS table generator.
@param [in] This Pointer to the Dynamic Table Factory Protocol.
diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/AcpiTableBuilder.c
b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/AcpiTableBuilder.c
new file mode 100644
index 0000000000..5021eab748
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/AcpiTableBuilder.c
@@ -0,0 +1,732 @@
+/** @file
+ Dynamic Table Manager Dxe
+
+ Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
+ Copyright (c) 2022 - 2023, NVIDIA CORPORATION & AFFILIATES. All rights
reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiTable.h>
+#include <Library/BaseMemoryLib.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <DeviceTreeTableGenerator.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Protocol/DynamicTableFactoryProtocol.h>
+
+/** This macro expands to a function that retrieves the ACPI Table
+ List from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceStandard,
+ EStdObjAcpiTableList,
+ CM_STD_OBJ_ACPI_TABLE_INFO
+ )
+
+/** A helper function to build and install a single ACPI table.
+
+ This is a helper function that invokes the Table generator interface
+ for building an ACPI table. It uses the AcpiTableProtocol to install the
+ table, then frees the resources allocated for generating it.
+
+ @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
+ interface.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Generator Pointer to the AcpiTable generator.
+ @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol.
+ @param [in] AcpiTableInfo Pointer to the ACPI table Info.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND Required object is not found.
+ @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager
+ is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildAndInstallSingleAcpiTable (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CONST ACPI_TABLE_GENERATOR *CONST Generator,
+ IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ EFI_ACPI_DESCRIPTION_HEADER *AcpiTable;
+ UINTN TableHandle;
+
+ AcpiTable = NULL;
+ Status = Generator->BuildAcpiTable (
+ Generator,
+ AcpiTableInfo,
+ CfgMgrProtocol,
+ &AcpiTable
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Build Table." \
+ " TableGeneratorId = 0x%x. Status = %r\n",
+ AcpiTableInfo->TableGeneratorId,
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ if (AcpiTable == NULL) {
+ Status = EFI_NOT_FOUND;
+ goto exit_handler;
+ }
+
+ // Dump ACPI Table Header
+ DUMP_ACPI_TABLE_HEADER (AcpiTable);
+
+ // Install ACPI table
+ Status = AcpiTableProtocol->InstallAcpiTable (
+ AcpiTableProtocol,
+ AcpiTable,
+ AcpiTable->Length,
+ &TableHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Install ACPI Table. Status = %r\n",
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: ACPI Table installed. Status = %r\n",
+ Status
+ ));
+
+exit_handler:
+ // Free any resources allocated for generating the tables.
+ if (Generator->FreeTableResources != NULL) {
+ Status1 = Generator->FreeTableResources (
+ Generator,
+ AcpiTableInfo,
+ CfgMgrProtocol,
+ &AcpiTable
+ );
+ if (EFI_ERROR (Status1)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Free Table Resources." \
+ "TableGeneratorId = 0x%x. Status = %r\n",
+ AcpiTableInfo->TableGeneratorId,
+ Status1
+ ));
+ }
+
+ // Return the first error status in case of failure
+ if (!EFI_ERROR (Status)) {
+ Status = Status1;
+ }
+ }
+
+ return Status;
+}
+
+/** A helper function to build and install multiple ACPI tables.
+
+ This is a helper function that invokes the Table generator interface
+ for building an ACPI table. It uses the AcpiTableProtocol to install the
+ table, then frees the resources allocated for generating it.
+
+ @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
+ interface.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Generator Pointer to the AcpiTable generator.
+ @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol.
+ @param [in] AcpiTableInfo Pointer to the ACPI table Info.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND Required object is not found.
+ @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager
+ is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildAndInstallMultipleAcpiTable (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CONST ACPI_TABLE_GENERATOR *CONST Generator,
+ IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ EFI_ACPI_DESCRIPTION_HEADER **AcpiTable;
+ UINTN TableCount;
+ UINTN TableHandle;
+ UINTN Index;
+
+ AcpiTable = NULL;
+ TableCount = 0;
+ Status = Generator->BuildAcpiTableEx (
+ Generator,
+ AcpiTableInfo,
+ CfgMgrProtocol,
+ &AcpiTable,
+ &TableCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Build Table." \
+ " TableGeneratorId = 0x%x. Status = %r\n",
+ AcpiTableInfo->TableGeneratorId,
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ if ((AcpiTable == NULL) || (TableCount == 0)) {
+ Status = EFI_NOT_FOUND;
+ goto exit_handler;
+ }
+
+ for (Index = 0; Index < TableCount; Index++) {
+ // Dump ACPI Table Header
+ DUMP_ACPI_TABLE_HEADER (AcpiTable[Index]);
+ // Install ACPI table
+ Status = AcpiTableProtocol->InstallAcpiTable (
+ AcpiTableProtocol,
+ AcpiTable[Index],
+ AcpiTable[Index]->Length,
+ &TableHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Install ACPI Table. Status = %r\n",
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: ACPI Table installed. Status = %r\n",
+ Status
+ ));
+ }
+
+exit_handler:
+ // Free any resources allocated for generating the tables.
+ if (Generator->FreeTableResourcesEx != NULL) {
+ Status1 = Generator->FreeTableResourcesEx (
+ Generator,
+ AcpiTableInfo,
+ CfgMgrProtocol,
+ &AcpiTable,
+ TableCount
+ );
+ if (EFI_ERROR (Status1)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Free Table Resources." \
+ "TableGeneratorId = 0x%x. Status = %r\n",
+ AcpiTableInfo->TableGeneratorId,
+ Status1
+ ));
+ }
+
+ // Return the first error status in case of failure
+ if (!EFI_ERROR (Status)) {
+ Status = Status1;
+ }
+ }
+
+ return Status;
+}
+
+/** A helper function to invoke a Table generator
+
+ This is a helper function that invokes the Table generator interface
+ for building an ACPI table. It uses the AcpiTableProtocol to install the
+ table, then frees the resources allocated for generating it.
+
+ @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
+ interface.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol.
+ @param [in] AcpiTableInfo Pointer to the ACPI table Info.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND Required object is not found.
+ @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager
+ is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildAndInstallAcpiTable (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo
+ )
+{
+ EFI_STATUS Status;
+ CONST ACPI_TABLE_GENERATOR *Generator;
+
+ ASSERT (TableFactoryProtocol != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (AcpiTableProtocol != NULL);
+ ASSERT (AcpiTableInfo != NULL);
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: EStdObjAcpiTableList: Address = 0x%p," \
+ " TableGeneratorId = 0x%x\n",
+ AcpiTableInfo,
+ AcpiTableInfo->TableGeneratorId
+ ));
+
+ Generator = NULL;
+ Status = TableFactoryProtocol->GetAcpiTableGenerator (
+ TableFactoryProtocol,
+ AcpiTableInfo->TableGeneratorId,
+ &Generator
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Table Generator not found." \
+ " TableGeneratorId = 0x%x. Status = %r\n",
+ AcpiTableInfo->TableGeneratorId,
+ Status
+ ));
+ return Status;
+ }
+
+ if (Generator == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: Generator found : %s\n",
+ Generator->Description
+ ));
+
+ if (Generator->BuildAcpiTableEx != NULL) {
+ Status = BuildAndInstallMultipleAcpiTable (
+ TableFactoryProtocol,
+ CfgMgrProtocol,
+ Generator,
+ AcpiTableProtocol,
+ AcpiTableInfo
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find build and install ACPI Table." \
+ " Status = %r\n",
+ Status
+ ));
+ }
+ } else if (Generator->BuildAcpiTable != NULL) {
+ Status = BuildAndInstallSingleAcpiTable (
+ TableFactoryProtocol,
+ CfgMgrProtocol,
+ Generator,
+ AcpiTableProtocol,
+ AcpiTableInfo
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find build and install ACPI Table." \
+ " Status = %r\n",
+ Status
+ ));
+ }
+ } else {
+ Status = EFI_INVALID_PARAMETER;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Table Generator does not implement the" \
+ " ACPI_TABLE_GENERATOR_BUILD_TABLE interface." \
+ " TableGeneratorId = 0x%x. Status = %r\n",
+ AcpiTableInfo->TableGeneratorId,
+ Status
+ ));
+ }
+
+ return Status;
+}
+
+/** The function checks if the Configuration Manager has provided the
+ mandatory ACPI tables for installation.
+
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info list.
+ @param [in] AcpiTableCount Count of ACPI Table Info.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_NOT_FOUND If mandatory table is not found.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+VerifyMandatoryTablesArePresent (
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
+ IN UINT32 AcpiTableCount
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN FadtFound;
+ BOOLEAN MadtFound;
+ BOOLEAN GtdtFound;
+ BOOLEAN DsdtFound;
+ BOOLEAN Dbg2Found;
+ BOOLEAN SpcrFound;
+
+ Status = EFI_SUCCESS;
+ FadtFound = FALSE;
+ MadtFound = FALSE;
+ GtdtFound = FALSE;
+ DsdtFound = FALSE;
+ Dbg2Found = FALSE;
+ SpcrFound = FALSE;
+ ASSERT (AcpiTableInfo != NULL);
+
+ while (AcpiTableCount-- != 0) {
+ switch (AcpiTableInfo[AcpiTableCount].AcpiTableSignature) {
+ case EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
+ FadtFound = TRUE;
+ break;
+ case EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
+ MadtFound = TRUE;
+ break;
+ case EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE:
+ GtdtFound = TRUE;
+ break;
+ case EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
+ DsdtFound = TRUE;
+ break;
+ case EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE:
+ Dbg2Found = TRUE;
+ break;
+ case EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE:
+ SpcrFound = TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // We need at least the FADT, MADT, GTDT and the DSDT tables to boot
+ if (!FadtFound) {
+ DEBUG ((DEBUG_ERROR, "ERROR: FADT Table not found\n"));
+ Status = EFI_NOT_FOUND;
+ }
+
+ if (!MadtFound) {
+ DEBUG ((DEBUG_ERROR, "ERROR: MADT Table not found.\n"));
+ Status = EFI_NOT_FOUND;
+ }
+
+ if (!GtdtFound) {
+ DEBUG ((DEBUG_ERROR, "ERROR: GTDT Table not found.\n"));
+ Status = EFI_NOT_FOUND;
+ }
+
+ if (!DsdtFound) {
+ DEBUG ((DEBUG_ERROR, "ERROR: DSDT Table not found.\n"));
+ Status = EFI_NOT_FOUND;
+ }
+
+ if (!Dbg2Found) {
+ DEBUG ((DEBUG_WARN, "WARNING: DBG2 Table not found.\n"));
+ }
+
+ if (!SpcrFound) {
+ DEBUG ((DEBUG_WARN, "WARNING: SPCR Table not found.\n"));
+ }
+
+ return Status;
+}
+
+/** Generate and install ACPI tables.
+
+ The function gathers the information necessary for installing the
+ ACPI tables from the Configuration Manager, invokes the generators
+ and installs them (via BuildAndInstallAcpiTable).
+
+ @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
+ interface.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_NOT_FOUND If a mandatory table or a generator is not found.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ProcessAcpiTables (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
+ CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo;
+ UINT32 AcpiTableCount;
+ UINT32 Idx;
+
+ ASSERT (TableFactoryProtocol != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+
+ // Find the AcpiTable protocol
+ Status = gBS->LocateProtocol (
+ &gEfiAcpiTableProtocolGuid,
+ NULL,
+ (VOID **)&AcpiTableProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find AcpiTable protocol. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ Status = GetEStdObjAcpiTableList (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &AcpiTableInfo,
+ &AcpiTableCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to get ACPI Table List. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ if (0 == AcpiTableCount) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: EStdObjAcpiTableList: AcpiTableCount = %d\n",
+ AcpiTableCount
+ ));
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: EStdObjAcpiTableList: AcpiTableCount = %d\n",
+ AcpiTableCount
+ ));
+
+ // Check if mandatory ACPI tables are present.
+ Status = VerifyMandatoryTablesArePresent (
+ AcpiTableInfo,
+ AcpiTableCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find mandatory ACPI Table(s)."
+ " Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ // Add the FADT Table first.
+ for (Idx = 0; Idx < AcpiTableCount; Idx++) {
+ if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) ==
+ AcpiTableInfo[Idx].TableGeneratorId)
+ {
+ Status = BuildAndInstallAcpiTable (
+ TableFactoryProtocol,
+ CfgMgrProtocol,
+ AcpiTableProtocol,
+ &AcpiTableInfo[Idx]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find build and install ACPI FADT Table." \
+ " Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ break;
+ }
+ } // for
+
+ // Add remaining ACPI Tables
+ for (Idx = 0; Idx < AcpiTableCount; Idx++) {
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: AcpiTableInfo[%d].TableGeneratorId = 0x%x\n",
+ Idx,
+ AcpiTableInfo[Idx].TableGeneratorId
+ ));
+
+ // Skip FADT Table since we have already added
+ if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) ==
+ AcpiTableInfo[Idx].TableGeneratorId)
+ {
+ continue;
+ }
+
+ // Skip the Reserved table Generator ID for standard generators
+ if ((IS_GENERATOR_NAMESPACE_STD (AcpiTableInfo[Idx].TableGeneratorId)) &&
+ ((CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdReserved) >=
+ AcpiTableInfo[Idx].TableGeneratorId) ||
+ (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMax) <=
+ AcpiTableInfo[Idx].TableGeneratorId)))
+ {
+ DEBUG ((
+ DEBUG_WARN,
+ "WARNING: Invalid ACPI Generator table ID = 0x%x, Skipping...\n",
+ AcpiTableInfo[Idx].TableGeneratorId
+ ));
+ continue;
+ }
+
+ Status = BuildAndInstallAcpiTable (
+ TableFactoryProtocol,
+ CfgMgrProtocol,
+ AcpiTableProtocol,
+ &AcpiTableInfo[Idx]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find, build, and install ACPI Table." \
+ " Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+ } // for
+
+ return Status;
+}
+
+/** Callback Function for Smbios table generation.
+
+ Callback function when SMBIOS protocol is installed, this function will then
+ invoke the code to install the available SMBIOS tables.
+
+ @param Event
+ @param Context
+
+ @retval None.
+**/
+VOID
+AcpiTableProtocolReady (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EDKII_CONFIGURATION_MANAGER_PROTOCOL *CfgMgrProtocol;
+ CM_STD_OBJ_CONFIGURATION_MANAGER_INFO *CfgMfrInfo;
+ EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *TableFactoryProtocol;
+
+ // Locate the Dynamic Table Factory
+ Status = gBS->LocateProtocol (
+ &gEdkiiDynamicTableFactoryProtocolGuid,
+ NULL,
+ (VOID **)&TableFactoryProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find Dynamic Table Factory protocol." \
+ " Status = %r\n",
+ Status
+ ));
+ return;
+ }
+
+ // Locate the Configuration Manager for the Platform
+ Status = gBS->LocateProtocol (
+ &gEdkiiConfigurationManagerProtocolGuid,
+ NULL,
+ (VOID **)&CfgMgrProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find Configuration Manager protocol. Status = %r\n",
+ Status
+ ));
+ return;
+ }
+
+ Status = GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to get Configuration Manager info. Status = %r\n",
+ Status
+ ));
+ return;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: Configuration Manager Version = 0x%x, OemID = %c%c%c%c%c%c\n",
+ CfgMfrInfo->Revision,
+ CfgMfrInfo->OemId[0],
+ CfgMfrInfo->OemId[1],
+ CfgMfrInfo->OemId[2],
+ CfgMfrInfo->OemId[3],
+ CfgMfrInfo->OemId[4],
+ CfgMfrInfo->OemId[5]
+ ));
+
+ Status = ProcessAcpiTables (TableFactoryProtocol, CfgMgrProtocol);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: ACPI Table processing failure. Status = %r\n",
+ Status
+ ));
+ }
+}
diff --git
a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
index 1e9b811c40..242c40be3b 100644
--- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
@@ -2,704 +2,39 @@
Dynamic Table Manager Dxe
Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
+ Copyright (c) 2022 - 2023, NVIDIA CORPORATION & AFFILIATES. All rights
reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
-#include <Protocol/AcpiSystemDescriptionTable.h>
-#include <Protocol/AcpiTable.h>
// Module specific include files.
-#include <AcpiTableGenerator.h>
#include <ConfigurationManagerObject.h>
#include <ConfigurationManagerHelper.h>
-#include <DeviceTreeTableGenerator.h>
#include <Library/TableHelperLib.h>
#include <Protocol/ConfigurationManagerProtocol.h>
-#include <Protocol/DynamicTableFactoryProtocol.h>
-#include <SmbiosTableGenerator.h>
-///
-/// Bit definitions for acceptable ACPI table presence formats.
-/// Currently only ACPI tables present in the ACPI info list and
-/// already installed will count towards "Table Present" during
-/// verification routine.
-///
-#define ACPI_TABLE_PRESENT_INFO_LIST BIT0
-#define ACPI_TABLE_PRESENT_INSTALLED BIT1
+STATIC VOID *AcpiTableProtocolRegistration;
+STATIC VOID *SmbiosProtocolRegistration;
-///
-/// Order of ACPI table being verified during presence inspection.
-///
-#define ACPI_TABLE_VERIFY_FADT 0
-#define ACPI_TABLE_VERIFY_MADT 1
-#define ACPI_TABLE_VERIFY_GTDT 2
-#define ACPI_TABLE_VERIFY_DSDT 3
-#define ACPI_TABLE_VERIFY_DBG2 4
-#define ACPI_TABLE_VERIFY_SPCR 5
-#define ACPI_TABLE_VERIFY_COUNT 6
+extern
+VOID
+SmbiosProtocolReady (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
-///
-/// Private data structure to verify the presence of mandatory
-/// or optional ACPI tables.
-///
-typedef struct {
- /// ESTD ID for the ACPI table of interest.
- ESTD_ACPI_TABLE_ID EstdTableId;
- /// Standard UINT32 ACPI signature.
- UINT32 AcpiTableSignature;
- /// 4 character ACPI table name (the 5th char8 is for null terminator).
- CHAR8 AcpiTableName[sizeof (UINT32) + 1];
- /// Indicator on whether the ACPI table is required.
- BOOLEAN IsMandatory;
- /// Formats of verified presences, as defined by ACPI_TABLE_PRESENT_*
- /// This field should be initialized to 0 and will be populated during
- /// verification routine.
- UINT16 Presence;
-} ACPI_TABLE_PRESENCE_INFO;
-
-///
-/// We require the FADT, MADT, GTDT and the DSDT tables to boot.
-/// This list also include optional ACPI tables: DBG2, SPCR.
-///
-ACPI_TABLE_PRESENCE_INFO mAcpiVerifyTables[ACPI_TABLE_VERIFY_COUNT] = {
- { EStdAcpiTableIdFadt, EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
"FADT", TRUE, 0 },
- { EStdAcpiTableIdMadt, EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
"MADT", TRUE, 0 },
- { EStdAcpiTableIdGtdt, EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
"GTDT", TRUE, 0 },
- { EStdAcpiTableIdDsdt, EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
"DSDT", TRUE, 0 },
- { EStdAcpiTableIdDbg2, EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE,
"DBG2", FALSE, 0 },
- { EStdAcpiTableIdSpcr, EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
"SPCR", FALSE, 0 },
-};
-
-/** This macro expands to a function that retrieves the ACPI Table
- List from the Configuration Manager.
-*/
-GET_OBJECT_LIST (
- EObjNameSpaceStandard,
- EStdObjAcpiTableList,
- CM_STD_OBJ_ACPI_TABLE_INFO
- )
-
-/** A helper function to build and install a single ACPI table.
-
- This is a helper function that invokes the Table generator interface
- for building an ACPI table. It uses the AcpiTableProtocol to install the
- table, then frees the resources allocated for generating it.
-
- @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
- interface.
- @param [in] CfgMgrProtocol Pointer to the Configuration Manager
- Protocol Interface.
- @param [in] Generator Pointer to the AcpiTable generator.
- @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol.
- @param [in] AcpiTableInfo Pointer to the ACPI table Info.
-
- @retval EFI_SUCCESS Success.
- @retval EFI_INVALID_PARAMETER A parameter is invalid.
- @retval EFI_NOT_FOUND Required object is not found.
- @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager
- is less than the Object size for the
- requested object.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-BuildAndInstallSingleAcpiTable (
- IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN CONST ACPI_TABLE_GENERATOR *CONST Generator,
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol,
- IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo
- )
-{
- EFI_STATUS Status;
- EFI_STATUS Status1;
- EFI_ACPI_DESCRIPTION_HEADER *AcpiTable;
- UINTN TableHandle;
-
- AcpiTable = NULL;
- Status = Generator->BuildAcpiTable (
- Generator,
- AcpiTableInfo,
- CfgMgrProtocol,
- &AcpiTable
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to Build Table." \
- " TableGeneratorId = 0x%x. Status = %r\n",
- AcpiTableInfo->TableGeneratorId,
- Status
- ));
- // Free any allocated resources.
- goto exit_handler;
- }
-
- if (AcpiTable == NULL) {
- Status = EFI_NOT_FOUND;
- goto exit_handler;
- }
-
- // Dump ACPI Table Header
- DUMP_ACPI_TABLE_HEADER (AcpiTable);
-
- // Install ACPI table
- Status = AcpiTableProtocol->InstallAcpiTable (
- AcpiTableProtocol,
- AcpiTable,
- AcpiTable->Length,
- &TableHandle
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to Install ACPI Table. Status = %r\n",
- Status
- ));
- // Free any allocated resources.
- goto exit_handler;
- }
-
- DEBUG ((
- DEBUG_INFO,
- "INFO: ACPI Table installed. Status = %r\n",
- Status
- ));
-
-exit_handler:
- // Free any resources allocated for generating the tables.
- if (Generator->FreeTableResources != NULL) {
- Status1 = Generator->FreeTableResources (
- Generator,
- AcpiTableInfo,
- CfgMgrProtocol,
- &AcpiTable
- );
- if (EFI_ERROR (Status1)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to Free Table Resources." \
- "TableGeneratorId = 0x%x. Status = %r\n",
- AcpiTableInfo->TableGeneratorId,
- Status1
- ));
- }
-
- // Return the first error status in case of failure
- if (!EFI_ERROR (Status)) {
- Status = Status1;
- }
- }
-
- return Status;
-}
-
-/** A helper function to build and install multiple ACPI tables.
-
- This is a helper function that invokes the Table generator interface
- for building an ACPI table. It uses the AcpiTableProtocol to install the
- table, then frees the resources allocated for generating it.
-
- @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
- interface.
- @param [in] CfgMgrProtocol Pointer to the Configuration Manager
- Protocol Interface.
- @param [in] Generator Pointer to the AcpiTable generator.
- @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol.
- @param [in] AcpiTableInfo Pointer to the ACPI table Info.
-
- @retval EFI_SUCCESS Success.
- @retval EFI_INVALID_PARAMETER A parameter is invalid.
- @retval EFI_NOT_FOUND Required object is not found.
- @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager
- is less than the Object size for the
- requested object.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-BuildAndInstallMultipleAcpiTable (
- IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN CONST ACPI_TABLE_GENERATOR *CONST Generator,
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol,
- IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo
- )
-{
- EFI_STATUS Status;
- EFI_STATUS Status1;
- EFI_ACPI_DESCRIPTION_HEADER **AcpiTable;
- UINTN TableCount;
- UINTN TableHandle;
- UINTN Index;
-
- AcpiTable = NULL;
- TableCount = 0;
- Status = Generator->BuildAcpiTableEx (
- Generator,
- AcpiTableInfo,
- CfgMgrProtocol,
- &AcpiTable,
- &TableCount
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to Build Table." \
- " TableGeneratorId = 0x%x. Status = %r\n",
- AcpiTableInfo->TableGeneratorId,
- Status
- ));
- // Free any allocated resources.
- goto exit_handler;
- }
-
- if ((AcpiTable == NULL) || (TableCount == 0)) {
- Status = EFI_NOT_FOUND;
- goto exit_handler;
- }
-
- for (Index = 0; Index < TableCount; Index++) {
- // Dump ACPI Table Header
- DUMP_ACPI_TABLE_HEADER (AcpiTable[Index]);
- // Install ACPI table
- Status = AcpiTableProtocol->InstallAcpiTable (
- AcpiTableProtocol,
- AcpiTable[Index],
- AcpiTable[Index]->Length,
- &TableHandle
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to Install ACPI Table. Status = %r\n",
- Status
- ));
- // Free any allocated resources.
- goto exit_handler;
- }
-
- DEBUG ((
- DEBUG_INFO,
- "INFO: ACPI Table installed. Status = %r\n",
- Status
- ));
- }
-
-exit_handler:
- // Free any resources allocated for generating the tables.
- if (Generator->FreeTableResourcesEx != NULL) {
- Status1 = Generator->FreeTableResourcesEx (
- Generator,
- AcpiTableInfo,
- CfgMgrProtocol,
- &AcpiTable,
- TableCount
- );
- if (EFI_ERROR (Status1)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to Free Table Resources." \
- "TableGeneratorId = 0x%x. Status = %r\n",
- AcpiTableInfo->TableGeneratorId,
- Status1
- ));
- }
-
- // Return the first error status in case of failure
- if (!EFI_ERROR (Status)) {
- Status = Status1;
- }
- }
-
- return Status;
-}
-
-/** A helper function to invoke a Table generator
-
- This is a helper function that invokes the Table generator interface
- for building an ACPI table. It uses the AcpiTableProtocol to install the
- table, then frees the resources allocated for generating it.
-
- @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
- interface.
- @param [in] CfgMgrProtocol Pointer to the Configuration Manager
- Protocol Interface.
- @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol.
- @param [in] AcpiTableInfo Pointer to the ACPI table Info.
-
- @retval EFI_SUCCESS Success.
- @retval EFI_INVALID_PARAMETER A parameter is invalid.
- @retval EFI_NOT_FOUND Required object is not found.
- @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager
- is less than the Object size for the
- requested object.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-BuildAndInstallAcpiTable (
- IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol,
- IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo
- )
-{
- EFI_STATUS Status;
- CONST ACPI_TABLE_GENERATOR *Generator;
-
- ASSERT (TableFactoryProtocol != NULL);
- ASSERT (CfgMgrProtocol != NULL);
- ASSERT (AcpiTableProtocol != NULL);
- ASSERT (AcpiTableInfo != NULL);
-
- DEBUG ((
- DEBUG_INFO,
- "INFO: EStdObjAcpiTableList: Address = 0x%p," \
- " TableGeneratorId = 0x%x\n",
- AcpiTableInfo,
- AcpiTableInfo->TableGeneratorId
- ));
-
- Generator = NULL;
- Status = TableFactoryProtocol->GetAcpiTableGenerator (
- TableFactoryProtocol,
- AcpiTableInfo->TableGeneratorId,
- &Generator
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Table Generator not found." \
- " TableGeneratorId = 0x%x. Status = %r\n",
- AcpiTableInfo->TableGeneratorId,
- Status
- ));
- return Status;
- }
-
- if (Generator == NULL) {
- return EFI_NOT_FOUND;
- }
-
- DEBUG ((
- DEBUG_INFO,
- "INFO: Generator found : %s\n",
- Generator->Description
- ));
-
- if (Generator->BuildAcpiTableEx != NULL) {
- Status = BuildAndInstallMultipleAcpiTable (
- TableFactoryProtocol,
- CfgMgrProtocol,
- Generator,
- AcpiTableProtocol,
- AcpiTableInfo
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to find build and install ACPI Table." \
- " Status = %r\n",
- Status
- ));
- }
- } else if (Generator->BuildAcpiTable != NULL) {
- Status = BuildAndInstallSingleAcpiTable (
- TableFactoryProtocol,
- CfgMgrProtocol,
- Generator,
- AcpiTableProtocol,
- AcpiTableInfo
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to find build and install ACPI Table." \
- " Status = %r\n",
- Status
- ));
- }
- } else {
- Status = EFI_INVALID_PARAMETER;
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Table Generator does not implement the" \
- " ACPI_TABLE_GENERATOR_BUILD_TABLE interface." \
- " TableGeneratorId = 0x%x. Status = %r\n",
- AcpiTableInfo->TableGeneratorId,
- Status
- ));
- }
-
- return Status;
-}
-
-/** The function checks if the Configuration Manager has provided the
- mandatory ACPI tables for installation.
-
- @param [in] AcpiTableInfo Pointer to the ACPI Table Info list.
- @param [in] AcpiTableCount Count of ACPI Table Info.
-
- @retval EFI_SUCCESS Success.
- @retval EFI_NOT_FOUND If mandatory table is not found.
- @retval EFI_ALREADY_STARTED If mandatory table found in AcpiTableInfo is
already installed.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-VerifyMandatoryTablesArePresent (
- IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
- IN UINT32 AcpiTableCount
- )
-{
- EFI_STATUS Status;
- UINTN Handle;
- UINTN Index;
- UINTN InstalledTableIndex;
- EFI_ACPI_DESCRIPTION_HEADER *DescHeader;
- EFI_ACPI_TABLE_VERSION Version;
- EFI_ACPI_SDT_PROTOCOL *AcpiSdt;
-
- ASSERT (AcpiTableInfo != NULL);
-
- Status = EFI_SUCCESS;
-
- // Check against the statically initialized ACPI tables to see if they are
in ACPI info list
- while (AcpiTableCount-- != 0) {
- for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) {
- if (AcpiTableInfo[AcpiTableCount].AcpiTableSignature ==
mAcpiVerifyTables[Index].AcpiTableSignature) {
- mAcpiVerifyTables[Index].Presence |= ACPI_TABLE_PRESENT_INFO_LIST;
- // Found this table, skip the rest.
- break;
- }
- }
- }
-
- // They also might be published already, so we can search from there
- if (FeaturePcdGet (PcdInstallAcpiSdtProtocol)) {
- AcpiSdt = NULL;
- Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID
**)&AcpiSdt);
-
- if (EFI_ERROR (Status) || (AcpiSdt == NULL)) {
- DEBUG ((DEBUG_ERROR, "ERROR: Failed to locate ACPI SDT protocol (0x%p) -
%r\n", AcpiSdt, Status));
- return Status;
- }
-
- for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) {
- Handle = 0;
- InstalledTableIndex = 0;
- do {
- Status = AcpiSdt->GetAcpiTable (InstalledTableIndex, (EFI_ACPI_SDT_HEADER
**)&DescHeader, &Version, &Handle);
- if (EFI_ERROR (Status)) {
- break;
- }
-
- InstalledTableIndex++;
- } while (DescHeader->Signature !=
mAcpiVerifyTables[Index].AcpiTableSignature);
-
- if (!EFI_ERROR (Status)) {
- mAcpiVerifyTables[Index].Presence |= ACPI_TABLE_PRESENT_INSTALLED;
- }
- }
- }
-
- // Reset the return Status value to EFI_SUCCESS. We do not fully care if the
table look up has failed.
- Status = EFI_SUCCESS;
- for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) {
- if (mAcpiVerifyTables[Index].Presence == 0) {
- if (mAcpiVerifyTables[Index].IsMandatory) {
- DEBUG ((DEBUG_ERROR, "ERROR: %a Table not found.\n",
mAcpiVerifyTables[Index].AcpiTableName));
- Status = EFI_NOT_FOUND;
- } else {
- DEBUG ((DEBUG_WARN, "WARNING: %a Table not found.\n",
mAcpiVerifyTables[Index].AcpiTableName));
- }
- } else if (mAcpiVerifyTables[Index].Presence ==
- (ACPI_TABLE_PRESENT_INFO_LIST | ACPI_TABLE_PRESENT_INSTALLED))
- {
- DEBUG ((DEBUG_ERROR, "ERROR: %a Table found while already published.\n",
mAcpiVerifyTables[Index].AcpiTableName));
- Status = EFI_ALREADY_STARTED;
- }
- }
-
- return Status;
-}
-
-/** Generate and install ACPI tables.
-
- The function gathers the information necessary for installing the
- ACPI tables from the Configuration Manager, invokes the generators
- and installs them (via BuildAndInstallAcpiTable).
-
- @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
- interface.
- @param [in] CfgMgrProtocol Pointer to the Configuration Manager
- Protocol Interface.
-
- @retval EFI_SUCCESS Success.
- @retval EFI_NOT_FOUND If a mandatory table or a generator is not
found.
- @retval EFI_ALREADY_STARTED If mandatory table found in AcpiTableInfo is
already installed.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-ProcessAcpiTables (
- IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol
- )
-{
- EFI_STATUS Status;
- EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
- CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo;
- UINT32 AcpiTableCount;
- UINT32 Idx;
-
- ASSERT (TableFactoryProtocol != NULL);
- ASSERT (CfgMgrProtocol != NULL);
-
- // Find the AcpiTable protocol
- Status = gBS->LocateProtocol (
- &gEfiAcpiTableProtocolGuid,
- NULL,
- (VOID **)&AcpiTableProtocol
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to find AcpiTable protocol. Status = %r\n",
- Status
- ));
- return Status;
- }
-
- Status = GetEStdObjAcpiTableList (
- CfgMgrProtocol,
- CM_NULL_TOKEN,
- &AcpiTableInfo,
- &AcpiTableCount
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to get ACPI Table List. Status = %r\n",
- Status
- ));
- return Status;
- }
-
- if (0 == AcpiTableCount) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: EStdObjAcpiTableList: AcpiTableCount = %d\n",
- AcpiTableCount
- ));
- return EFI_NOT_FOUND;
- }
-
- DEBUG ((
- DEBUG_INFO,
- "INFO: EStdObjAcpiTableList: AcpiTableCount = %d\n",
- AcpiTableCount
- ));
-
- // Check if mandatory ACPI tables are present.
- Status = VerifyMandatoryTablesArePresent (
- AcpiTableInfo,
- AcpiTableCount
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to verify mandatory ACPI Table(s) presence."
- " Status = %r\n",
- Status
- ));
- return Status;
- }
-
- // Add the FADT Table first.
- if ((mAcpiVerifyTables[ACPI_TABLE_VERIFY_FADT].Presence &
ACPI_TABLE_PRESENT_INSTALLED) == 0) {
- // FADT is not yet installed
- for (Idx = 0; Idx < AcpiTableCount; Idx++) {
- if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) ==
- AcpiTableInfo[Idx].TableGeneratorId)
- {
- Status = BuildAndInstallAcpiTable (
- TableFactoryProtocol,
- CfgMgrProtocol,
- AcpiTableProtocol,
- &AcpiTableInfo[Idx]
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to find build and install ACPI FADT Table." \
- " Status = %r\n",
- Status
- ));
- return Status;
- }
-
- break;
- }
- } // for
- }
-
- // Add remaining ACPI Tables
- for (Idx = 0; Idx < AcpiTableCount; Idx++) {
- DEBUG ((
- DEBUG_INFO,
- "INFO: AcpiTableInfo[%d].TableGeneratorId = 0x%x\n",
- Idx,
- AcpiTableInfo[Idx].TableGeneratorId
- ));
-
- // Skip FADT Table since we have already added
- if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) ==
- AcpiTableInfo[Idx].TableGeneratorId)
- {
- continue;
- }
-
- // Skip the Reserved table Generator ID for standard generators
- if ((IS_GENERATOR_NAMESPACE_STD (AcpiTableInfo[Idx].TableGeneratorId)) &&
- ((CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdReserved) >=
- AcpiTableInfo[Idx].TableGeneratorId) ||
- (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMax) <=
- AcpiTableInfo[Idx].TableGeneratorId)))
- {
- DEBUG ((
- DEBUG_WARN,
- "WARNING: Invalid ACPI Generator table ID = 0x%x, Skipping...\n",
- AcpiTableInfo[Idx].TableGeneratorId
- ));
- continue;
- }
-
- Status = BuildAndInstallAcpiTable (
- TableFactoryProtocol,
- CfgMgrProtocol,
- AcpiTableProtocol,
- &AcpiTableInfo[Idx]
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to find, build, and install ACPI Table." \
- " Status = %r\n",
- Status
- ));
- return Status;
- }
- } // for
-
- return Status;
-}
+extern
+VOID
+AcpiTableProtocolReady (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );