* Re: [edk2-devel] [PATCH v2 1/1] DynamicTablesPkg: Add SMBIOS table generation
[not found] <173E4FD875129A15.17319@groups.io>
@ 2023-02-21 15:36 ` Girish Mahadevan
0 siblings, 0 replies; only message in thread
From: Girish Mahadevan @ 2023-02-21 15:36 UTC (permalink / raw)
To: devel, sami.mujawar, Alexei.Fedorov, pierre.gondois
Cc: jbrasen, ashishsingha, nramirez
Hello Sami,
Mind taking a quick look whenever you have some bandwidth.
Thanks
Girish
On 1/27/2023 4:58 PM, Girish Mahadevan via groups.io wrote:
> External email: Use caution opening links or attachments
>
>
> Add the SMBIOS Table generator code to the DynamicTablesPkg.
>
> This change includes adding new logic to the DynamicTableManager
> to process and add SMBIOS tables and augmenting the existing SMBIOS
> Factory generator to include installing multiple SMBIOS tables .
> Also included is running the SMBIOS and ACPI table generation as part
> of the SMBIOS and ACPI protocol GUID callback notifications respectively.
>
> The change can be seen at
> https://github.com/gmahadevan/edk2-upstream/commits/RFC/smbios-dyntables
>
> Signed-off-by: Girish Mahadevan <gmahadevan@nvidia.com>
> Reviewed-by: Jeff Brasen <jbrasen@nvidia.com>
> ---
> .../DynamicTableFactory.h | 5 +
> .../DynamicTableFactoryDxe.c | 7 +
> .../SmbiosTableFactory/SmbiosTableFactory.c | 66 ++
> .../DynamicTableManagerDxe/AcpiTableBuilder.c | 732 ++++++++++++++++
> .../DynamicTableManagerDxe.c | 794 +-----------------
> .../DynamicTableManagerDxe.inf | 5 +-
> .../SmbiosTableBuilder.c | 608 ++++++++++++++
> .../Include/ConfigurationManagerObject.h | 18 +-
> .../Protocol/DynamicTableFactoryProtocol.h | 8 +
> .../Include/SmbiosTableGenerator.h | 165 +++-
> 10 files changed, 1653 insertions(+), 755 deletions(-)
> create mode 100644 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/AcpiTableBuilder.c
> create mode 100644 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/SmbiosTableBuilder.c
>
> diff --git a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory.h b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory.h
> index b160dcf8ad..20e438ea70 100644
> --- a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory.h
> +++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory.h
> @@ -49,6 +49,11 @@ typedef struct DynamicTableFactoryInfo {
> CustomDtTableGeneratorList[FixedPcdGet16 (
> PcdMaxCustomDTGenerators
> )];
> +
> + /// An array for holding a map of SMBIOS handles and the CM Object
> + /// token used to build the SMBIOS record.
> + SMBIOS_HANDLE_MAP
> + SmbiosHandleMap[MAX_SMBIOS_HANDLES];
> } EDKII_DYNAMIC_TABLE_FACTORY_INFO;
>
> /** Return a pointer to the ACPI table generator.
> diff --git a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c
> index 6d6d3fa746..d0ee5d7b3b 100644
> --- a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c
> +++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c
> @@ -44,6 +44,8 @@ EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL DynamicTableFactoryProtocol = {
> GetDtTableGenerator,
> RegisterDtTableGenerator,
> DeregisterDtTableGenerator,
> + AddSmbiosHandle,
> + FindSmbiosHandle,
> &TableFactoryInfo
> };
>
> @@ -65,7 +67,12 @@ DynamicTableFactoryDxeInitialize (
> )
> {
> EFI_STATUS Status;
> + UINTN Idx;
>
> + for (Idx = 0; Idx < MAX_SMBIOS_HANDLES; Idx++) {
> + TableFactoryInfo.SmbiosHandleMap[Idx].SmbiosTblHandle = SMBIOS_HANDLE_PI_RESERVED;
> + TableFactoryInfo.SmbiosHandleMap[Idx].SmbiosCmToken = 0;
> + }
> Status = gBS->InstallProtocolInterface (
> &ImageHandle,
> &gEdkiiDynamicTableFactoryProtocolGuid,
> diff --git a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c
> index 87795919f8..b81724d2a0 100644
> --- a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c
> +++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c
> @@ -12,6 +12,7 @@
> #include <IndustryStandard/SmBios.h>
> #include <Library/BaseLib.h>
> #include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> #include <Library/DebugLib.h>
>
> // Module specific include files.
> @@ -24,6 +25,71 @@
>
> extern EDKII_DYNAMIC_TABLE_FACTORY_INFO TableFactoryInfo;
>
> +/** Add a new entry to the SMBIOS table Map.
> +
> + @param [in] Smbios SMBIOS Protocol pointer.
> + @param [in] SmbiosHandle SMBIOS Handle to be added, if the value SMBIOS_HANDLE_PI_RESERVED
> + is passed then a new SmbiosHandle is assigned.
> + @param [in] CmObjectToken CmObjectToken of the CM_OBJECT used to build the SMBIOS Table
> + @param [in] SmbiosId Smbios Table Generator Id.
> +
> + @retval EFI_SUCCESS Successfully added/generated the handle.
> + @retval EFI_OUT_OF_RESOURCESNULL Failure to add/generate the handle.
> +**/
> +EFI_STATUS
> +EFIAPI
> +AddSmbiosHandle (
> + IN EFI_SMBIOS_PROTOCOL *Smbios,
> + IN SMBIOS_HANDLE *SmbiosHandle,
> + IN CM_OBJECT_TOKEN CmObjectToken,
> + IN ESTD_SMBIOS_TABLE_ID SmbiosId
> + )
> +{
> + EFI_STATUS Status;
> + UINTN Index;
> +
> + Status = EFI_OUT_OF_RESOURCES;
> +
> + for (Index = 0; Index < MAX_SMBIOS_HANDLES; Index++) {
> + if (TableFactoryInfo.SmbiosHandleMap[Index].SmbiosTblHandle == SMBIOS_HANDLE_PI_RESERVED) {
> + TableFactoryInfo.SmbiosHandleMap[Index].SmbiosTblHandle = *SmbiosHandle;
> + TableFactoryInfo.SmbiosHandleMap[Index].SmbiosCmToken = CmObjectToken;
> + TableFactoryInfo.SmbiosHandleMap[Index].SmbiosTableId = SmbiosId;
> + Status = EFI_SUCCESS;
> + break;
> + }
> + }
> +
> + return Status;
> +}
> +
> +/** Return a pointer to the SMBIOS table Map.
> +
> + @param [in] GeneratorId The CmObjectToken to look up an SMBIOS Handle.
> +
> + @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
> + );
>
> /** Entrypoint of Dynamic Table Manager Dxe.
>
> @@ -727,72 +62,33 @@ DynamicTableManagerDxeInitialize (
> IN EFI_SYSTEM_TABLE *SystemTable
> )
> {
> - 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 Status;
> - }
> -
> - // 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;
> - }
> -
> - Status = GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((
> - DEBUG_ERROR,
> - "ERROR: Failed to get Configuration Manager info. Status = %r\n",
> - Status
> - ));
> - return Status;
> - }
> -
> - 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
> - ));
> - }
> -
> - return Status;
> + EFI_EVENT AcpiEvent;
> + EFI_EVENT SmbiosEvent;
> +
> + AcpiEvent = EfiCreateProtocolNotifyEvent (
> + &gEfiAcpiTableProtocolGuid,
> + TPL_CALLBACK,
> + AcpiTableProtocolReady,
> + NULL,
> + &AcpiTableProtocolRegistration
> + );
> + if (AcpiEvent == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a: Failed to ACPI create protocol event\r\n", __FUNCTION__));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + SmbiosEvent = EfiCreateProtocolNotifyEvent (
> + &gEfiSmbiosProtocolGuid,
> + TPL_CALLBACK,
> + SmbiosProtocolReady,
> + NULL,
> + &SmbiosProtocolRegistration
> + );
> + if (SmbiosEvent == NULL) {
> + DEBUG ((DEBUG_ERROR, "%a: Failed to SMBIOS create protocol event\r\n", __FUNCTION__));
> + gBS->CloseEvent (AcpiEvent);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + return EFI_SUCCESS;
> }
> diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
> index b09272d883..9d020f0264 100644
> --- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
> +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
> @@ -22,6 +22,8 @@
>
> [Sources]
> DynamicTableManagerDxe.c
> + SmbiosTableBuilder.c
> + AcpiTableBuilder.c
> SmbiosTableDispatcher.c
> SmbiosTableDispatcher.h
>
> @@ -33,6 +35,7 @@
> [LibraryClasses]
> PrintLib
> TableHelperLib
> + UefiLib
> UefiBootServicesTableLib
> UefiDriverEntryPoint
>
> @@ -42,12 +45,12 @@
> [Protocols]
> gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
> gEfiAcpiSdtProtocolGuid # PROTOCOL ALWAYS_CONSUMED
> + gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
>
> gEdkiiConfigurationManagerProtocolGuid # PROTOCOL ALWAYS_CONSUMED
> gEdkiiDynamicTableFactoryProtocolGuid # PROTOCOL ALWAYS_CONSUMED
>
> [Depex]
> - gEfiAcpiTableProtocolGuid AND
> gEdkiiConfigurationManagerProtocolGuid AND
> gEdkiiDynamicTableFactoryProtocolGuid
>
> diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/SmbiosTableBuilder.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/SmbiosTableBuilder.c
> new file mode 100644
> index 0000000000..9ca690c16b
> --- /dev/null
> +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/SmbiosTableBuilder.c
> @@ -0,0 +1,608 @@
> +/** @file
> + SMBIOS Table Builder
> +
> + 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 <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;
> + SMBIOS_HANDLE_MAP *HandleMap;
> +
> + 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;
> + }
> +
> + HandleMap = TableFactoryProtocol->GetSmbiosHandle (CmObjToken);
> + if (HandleMap == NULL) {
> + TableHandle = SMBIOS_HANDLE_PI_RESERVED;
> + } else {
> + TableHandle = HandleMap->SmbiosTblHandle;
> + }
> +
> + // 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;
> + }
> +
> + // If a new handle was generated then add it to the handle map.
> + if (HandleMap == NULL) {
> + TableFactoryProtocol->AddSmbiosHandle (
> + SmbiosProtocol,
> + &TableHandle,
> + CmObjToken,
> + SmbiosTableInfo->TableGeneratorId
> + );
> + }
> +
> + 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;
> + SMBIOS_HANDLE_MAP *HandleMap;
> +
> + 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++) {
> + HandleMap = TableFactoryProtocol->GetSmbiosHandle (CmObjToken[Index]);
> + if (HandleMap == NULL) {
> + TableHandle = SMBIOS_HANDLE_PI_RESERVED;
> + } else {
> + TableHandle = HandleMap->SmbiosTblHandle;
> + }
> +
> + // 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;
> + }
> +
> + // If a new handle was generated then add it to the handle map.
> + if (HandleMap == NULL) {
> + TableFactoryProtocol->AddSmbiosHandle (
> + SmbiosProtocol,
> + &TableHandle,
> + CmObjToken[Index],
> + SmbiosTableInfo->TableGeneratorId
> + );
> + }
> +
> + 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;
> + UINT32 Idx;
> +
> + 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
> + ));
> +
> + for (Idx = 0; Idx < SmbiosTableCount; Idx++) {
> + Status = DispatchSmbiosTable (
> + SmbiosTableInfo[Idx].TableType,
> + TableFactoryProtocol,
> + CfgMgrProtocol,
> + SmbiosProtocol,
> + SmbiosTableInfo,
> + SmbiosTableCount
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "ERROR: Failed to install SMBIOS Table." \
> + " Id = %u Status = %r\n",
> + SmbiosTableInfo[Idx].TableGeneratorId,
> + Status
> + ));
> + }
> + }
> +
> + DEBUG ((DEBUG_ERROR, "%a: Returning %r\n", __FUNCTION__, Status));
> + 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
> +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
> + ));
> + }
> +}
> diff --git a/DynamicTablesPkg/Include/ConfigurationManagerObject.h b/DynamicTablesPkg/Include/ConfigurationManagerObject.h
> index 74ad25d5d9..0c97e70996 100644
> --- a/DynamicTablesPkg/Include/ConfigurationManagerObject.h
> +++ b/DynamicTablesPkg/Include/ConfigurationManagerObject.h
> @@ -31,6 +31,7 @@ Bits: [31:28] - Name Space ID
> 0000 - Standard
> 0001 - ARM
> 1000 - Custom/OEM
> + 1010 - SMBIOS
> All other values are reserved.
>
> Bits: [27:16] - Reserved.
> @@ -105,9 +106,10 @@ typedef UINT32 CM_OBJECT_ID;
> for the Configuration Manager Objects.
> */
> typedef enum ObjectNameSpaceID {
> - EObjNameSpaceStandard, ///< Standard Objects Namespace
> - EObjNameSpaceArm, ///< ARM Objects Namespace
> - EObjNameSpaceOem = 0x8, ///< OEM Objects Namespace
> + EObjNameSpaceStandard, ///< Standard Objects Namespace
> + EObjNameSpaceArm, ///< ARM Objects Namespace
> + EObjNameSpaceOem = 0x8, ///< OEM Objects Namespace
> + EObjNameSpaceSmbios = 0xA, ///< SMBIOS Objects Namespace
> EObjNameSpaceMax
> } EOBJECT_NAMESPACE_ID;
>
> @@ -192,4 +194,14 @@ typedef struct CmObjDescriptor {
> #define CREATE_CM_OEM_OBJECT_ID(ObjectId) \
> (CREATE_CM_OBJECT_ID (EObjNameSpaceOem, ObjectId))
>
> +/** This macro returns a Configuration Manager Object ID
> + in the SMBIOS Object Namespace.
> +
> + @param [in] ObjectId The Object ID.
> +
> + @retval Returns an SMBIOS Configuration Manager Object ID.
> +**/
> +#define CREATE_CM_SMBIOS_OBJECT_ID(ObjectId) \
> + (CREATE_CM_OBJECT_ID (EObjNameSpaceSmbios, ObjectId))
> +
> #endif // CONFIGURATION_MANAGER_OBJECT_H_
> diff --git a/DynamicTablesPkg/Include/Protocol/DynamicTableFactoryProtocol.h b/DynamicTablesPkg/Include/Protocol/DynamicTableFactoryProtocol.h
> index b11fc0c9f1..0670a8fb27 100644
> --- a/DynamicTablesPkg/Include/Protocol/DynamicTableFactoryProtocol.h
> +++ b/DynamicTablesPkg/Include/Protocol/DynamicTableFactoryProtocol.h
> @@ -239,12 +239,20 @@ typedef struct DynamicTableFactoryProtocol {
> EDKII_DYNAMIC_TABLE_FACTORY_DEREGISTER_DT_TABLE_GENERATOR
> DeregisterDtTableGenerator;
>
> + EDKII_DYNAMIC_TABLE_FACTORY_SMBIOS_TABLE_ADD_HANDLE
> + AddSmbiosHandle;
> +
> + EDKII_DYNAMIC_TABLE_FACTORY_SMBIOS_TABLE_GET_HANDLE
> + GetSmbiosHandle;
> +
> /** Pointer to the data structure that holds the
> list of registered table generators
> */
> EDKII_DYNAMIC_TABLE_FACTORY_INFO *TableFactoryInfo;
> } EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL;
>
> +
> +
> /** The Dynamic Table Factory Protocol GUID.
> */
> extern EFI_GUID gEdkiiDynamicTableFactoryProtocolGuid;
> diff --git a/DynamicTablesPkg/Include/SmbiosTableGenerator.h b/DynamicTablesPkg/Include/SmbiosTableGenerator.h
> index 934d56c90d..d81eb8f124 100644
> --- a/DynamicTablesPkg/Include/SmbiosTableGenerator.h
> +++ b/DynamicTablesPkg/Include/SmbiosTableGenerator.h
> @@ -10,7 +10,7 @@
> #define SMBIOS_TABLE_GENERATOR_H_
>
> #include <IndustryStandard/SmBios.h>
> -
> +#include <Protocol/Smbios.h>
> #include <TableGenerator.h>
>
> #pragma pack(1)
> @@ -121,12 +121,21 @@ typedef enum StdSmbiosTableGeneratorId {
> ETableGeneratorNameSpaceStd, \
> TableId \
> )
> +#define MAX_SMBIOS_HANDLES (255)
>
> /** Forward declarations.
> */
> typedef struct ConfigurationManagerProtocol EDKII_CONFIGURATION_MANAGER_PROTOCOL;
> typedef struct CmStdObjSmbiosTableInfo CM_STD_OBJ_SMBIOS_TABLE_INFO;
> typedef struct SmbiosTableGenerator SMBIOS_TABLE_GENERATOR;
> +typedef struct DynamicTableFactoryProtocol EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL;
> +typedef UINTN CM_OBJECT_TOKEN;
> +
> +typedef struct SmbiosHandleCmObjMap {
> + ESTD_SMBIOS_TABLE_ID SmbiosTableId;
> + SMBIOS_HANDLE SmbiosTblHandle;
> + CM_OBJECT_TOKEN SmbiosCmToken;
> +} SMBIOS_HANDLE_MAP;
>
> /** This function pointer describes the interface to SMBIOS table build
> functions provided by the SMBIOS table generator and called by the
> @@ -143,9 +152,11 @@ typedef struct SmbiosTableGenerator SMBIOS_TABLE_GENERATOR;
> **/
> typedef EFI_STATUS (*SMBIOS_TABLE_GENERATOR_BUILD_TABLE) (
> IN CONST SMBIOS_TABLE_GENERATOR *Generator,
> + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
> IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo,
> IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
> - OUT SMBIOS_STRUCTURE **Table
> + OUT SMBIOS_STRUCTURE **Table,
> + OUT CM_OBJECT_TOKEN *CmObjToken
> );
>
> /** This function pointer describes the interface to used by the
> @@ -163,11 +174,105 @@ typedef EFI_STATUS (*SMBIOS_TABLE_GENERATOR_BUILD_TABLE) (
> **/
> typedef EFI_STATUS (*SMBIOS_TABLE_GENERATOR_FREE_TABLE) (
> IN CONST SMBIOS_TABLE_GENERATOR *Generator,
> + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
> IN CONST CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo,
> IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
> IN SMBIOS_STRUCTURE **Table
> );
>
> +/** This function pointer describes the interface to SMBIOS table build
> + functions provided by the SMBIOS table generator and called by the
> + Table Manager to build an SMBIOS table.
> +
> + @param [in] Generator Pointer to the SMBIOS table generator.
> + @param [in] SmbiosTableInfo Pointer to the SMBIOS table information.
> + @param [in] CfgMgrProtocol Pointer to the Configuration Manager
> + Protocol interface.
> + @param [out] Table Pointer to the generated SMBIOS table.
> +
> + @return EFI_SUCCESS If the table is generated successfully or other
> + failure codes as returned by the generator.
> +**/
> +typedef EFI_STATUS (*SMBIOS_TABLE_GENERATOR_BUILD_TABLEEX) (
> + IN CONST SMBIOS_TABLE_GENERATOR *Generator,
> + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
> + IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo,
> + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
> + OUT SMBIOS_STRUCTURE ***Table,
> + OUT CM_OBJECT_TOKEN **CmObjectToken,
> + OUT UINTN *CONST TableCount
> + );
> +
> +/** This function pointer describes the interface to used by the
> + Table Manager to give the generator an opportunity to free
> + any resources allocated for building the SMBIOS table.
> +
> + @param [in] Generator Pointer to the SMBIOS table generator.
> + @param [in] SmbiosTableInfo Pointer to the SMBIOS table information.
> + @param [in] CfgMgrProtocol Pointer to the Configuration Manager
> + Protocol interface.
> + @param [in] Table Pointer to the generated SMBIOS table.
> +
> + @return EFI_SUCCESS If freed successfully or other failure codes
> + as returned by the generator.
> +**/
> +typedef EFI_STATUS (*SMBIOS_TABLE_GENERATOR_FREE_TABLEEX) (
> + IN CONST SMBIOS_TABLE_GENERATOR *Generator,
> + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
> + IN CONST CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo,
> + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
> + IN SMBIOS_STRUCTURE ***Table,
> + IN CM_OBJECT_TOKEN **CmObjectToken,
> + IN CONST UINTN TableCount
> + );
> +
> +/** This function pointer describes the interface to used by the
> + Table Manager to give the generator an opportunity to add
> + an SMBIOS Handle.
> +
> + This function is called by the Dynamic Table Manager to add a newly added
> + SMBIOS Table OR it can be called by an SMBIOS Table generator to create
> + and add a new SMBIOS Handle if there is a reference to another table and
> + if there is a generator for that table that hasn't been called yet.
> +
> + @param [in] Smbios Pointer to the SMBIOS protocol.
> + @param [in] SmbiosHandle Pointer to an SMBIOS handle (either generated by
> + SmbiosDxe Driver or SMBIOS_HANDLE_PI_RESERVED
> + if a handle needs to be generated).
> + @param [in] CmObjectToken The CM Object token for that is used to generate
> + SMBIOS record.
> + @param [in] SmbiosId The SMBIOS table generator Id.
> +
> + @retval EFI_SUCCESS Success.
> + @retval EFI_OUT_OF_RESOURCES Unable to add the handle.
> + @retval EFI_NOT_FOUND The requested generator is not found
> + in the list of registered generators.
> +**/
> +typedef EFI_STATUS (*EDKII_DYNAMIC_TABLE_FACTORY_SMBIOS_TABLE_ADD_HANDLE) (
> + IN EFI_SMBIOS_PROTOCOL *Smbios,
> + IN SMBIOS_HANDLE *SmbiosHandle,
> + IN CM_OBJECT_TOKEN CmObjectToken,
> + IN ESTD_SMBIOS_TABLE_ID SmbiosId
> + );
> +
> +/** This function pointer describes the interface to used by the
> + Table Manager to give the generator an opportunity to find
> + an SMBIOS Handle.
> +
> + This function is called by the SMBIOS table generator to find an SMBIOS
> + handle needed as part of generating an SMBIOS Table.
> +
> + @param [in] CmObjectToken The CM Object token used to generate the SMBIOS
> + record.
> +
> + @retval EFI_SUCCESS Success.
> + @retval EFI_NOT_FOUND The requested generator is not found
> + in the list of registered generators.
> +**/
> +typedef SMBIOS_HANDLE_MAP * (*EDKII_DYNAMIC_TABLE_FACTORY_SMBIOS_TABLE_GET_HANDLE) (
> + IN CM_OBJECT_TOKEN CmObjectToken
> + );
> +
> /** The SMBIOS_TABLE_GENERATOR structure provides an interface that the
> Table Manager can use to invoke the functions to build SMBIOS tables.
> */
> @@ -189,6 +294,14 @@ typedef struct SmbiosTableGenerator {
> allocated for building the SMBIOS table.
> */
> SMBIOS_TABLE_GENERATOR_FREE_TABLE FreeTableResources;
> +
> + /// SMBIOS table extended build function pointer.
> + SMBIOS_TABLE_GENERATOR_BUILD_TABLEEX BuildSmbiosTableEx;
> +
> + /** The function to free any resources
> + allocated for building the SMBIOS table.
> + */
> + SMBIOS_TABLE_GENERATOR_FREE_TABLEEX FreeTableResourcesEx;
> } SMBIOS_TABLE_GENERATOR;
>
> /** Register SMBIOS table factory generator.
> @@ -229,6 +342,54 @@ DeregisterSmbiosTableGenerator (
> IN CONST SMBIOS_TABLE_GENERATOR *CONST Generator
> );
>
> +/** Add SMBIOS Handle.
> +
> + This function is called by the Dynamic Table Manager to add a newly added
> + SMBIOS Table OR it can be called by an SMBIOS Table generator to create
> + and add a new SMBIOS Handle if there is a reference to another table and
> + if there is a generator for that table that hasn't been called yet.
> +
> + @param [in] Smbios Pointer to the SMBIOS protocol.
> + @param [in] SmbiosHandle Pointer to an SMBIOS handle (either generated by
> + SmbiosDxe Driver or SMBIOS_HANDLE_PI_RESERVED
> + if a handle needs to be generated).
> + @param [in] CmObjectToken The CM Object token for that is used to generate
> + SMBIOS record.
> + @param [in] SmbiosId The SMBIOS table generator Id.
> +
> + @retval EFI_SUCCESS Success.
> + @retval EFI_OUT_OF_RESOURCES Unable to add the handle.
> + @retval EFI_NOT_FOUND The requested generator is not found
> + in the list of registered generators.
> +**/
> +EFI_STATUS
> +EFIAPI
> +AddSmbiosHandle (
> + IN EFI_SMBIOS_PROTOCOL *Smbios,
> + IN SMBIOS_HANDLE *SmbiosHandle,
> + IN CM_OBJECT_TOKEN CmObjectToken,
> + IN ESTD_SMBIOS_TABLE_ID SmbiosId
> + );
> +
> +/** Find SMBIOS Handle given the CM Object token used to generate the SMBIOS
> + record..
> +
> + This function is called by the SMBIOS table generator to find an SMBIOS
> + handle needed as part of generating an SMBIOS Table.
> +
> + @param [in] CmObjectToken The CM Object token used to generate the SMBIOS
> + record.
> +
> + @retval EFI_SUCCESS Success.
> + @retval EFI_NOT_FOUND The requested generator is not found
> + in the list of registered generators.
> +**/
> +SMBIOS_HANDLE_MAP *
> +EFIAPI
> +FindSmbiosHandle (
> + IN CM_OBJECT_TOKEN CmObjectToken
> + );
> +
> #pragma pack()
>
> #endif // SMBIOS_TABLE_GENERATOR_H_
> --
> 2.17.1
>
>
>
>
>
>
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-02-21 15:36 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <173E4FD875129A15.17319@groups.io>
2023-02-21 15:36 ` [edk2-devel] [PATCH v2 1/1] DynamicTablesPkg: Add SMBIOS table generation Girish Mahadevan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox