From: "Girish Mahadevan via groups.io" <gmahadevan=nvidia.com@groups.io>
To: <devel@edk2.groups.io>, <sami.mujawar@arm.com>
Cc: <gmahadevan@nvidia.com>, <Alexei.Fedorov@arm.com>,
<Pierre.Gondois@arm.com>, <jbrasen@nvidia.com>,
<ashishsingha@nvidia.com>, <nramirez@nvidia.com>
Subject: [edk2-devel] [PATCH v3 2/5] DynamicTablesPkg: Split the ACPI and SMBIOS table generators
Date: Tue, 25 Jul 2023 23:38:02 +0000 [thread overview]
Message-ID: <20230725233805.646668-3-gmahadevan@nvidia.com> (raw)
In-Reply-To: <20230725233805.646668-1-gmahadevan@nvidia.com>
Split the SMBIOS and ACPI table generators into their own files.
Signed-off-by: Girish Mahadevan <gmahadevan@nvidia.com>
Reviewed-by: Jeff Brasen <jbrasen@nvidia.com>
---
.../DynamicTableManagerDxe/AcpiTableBuilder.c | 798 ++++++++++
.../DynamicTableManagerDxe.c | 1356 +----------------
.../DynamicTableManagerDxe.inf | 2 +
.../SmbiosTableBuilder.c | 606 ++++++++
4 files changed, 1419 insertions(+), 1343 deletions(-)
create mode 100644 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/AcpiTableBuilder.c
create mode 100644 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/SmbiosTableBuilder.c
diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/AcpiTableBuilder.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/AcpiTableBuilder.c
new file mode 100644
index 0000000000..2adfb0378e
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/AcpiTableBuilder.c
@@ -0,0 +1,798 @@
+/** @file
+ Acpi 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>
+#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>
+
+///
+/// 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
+
+///
+/// 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
+
+///
+/// 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;
+}
+
+/** Entrypoint of Dynamic Table Manager Dxe.
+
+ The Dynamic Table Manager uses the Configuration Manager Protocol
+ to get the list of ACPI and SMBIOS tables to install. For each table
+ in the list it requests the corresponding ACPI/SMBIOS table factory for
+ a generator capable of building the ACPI/SMBIOS table.
+ If a suitable table generator is found, it invokes the generator interface
+ to build the table. The Dynamic Table Manager then installs the
+ table and invokes another generator interface to free any resources
+ allocated for building the table.
+
+ @param ImageHandle
+ @param SystemTable
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+ @retval EFI_NOT_FOUND Required interface/object was not found.
+ @retval EFI_INVALID_PARAMETER Some parameter is incorrect/invalid.
+**/
+VOID
+EFIAPI
+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 26aa9b55cf..6ad2e623b2 100644
--- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
@@ -2,6 +2,7 @@
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
@@ -11,10 +12,6 @@
#include <Library/UefiLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
-#include <Protocol/AcpiSystemDescriptionTable.h>
-#include <Protocol/AcpiTable.h>
-#include <Protocol/Smbios.h>
-#include <Library/BaseMemoryLib.h>
// Module specific include files.
#include <AcpiTableGenerator.h>
@@ -24,1351 +21,25 @@
#include <Library/TableHelperLib.h>
#include <Protocol/ConfigurationManagerProtocol.h>
#include <Protocol/DynamicTableFactoryProtocol.h>
-#include <SmbiosTableGenerator.h>
-#include <SmbiosTableDispatcher.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
-
-///
-/// 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
-
-///
-/// 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
- )
-
-/** This macro expands to a function that retrieves the SMBIOS Table
- List from the Configuration Manager.
-*/
-GET_OBJECT_LIST (
- EObjNameSpaceStandard,
- EStdObjSmbiosTableList,
- CM_STD_OBJ_SMBIOS_TABLE_INFO
- )
-
-STATIC VOID *AcpiTableProtocolRegistration;
+STATIC VOID *AcpiTableProtocolRegistration;
STATIC VOID *SmbiosProtocolRegistration;
-/** 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;
-}
-
-/** A helper function to build and install an SMBIOS table.
-
- This is a helper function that invokes the Table generator interface
- for building an SMBIOS table. It uses the SmbiosProtocol 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] SmbiosProtocol Pointer to the SMBIOS protocol.
- @param [in] SmbiosTableInfo Pointer to the SMBIOS 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
-BuildAndInstallSingleSmbiosTable (
- IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN CONST SMBIOS_TABLE_GENERATOR *CONST Generator,
- IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol,
- IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo
- )
-{
- EFI_STATUS Status;
- EFI_STATUS Status1;
- SMBIOS_STRUCTURE *SmbiosTable;
- CM_OBJECT_TOKEN CmObjToken;
- EFI_SMBIOS_HANDLE TableHandle;
-
- SmbiosTable = NULL;
- Status = Generator->BuildSmbiosTable (
- Generator,
- TableFactoryProtocol,
- SmbiosTableInfo,
- CfgMgrProtocol,
- &SmbiosTable,
- &CmObjToken
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to Build Table." \
- " TableGeneratorId = 0x%x. Status = %r\n",
- SmbiosTableInfo->TableGeneratorId,
- Status
- ));
- // Free any allocated resources.
- goto exit_handler;
- }
-
- if (SmbiosTable == NULL) {
- Status = EFI_NOT_FOUND;
- goto exit_handler;
- }
-
- TableHandle = SMBIOS_HANDLE_PI_RESERVED;
- // Install SMBIOS table
- Status = SmbiosProtocol->Add (
- SmbiosProtocol,
- NULL,
- &TableHandle,
- SmbiosTable
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to Install SMBIOS Table. Status = %r\n",
- Status
- ));
- // Free any allocated resources.
- goto exit_handler;
- }
-
- Status = TableFactoryProtocol->AddSmbiosHandle (
- SmbiosProtocol,
- &TableHandle,
- CmObjToken,
- SmbiosTableInfo->TableGeneratorId
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to Add SMBIOS Handle. Status = %r\n",
- Status
- ));
- // Free any allocated resources.
- goto exit_handler;
- }
-
- DEBUG ((
- DEBUG_INFO,
- "INFO: SMBIOS Table installed. Status = %r\n",
- Status
- ));
-
-exit_handler:
- // Free any resources allocated for generating the tables.
- if (Generator->FreeTableResources != NULL) {
- Status1 = Generator->FreeTableResources (
- Generator,
- TableFactoryProtocol,
- SmbiosTableInfo,
- CfgMgrProtocol,
- &SmbiosTable
- );
- if (EFI_ERROR (Status1)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to Free Table Resources." \
- "TableGeneratorId = 0x%x. Status = %r\n",
- SmbiosTableInfo->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 SMBIOS tables.
-
- This is a helper function that invokes the Table generator interface
- for building SMBIOS tables. It uses the SmbiosProtocol to install the
- tables, 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 SmbiosTable generator.
- @param [in] SmbiosProtocol Pointer to the Smbios protocol.
- @param [in] AcpiTableInfo Pointer to the SMBIOS 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
-BuildAndInstallMultipleSmbiosTables (
- IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN CONST SMBIOS_TABLE_GENERATOR *CONST Generator,
- IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol,
- IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo
- )
-{
- EFI_STATUS Status;
- EFI_STATUS Status1;
- SMBIOS_STRUCTURE **SmbiosTable;
- CM_OBJECT_TOKEN *CmObjToken;
- EFI_SMBIOS_HANDLE TableHandle;
- UINTN TableCount;
- UINTN Index;
-
- TableCount = 0;
- Status = Generator->BuildSmbiosTableEx (
- Generator,
- TableFactoryProtocol,
- SmbiosTableInfo,
- CfgMgrProtocol,
- &SmbiosTable,
- &CmObjToken,
- &TableCount
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to Build Table." \
- " TableGeneratorId = 0x%x. Status = %r\n",
- SmbiosTableInfo->TableGeneratorId,
- Status
- ));
- // Free any allocated resources.
- goto exit_handler;
- }
-
- if ((SmbiosTable == NULL) || (TableCount == 0)) {
- Status = EFI_NOT_FOUND;
- DEBUG ((
- DEBUG_ERROR,
- "%a: TableCount %u SmbiosTable %p \n",
- __FUNCTION__,
- TableCount,
- SmbiosTable
- ));
- goto exit_handler;
- }
-
- for (Index = 0; Index < TableCount; Index++) {
- TableHandle = SMBIOS_HANDLE_PI_RESERVED;
-
- // Install SMBIOS table
- Status = SmbiosProtocol->Add (
- SmbiosProtocol,
- NULL,
- &TableHandle,
- SmbiosTable[Index]
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to Install SMBIOS Table. Status = %r\n",
- Status
- ));
- // Free any allocated resources.
- goto exit_handler;
- }
-
- Status = TableFactoryProtocol->AddSmbiosHandle (
- SmbiosProtocol,
- &TableHandle,
- CmObjToken[Index],
- SmbiosTableInfo->TableGeneratorId
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to Add SMBIOS Handle. Status = %r\n",
- Status
- ));
- // Free any allocated resources.
- goto exit_handler;
- }
-
- DEBUG ((
- DEBUG_INFO,
- "INFO: SMBIOS Table installed. Status = %r\n",
- Status
- ));
- }
-
-exit_handler:
- // Free any resources allocated for generating the tables.
- if (Generator->FreeTableResourcesEx != NULL) {
- Status1 = Generator->FreeTableResourcesEx (
- Generator,
- TableFactoryProtocol,
- SmbiosTableInfo,
- CfgMgrProtocol,
- &SmbiosTable,
- &CmObjToken,
- TableCount
- );
- if (EFI_ERROR (Status1)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to Free Table Resources." \
- "TableGeneratorId = 0x%x. Status = %r\n",
- SmbiosTableInfo->TableGeneratorId,
- Status1
- ));
- }
-
- // Return the first error status in case of failure
- if (!EFI_ERROR (Status)) {
- Status = Status1;
- }
- }
-
- DEBUG ((DEBUG_ERROR, "%a: Returning %r\n", __FUNCTION__, Status));
- return Status;
-}
-
-/** A helper function to invoke a Table generator
-
- This is a helper function that invokes the Table generator interface
- for building an SMBIOS table. It uses the SmbiosProtocol 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] SmbiosProtocol Pointer to the SMBIOS protocol.
- @param [in] SmbiosTableInfo Pointer to the SMBIOS 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.
-**/
-EFI_STATUS
-EFIAPI
-BuildAndInstallSmbiosTable (
- IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol,
- IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo
- )
-{
- EFI_STATUS Status;
- CONST SMBIOS_TABLE_GENERATOR *Generator;
-
- ASSERT (TableFactoryProtocol != NULL);
- ASSERT (CfgMgrProtocol != NULL);
- ASSERT (SmbiosProtocol != NULL);
- ASSERT (SmbiosTableInfo != NULL);
-
- DEBUG ((
- DEBUG_INFO,
- "INFO: EStdObjSmbiosTableList: Address = 0x%p," \
- " TableGeneratorId = 0x%x\n",
- SmbiosTableInfo,
- SmbiosTableInfo->TableGeneratorId
- ));
-
- Generator = NULL;
- Status = TableFactoryProtocol->GetSmbiosTableGenerator (
- TableFactoryProtocol,
- SmbiosTableInfo->TableGeneratorId,
- &Generator
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Table Generator not found." \
- " TableGeneratorId = 0x%x. Status = %r\n",
- SmbiosTableInfo->TableGeneratorId,
- Status
- ));
- return Status;
- }
-
- if (Generator == NULL) {
- return EFI_NOT_FOUND;
- }
-
- DEBUG ((
- DEBUG_INFO,
- "INFO: Generator found : %s\n",
- Generator->Description
- ));
-
- if (Generator->BuildSmbiosTableEx != NULL) {
- Status = BuildAndInstallMultipleSmbiosTables (
- TableFactoryProtocol,
- CfgMgrProtocol,
- Generator,
- SmbiosProtocol,
- SmbiosTableInfo
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to find build and install SMBIOS Tables." \
- " Status = %r\n",
- Status
- ));
- }
- } else if (Generator->BuildSmbiosTable != NULL) {
- Status = BuildAndInstallSingleSmbiosTable (
- TableFactoryProtocol,
- CfgMgrProtocol,
- Generator,
- SmbiosProtocol,
- SmbiosTableInfo
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to find build and install SMBIOS Table." \
- " Status = %r\n",
- Status
- ));
- }
- } else {
- Status = EFI_INVALID_PARAMETER;
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Table Generator does not implement the" \
- "SMBIOS_TABLE_GENERATOR_BUILD_TABLE interface." \
- " TableGeneratorId = 0x%x. Status = %r\n",
- SmbiosTableInfo->TableGeneratorId,
- Status
- ));
- }
-
- DEBUG ((DEBUG_ERROR, "%a: Returning %r\n", __FUNCTION__, Status));
- return Status;
-}
-
-/** Generate and install SMBIOS tables.
-
- The function gathers the information necessary for installing the
- SMBIOS 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
-ProcessSmbiosTables (
- IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol
- )
-{
- EFI_STATUS Status;
- EFI_SMBIOS_PROTOCOL *SmbiosProtocol;
- CM_STD_OBJ_SMBIOS_TABLE_INFO *SmbiosTableInfo;
- UINT32 SmbiosTableCount;
-
- Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&SmbiosProtocol);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol. %r\n", Status));
- return Status;
- }
-
- Status = GetEStdObjSmbiosTableList (
- CfgMgrProtocol,
- CM_NULL_TOKEN,
- &SmbiosTableInfo,
- &SmbiosTableCount
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to get SMBIOS Table List. Status = %r\n",
- Status
- ));
- return Status;
- }
-
- if (SmbiosTableCount == 0) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: EStdObjSmbiosTableList: SmbiosTableCount = %d\n",
- SmbiosTableCount
- ));
- return EFI_NOT_FOUND;
- }
-
- DEBUG ((
- DEBUG_INFO,
- "INFO: EStdObjSmbiosTableList: SmbiosTableCount = %d\n",
- SmbiosTableCount
- ));
-
- InitSmbiosTableDispatcher (SmbiosTableInfo, SmbiosTableCount);
-
- Status = DispatchSmbiosTables (
- TableFactoryProtocol,
- CfgMgrProtocol,
- SmbiosProtocol,
- SmbiosTableInfo,
- SmbiosTableCount
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: Failed to install SMBIOS Tables.Status = %r\n",
- Status
- ));
- }
-
- 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;
-}
-
-/** Callback function for ACPI Protocol .
-
- Callback function for ACPI protocol that installs ACPI tables
-
- @param Event
- @param Context
-
- @retval None
-**/
-STATIC
+extern
VOID
-AcpiTableProtocolReady (
+EFIAPI
+SmbiosProtocolReady (
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
- ));
- }
-}
-
-/** Callback function for SMBIOS Protocol .
-
- Callback function for SMBIOS protocol that installs SMBIOS tables
- that use the DynamicTables Package.
-
- @param Event
- @param Context
-
- @retval None
-**/
-STATIC
+extern
VOID
-SmbiosProtocolReady (
+EFIAPI
+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 = ProcessSmbiosTables (TableFactoryProtocol, CfgMgrProtocol);
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: SMBIOS Table processing failure. Status = %r\n",
- Status
- ));
- }
-}
+ );
/** Entrypoint of Dynamic Table Manager Dxe.
@@ -1396,9 +67,8 @@ DynamicTableManagerDxeInitialize (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
- EFI_STATUS Status;
- EFI_EVENT AcpiEvent;
- EFI_EVENT SmbiosEvent;
+ EFI_EVENT AcpiEvent;
+ EFI_EVENT SmbiosEvent;
AcpiEvent = EfiCreateProtocolNotifyEvent (
&gEfiAcpiTableProtocolGuid,
@@ -1425,5 +95,5 @@ DynamicTableManagerDxeInitialize (
return EFI_OUT_OF_RESOURCES;
}
- return Status;
+ return EFI_SUCCESS;
}
diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
index 3beab7420a..93fde9f44f 100644
--- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
@@ -24,6 +24,8 @@
DynamicTableManagerDxe.c
SmbiosTableDispatcher.c
SmbiosTableDispatcher.h
+ AcpiTableBuilder.c
+ SmbiosTableBuilder.c
[Packages]
MdePkg/MdePkg.dec
diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/SmbiosTableBuilder.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/SmbiosTableBuilder.c
new file mode 100644
index 0000000000..bfddaac3aa
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/SmbiosTableBuilder.c
@@ -0,0 +1,606 @@
+/** @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/Smbios.h>
+#include <Library/BaseMemoryLib.h>
+
+// Module specific include files.
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <DeviceTreeTableGenerator.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Protocol/DynamicTableFactoryProtocol.h>
+#include <SmbiosTableGenerator.h>
+#include <SmbiosTableDispatcher.h>
+
+/** This macro expands to a function that retrieves the SMBIOS Table
+ List from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceStandard,
+ EStdObjSmbiosTableList,
+ CM_STD_OBJ_SMBIOS_TABLE_INFO
+ )
+
+/** A helper function to build and install an SMBIOS table.
+
+ This is a helper function that invokes the Table generator interface
+ for building an SMBIOS table. It uses the SmbiosProtocol 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] SmbiosProtocol Pointer to the SMBIOS protocol.
+ @param [in] SmbiosTableInfo Pointer to the SMBIOS 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
+BuildAndInstallSingleSmbiosTable (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CONST SMBIOS_TABLE_GENERATOR *CONST Generator,
+ IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol,
+ IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ SMBIOS_STRUCTURE *SmbiosTable;
+ CM_OBJECT_TOKEN CmObjToken;
+ EFI_SMBIOS_HANDLE TableHandle;
+
+ SmbiosTable = NULL;
+ Status = Generator->BuildSmbiosTable (
+ Generator,
+ TableFactoryProtocol,
+ SmbiosTableInfo,
+ CfgMgrProtocol,
+ &SmbiosTable,
+ &CmObjToken
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Build Table." \
+ " TableGeneratorId = 0x%x. Status = %r\n",
+ SmbiosTableInfo->TableGeneratorId,
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ if (SmbiosTable == NULL) {
+ Status = EFI_NOT_FOUND;
+ goto exit_handler;
+ }
+
+ TableHandle = SMBIOS_HANDLE_PI_RESERVED;
+
+ // Install SMBIOS table
+ Status = SmbiosProtocol->Add (
+ SmbiosProtocol,
+ NULL,
+ &TableHandle,
+ SmbiosTable
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Install SMBIOS Table. Status = %r\n",
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ Status = TableFactoryProtocol->AddSmbiosHandle (
+ SmbiosProtocol,
+ &TableHandle,
+ CmObjToken,
+ SmbiosTableInfo->TableGeneratorId
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Add SMBIOS Handle. Status = %r\n",
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: SMBIOS Table installed. Status = %r\n",
+ Status
+ ));
+
+exit_handler:
+ // Free any resources allocated for generating the tables.
+ if (Generator->FreeTableResources != NULL) {
+ Status1 = Generator->FreeTableResources (
+ Generator,
+ TableFactoryProtocol,
+ SmbiosTableInfo,
+ CfgMgrProtocol,
+ &SmbiosTable
+ );
+ if (EFI_ERROR (Status1)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Free Table Resources." \
+ "TableGeneratorId = 0x%x. Status = %r\n",
+ SmbiosTableInfo->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 SMBIOS tables.
+
+ This is a helper function that invokes the Table generator interface
+ for building SMBIOS tables. It uses the SmbiosProtocol to install the
+ tables, 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 SmbiosTable generator.
+ @param [in] SmbiosProtocol Pointer to the Smbios protocol.
+ @param [in] AcpiTableInfo Pointer to the SMBIOS 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
+BuildAndInstallMultipleSmbiosTables (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CONST SMBIOS_TABLE_GENERATOR *CONST Generator,
+ IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol,
+ IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ SMBIOS_STRUCTURE **SmbiosTable;
+ CM_OBJECT_TOKEN *CmObjToken;
+ EFI_SMBIOS_HANDLE TableHandle;
+ UINTN TableCount;
+ UINTN Index;
+
+ TableCount = 0;
+ Status = Generator->BuildSmbiosTableEx (
+ Generator,
+ TableFactoryProtocol,
+ SmbiosTableInfo,
+ CfgMgrProtocol,
+ &SmbiosTable,
+ &CmObjToken,
+ &TableCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Build Table." \
+ " TableGeneratorId = 0x%x. Status = %r\n",
+ SmbiosTableInfo->TableGeneratorId,
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ if ((SmbiosTable == NULL) || (TableCount == 0)) {
+ Status = EFI_NOT_FOUND;
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: TableCount %u SmbiosTable %p \n",
+ __FUNCTION__,
+ TableCount,
+ SmbiosTable
+ ));
+ goto exit_handler;
+ }
+
+ for (Index = 0; Index < TableCount; Index++) {
+ TableHandle = SMBIOS_HANDLE_PI_RESERVED;
+
+ // Install SMBIOS table
+ Status = SmbiosProtocol->Add (
+ SmbiosProtocol,
+ NULL,
+ &TableHandle,
+ SmbiosTable[Index]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Install SMBIOS Table. Status = %r\n",
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ Status = TableFactoryProtocol->AddSmbiosHandle (
+ SmbiosProtocol,
+ &TableHandle,
+ CmObjToken[Index],
+ SmbiosTableInfo->TableGeneratorId
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Add SMBIOS Handle. Status = %r\n",
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: SMBIOS Table installed. Status = %r\n",
+ Status
+ ));
+ }
+
+exit_handler:
+ // Free any resources allocated for generating the tables.
+ if (Generator->FreeTableResourcesEx != NULL) {
+ Status1 = Generator->FreeTableResourcesEx (
+ Generator,
+ TableFactoryProtocol,
+ SmbiosTableInfo,
+ CfgMgrProtocol,
+ &SmbiosTable,
+ &CmObjToken,
+ TableCount
+ );
+ if (EFI_ERROR (Status1)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Free Table Resources." \
+ "TableGeneratorId = 0x%x. Status = %r\n",
+ SmbiosTableInfo->TableGeneratorId,
+ Status1
+ ));
+ }
+
+ // Return the first error status in case of failure
+ if (!EFI_ERROR (Status)) {
+ Status = Status1;
+ }
+ }
+
+ DEBUG ((DEBUG_ERROR, "%a: Returning %r\n", __FUNCTION__, Status));
+ return Status;
+}
+
+/** A helper function to invoke a Table generator
+
+ This is a helper function that invokes the Table generator interface
+ for building an SMBIOS table. It uses the SmbiosProtocol 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] SmbiosProtocol Pointer to the SMBIOS protocol.
+ @param [in] SmbiosTableInfo Pointer to the SMBIOS 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.
+**/
+EFI_STATUS
+EFIAPI
+BuildAndInstallSmbiosTable (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol,
+ IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo
+ )
+{
+ EFI_STATUS Status;
+ CONST SMBIOS_TABLE_GENERATOR *Generator;
+
+ ASSERT (TableFactoryProtocol != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (SmbiosProtocol != NULL);
+ ASSERT (SmbiosTableInfo != NULL);
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: EStdObjSmbiosTableList: Address = 0x%p," \
+ " TableGeneratorId = 0x%x\n",
+ SmbiosTableInfo,
+ SmbiosTableInfo->TableGeneratorId
+ ));
+
+ Generator = NULL;
+ Status = TableFactoryProtocol->GetSmbiosTableGenerator (
+ TableFactoryProtocol,
+ SmbiosTableInfo->TableGeneratorId,
+ &Generator
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Table Generator not found." \
+ " TableGeneratorId = 0x%x. Status = %r\n",
+ SmbiosTableInfo->TableGeneratorId,
+ Status
+ ));
+ return Status;
+ }
+
+ if (Generator == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: Generator found : %s\n",
+ Generator->Description
+ ));
+
+ if (Generator->BuildSmbiosTableEx != NULL) {
+ Status = BuildAndInstallMultipleSmbiosTables (
+ TableFactoryProtocol,
+ CfgMgrProtocol,
+ Generator,
+ SmbiosProtocol,
+ SmbiosTableInfo
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find build and install SMBIOS Tables." \
+ " Status = %r\n",
+ Status
+ ));
+ }
+ } else if (Generator->BuildSmbiosTable != NULL) {
+ Status = BuildAndInstallSingleSmbiosTable (
+ TableFactoryProtocol,
+ CfgMgrProtocol,
+ Generator,
+ SmbiosProtocol,
+ SmbiosTableInfo
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find build and install SMBIOS Table." \
+ " Status = %r\n",
+ Status
+ ));
+ }
+ } else {
+ Status = EFI_INVALID_PARAMETER;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Table Generator does not implement the" \
+ "SMBIOS_TABLE_GENERATOR_BUILD_TABLE interface." \
+ " TableGeneratorId = 0x%x. Status = %r\n",
+ SmbiosTableInfo->TableGeneratorId,
+ Status
+ ));
+ }
+
+ DEBUG ((DEBUG_ERROR, "%a: Returning %r\n", __FUNCTION__, Status));
+ return Status;
+}
+
+/** Generate and install SMBIOS tables.
+
+ The function gathers the information necessary for installing the
+ SMBIOS 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
+ProcessSmbiosTables (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBIOS_PROTOCOL *SmbiosProtocol;
+ CM_STD_OBJ_SMBIOS_TABLE_INFO *SmbiosTableInfo;
+ UINT32 SmbiosTableCount;
+
+ Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&SmbiosProtocol);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol. %r\n", Status));
+ return Status;
+ }
+
+ Status = GetEStdObjSmbiosTableList (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &SmbiosTableInfo,
+ &SmbiosTableCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to get SMBIOS Table List. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ if (SmbiosTableCount == 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: EStdObjSmbiosTableList: SmbiosTableCount = %d\n",
+ SmbiosTableCount
+ ));
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: EStdObjSmbiosTableList: SmbiosTableCount = %d\n",
+ SmbiosTableCount
+ ));
+
+ InitSmbiosTableDispatcher (SmbiosTableInfo, SmbiosTableCount);
+
+ Status = DispatchSmbiosTables (
+ TableFactoryProtocol,
+ CfgMgrProtocol,
+ SmbiosProtocol,
+ SmbiosTableInfo,
+ SmbiosTableCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to install SMBIOS Tables.Status = %r\n",
+ Status
+ ));
+ }
+
+ DEBUG ((DEBUG_ERROR, "%a: Returning %r\n", __FUNCTION__, Status));
+ return Status;
+}
+
+/** Callback function for SMBIOS Protocol .
+
+ Callback function for SMBIOS protocol that installs SMBIOS tables
+ that use the DynamicTables Package.
+
+ @param Event
+ @param Context
+
+ @retval None
+**/
+VOID
+EFIAPI
+SmbiosProtocolReady (
+ 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 = ProcessSmbiosTables (TableFactoryProtocol, CfgMgrProtocol);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SMBIOS Table processing failure. Status = %r\n",
+ Status
+ ));
+ }
+}
--
2.17.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107257): https://edk2.groups.io/g/devel/message/107257
Mute This Topic: https://groups.io/mt/100361561/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2023-07-25 23:38 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-25 23:38 [edk2-devel] [PATCH v3 0/5] DynamicTablesPkg: Add SMBIOS Table Generation Girish Mahadevan via groups.io
2023-07-25 23:38 ` [edk2-devel] [PATCH v3 1/5] DynamicTablesPkg: Add SMBIOS table generation Girish Mahadevan via groups.io
2023-08-24 19:02 ` Jose Marinho
2023-07-25 23:38 ` Girish Mahadevan via groups.io [this message]
2023-07-25 23:38 ` [edk2-devel] [PATCH v3 3/5] DynamicTablesPkg: Introduce new namespace for SMBIOS Objects Girish Mahadevan via groups.io
2023-07-25 23:38 ` [edk2-devel] [PATCH v3 4/5] DynamicTablesPkg: Smbios Memory Device (Type 17) Girish Mahadevan via groups.io
2023-07-25 23:38 ` [edk2-devel] [PATCH v3 5/5] DynamicTablesPkg: Smbios Physical Memory Array (Type 16) Girish Mahadevan via groups.io
2023-08-24 19:36 ` Jose Marinho
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230725233805.646668-3-gmahadevan@nvidia.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox