[edk2-devel] [PATCH] DynamicTablesPkg: Add library for SMBIOS table generation

Leif Lindholm leif at nuviainc.com
Mon Nov 9 16:27:57 UTC 2020


On Fri, Nov 06, 2020 at 07:27:31 -0500, Irene Park wrote:
> From: Irene Park <ipark at nvidia.com>
> 
> The Configuration Manager supports the ACPI generation but the SMBIOS
> has been out of its coverage. This adds the SMBIOS table generation
> in the table type of 0,1,2,3,4,7,8,9,11,13,15,16,17,19,32,38,41 which
> are required or recommended to meet the SBBR spec.
> 
> This provides the following features.
> - Support RAW table generation in any SMBIOS version
> - Support table generation for SBBR where SMBIOS version >= 3.2
> - Use string in place of a string index
> - Use CM_OBJECT_TOKEN in place of a direct handle assignment
> - Use a universal data type to describe any capacity
> 
> Signed-off-by: Irene Park <ipark at nvidia.com>
> 
> ---
>  .../DynamicTableManagerDxe/DynamicTableManager.h   |   25 +
>  .../DynamicTableManagerDxe.c                       |   13 +
>  .../DynamicTableManagerDxe.inf                     |    6 +-
>  .../DynamicTableManagerSmbios.c                    |  505 +++++++++
>  .../Include/ConfigurationManagerObject.h           |   34 +
>  DynamicTablesPkg/Include/SmbiosNameSpaceObjects.h  |  559 ++++++++++
>  DynamicTablesPkg/Include/SmbiosTableGenerator.h    |  179 +++-
>  .../Include/StandardNameSpaceObjects.h             |    6 +-
>  .../Library/Smbios/SmbiosBasicLib/BasicGenerator.c |  554 ++++++++++
>  .../Library/Smbios/SmbiosBasicLib/BasicGenerator.h |  171 ++++
>  .../Library/Smbios/SmbiosBasicLib/BasicObjects.c   | 1077 ++++++++++++++++++++
>  .../Library/Smbios/SmbiosBasicLib/BasicObjects.h   |  102 ++
>  .../Smbios/SmbiosBasicLib/SmbiosBasicLib.inf       |   39 +
>  .../Library/Smbios/SmbiosRawLib/RawGenerator.c     |  136 +++
>  .../Library/Smbios/SmbiosRawLib/SmbiosRawLib.inf   |   36 +
>  15 files changed, 3385 insertions(+), 57 deletions(-)
>  create mode 100644 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManager.h
>  create mode 100644 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerSmbios.c
>  create mode 100644 DynamicTablesPkg/Include/SmbiosNameSpaceObjects.h
>  create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.c
>  create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.h
>  create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.c
>  create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.h
>  create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/SmbiosBasicLib.inf
>  create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosRawLib/RawGenerator.c
>  create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosRawLib/SmbiosRawLib.inf
> 
> diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManager.h b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManager.h
> new file mode 100644
> index 0000000..efa11ee
> --- /dev/null
> +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManager.h
> @@ -0,0 +1,25 @@
> +/** @file
> +
> +  Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
> +  Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  @par Glossary:
> +    - Std    - Standard
> +    - ACPI   - Advanced Configuration and Power Interface
> +    - SMBIOS - System Management BIOS
> +    - DT     - Device Tree
> +**/
> +
> +#ifndef DYNAMIC_TABLE_MANAGER_H_
> +#define DYNAMIC_TABLE_MANAGER_H_
> +
> +EFI_STATUS
> +EFIAPI
> +ProcessSmbiosTables (
> +  IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL  * CONST TableFactoryProtocol,
> +  IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST CfgMgrProtocol
> +  );
> +
> +#endif // DYNAMIC_TABLE_MANAGER_H_
> diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
> index e27dcaf..c783cac 100644
> --- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
> +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
> @@ -1,6 +1,7 @@
>  /** @file
>    Dynamic Table Manager Dxe
>  
> +  Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
>    Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
>  
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> @@ -22,6 +23,8 @@
>  #include <Protocol/DynamicTableFactoryProtocol.h>
>  #include <SmbiosTableGenerator.h>
>  
> +#include "DynamicTableManager.h"
> +
>  /** This macro expands to a function that retrieves the ACPI Table
>      List from the Configuration Manager.
>  */
> @@ -724,6 +727,16 @@ DynamicTableManagerDxeInitialize (
>        "ERROR: ACPI Table processing failure. Status = %r\n",
>        Status
>        ));
> +    return Status;
> +  }
> +
> +  Status = ProcessSmbiosTables (TableFactoryProtocol, CfgMgrProtocol);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "ERROR: SMBIOS processing failure. Status = %r\n",
> +      Status
> +      ));
>    }
>    return Status;
>  }
> diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
> index 028c3d4..b15a9e9 100644
> --- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
> +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
> @@ -1,6 +1,7 @@
>  ## @file
>  # Module that drives the table generation and installation process.
>  #
> +#  Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
>  #  Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
>  #
>  #  SPDX-License-Identifier: BSD-2-Clause-Patent
> @@ -22,6 +23,7 @@
>  
>  [Sources]
>    DynamicTableManagerDxe.c
> +  DynamicTableManagerSmbios.c
>  
>  [Packages]
>    MdePkg/MdePkg.dec
> @@ -36,12 +38,12 @@
>  
>  [Protocols]
>    gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED
> -
> +  gEfiSmbiosProtocolGuid                        # PROTOCOL ALWAYS_CONSUMED
>    gEdkiiConfigurationManagerProtocolGuid        # PROTOCOL ALWAYS_CONSUMED
>    gEdkiiDynamicTableFactoryProtocolGuid         # PROTOCOL ALWAYS_CONSUMED
>  
>  [Depex]
>    gEfiAcpiTableProtocolGuid AND
> +  gEfiSmbiosProtocolGuid AND
>    gEdkiiConfigurationManagerProtocolGuid AND
>    gEdkiiDynamicTableFactoryProtocolGuid
> -
> diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerSmbios.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerSmbios.c
> new file mode 100644
> index 0000000..d210fa4
> --- /dev/null
> +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerSmbios.c
> @@ -0,0 +1,505 @@
> +/** @file
> +  Dynamic Table Manager for SMBIOS
> +
> +  Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
> +  Copyright (c) 2017 - 2020, ARM Limited. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/Smbios.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>
> +
> +/** 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 a single SMBIOS table.
> +
> +  This is a helper function that invokes the Table generator interface
> +  for building an SMBIOS table. It uses the SmbiosTableProtocol 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 SmbiosTable generator.
> +  @param [in]  SmbiosTableProtocol    Pointer to the SmbiosTable 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                   *       SmbiosTableProtocol,
> +  IN       CM_STD_OBJ_SMBIOS_TABLE_INFO          * CONST SmbiosTableInfo
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_STATUS                    Status1;
> +  EFI_SMBIOS_TABLE_HEADER     * SmbiosTable;
> +  UINTN                         TableCount;
> +
> +  SmbiosTable = NULL;
> +  TableCount = 0;
> +  Status = Generator->BuildSmbiosTable (
> +                        Generator,
> +                        SmbiosTableInfo,
> +                        CfgMgrProtocol,
> +                        &SmbiosTable
> +                        );
> +  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;
> +  }
> +
> +  // Dump SMBIOS Table Header
> +  DUMP_SMBIOS_TABLE_HEADER (SmbiosTable);
> +
> +  // Install SMBIOS table
> +  Status = SmbiosTableProtocol->Add (
> +                                SmbiosTableProtocol,
> +                                NULL,
> +                                &SmbiosTable->Handle,
> +                                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;
> +  }
> +
> +
> +  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,
> +                          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 an SMBIOS table. It uses the SmbiosTableProtocol 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 SmbiosTable generator.
> +  @param [in]  SmbiosTableProtocol    Pointer to the SmbiosTable 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
> +BuildAndInstallMultipleSmbiosTable (
> +  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                   *       SmbiosTableProtocol,
> +  IN       CM_STD_OBJ_SMBIOS_TABLE_INFO          * CONST SmbiosTableInfo
> +  )
> +{
> +  EFI_STATUS                     Status;
> +  EFI_STATUS                     Status1;
> +  EFI_SMBIOS_TABLE_HEADER     ** SmbiosTable;
> +  UINTN                          TableCount;
> +  UINTN                          Index;
> +
> +  SmbiosTable = NULL;
> +  TableCount = 0;
> +  Status = Generator->BuildSmbiosTableEx (
> +                        Generator,
> +                        SmbiosTableInfo,
> +                        CfgMgrProtocol,
> +                        &SmbiosTable,
> +                        &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;
> +    goto exit_handler;
> +  }
> +
> +  for (Index = 0; Index < TableCount; Index++) {
> +    // Dump SMBIOS Table Header
> +    DUMP_SMBIOS_TABLE_HEADER (SmbiosTable[Index]);
> +    // Install SMBIOS table
> +    Status = SmbiosTableProtocol->Add (
> +                                  SmbiosTableProtocol,
> +                                  NULL,
> +                                  &SmbiosTable[Index]->Handle,
> +                                  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;
> +    }
> +
> +    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,
> +                          SmbiosTableInfo,
> +                          CfgMgrProtocol,
> +                          &SmbiosTable,
> +                          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;
> +    }
> +  }
> +  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 SmbiosTableProtocol 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]  SmbiosTableProtocol    Pointer to the SmbiosTable 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
> +BuildAndInstallSmbiosTable (
> +  IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL  * CONST TableFactoryProtocol,
> +  IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST CfgMgrProtocol,
> +  IN       EFI_SMBIOS_PROTOCOL                   *       SmbiosTableProtocol,
> +  IN       CM_STD_OBJ_SMBIOS_TABLE_INFO          * CONST SmbiosTableInfo
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  CONST SMBIOS_TABLE_GENERATOR  * Generator;
> +
> +  ASSERT (TableFactoryProtocol != NULL);
> +  ASSERT (CfgMgrProtocol != NULL);
> +  ASSERT (SmbiosTableProtocol != 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 = BuildAndInstallMultipleSmbiosTable (
> +               TableFactoryProtocol,
> +               CfgMgrProtocol,
> +               Generator,
> +               SmbiosTableProtocol,
> +               SmbiosTableInfo
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((
> +        DEBUG_ERROR,
> +        "ERROR: Failed to find build and install multiple SMBIOS Tables." \
> +        " Status = %r\n",
> +        Status
> +        ));
> +    }
> +  } else if (Generator->BuildSmbiosTable != NULL) {
> +    Status = BuildAndInstallSingleSmbiosTable (
> +               TableFactoryProtocol,
> +               CfgMgrProtocol,
> +               Generator,
> +               SmbiosTableProtocol,
> +               SmbiosTableInfo
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((
> +        DEBUG_ERROR,
> +        "ERROR: Failed to find build and install a single 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
> +      ));
> +  }
> +
> +  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 BuildAndInstallSmbiosTable).
> +
> +  @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.
> +**/
> +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     * SmbiosTableProtocol;
> +  CM_STD_OBJ_SMBIOS_TABLE_INFO  * SmbiosTableInfo;
> +  UINT32                        SmbiosTableCount;
> +  UINT32                        Idx;
> +
> +  ASSERT (TableFactoryProtocol != NULL);
> +  ASSERT (CfgMgrProtocol != NULL);
> +
> +  // Find the SmbiosTable protocol
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSmbiosProtocolGuid,
> +                  NULL,
> +                  (VOID**)&SmbiosTableProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "ERROR: Failed to find SmbiosTable protocol. Status = %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 (0 == SmbiosTableCount) {

No jeopardy-comparisons please. Flip around.

> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "ERROR: EStdObjSmbiosTableList: SmbiosTableCount = %d\n",
> +      SmbiosTableCount
> +      ));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  DEBUG ((
> +    DEBUG_INFO,
> +    "INFO: EStdObjSmbiosTableList: SmbiosTableCount = %d\n",
> +    SmbiosTableCount
> +    ));
> +
> +  // Add remaining SMBIOS Tables
> +  for (Idx = 0; Idx < SmbiosTableCount; Idx++) {
> +    DEBUG ((
> +      DEBUG_INFO,
> +      "INFO: SmbiosTableInfo[%d].TableGeneratorId = 0x%x\n",
> +      Idx,
> +      SmbiosTableInfo[Idx].TableGeneratorId
> +      ));
> +
> +    // Skip the Reserved table Generator ID for standard generators
> +    if ((IS_GENERATOR_NAMESPACE_STD (SmbiosTableInfo[Idx].TableGeneratorId)) &&
> +        ((CREATE_STD_SMBIOS_TABLE_GEN_ID (EStdSmbiosTableIdReserved)           >=
> +            SmbiosTableInfo[Idx].TableGeneratorId)                           ||
> +         (CREATE_STD_SMBIOS_TABLE_GEN_ID (EStdSmbiosTableIdMax)                <=
> +            SmbiosTableInfo[Idx].TableGeneratorId))) {
> +      DEBUG ((
> +        DEBUG_WARN,
> +        "WARNING: Invalid SMBIOS Generator table ID = 0x%x, Skipping...\n",
> +        SmbiosTableInfo[Idx].TableGeneratorId
> +        ));
> +      continue;
> +    }
> +
> +    Status = BuildAndInstallSmbiosTable (
> +               TableFactoryProtocol,
> +               CfgMgrProtocol,
> +               SmbiosTableProtocol,
> +               &SmbiosTableInfo[Idx]
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((
> +        DEBUG_ERROR,
> +        "ERROR: Failed to find, build, and install SMBIOS Table." \
> +        " Status = %r\n",
> +        Status
> +        ));
> +      return Status;
> +    }
> +  } // for
> +
> +  return Status;
> +}
> diff --git a/DynamicTablesPkg/Include/ConfigurationManagerObject.h b/DynamicTablesPkg/Include/ConfigurationManagerObject.h
> index b0d3e70..2439035 100644
> --- a/DynamicTablesPkg/Include/ConfigurationManagerObject.h
> +++ b/DynamicTablesPkg/Include/ConfigurationManagerObject.h
> @@ -1,5 +1,6 @@
>  /** @file
>  
> +  Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
>    Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
>  
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> @@ -14,6 +15,7 @@
>  
>  #include <ArmNameSpaceObjects.h>
>  #include <StandardNameSpaceObjects.h>
> +#include <SmbiosNameSpaceObjects.h>
>  
>  #pragma pack(1)
>  
> @@ -30,6 +32,7 @@ _______________________________________________________________________________
>  Bits: [31:28] - Name Space ID
>                  0000 - Standard
>                  0001 - ARM
> +                0010 - Smbios
>                  1000 - Custom/OEM
>                  All other values are reserved.
>  
> @@ -81,6 +84,26 @@ Object ID's in the ARM Namespace:
>    28 - Cache Info
>    29 - Processor Hierarchy Node ID Info
>    30 - CM Object Reference
> +
> +Object ID's in the Smbios Namespace:
> +   0 - Reserved
> +   1 - Bios Info
> +   2 - System Info
> +   3 - Baseboard Info
> +   4 - System Enclosure
> +   5 - Processor Info
> +   6 - Cache Info
> +   7 - Port Connector Info
> +   8 - System Slots
> +   9 - Oem Strings
> +  10 - Bios Language Info
> +  11 - System Event Log
> +  12 - Physical Memory Array
> +  13 - Memory Device
> +  14 - Memory Array Mapped Address
> +  15 - System Boot Info
> +  16 - Ipmi Device Info
> +  17 - Onboard Devices Extended Info
>  */
>  typedef UINT32  CM_OBJECT_ID;
>  
> @@ -102,6 +125,7 @@ typedef UINT32  CM_OBJECT_ID;
>  typedef enum ObjectNameSpaceID {
>    EObjNameSpaceStandard,      ///< Standard Objects Namespace
>    EObjNameSpaceArm,           ///< ARM Objects Namespace
> +  EObjNameSpaceSmbios,        ///< Smbios Objects Namespace
>    EObjNameSpaceOem = 0x8,     ///< OEM Objects Namespace
>    EObjNameSpaceMax
>  } EOBJECT_NAMESPACE_ID;
> @@ -178,6 +202,16 @@ typedef struct CmObjDescriptor {
>            (CREATE_CM_OBJECT_ID (EObjNameSpaceArm, 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))
> +
> +/** This macro returns a Configuration Manager Object ID
>      in the OEM Object Namespace.
>  
>    @param [in] ObjectId    The Object ID.
> diff --git a/DynamicTablesPkg/Include/SmbiosNameSpaceObjects.h b/DynamicTablesPkg/Include/SmbiosNameSpaceObjects.h
> new file mode 100644
> index 0000000..6298723
> --- /dev/null
> +++ b/DynamicTablesPkg/Include/SmbiosNameSpaceObjects.h
> @@ -0,0 +1,559 @@
> +/** @file
> +
> +  Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
> +  Copyright (c) 2017 - 2020, ARM Limited. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  @par Glossary:
> +    - Cm or CM   - Configuration Manager
> +    - Obj or OBJ - Object
> +    - Std or STD - Standard
> +**/
> +
> +#ifndef SMBIOS_NAMESPACE_OBJECTS_H_
> +#define SMBIOS_NAMESPACE_OBJECTS_H_
> +
> +#include <StandardNameSpaceObjects.h>
> +
> +#pragma pack(1)
> +
> +/** The ESMBIOS_OBJECT_ID enum describes the Object IDs
> +    in the SMBIOS Namespace
> +*/
> +typedef enum SmbiosObjectID {
> +  ESmbiosObjReserved,                           ///< 0  - Reserved
> +  ///
> +  /// SMBIOS table ObjectIDs required or recommended
> +  ///
> +  ESmbiosObjBiosInfo,                           ///< 1  - Type  0
> +  ESmbiosObjSystemInfo,                         ///< 2  - Type  1
> +  ESmbiosObjBaseboardInfo,                      ///< 3  - Type  2
> +  ESmbiosObjSystemEnclosure,                    ///< 4  - Type  3
> +  ESmbiosObjProcessorInfo,                      ///< 5  - Type  4
> +  ESmbiosObjCacheInfo,                          ///< 6  - Type  7
> +  ESmbiosObjPortConnectorInfo,                  ///< 7  - Type  8
> +  ESmbiosObjSystemSlots,                        ///< 8  - Type  9
> +  ESmbiosObjOemStrings,                         ///< 9  - Type 11
> +  ESmbiosObjBiosLanguageInfo,                   ///< 10 - Type 13
> +  ESmbiosObjSystemEventLog,                     ///< 11 - Type 15
> +  ESmbiosObjPhysicalMemoryArray,                ///< 12 - Type 16
> +  ESmbiosObjMemoryDevice,                       ///< 13 - Type 17
> +  ESmbiosObjMemoryArrayMappedAddress,           ///< 14 - Type 19
> +  ESmbiosObjSystemBootInfo,                     ///< 15 - Type 32
> +  ESmbiosObjIpmiDeviceInfo,                     ///< 16 - Type 38
> +  ESmbiosObjOnboardDevicesExtendedInfo,         ///< 17 - Type 41
> +  ESmbiosObjMax
> +} ESMBIOS_OBJECT_ID;
> +
> +
> +///
> +/// BIOS Information
> +/// Type 0: ESmbiosObjBiosInfo
> +///
> +typedef struct CmSmbiosBiosInfo {
> +  CONST CHAR8*          Vendor;
> +  CONST CHAR8*          BiosVersion;
> +  CONST CHAR8*          BiosReleaseDate;
> +  UINT32                BiosSize; // 64KB granule
> +  UINT16                BiosSegment;
> +  UINT64                BiosCharacteristics;
> +  UINT8                 BiosCharacteristicsExtensionByte1;
> +  UINT8                 BiosCharacteristicsExtensionByte2;
> +  UINT16                SystemBiosRelease;
> +  UINT16                EmbeddedControllerFirmwareRelease;
> +} CM_SMBIOS_BIOS_INFO;

This (whole file) appears to be mostly redefining things described by
IndustryStandard/SmBios.h. Is that really necessary?

> +
> +///
> +/// System Information
> +/// Type 1: ESmbiosObjSystemInfo
> +///
> +typedef struct CmSmbiosSystemInfo {
> +  CONST CHAR8*          Manufacturer;
> +  CONST CHAR8*          ProductName;
> +  CONST CHAR8*          Version;
> +  CONST CHAR8*          SerialNumber;
> +  CONST CHAR8*          SKUNumber;
> +  CONST CHAR8*          Family;
> +  GUID                  Uuid;
> +  UINT8                 WakeUpType;           ///< MISC_SYSTEM_WAKEUP_TYPE.
> +} CM_SMBIOS_SYSTEM_INFO;
> +
> +///
> +/// Base Board Information
> +/// Type 2: ESmbiosObjBaseboardInfo
> +///
> +typedef struct CmSmbiosBaseboardInfo {
> +  CONST CHAR8*          Manufacturer;
> +  CONST CHAR8*          ProductName;
> +  CONST CHAR8*          Version;
> +  CONST CHAR8*          SerialNumber;
> +  CONST CHAR8*          AssetTag;
> +  CONST CHAR8*          LocationInChassis;
> +  CM_OBJECT_TOKEN       ReferenceToken;
> +  CM_OBJECT_TOKEN       ChassisHandle;
> +  UINT8                 FeatureFlag;
> +  UINT8                 BoardType;              ///< BASE_BOARD_TYPE.
> +  UINT8                 NumberOfContainedObjectHandles;
> +  CM_OBJECT_TOKEN       ContainedObjectHandles;
> +} CM_SMBIOS_BASEBOARD_INFO;
> +
> +///
> +/// System Enclosure or Chassis
> +/// Type 3: ESmbiosObjSystemEnclosure
> +///
> +typedef struct CmSmbiosSystemEnclosure {
> +  CONST CHAR8*          Manufacturer;
> +  CONST CHAR8*          Version;
> +  CONST CHAR8*          SerialNumber;
> +  CONST CHAR8*          AssetTag;
> +  CONST CHAR8*          SKUNumber;
> +  CM_OBJECT_TOKEN       ReferenceToken;
> +  UINT8                 Type;
> +  UINT8                 BootupState;            ///< MISC_CHASSIS_STATE.
> +  UINT8                 PowerSupplyState;       ///< MISC_CHASSIS_STATE.
> +  UINT8                 ThermalState;           ///< MISC_CHASSIS_STATE.
> +  UINT8                 SecurityStatus;         ///< MISC_CHASSIS_SECURITY_STATE.
> +  UINT32                OemDefined;
> +  UINT8                 Height;
> +  UINT8                 NumberofPowerCords;
> +  UINT8                 ContainedElementCount;
> +  UINT8                 ContainedElementRecordLength;
> +  CONTAINED_ELEMENT    *ContainedElements;
> +  // Since ContainedElements has a variable number of entries, must not define SKUNumber in
> +  // the structure.  Need to reference it by starting at offset 0x15 and adding
> +  // (ContainedElementCount * ContainedElementRecordLength) bytes.
> +  //
> +} CM_SMBIOS_SYSTEM_ENCLOSURE;
> +
> +///
> +/// Processor Information
> +/// Type 4: ESmbiosObjProcessorInfo
> +///
> +typedef struct CmSmbiosProcessorInfo {
> +  CONST CHAR8*          Socket;
> +  CONST CHAR8*          ProcessorManufacture;
> +  CONST CHAR8*          ProcessorVersion;
> +  CONST CHAR8*          SerialNumber;
> +  CONST CHAR8*          AssetTag;
> +  CONST CHAR8*          PartNumber;
> +  CM_OBJECT_TOKEN       ReferenceToken;
> +  UINT8                 ProcessorType;          ///< PROCESSOR_TYPE_DATA.
> +  UINT8                 ProcessorFamily;        ///< PROCESSOR_FAMILY_DATA.
> +  UINT32                ProcessorId[2];
> +  UINT8                 Voltage;
> +  UINT16                ExternalClock;
> +  UINT16                MaxSpeed;
> +  UINT16                CurrentSpeed;
> +  UINT8                 Status;
> +  UINT8                 ProcessorUpgrade;      ///< PROCESSOR_UPGRADE.
> +  CM_OBJECT_TOKEN       L1CacheHandle;
> +  CM_OBJECT_TOKEN       L2CacheHandle;
> +  CM_OBJECT_TOKEN       L3CacheHandle;
> +  UINT8                 CoreCount;
> +  UINT8                 EnabledCoreCount;
> +  UINT8                 ThreadCount;
> +  UINT16                ProcessorCharacteristics;
> +  UINT16                ProcessorFamily2;
> +  UINT16                CoreCount2;
> +  UINT16                EnabledCoreCount2;
> +  UINT16                ThreadCount2;
> +} CM_SMBIOS_PROCESSOR_INFO;
> +
> +///
> +/// Cache Information
> +/// Type 7: ESmbiosObjCacheInfo
> +///
> +typedef struct CmSmbiosCacheInfo {
> +  CONST CHAR8*          SocketDesignation;
> +  CM_OBJECT_TOKEN       ReferenceToken;
> +  UINT16                CacheConfiguration;
> +  UINT16                MaximumCacheSize;
> +  UINT16                InstalledSize;
> +  UINT16                SupportedSRAMType;
> +  UINT16                CurrentSRAMType;
> +  UINT8                 CacheSpeed;
> +  UINT8                 ErrorCorrectionType;            ///< CACHE_ERROR_TYPE_DATA.
> +  UINT8                 SystemCacheType;                ///< CACHE_TYPE_DATA.
> +  UINT8                 Associativity;                  ///< CACHE_ASSOCIATIVITY_DATA.
> +  UINT32                MaximumCacheSize2;
> +  UINT32                InstalledSize2;
> +} CM_SMBIOS_CACHE_INFO;
> +
> +///
> +/// Port Connector Information
> +/// Type 8: ESmbiosObjPortConnectorInfo
> +///
> +typedef struct CmSmbiosPortConnectorInfo {
> +  CONST CHAR8*          InternalReferenceDesignator;
> +  CONST CHAR8*          ExternalReferenceDesignator;
> +  CM_OBJECT_TOKEN       ReferenceToken;
> +  UINT8                 InternalConnectorType;          ///< MISC_PORT_CONNECTOR_TYPE.
> +  UINT8                 ExternalConnectorType;          ///< MISC_PORT_CONNECTOR_TYPE.
> +  UINT8                 PortType;                       ///< MISC_PORT_TYPE.
> +} CM_SMBIOS_PORT_CONNECTOR_INFO;
> +
> +///
> +/// System Slots
> +/// Type 9: ESmbiosObjSystemSlots
> +///
> +typedef struct CmSmbiosSystemSlots {
> +  CONST CHAR8*          SlotDesignation;
> +  CM_OBJECT_TOKEN       ReferenceToken;
> +  UINT8                 SlotType;                 ///< MISC_SLOT_TYPE.
> +  UINT8                 SlotDataBusWidth;         ///< MISC_SLOT_DATA_BUS_WIDTH.
> +  UINT8                 CurrentUsage;             ///< MISC_SLOT_USAGE.
> +  UINT8                 SlotLength;               ///< MISC_SLOT_LENGTH.
> +  UINT16                SlotID;
> +  UINT8                 SlotCharacteristics1;
> +  UINT8                 SlotCharacteristics2;
> +  UINT16                SegmentGroupNum;
> +  UINT8                 BusNum;
> +  UINT8                 DevFuncNum;
> +  UINT8                 DataBusWidth;
> +  UINT8                 PeerGroupingCount;
> +  MISC_SLOT_PEER_GROUP *PeerGroups;
> +} CM_SMBIOS_SYSTEM_SLOTS;
> +
> +///
> +/// OEM Strings
> +/// Type 11: ESmbiosObjOemStrings
> +///
> +typedef struct CmSmbiosOemStrings {
> +  CONST CHAR8*          Strings; // NULL separated strings
> +  UINT8                 StringCount;
> +} CM_SMBIOS_OEM_STRINGS;
> +
> +///
> +/// BIOS Language Information
> +/// Type 13: ESmbiosObjBiosLanguageInfo
> +///
> +typedef struct CmSmbiosBiosLanguageInfo {
> +  CONST CHAR8*          Languages; // NULL separated strings
> +  UINT8                 InstallableLanguages;
> +  UINT8                 Flags;
> +  UINT8                 CurrentLanguages;
> +} CM_SMBIOS_BIOS_LANGUAGE_INFO;
> +
> +///
> +/// System Event Log
> +/// Type 15: ESmbiosObjSystemEventLog
> +///
> +typedef struct CmSmbiosSystemEventLog {
> +  UINT16                LogAreaLength;
> +  UINT16                LogHeaderStartOffset;
> +  UINT16                LogDataStartOffset;
> +  UINT8                 AccessMethod;
> +  UINT8                 LogStatus;
> +  UINT32                LogChangeToken;
> +  UINT32                AccessMethodAddress;
> +  UINT8                 LogHeaderFormat;
> +  UINT8                 NumberOfSupportedLogTypeDescriptors;
> +  UINT8                 LengthOfLogTypeDescriptor;
> +  EVENT_LOG_TYPE       *EventLogTypeDescriptors;
> +} CM_SMBIOS_SYSTEM_EVENT_LOG;
> +
> +///
> +/// Physical Memory Array
> +/// Type 16: ESmbiosObjPhysicalMemoryArray
> +///
> +typedef struct CmSmbiosPhysicalMemoryArray {
> +  CM_OBJECT_TOKEN       ReferenceToken;
> +  UINT8                 Location;               ///< MEMORY_ARRAY_LOCATION.
> +  UINT8                 Use;                    ///< MEMORY_ARRAY_USE.
> +  UINT8                 MemoryErrorCorrection;  ///< MEMORY_ERROR_CORRECTION.
> +  UINT64                MaximumCapacity;        ///< in Bytes
> +  CM_OBJECT_TOKEN       MemoryErrorInformationHandle;
> +  UINT16                NumberOfMemoryDevices;
> +} CM_SMBIOS_PHYSICAL_MEMORY_ARRAY;
> +
> +///
> +/// Memory Device
> +/// Type 17: ESmbiosObjMemoryDevice
> +///
> +typedef struct CmSmbiosMemoryDevice {
> +  CONST CHAR8*          DeviceLocator;
> +  CONST CHAR8*          BankLocator;
> +  CONST CHAR8*          Manufacturer;
> +  CONST CHAR8*          SerialNumber;
> +  CONST CHAR8*          AssetTag;
> +  CONST CHAR8*          PartNumber;
> +  CONST CHAR8*          FirwareVersion;
> +  CM_OBJECT_TOKEN       ReferenceToken;
> +  CM_OBJECT_TOKEN       MemoryArrayHandle;
> +  CM_OBJECT_TOKEN       MemoryErrorInformationHandle;
> +  UINT16                TotalWidth;
> +  UINT16                DataWidth;
> +  UINT64                Size;                   ///< in Bytes
> +  UINT8                 FormFactor;             ///< MEMORY_FORM_FACTOR.
> +  UINT8                 DeviceSet;
> +  UINT8                 MemoryType;             ///< MEMORY_DEVICE_TYPE.
> +  UINT16                TypeDetail;
> +  UINT8                 Attributes;
> +  UINT32                Speed;                  ///< Transfer rate
> +  UINT32                ConfiguredMemorySpeed;  ///< Transfer rate
> +  UINT16                MinimumVoltage;
> +  UINT16                MaximumVoltage;
> +  UINT16                ConfiguredVoltage;
> +  UINT8                 MemoryTechnology;       ///< MEMORY_DEVICE_TECHNOLOGY
> +  UINT16                MemoryOperatingModeCapability;
> +  UINT16                ModuleManufacturerID;
> +  UINT16                ModuleProductID;
> +  UINT16                MemorySubsystemControllerManufacturerID;
> +  UINT16                MemorySubsystemControllerProductID;
> +  UINT64                NonVolatileSize;
> +  UINT64                VolatileSize;
> +  UINT64                CacheSize;
> +  UINT64                LogicalSize;
> +} CM_SMBIOS_MEMORY_DEVICE;
> +
> +
> +///
> +/// Memory Array Mapped Address
> +/// Type 19: ESmbiosObjMemoryArrayMappedAddress
> +///
> +typedef struct CmSmbiosMemoryArrayMappedAddress {
> +  CM_OBJECT_TOKEN       ReferenceToken;
> +  UINT64                StartingAddress;
> +  UINT64                EndingAddress;
> +  CM_OBJECT_TOKEN       MemoryArrayHandle;
> +  UINT8                 PartitionWidth;
> +} CM_SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS;
> +
> +///
> +/// System Boot Information
> +/// Type 32: ESmbiosObjSystemBootInfo
> +///
> +typedef struct CmSmbiosSystemBootInfo {
> +  UINT8                 BootStatus;     ///< MISC_BOOT_INFORMATION_STATUS_DATA_TYPE.
> +} CM_SMBIOS_SYSTEM_BOOT_INFO;
> +
> +///
> +/// IPMI Device Information
> +/// Type 38: ESmbiosObjIpmiDeviceInfo
> +///
> +typedef struct CmSmbiosIpmiDeviceInfo {
> +  UINT8                 InterfaceType;              ///< BMC_INTERFACE_TYPE.
> +  UINT8                 IPMISpecificationRevision;
> +  UINT8                 I2CSlaveAddress;
> +  UINT8                 NVStorageDeviceAddress;
> +  UINT8                 BaseAddressModifier_InterruptInfo;
> +  UINT8                 InterruptNumber;
> +  UINT64                BaseAddress;
> +} CM_SMBIOS_IPMI_DEVICE_INFO;
> +
> +///
> +/// Onboard Devices Extended Information
> +/// Type 41: ESmbiosObjOnboardDevicesExtendedInfo
> +///
> +typedef struct CmSmbiosOnboardDevicesExtendedInfo {
> +  CONST CHAR8*          ReferenceDesignation;
> +  UINT8                 DeviceType;             ///< ONBOARD_DEVICE_EXTENDED_INFO_TYPE
> +  UINT8                 DeviceTypeInstance;
> +  UINT16                SegmentGroupNum;
> +  UINT8                 BusNum;
> +  UINT8                 DevFuncNum;
> +} CM_SMBIOS_ONBOARD_DEVICES_EXTENDED_INFO;
> +
> +#pragma pack()
> +
> +
> +///
> +/// Index of SMBIOS_TABLE_STRING
> +///
> +#define SMBIOS_TABLE_STRING_NULL        0x00
> +#define SMBIOS_TABLE_STRING_0           0x00
> +#define SMBIOS_TABLE_STRING_1           0x01
> +#define SMBIOS_TABLE_STRING_2           0x02
> +#define SMBIOS_TABLE_STRING_3           0x03
> +#define SMBIOS_TABLE_STRING_4           0x04
> +#define SMBIOS_TABLE_STRING_5           0x05
> +#define SMBIOS_TABLE_STRING_6           0x06
> +#define SMBIOS_TABLE_STRING_7           0x07
> +#define SMBIOS_TABLE_STRING_8           0x08
> +
> +///
> +/// CM_OBJEC_TOKEN
> +///
> +#define CM_OBJECT_TOKEN_NONE                            0xFFFFFFFFFFFFUL
> +#define CM_OBJECT_TOKEN_NO_ERR_DETECTED                 0xFFFFFFFFFFFFUL
> +#define CM_OBJECT_TOKEN_NO_ERR_INFO                     0xFFFEFFFEFFFEUL
> +
> +///
> +/// SMBIOS Table Revisions
> +///
> +#define EFI_SMBIOS_3_0_FIXED_SMBIOS_TABLE_REVISION      0x0300
> +#define EFI_SMBIOS_3_1_FIXED_SMBIOS_TABLE_REVISION      0x0301
> +#define EFI_SMBIOS_3_2_FIXED_SMBIOS_TABLE_REVISION      0x0302
> +#define EFI_SMBIOS_3_3_FIXED_SMBIOS_TABLE_REVISION      0x0303
> +#define EFI_SMBIOS_3_4_FIXED_SMBIOS_TABLE_REVISION      0x0304
> +
> +
> +///
> +/// BIOS Characteristics
> +///
> +#define EFI_SMBIOS_CHARACT_UNKNOWN                                        BIT2
> +#define EFI_SMBIOS_CHARACT_BIOS_CHARACTERISTICS_NOT_SUPPORTED             BIT3
> +#define EFI_SMBIOS_CHARACT_ISA_SUPPORTED                                  BIT4
> +#define EFI_SMBIOS_CHARACT_MCA_SUPPORTED                                  BIT5
> +#define EFI_SMBIOS_CHARACT_EISA_SUPPORTED                                 BIT6
> +#define EFI_SMBIOS_CHARACT_PCI_SUPPORTED                                  BIT7
> +#define EFI_SMBIOS_CHARACT_PCMCIA_SUPPORTED                               BIT8
> +#define EFI_SMBIOS_CHARACT_PLUGANDPLAY_SUPPORTED                          BIT9
> +#define EFI_SMBIOS_CHARACT_APM_SUPPORTED                                  BIT10
> +#define EFI_SMBIOS_CHARACT_BIOS_UPGRADABLE                                BIT11
> +#define EFI_SMBIOS_CHARACT_BIOS_SHADOWING_ALLOWED                         BIT12
> +#define EFI_SMBIOS_CHARACT_VLVESA_SUPPORTED                               BIT13
> +#define EFI_SMBIOS_CHARACT_ESCD_SUPPORT_AVAILABLE                         BIT14
> +#define EFI_SMBIOS_CHARACT_BOOTFROMCD_SUPPORTED                           BIT15
> +#define EFI_SMBIOS_CHARACT_SELECTABLEBOOT_SUPPORTED                       BIT16
> +#define EFI_SMBIOS_CHARACT_ROMBIOS_SOCKETED                               BIT17
> +#define EFI_SMBIOS_CHARACT_BOOTFROMPCMCIA_SUPPORTED                       BIT18
> +#define EFI_SMBIOS_CHARACT_EDD_SPECIFICATION_SUPPORTED                    BIT19
> +#define EFI_SMBIOS_CHARACT_JAPANESE_NEC_FLOPPY_SUPPORTED                  BIT20
> +#define EFI_SMBIOS_CHARACT_JAPANESE_TOSHIBA_FLOPPY_SUPPORTED              BIT21
> +#define EFI_SMBIOS_CHARACT_FLOPPY525_360_SUPPORTED                        BIT22
> +#define EFI_SMBIOS_CHARACT_FLOPPY525_12_SUPPORTED                         BIT23
> +#define EFI_SMBIOS_CHARACT_FLOPPY35_720_SUPPORTED                         BIT24
> +#define EFI_SMBIOS_CHARACT_FLOPPY35_288_SUPPORTED                         BIT25
> +#define EFI_SMBIOS_CHARACT_PRINTSCREEN_SUPPORTED                          BIT26
> +#define EFI_SMBIOS_CHARACT_KEYBOARD8042_SUPPORTED                         BIT27
> +#define EFI_SMBIOS_CHARACT_SERIAL_SUPPORTED                               BIT28
> +#define EFI_SMBIOS_CHARACT_PRINTER_SUPPORTED                              BIT29
> +#define EFI_SMBIOS_CHARACT_CGAMONO_SUPPORTED                              BIT30
> +#define EFI_SMBIOS_CHARACT_NECPC98                                        BIT31
> +
> +///
> +/// BIOS Characteristics Extension Byte 1.
> +///
> +#define EFI_SMBIOS_CHARACT_EXT1_ACPI_SUPPORTED                            BIT0
> +#define EFI_SMBIOS_CHARACT_EXT1_USB_LEGACY_SUPPORTED                      BIT1
> +#define EFI_SMBIOS_CHARACT_EXT1_AGP_SUPPORTED                             BIT2
> +#define EFI_SMBIOS_CHARACT_EXT1_I2OBOOT_SUPPORTED                         BIT3
> +#define EFI_SMBIOS_CHARACT_EXT1_LS120BOOT_SUPPORTED                       BIT4
> +#define EFI_SMBIOS_CHARACT_EXT1_ATAPIZIP_DRIVEBOOT_SUPPORTED              BIT5
> +#define EFI_SMBIOS_CHARACT_EXT1_BOOT1394_SUPPORTED                        BIT6
> +#define EFI_SMBIOS_CHARACT_EXT1_SMARTBATTERY_SUPPORTED                    BIT7
> +
> +///
> +/// BIOS Characteristics Extension Byte 2.
> +///
> +#define EFI_SMBIOS_CHARACT_EXT2_BIOS_BOOT_SPEC_SUPPORTED                  BIT0
> +#define EFI_SMBIOS_CHARACT_EXT2_FUNCTION_KEY_NETWORK_BOOT_SUPPORTED       BIT1
> +#define EFI_SMBIOS_CHARACT_EXT2_TARGET_CONTENT_DISTRIBUTION_ENABLED       BIT2
> +#define EFI_SMBIOS_CHARACT_EXT2_UEFI_SPECIFICATION_SUPPORTED              BIT3
> +#define EFI_SMBIOS_CHARACT_EXT2_VIRTUAL_MACHINE_SUPPORTED                 BIT4
> +
> +///
> +/// BIOS Extended ROM size.
> +///
> +#define EFI_SMBIOS_EXTENDED_BIOS_ROM_SIZE_IN_1MB                          0
> +#define EFI_SMBIOS_EXTENDED_BIOS_ROM_SIZE_IN_1GB                          BIT0
> +
> +///
> +///  Base Board - Feature Flags.
> +///
> +#define EFI_SMBIOS_BASE_BOARD_FEATURE_MOTHER_BOARD                        BIT0
> +#define EFI_SMBIOS_BASE_BOARD_FEATURE_REQUIRES_DAUGHTER_CARD              BIT1
> +#define EFI_SMBIOS_BASE_BOARD_FEATURE_REMOVABLE                           BIT2
> +#define EFI_SMBIOS_BASE_BOARD_FEATURE_REPLACEABLE                         BIT3
> +#define EFI_SMBIOS_BASE_BOARD_FEATURE_HOT_SWAPPABLE                       BIT4
> +
> +///
> +/// Processor Information - Voltage.
> +///
> +#define EFI_SMBIOS_PROCESSOR_VOLTAGE_CAPABILITY5V                         BIT0
> +#define EFI_SMBIOS_PROCESSOR_VOLTAGE_CAPABILITY3_3V                       BIT1
> +#define EFI_SMBIOS_PROCESSOR_VOLTAGE_CAPABILITY2_9V                       BIT2
> +#define EFI_SMBIOS_PROCESSOR_VOLTAGE_LEGACY                               0x00
> +#define EFI_SMBIOS_PROCESSOR_VOLTAGE_NON_LEGACY                           BIT7
> +
> +
> +///
> +/// Processor Information - Characteristics.
> +///
> +#define EFI_SMBIOS_PROCESSOR_CHARACT_RESERVED1                            BIT0
> +#define EFI_SMBIOS_PROCESSOR_CHARACT_UNKNOWN                              BIT1
> +#define EFI_SMBIOS_PROCESSOR_CHARACT_64BIT_CAPBLE                         BIT2
> +#define EFI_SMBIOS_PROCESSOR_CHARACT_MULTICORE                            BIT3
> +#define EFI_SMBIOS_PROCESSOR_CHARACT_HARDWARE_THREAD                      BIT4
> +#define EFI_SMBIOS_PROCESSOR_CHARACT_EXECUTE_PROTECTION                   BIT5
> +#define EFI_SMBIOS_PROCESSOR_CHARACT_ENHANCED_VIRTULIZATION               BIT6
> +#define EFI_SMBIOS_PROCESSOR_CHARACT_POWER_PERFORMANCE_CTRL               BIT7
> +#define EFI_SMBIOS_PROCESSOR_CHARACT_128BIT_CAPBLE                        BIT8
> +#define EFI_SMBIOS_PROCESSOR_CHARACT_ARM64_SOC_ID                         BIT9 // 3.4
> +
> +///
> +/// Processor Information - Status.
> +///
> +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_UNKNOWN                           0x00
> +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_ENABLED                           0x01
> +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_DISABLED_BY_USER                  0x02
> +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_DISABLED_BY_BIOS                  0x03
> +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_IDLE                              0x04
> +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_OTHER                             0x07
> +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_SOCKET_POPULATED                  BIT6
> +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_SOCKET_NOT_POPULATED              0x00
> +
> +
> +///
> +/// Cache SRAM type data
> +///
> +#define EFI_SMBIOS_CACHE_SRAM_TYPE_OTHER                                  BIT0
> +#define EFI_SMBIOS_CACHE_SRAM_TYPE_UNKNOWN                                BIT1
> +#define EFI_SMBIOS_CACHE_SRAM_TYPE_NONBURST                               BIT2
> +#define EFI_SMBIOS_CACHE_SRAM_TYPE_BURST                                  BIT3
> +#define EFI_SMBIOS_CACHE_SRAM_TYPE_PIPELINEBURST                          BIT4
> +#define EFI_SMBIOS_CACHE_SRAM_TYPE_SYNCHRONOUS                            BIT5
> +#define EFI_SMBIOS_CACHE_SRAM_TYPE_ASYNCHRONOUS                           BIT6
> +
> +///
> +/// System Slots - Slot Characteristics 1.
> +///
> +#define EFI_SMBIOS_SLOT_CHARACT1_CHARACTERISTICS_UNKNOWN                  BIT0
> +#define EFI_SMBIOS_SLOT_CHARACT1_PROVIDE_50VOLTS                          BIT1
> +#define EFI_SMBIOS_SLOT_CHARACT1_PROVIDE_33VOLTS                          BIT2
> +#define EFI_SMBIOS_SLOT_CHARACT1_SHARED_SLOT                              BIT3
> +#define EFI_SMBIOS_SLOT_CHARACT1_PCCARD16_SUPPORTED                       BIT4
> +#define EFI_SMBIOS_SLOT_CHARACT1_CARDBUS_SUPPORTED                        BIT5
> +#define EFI_SMBIOS_SLOT_CHARACT1_ZOOMVIDEO_SUPPORTED                      BIT6
> +#define EFI_SMBIOS_SLOT_CHARACT1_MODEMRINGRESUME_SUPPORTED                BIT7
> +
> +///
> +/// System Slots - Slot Characteristics 2.
> +///
> +#define EFI_SMBIOS_SLOT_CHARACT2_PMESIGNAL_SUPPORTED                      BIT0
> +#define EFI_SMBIOS_SLOT_CHARACT2_HOTPLUGDEVICES_SUPPORTED                 BIT1
> +#define EFI_SMBIOS_SLOT_CHARACT2_SMBUSSIGNAL_SUPPORTED                    BIT2
> +#define EFI_SMBIOS_SLOT_CHARACT2_BIFURCATION_SUPPORTED                    BIT3
> +
> +///
> +/// Memory Device - Type Detail
> +///
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_RESERVED                            BIT0
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_OTHER                               BIT1
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_UNKNOWN                             BIT2
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_FASTPAGED                           BIT3
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_STATICCOLUMN                        BIT4
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_PSEUDOSTATIC                        BIT5
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_RAMBUS                              BIT6
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_SYNCHRONOUS                         BIT7
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_CMOS                                BIT8
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_EDO                                 BIT9
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_WINDOWDRAM                          BIT10
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_CACHEDRAM                           BIT11
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_NONVOLATILE                         BIT12
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_REGISTERED                          BIT13
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_UNBUFFERED                          BIT14
> +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_LRDIMM                              BIT15
> +
> +///
> +/// Memory Device - Memory Operating Mode Capability
> +///
> +#define EFI_SMBIOS_MEMORY_DEVICE_OP_MODE_OTHER                            BIT1
> +#define EFI_SMBIOS_MEMORY_DEVICE_OP_MODE_UNKNOWN                          BIT2
> +#define EFI_SMBIOS_MEMORY_DEVICE_OP_MODE_VOLATILE_MEMORY                  BIT3
> +#define EFI_SMBIOS_MEMORY_DEVICE_OP_MODE_BYTE_ACCESS_PERSISTENT_MEMORY    BIT4
> +#define EFI_SMBIOS_MEMORY_DEVICE_OP_MODE_BLOCK_ACCESS_PERSISTENT_MEMORY   BIT5
> +
> +#endif // SMBIOS_NAMESPACE_OBJECTS_H_
> diff --git a/DynamicTablesPkg/Include/SmbiosTableGenerator.h b/DynamicTablesPkg/Include/SmbiosTableGenerator.h
> index 9fbf9fc..2a1656d 100644
> --- a/DynamicTablesPkg/Include/SmbiosTableGenerator.h
> +++ b/DynamicTablesPkg/Include/SmbiosTableGenerator.h
> @@ -1,5 +1,6 @@
>  /** @file
>  
> +  Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
>    Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
>  
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> @@ -27,58 +28,35 @@ typedef TABLE_GENERATOR_ID SMBIOS_TABLE_GENERATOR_ID;
>  */
>  typedef enum StdSmbiosTableGeneratorId {
>    EStdSmbiosTableIdReserved = 0x0000,
> -  EStdSmbiosTableIdRAW,
> -  EStdSmbiosTableIdType00,
> -  EStdSmbiosTableIdType01,
> -  EStdSmbiosTableIdType02,
> -  EStdSmbiosTableIdType03,
> -  EStdSmbiosTableIdType04,
> -  EStdSmbiosTableIdType05,
> -  EStdSmbiosTableIdType06,
> -  EStdSmbiosTableIdType07,
> -  EStdSmbiosTableIdType08,
> -  EStdSmbiosTableIdType09,
> -  EStdSmbiosTableIdType10,
> -  EStdSmbiosTableIdType11,
> -  EStdSmbiosTableIdType12,
> -  EStdSmbiosTableIdType13,
> -  EStdSmbiosTableIdType14,
> -  EStdSmbiosTableIdType15,
> -  EStdSmbiosTableIdType16,
> -  EStdSmbiosTableIdType17,
> -  EStdSmbiosTableIdType18,
> -  EStdSmbiosTableIdType19,
> -  EStdSmbiosTableIdType20,
> -  EStdSmbiosTableIdType21,
> -  EStdSmbiosTableIdType22,
> -  EStdSmbiosTableIdType23,
> -  EStdSmbiosTableIdType24,
> -  EStdSmbiosTableIdType25,
> -  EStdSmbiosTableIdType26,
> -  EStdSmbiosTableIdType27,
> -  EStdSmbiosTableIdType28,
> -  EStdSmbiosTableIdType29,
> -  EStdSmbiosTableIdType30,
> -  EStdSmbiosTableIdType31,
> -  EStdSmbiosTableIdType32,
> -  EStdSmbiosTableIdType33,
> -  EStdSmbiosTableIdType34,
> -  EStdSmbiosTableIdType35,
> -  EStdSmbiosTableIdType36,
> -  EStdSmbiosTableIdType37,
> -  EStdSmbiosTableIdType38,
> -  EStdSmbiosTableIdType39,
> -  EStdSmbiosTableIdType40,
> -  EStdSmbiosTableIdType41,
> -  EStdSmbiosTableIdType42,
> -
> -  // IDs 43 - 125 are reserved
> -
> -  EStdSmbiosTableIdType126 = (EStdSmbiosTableIdType00 + 126),
> -  EStdSmbiosTableIdType127,
> -  EStdSmbiosTableIdMax
> +  EStdSmbiosTableIdRaw,       ///< RAW Generator
> +  EStdSmbiosTableIdBasic,     ///< Basic Generator for the required or recommended tables
> +  EStdSmbiosTableIdMax                  

An awful lot of trailing spaces on above line. Please run
PatchCheck.py before posting.

>  } ESTD_SMBIOS_TABLE_ID;
>  
> +
> +#define EFI_SMBIOS_TABLE_TYPES_MANDATORY        ( \
> +  BIT0    /* BIOS info */                       | \
> +  BIT1    /* System info */                     | \
> +  BIT3    /* System chassis */                  | \
> +  BIT4    /* Processor info */                  | \
> +  BIT7    /* Cache info */                      | \
> +  BIT9    /* System slot */                     | \
> +  BIT16   /* Physical memory array */           | \
> +  BIT17   /* Memory device */                   | \
> +  BIT19   /* Memory array mapped address */     | \
> +  BIT32   /* System boot info */                  \
> +  )
> +
> +#define EFI_SMBIOS_TABLE_TYPES_OPTIONAL         ( \
> +  BIT2    /* Baseboard info */                  | \
> +  BIT8    /* Port connector info */             | \
> +  BIT11   /* OEM string */                      | \
> +  BIT13   /* BIOS language info */              | \
> +  BIT15   /* System event log */                | \
> +  BIT38   /* IPMI device info */                | \
> +  BIT41   /* Onboard device extended info */      \
> +  )
> +
>  /** This macro checks if the Table Generator ID is for an SMBIOS Table
>      Generator.
>  
> @@ -122,6 +100,44 @@ typedef enum StdSmbiosTableGeneratorId {
>              TableId                             \
>              )
>  
> +/** This macro creates an OEM SMBIOS Table Generator ID.
> +
> +  @param [in] TableId  The table generator ID.
> +
> +  @return an OEM SMBIOS table generator ID.
> +**/
> +#define CREATE_OEM_SMBIOS_TABLE_GEN_ID(TableId) \
> +          CREATE_TABLE_GEN_ID (                 \
> +            ETableGeneratorTypeSmbios,          \
> +            ETableGeneratorNameSpaceOem,        \
> +            TableId                             \
> +            )
> +
> +/** A macro to initialise the common header part of EFI SMBIOS tables as
> +    defined by the EFI_SMBIOS_TABLE_HEADER structure.
> +
> +  @param [in] Type      The SMBIOS table type.
> +  @param [in] Length    The SMBIOS table length.
> +  @param [in] Handle    The SMBIOS table handle.
> +**/
> +#define SMBIOS_HEADER(Type, Length, Handle) {               \
> +          Type,                  /* UINT8   Type */         \
> +          Length,                /* UINT8   Length */       \
> +          Handle                 /* UINT16  Handle */       \
> +          }
> +
> +/** A macro to dump the common header part of EFI SMBIOS tables as
> +    defined by the EFI_SMBIOS_TABLE_HEADER structure.
> +
> +  @param [in] Header  The pointer to the SMBIOS table header.
> +**/
> +#define DUMP_SMBIOS_TABLE_HEADER(Header)                    \
> +          DEBUG ((                                          \
> +            DEBUG_INFO,                                     \
> +            "SMBIOS: Type %d, Length 0x%x, Handle 0x%x\n",  \
> +            Header->Type, Header->Length, Header->Handle    \
> +            ));
> +
>  /** Forward declarations.
>  */
>  typedef struct ConfigurationManagerProtocol EDKII_CONFIGURATION_MANAGER_PROTOCOL;
> @@ -168,6 +184,48 @@ typedef EFI_STATUS (*SMBIOS_TABLE_GENERATOR_FREE_TABLE) (
>    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        CM_STD_OBJ_SMBIOS_TABLE_INFO          * CONST SmbiosTableInfo,
> +  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST CfgMgrProtocol,
> +  OUT       SMBIOS_STRUCTURE                    ***       Table,
> +  OUT       UINTN                                 *       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        CM_STD_OBJ_SMBIOS_TABLE_INFO          * CONST SmbiosTableInfo,
> +  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST CfgMgrProtocol,
> +  IN        SMBIOS_STRUCTURE                    ***       Table,
> +  IN        UINTN                                         TableCount  
> +  );
> +
>  /** The SMBIOS_TABLE_GENERATOR structure provides an interface that the
>      Table Manager can use to invoke the functions to build SMBIOS tables.
>  */
> @@ -175,12 +233,17 @@ typedef struct SmbiosTableGenerator {
>    /// The SMBIOS table generator ID.
>    SMBIOS_TABLE_GENERATOR_ID                GeneratorID;
>  
> -  /// String describing the DT table
> -  /// generator.
> +  /// String describing the SMBIOS table generator.
>    CONST CHAR16*                            Description;
>  
> +  /// The SMBIOS table revision
> +  UINT16                                   SmbiosTableRevision;
> +
> +  /// The minimum supported SMBIOS table revision.
> +  UINT16                                   MinSmbiosTableRevision;
> +  
>    /// The SMBIOS table type.
> -  SMBIOS_TYPE                              Type;
> +  /// SMBIOS_TYPE                              Type;

Please delete lines instead of commenting out.
Also, what is /// ? C++-style comments are //.

>  
>    /// SMBIOS table build function pointer.
>    SMBIOS_TABLE_GENERATOR_BUILD_TABLE       BuildSmbiosTable;
> @@ -189,6 +252,15 @@ 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
> +      using the extended interface.
> +  */
> +  SMBIOS_TABLE_GENERATOR_FREE_TABLEEX      FreeTableResourcesEx;
>  } SMBIOS_TABLE_GENERATOR;
>  
>  /** Register SMBIOS table factory generator.
> @@ -231,4 +303,3 @@ DeregisterSmbiosTableGenerator (
>  #pragma pack()
>  
>  #endif // SMBIOS_TABLE_GENERATOR_H_
> -
> diff --git a/DynamicTablesPkg/Include/StandardNameSpaceObjects.h b/DynamicTablesPkg/Include/StandardNameSpaceObjects.h
> index 0ba6b16..03faac3 100644
> --- a/DynamicTablesPkg/Include/StandardNameSpaceObjects.h
> +++ b/DynamicTablesPkg/Include/StandardNameSpaceObjects.h
> @@ -1,5 +1,6 @@
>  /** @file
>  
> +  Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
>    Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
>  
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> @@ -122,8 +123,11 @@ typedef struct CmStdObjSmbiosTableInfo {
>    /// The SMBIOS Table Generator ID
>    SMBIOS_TABLE_GENERATOR_ID   TableGeneratorId;
>  
> +  /// The SMBIOS table revision
> +  UINT16                      SmbiosTableRevision;
> +
>    /// Optional pointer to the SMBIOS table data
> -  SMBIOS_STRUCTURE           * SmbiosTableData;
> +  SMBIOS_STRUCTURE          * SmbiosTableData;
>  } CM_STD_OBJ_SMBIOS_TABLE_INFO;
>  
>  #pragma pack()
> diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.c b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.c
> new file mode 100644
> index 0000000..fd06a80
> --- /dev/null
> +++ b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.c
> @@ -0,0 +1,554 @@
> +/** @file
> +  Generator of the required or recommended SMBIOS tables
> +
> +  Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
> +  Copyright (c) 2017 - 2020, ARM Limited. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Protocol/Smbios.h>
> +
> +// Module specific include files.
> +#include <SmbiosTableGenerator.h>
> +#include <ConfigurationManagerObject.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +
> +#include "BasicGenerator.h"
> +
> +
> +/** The pre-populated data of the SMBIOS tables and the associated Configuration
> +  Manager Object to interface the Basic Table Generator.
> +*/
> +STATIC SMBIOS_OBJECT_INFO BasicGeneratorHelper[] = {
> +  CREATE_SMBIOS_OBJECT_INFO (0,  TRUE,  0x03, BiosInfo),
> +  CREATE_SMBIOS_OBJECT_INFO (1,  TRUE,  0x06, SystemInfo),
> +  CREATE_SMBIOS_OBJECT_INFO (2,  FALSE, 0x06, BaseboardInfo),
> +  CREATE_SMBIOS_OBJECT_INFO (3,  TRUE,  0x05, SystemEnclosure),
> +  CREATE_SMBIOS_OBJECT_INFO (4,  TRUE,  0x06, ProcessorInfo),
> +  CREATE_SMBIOS_OBJECT_INFO (7,  TRUE,  0x01, CacheInfo),
> +  CREATE_SMBIOS_OBJECT_INFO (8,  FALSE, 0x02, PortConnectorInfo),
> +  CREATE_SMBIOS_OBJECT_INFO (9,  TRUE,  0x01, SystemSlots),
> +  CREATE_SMBIOS_OBJECT_INFO (11, FALSE, 0xFF, OemStrings),
> +  CREATE_SMBIOS_OBJECT_INFO (13, FALSE, 0xFF, BiosLanguageInfo),
> +  CREATE_SMBIOS_OBJECT_INFO (15, FALSE, 0x00, SystemEventLog),
> +  CREATE_SMBIOS_OBJECT_INFO (16, TRUE,  0x00, PhysicalMemoryArray),
> +  CREATE_SMBIOS_OBJECT_INFO (17, TRUE,  0x07, MemoryDevice),
> +  CREATE_SMBIOS_OBJECT_INFO (19, TRUE,  0x00, MemoryArrayMappedAddress),
> +  CREATE_SMBIOS_OBJECT_INFO (32, TRUE,  0x00, SystemBootInfo),
> +  CREATE_SMBIOS_OBJECT_INFO (38, FALSE, 0x00, IpmiDeviceInfo),
> +  CREATE_SMBIOS_OBJECT_INFO (41, FALSE, 0x01, OnboardDevicesExtendedInfo),
> +};
> +
> +
> +/** Retrieve an object or an object list from the Configuration Manager using
> +  the Configuration Manager Protocol interface.
> +**/
> +STATIC
> +EFI_STATUS
> +GetCmObjectList (
> +  IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST CfgMgrProtocol,
> +  IN      CONST CM_OBJECT_TOKEN                               Token OPTIONAL,
> +  IN OUT  CM_OBJECT_TYPE_INFO                         *       CmObjectInfo
> +  )
> +{
> +  EFI_STATUS         Status;
> +  ESMBIOS_OBJECT_ID  CmObjectId;
> +  CM_OBJ_DESCRIPTOR  CmObjectDesc;
> +  UINTN              CmObjectSize;
> +  UINT32             ObjCount;
> +  VOID             **List;
> +
> +  ObjCount = 0;
> +  CmObjectId = CmObjectInfo->Id;
> +  CmObjectSize = CmObjectInfo->Size;
> +  List = &CmObjectInfo->Data;
> +
> +  ASSERT (List != NULL);
> +
> +  Status = CfgMgrProtocol->GetObject (
> +                             CfgMgrProtocol,
> +                             CREATE_CM_OBJECT_ID (EObjNameSpaceSmbios, CmObjectId),
> +                             Token,
> +                             &CmObjectDesc
> +                             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((
> +      DEBUG_INFO,
> +      "INFO: Get CmObjectId 0x%x: Not implemented. Status = %r\n",
> +      CmObjectId, Status
> +      ));
> +    *List = NULL;
> +    goto error_handler;
> +  }
> +
> +  if (CmObjectDesc.ObjectId != CREATE_CM_OBJECT_ID (EObjNameSpaceSmbios, CmObjectId)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "ERROR: Get CmObjectId 0x%x: Invalid, Expected - 0x%x\n",
> +      CmObjectDesc.ObjectId, CREATE_CM_OBJECT_ID (EObjNameSpaceSmbios, CmObjectId)
> +      ));
> +    ASSERT (FALSE);
> +    Status = EFI_INVALID_PARAMETER;
> +    goto error_handler;
> +  }
> +
> +  if (CmObjectDesc.Size < (CmObjectSize * CmObjectDesc.Count)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "ERROR: GetCmObjectId 0x%x: Buffer too small, size = 0x%x\n",
> +      CmObjectId, CmObjectDesc.Size
> +      ));
> +    ASSERT (FALSE);
> +    Status = EFI_BAD_BUFFER_SIZE;
> +    goto error_handler;
> +  }
> +
> +  ObjCount = CmObjectDesc.Count;
> +  *List = (VOID *)CmObjectDesc.Data;
> +
> +error_handler:
> +  if (*List != NULL) {
> +    CmObjectInfo->Count = ObjCount;
> +  }
> +  return Status;
> +}
> +
> +/** Populate the additional size of variable SMBIOS tables.
> +
> +  This function calculates the length of a variable data structure present
> +  in some SMBIOS tables and helps get the total size of a table.
> +**/
> +STATIC
> +UINTN
> +GetSmbiosObjectSize (
> +  IN    UINT16                      TableRevision,
> +  IN    VOID                      * SrcObject,
> +  IN    ESMBIOS_OBJECT_ID           CmObjectId
> +  )
> +{
> +  UINTN Len;
> +
> +  switch (CmObjectId) {
> +  case ESmbiosObjBaseboardInfo:
> +    Len = GetSmbiosSizeBaseboardInfo (TableRevision, SrcObject);
> +    break;
> +
> +  case ESmbiosObjSystemEnclosure:
> +    Len = GetSmbiosSizeSystemEnclosure (TableRevision, SrcObject);
> +    break;
> +
> +  case ESmbiosObjSystemSlots:
> +    Len = GetSmbiosSizeSystemSlots (TableRevision, SrcObject);
> +    break;
> +
> +  case ESmbiosObjSystemEventLog:
> +    Len = GetSmbiosSizeSystemEventLog (TableRevision, SrcObject);
> +    break;
> +
> +  default:
> +    Len = 0;
> +  }
> +  return Len;
> +}
> +
> +/** Populate the size of strings attached to a SMBIOS table.
> +
> +  This function calculates the size of strings to be contained in
> +  a table and helps get the total size of a table.
> +**/
> +STATIC
> +UINTN
> +GetSmbiosStringLength (

If the count is across multiple strings, should the name not then be
GetSmbiosStringsLength?

> +  IN    SMBIOS_OBJECT_TYPE_INFO   * SmbiosObjectInfo,
> +  IN    VOID                      * Object
> +  )
> +{
> +  UINTN                 Index;
> +  UINTN                 Len;
> +  UINTN                 Size;
> +  CONST CHAR8         * Strings;
> +  CONST CHAR8        ** StringArray;
> +
> +  ASSERT (SmbiosObjectInfo != NULL);
> +  ASSERT (Object != NULL);
> +
> +  Len = 0;
> +
> +  switch (SmbiosObjectInfo->NumStrings) {
> +  case (0x00):
> +    break;
> +
> +  case (0xFF):
> +    Strings = (CONST CHAR8 *)Object;
> +    // One pointer contains multiple NULL-terminated strings
> +    while (*Strings != '\0') {
> +      Size = AsciiStrSize (Strings);
> +      Len += Size;
> +      Strings += Size;
> +    }
> +    Len++; // The last NULL
> +    break;
> +
> +  default:
> +    StringArray = (CONST CHAR8 **)Object;
> +    for (Index = 0; Index < SmbiosObjectInfo->NumStrings; Index++) {
> +      if (StringArray[Index] != NULL) {
> +        Len += AsciiStrSize (StringArray[Index]);
> +      }
> +    }
> +    Len++; // The last NULL
> +  }
> +  return Len;
> +}
> +
> +
> +/** Populate SMBIOS table(s) based on the given information of the
> +  Configuration Manager Object description and the pre-populated data
> +  of a SMBIOS table type.
> +**/
> +EFI_STATUS
> +BuildSmbiosObject (
> +  IN    UINT16                      TableRevision,
> +  IN    VOID                      * ObjectTableInfo,
> +  OUT   EFI_SMBIOS_TABLE_HEADER  ** Table
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  SMBIOS_OBJECT_INFO        * ObjectInfo;
> +  SMBIOS_OBJECT_TYPE_INFO   * SmbiosObjectInfo;
> +  CM_OBJECT_TYPE_INFO       * CmObjectInfo;
> +  VOID                      * SrcObject;
> +  EFI_SMBIOS_TABLE_HEADER   * DstObject;
> +  UINTN                       Index;
> +  UINTN                       ObjLen;
> +  UINTN                       StrLen;
> +
> +  ASSERT (Table != NULL);
> +  ASSERT (ObjectTableInfo != NULL);
> +
> +  ObjectInfo = (SMBIOS_OBJECT_INFO *)ObjectTableInfo;
> +  CmObjectInfo = &ObjectInfo->CmObjectInfo;
> +  SmbiosObjectInfo = &ObjectInfo->SmbiosObjectInfo;
> +
> +  for (Index = 0; Index < CmObjectInfo->Count; Index++) {
> +    SrcObject = CmObjectInfo->Data + (Index * CmObjectInfo->Size);
> +
> +    ObjLen = SmbiosObjectInfo->Length;
> +    ObjLen += GetSmbiosObjectSize (TableRevision, SrcObject, CmObjectInfo->Id);
> +    StrLen = GetSmbiosStringLength (SmbiosObjectInfo, SrcObject);
> +
> +    DstObject = (EFI_SMBIOS_TABLE_HEADER *)AllocateZeroPool (ObjLen + StrLen);
> +    if (DstObject == NULL) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +      DEBUG ((
> +        DEBUG_ERROR,
> +        "ERROR: Failed to allocate memory for %d th SMBIOS Table"
> +        " of Id %x, Status = %r\n",
> +        Index,
> +        CmObjectInfo->Id,
> +        Status
> +        ));
> +      goto error_handler;
> +    }
> +
> +    // Update the table type and the length in the header
> +    DstObject->Type = SmbiosObjectInfo->Type;
> +    DstObject->Length = ObjLen;
> +
> +    // Build this specific object of the SMBIOS table
> +    Status = ObjectInfo->BuildObject (TableRevision,
> +                                     (VOID *)SrcObject,
> +                                     (VOID *)DstObject
> +                                     );
> +    if (EFI_ERROR (Status)) {
> +      goto error_handler;
> +    }
> +    Table[Index] = DstObject;
> +  }
> +
> +error_handler:
> +  return Status;
> +}
> +
> +
> +/** Free the resources allocated for building the SMBIOS tables.
> +**/
> +STATIC
> +VOID
> +FreeSmbiosBasicTable (
> +  IN  EFI_SMBIOS_TABLE_HEADER *** Table,
> +  IN  UINTN                       TableCount
> +  )
> +{
> +  UINTN   Index;
> +  EFI_SMBIOS_TABLE_HEADER      ** SmbiosTable;
> +
> +  ASSERT (Table != NULL);
> +
> +  SmbiosTable = *Table;
> +  if (SmbiosTable != NULL) {
> +    for (Index = 0; Index < TableCount; Index++) {
> +      if (SmbiosTable[Index] != NULL) {
> +        FreePool (SmbiosTable[Index]);
> +      }
> +    }
> +    FreePool (SmbiosTable);
> +  }
> +}
> +
> +/** Construct the SMBIOS table using the SMBIOS table data provided.
> +
> +  This function invokes the Configuration Manager protocol interface
> +  to get the required hardware information for generating the SMBIOS
> +  table.
> +
> +  If this function allocates any resources then they must be freed
> +  in the FreeXXXXTableResources function.
> +
> +  @param [in]  This             Pointer to the table generator.
> +  @param [in]  SmbiosTableInfo  Pointer to the SMBIOS Table Info.
> +  @param [in]  CfgMgrProtocol   Pointer to the Configuration Manager
> +                                Protocol Interface.
> +  @param [out] Table            Pointer to the constructed SMBIOS Table.
> +
> +  @retval EFI_SUCCESS           Table generated successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +BuildBasicTable (
> +  IN  CONST SMBIOS_TABLE_GENERATOR                  * CONST This,
> +  IN        CM_STD_OBJ_SMBIOS_TABLE_INFO            * CONST SmbiosTableInfo,
> +  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL    * CONST CfgMgrProtocol,
> +  OUT       EFI_SMBIOS_TABLE_HEADER               ***       Table,
> +  OUT       UINTN                                   *       TableCount
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  SMBIOS_OBJECT_INFO         *ObjectInfo;
> +  CM_OBJECT_TYPE_INFO        *CmObjectInfo;
> +  UINTN                       Index;
> +  UINTN                       LocalTableCount;
> +  EFI_SMBIOS_TABLE_HEADER   **LocalTable;
> +  UINT16                      TableRevision;
> +
> +  ASSERT (This != NULL);
> +  ASSERT (SmbiosTableInfo != NULL);
> +  ASSERT (CfgMgrProtocol != NULL);
> +  ASSERT (Table != NULL);
> +  ASSERT (TableCount != NULL);
> +  ASSERT (SmbiosTableInfo->TableGeneratorId == This->GeneratorID);
> +
> +  TableRevision = SmbiosTableInfo->SmbiosTableRevision;
> +
> +  if ((TableRevision < This->MinSmbiosTableRevision) ||
> +      (TableRevision > This->SmbiosTableRevision)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "ERROR: SMBIOS Basic: Requested table rev = %d, is not supported."
> +      "Supported table rev: Min = %d, Max = %d\n",
> +      TableRevision,
> +      This->MinSmbiosTableRevision,
> +      This->SmbiosTableRevision
> +      ));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *Table = NULL;
> +  *TableCount = 0;
> +  LocalTableCount = 0;
> +
> +  // Collect the required data prior to allocating a space for SMBIOS tables
> +  for (Index = 0; Index < ARRAY_SIZE (BasicGeneratorHelper); Index++) {
> +    CmObjectInfo = &BasicGeneratorHelper[Index].CmObjectInfo;
> +    // Get the pointer to CmObject data and their count
> +    Status = GetCmObjectList (CfgMgrProtocol, CM_NULL_TOKEN, CmObjectInfo);
> +    if (EFI_ERROR (Status)) {
> +      continue;
> +    }
> +    // Count the number of the SMBIOS tables to be installed
> +    LocalTableCount += CmObjectInfo->Count;
> +  }
> +
> +  // Allocate a space for the entire SMBIOS tables
> +  LocalTable = (EFI_SMBIOS_TABLE_HEADER **)AllocateZeroPool (LocalTableCount
> +                                        * sizeof (EFI_SMBIOS_TABLE_HEADER *));
> +  if (LocalTable == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "ERROR: Failed to allocate memory for %d SMBIOS Tables,"
> +      " Status = %r\n",
> +      LocalTableCount,
> +      Status
> +      ));
> +    goto error_handler;
> +  }
> +  *Table = LocalTable;
> +  *TableCount = LocalTableCount;
> +
> +  // Create a space to assign the SMBIOS handles prior to building each table
> +  Status = BuildSmbiosHandleTable (LocalTableCount);
> +  if (EFI_ERROR (Status)) {
> +    goto error_handler;
> +  }
> +
> +  // Build all basic SMBIOS tables
> +  for (Index = 0; Index < ARRAY_SIZE (BasicGeneratorHelper); Index++) {
> +    ObjectInfo = &BasicGeneratorHelper[Index];
> +
> +    if (ObjectInfo->CmObjectInfo.Count != 0) {
> +      Status = BuildSmbiosObject (TableRevision, ObjectInfo, LocalTable);
> +      if (EFI_ERROR (Status)) {
> +        goto error_handler;
> +      }
> +
> +      if ((UINTN)LocalTable >= (UINTN)(*Table + LocalTableCount)) {
> +        Status = EFI_BAD_BUFFER_SIZE;
> +        goto error_handler;
> +      }
> +      LocalTable += ObjectInfo->CmObjectInfo.Count;
> +    }
> +  }
> +  if ((UINTN)LocalTable != (UINTN)(*Table + LocalTableCount)) {
> +    Status = EFI_BAD_BUFFER_SIZE;
> +    goto error_handler;
> +  }
> +
> +error_handler:
> +  if (EFI_ERROR (Status)) {
> +    FreeSmbiosHandleTable ();
> +    FreeSmbiosBasicTable (Table, *TableCount);
> +
> +    *Table = NULL;
> +    *TableCount = 0;
> +  }
> +
> +  return Status;
> +}
> +
> +/** Free any resources allocated for constructing the tables.
> +
> +  @param [in]      This           Pointer to the SMBIOS table generator.
> +  @param [in]      SmbiosTableInfo  Pointer to the SMBIOS Table Info.
> +  @param [in]      CfgMgrProtocol Pointer to the Configuration Manager
> +                                  Protocol Interface.
> +  @param [in, out] Table          Pointer to an array of pointers
> +                                  to SMBIOS Table(s).
> +  @param [in]      TableCount     Number of SMBIOS table(s).
> +
> +  @retval EFI_SUCCESS           The resources were freed successfully.
> +  @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +FreeBasicTable (
> +  IN  CONST SMBIOS_TABLE_GENERATOR                *       This,
> +  IN        CM_STD_OBJ_SMBIOS_TABLE_INFO          * CONST SmbiosTableInfo,
> +  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST CfgMgrProtocol,
> +  IN        SMBIOS_STRUCTURE                    ***       Table,
> +  IN        UINTN                                         TableCount
> +)
> +{
> +
> +  ASSERT (This != NULL);
> +  ASSERT (SmbiosTableInfo != NULL);
> +  ASSERT (CfgMgrProtocol != NULL);
> +  ASSERT (SmbiosTableInfo->TableGeneratorId == This->GeneratorID);
> +
> +
> +  if (Table == NULL) {
> +    DEBUG ((DEBUG_ERROR, "ERROR: SMBIOS: Invalid Table Pointer\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  FreeSmbiosHandleTable ();
> +  FreeSmbiosBasicTable (Table, TableCount);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/** This macro defines the Raw Generator revision.
> +*/
> +#define RAW_GENERATOR_REVISION CREATE_REVISION (1, 0)
> +
> +/** The interface for the Raw Table Generator.
> +*/
> +STATIC
> +CONST
> +SMBIOS_TABLE_GENERATOR BasicGenerator = {
> +  // Generator ID
> +  CREATE_STD_SMBIOS_TABLE_GEN_ID (EStdSmbiosTableIdBasic),
> +  // Generator Description
> +  L"SMBIOS.STD.BASIC.GENERATOR",
> +  // SMBIOS Table Revision supported by this Generator
> +  EFI_SMBIOS_3_4_FIXED_SMBIOS_TABLE_REVISION,
> +  // Minimum supported SMBIOS Table Revision
> +  EFI_SMBIOS_3_2_FIXED_SMBIOS_TABLE_REVISION,
> +  // SMBIOS Table Type
> +  // 0,
> +  // Build Table function
> +  NULL,
> +  // No additional resources are allocated by the generator.
> +  // Hence the Free Resource function is not required.
> +  NULL,
> +  // Build TableEx function
> +  BuildBasicTable,
> +  // Free ResouceEx function
> +  FreeBasicTable,
> +};
> +
> +/** Register the Generator with the SMBIOS Table Factory.
> +
> +  @param [in]  ImageHandle  The handle to the image.
> +  @param [in]  SystemTable  Pointer to the System Table.
> +
> +  @retval EFI_SUCCESS           The Generator is registered.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_ALREADY_STARTED   The Generator for the Table ID
> +                                is already registered.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmbiosBasicLibConstructor (
> +  IN  EFI_HANDLE           ImageHandle,
> +  IN  EFI_SYSTEM_TABLE  *  SystemTable
> +  )
> +{
> +  EFI_STATUS  Status;
> +  Status = RegisterSmbiosTableGenerator (&BasicGenerator);
> +  DEBUG ((DEBUG_INFO, "Basic: Register Generator. Status = %r\n", Status));
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> +
> +/** Deregister the Generator from the SMBIOS Table Factory.
> +
> +  @param [in]  ImageHandle  The handle to the image.
> +  @param [in]  SystemTable  Pointer to the System Table.
> +
> +  @retval EFI_SUCCESS           The Generator is deregistered.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_NOT_FOUND         The Generator is not registered.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmbiosBasicLibDestructor (
> +  IN  EFI_HANDLE           ImageHandle,
> +  IN  EFI_SYSTEM_TABLE  *  SystemTable
> +  )
> +{
> +  EFI_STATUS  Status;
> +  Status = DeregisterSmbiosTableGenerator (&BasicGenerator);
> +  DEBUG ((DEBUG_INFO, "Basic: Deregister Generator. Status = %r\n", Status));
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.h b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.h
> new file mode 100644
> index 0000000..edcd404
> --- /dev/null
> +++ b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.h
> @@ -0,0 +1,171 @@
> +/** @file
> +  Basic Generator of the required or recommended SMBIOS tables
> +
> +  Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
> +  Copyright (c) 2017 - 2020, ARM Limited. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +
> +#ifndef SMBIOS_BASIC_GENERATOR_H_
> +#define SMBIOS_BASIC_GENERATOR_H_
> +
> +#include "BasicObjects.h"
> +
> +
> +
> +EFI_STATUS
> +BuildSmbiosHandleTable (
> +  IN    UINTN             TableCount
> +  );
> +
> +VOID
> +FreeSmbiosHandleTable (
> +  VOID
> +  );
> +
> +UINTN
> +GetSmbiosSizeBaseboardInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject
> +  );
> +
> +UINTN
> +GetSmbiosSizeSystemEnclosure (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject
> +  );
> +
> +UINTN
> +GetSmbiosSizeSystemSlots (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject
> +  );
> +
> +UINTN
> +GetSmbiosSizeSystemEventLog (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosBiosInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosSystemInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosBaseboardInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosSystemEnclosure (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosProcessorInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosCacheInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosPortConnectorInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosSystemSlots (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosOemStrings (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosBiosLanguageInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosSystemEventLog (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosPhysicalMemoryArray (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosMemoryDevice (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosMemoryArrayMappedAddress (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosSystemBootInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosIpmiDeviceInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +EFI_STATUS
> +BuildSmbiosOnboardDevicesExtendedInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +#endif
> \ No newline at end of file

^

/
    Leif

> diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.c b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.c
> new file mode 100644
> index 0000000..3030527
> --- /dev/null
> +++ b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.c
> @@ -0,0 +1,1077 @@
> +/** @file
> +  Generator of the required or recommended SMBIOS table objects
> +
> +  Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
> +  Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Protocol/Smbios.h>
> +
> +// Module specific include files.
> +#include <SmbiosTableGenerator.h>
> +#include <ConfigurationManagerObject.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +
> +#include "BasicObjects.h"
> +
> +
> +/** A local data to retain the mapping from a reference token to a handle
> +**/
> +STATIC SMBIOS_OBJECT_HANDLE     mHandle;
> +
> +
> +/** Allocate a resource for a table to map a reference token to a handle
> +**/
> +EFI_STATUS
> +BuildSmbiosHandleTable (
> +  IN    UINTN           TableCount
> +  )
> +{
> +  if (TableCount != 0) {
> +    mHandle.Count = TableCount;
> +    mHandle.Base = 0x1000;
> +    // TODO: Get mHandle.Base from PCD

TODO:s are ok in an RFC, a patch should have none.

> +    if (((UINTN)mHandle.Base + mHandle.Count) >= (UINTN)SMBIOS_HANDLE_RESERVED_BEGIN) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    mHandle.Table = AllocateZeroPool (mHandle.Count * sizeof (SMBIOS_HANDLE_MAPPING));
> +    if (mHandle.Table == NULL) {
> +      DEBUG ((
> +        DEBUG_ERROR,
> +        "ERROR: Failed to allocate memory for %d SMBIOS HandleTable\n",
> +        mHandle.Count
> +        ));
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/** Free a resouce allocated for a mapping table of the reference token and the handle.
> +**/
> +VOID
> +FreeSmbiosHandleTable (
> +  VOID
> +  )
> +{
> +  if (mHandle.Table != NULL) {
> +    DEBUG ((DEBUG_ERROR, "Freeing SMBIOS handle table\n"));
> +    FreePool (mHandle.Table);
> +  }
> +}
> +
> +
> +/** Map a reference token to a handle.
> +**/
> +STATIC
> +SMBIOS_HANDLE
> +GetSmbiosHandle (
> +  CM_OBJECT_TOKEN         RefToken
> +)
> +{
> +  STATIC UINTN            IndexTop;
> +  UINTN                   Index;
> +  SMBIOS_HANDLE_MAPPING * Object;
> +
> +  Object = mHandle.Table;
> +  Index = 0;
> +
> +  if (RefToken == CM_OBJECT_TOKEN_NONE) {
> +    return SMBIOS_TABLE_MAX_LENGTH;
> +  } else if (RefToken == CM_OBJECT_TOKEN_NO_ERR_INFO) {
> +    return SMBIOS_HANDLE_PI_RESERVED;
> +  }
> +
> +  if (IndexTop == 0) {
> +    Object->RefToken = RefToken;
> +    Object->Handle = mHandle.Base;
> +    IndexTop++;
> +    mHandle.Base++;
> +
> +  } else if (IndexTop <= mHandle.Count) {
> +    while (Index < IndexTop) {
> +      if (Object->RefToken == RefToken) {
> +        goto assign_handle; // return (Object->Handle);
> +      }
> +      Object++;
> +      Index++;
> +    }
> +    if ((Index == IndexTop) && (IndexTop < mHandle.Count)) {
> +      Object->RefToken = RefToken;
> +      Object->Handle = mHandle.Base;
> +      IndexTop++;
> +      mHandle.Base++;
> +    } else {
> +      // This shouldn't happen
> +      DEBUG ((
> +        DEBUG_ERROR,
> +        "ERROR: SMBIOS HandleTable is Out of Range %d\n",
> +        mHandle.Count
> +        ));
> +      ASSERT (FALSE);
> +    }
> +  }
> +
> +assign_handle:
> +  DEBUG ((DEBUG_ERROR, "RefToken %p set to [%02x] %04x\n", RefToken, Index, Object->Handle));
> +  return (Object->Handle);
> +}
> +
> +
> +/** Copy a string from a given pointer to a space reserved for a string
> +  within a SMBIOS table and set SMBIOS_TABLE_STRING accordingly.
> +**/
> +STATIC
> +UINTN
> +SetSmbiosTableString (
> +  IN OUT  UINT8         * StrIndex,
> +  IN OUT  CHAR8        ** StringsOut,
> +  OUT     UINT8         * SmbiosStringIndex,
> +  IN      CONST CHAR8   * StringsIn
> +  )
> +{
> +  UINTN     Len = 0;
> +  UINT8     StrInx;
> +
> +  ASSERT (StrIndex != NULL);
> +  ASSERT (StringsOut != NULL);
> +  ASSERT (SmbiosStringIndex != NULL);
> +
> +  StrInx = *StrIndex;
> +  if (StringsIn != NULL) {
> +    Len = AsciiStrSize (StringsIn);
> +    AsciiStrCpyS (*StringsOut, Len, StringsIn);
> +    *StringsOut += Len;
> +    *SmbiosStringIndex = StrInx++;
> +    *StrIndex = StrInx;
> +  }
> +  return Len;
> +}
> +
> +/** Get the length of a variable data structure of Baseboard Info,
> +  SMBIOS type 2
> +**/
> +UINTN
> +GetSmbiosSizeBaseboardInfo (
> +  IN    UINT16             Revision,
> +  IN    VOID             * SrcObject
> +  )
> +{
> +  CM_SMBIOS_BASEBOARD_INFO  * Src;
> +
> +  ASSERT (SrcObject != NULL);
> +
> +  Src = SrcObject;
> +  if (Src->NumberOfContainedObjectHandles != 0) {
> +    ASSERT (Src->ContainedObjectHandles != 0);
> +  }
> +
> +  // This will leave one 16bit space blank
> +  return (Src->NumberOfContainedObjectHandles  * sizeof (SMBIOS_HANDLE));
> +}
> +
> +/** Get the length of a variable data structure of System Enclose,
> +  SMBIOS type 3
> +**/
> +UINTN
> +GetSmbiosSizeSystemEnclosure  (
> +  IN    UINT16             Revision,
> +  IN    VOID             * SrcObject
> +  )
> +{
> +  CM_SMBIOS_SYSTEM_ENCLOSURE  * Src;
> +  UINTN                         Len;
> +
> +  ASSERT (SrcObject != NULL);
> +
> +  Src = SrcObject;
> +  Len = sizeof (SMBIOS_TABLE_STRING); // String number for SKUNumber
> +
> +  if (Src->ContainedElementCount != 0) {
> +    ASSERT (Src->ContainedElements != NULL);
> +    ASSERT (Src->ContainedElementRecordLength == sizeof (CONTAINED_ELEMENT));
> +  }
> +
> +  return (Len + (Src->ContainedElementCount * sizeof (CONTAINED_ELEMENT)));
> +}
> +
> +/** Get the length of a variable data structure of System Slots,
> +  SMBIOS type 9
> +**/
> +UINTN
> +GetSmbiosSizeSystemSlots  (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject
> +  )
> +{
> +  CM_SMBIOS_SYSTEM_SLOTS    * Src;
> +  UINTN                       Len;
> +
> +  ASSERT (SrcObject != NULL);
> +
> +  Src = SrcObject;
> +  Len = 0;
> +
> +  if (Src->PeerGroupingCount != 0) {
> +    ASSERT (Src->PeerGroups != NULL);
> +  }
> +  if (Revision >= EFI_SMBIOS_3_4_FIXED_SMBIOS_TABLE_REVISION) {
> +    Len += 4; // SlotInfo (1) + SlotWidth (1) + SlotPitch (2)
> +  }
> +
> +  return (Len + (Src->PeerGroupingCount * sizeof (MISC_SLOT_PEER_GROUP)));
> +}
> +
> +/** Get the length of a variable data structure of System Event Log,
> +  SMBIOS type 15
> +**/
> +UINTN
> +GetSmbiosSizeSystemEventLog  (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject
> +  )
> +{
> +  CM_SMBIOS_SYSTEM_EVENT_LOG  * Src;
> +
> +  ASSERT (SrcObject != NULL);
> +
> +  Src = SrcObject;
> +  ASSERT (Src->LengthOfLogTypeDescriptor != sizeof (EVENT_LOG_TYPE));
> +  if (Src->NumberOfSupportedLogTypeDescriptors != 0) {
> +    ASSERT (Src->EventLogTypeDescriptors != NULL);
> +  }
> +
> +  return (Src->NumberOfSupportedLogTypeDescriptors + sizeof (EVENT_LOG_TYPE));
> +}
> +
> +
> +/** Set up the SMBIOS table of Bios Info,
> +  SMBIOS type 0
> +**/
> +EFI_STATUS
> +BuildSmbiosBiosInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_BIOS_INFO   * Src;
> +  SMBIOS_TABLE_TYPE0    * Dst;
> +  CHAR8                 * Strings;
> +  UINT8                   StrIndex;
> +  UINTN                   Len;
> +  UINT32                  BiosSize;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
> +
> +  Len = 0;
> +  StrIndex = 0;
> +  Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length;
> +  // Update the strings
> +  Len += SET_SMBIOS_TABLE_STRING (Vendor);
> +  Len += SET_SMBIOS_TABLE_STRING (BiosVersion);
> +  Len += SET_SMBIOS_TABLE_STRING (BiosReleaseDate);
> +
> +  Dst->BiosSegment = Src->BiosSegment;
> +
> +  // Src->BiosSize in 64KB granule
> +  // 8bit in 64KB, max 16MB
> +  // 14bit in 1MB, max 16GB
> +  // 14bit in 1GB, max 16TB
> +  if (Src->BiosSize < SIZE_16MB_BY_64KB) {
> +    Dst->BiosSize = (UINT8)Src->BiosSize;
> +    Dst->ExtendedBiosSize.Size = 0;
> +  } else if (Src->BiosSize < SIZE_16GB_BY_64KB) {
> +    SET_EXTENDED_BIOS_ROM_SIZE (Dst, Src, BiosSize, 1MB);
> +  } else {
> +    SET_EXTENDED_BIOS_ROM_SIZE (Dst, Src, BiosSize, 1GB);
> +  }
> +
> +  BiosSize = sizeof (Dst->BiosCharacteristics)
> +           + sizeof (Dst->BIOSCharacteristicsExtensionBytes) * 2;
> +  CopyMem (&Dst->BiosCharacteristics, &Src->BiosCharacteristics, BiosSize);
> +
> +  Dst->SystemBiosMajorRelease = GET_MAJOR_REV_NUM (Src->SystemBiosRelease);
> +  Dst->SystemBiosMinorRelease = GET_MINOR_REV_NUM (Src->SystemBiosRelease);
> +  Dst->EmbeddedControllerFirmwareMajorRelease =
> +                                GET_MAJOR_REV_NUM (Src->EmbeddedControllerFirmwareRelease);
> +  Dst->EmbeddedControllerFirmwareMinorRelease =
> +                                GET_MINOR_REV_NUM (Src->EmbeddedControllerFirmwareRelease);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** Set up the SMBIOS table of System Info,
> +  SMBIOS type 1
> +**/
> +EFI_STATUS
> +BuildSmbiosSystemInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_SYSTEM_INFO * Src;
> +  SMBIOS_TABLE_TYPE1    * Dst;
> +  CHAR8                 * Strings;
> +  UINT8                   StrIndex;
> +  UINTN                   Len;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
> +
> +  Len = 0;
> +  StrIndex = 0;
> +  Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length;
> +  // Update the strings
> +  Len += SET_SMBIOS_TABLE_STRING (Manufacturer);
> +  Len += SET_SMBIOS_TABLE_STRING (ProductName);
> +  Len += SET_SMBIOS_TABLE_STRING (Version);
> +  Len += SET_SMBIOS_TABLE_STRING (SerialNumber);
> +  Len += SET_SMBIOS_TABLE_STRING (SKUNumber);
> +  Len += SET_SMBIOS_TABLE_STRING (Family);
> +
> +  CopyMem (&Dst->Uuid, &Src->Uuid, sizeof (Dst->Uuid));
> +  Dst->WakeUpType = Src->WakeUpType;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** Set up the SMBIOS table of Baseboard Info,
> +  SMBIOS type 2
> +**/
> +EFI_STATUS
> +BuildSmbiosBaseboardInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_BASEBOARD_INFO  * Src;
> +  SMBIOS_TABLE_TYPE2    * Dst;
> +  CHAR8                 * Strings;
> +  UINT8                   StrIndex;
> +  UINTN                   Len;
> +  SMBIOS_HANDLE         * Handle;
> +  CM_OBJECT_TOKEN       * ContainedObjectHandles;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken);
> +
> +  Len = 0;
> +  StrIndex = 0;
> +  Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length;
> +  // Update the strings
> +  Len += SET_SMBIOS_TABLE_STRING (Manufacturer);
> +  Len += SET_SMBIOS_TABLE_STRING (ProductName);
> +  Len += SET_SMBIOS_TABLE_STRING (Version);
> +  Len += SET_SMBIOS_TABLE_STRING (SerialNumber);
> +  Len += SET_SMBIOS_TABLE_STRING (AssetTag);
> +  Len += SET_SMBIOS_TABLE_STRING (LocationInChassis);
> +
> +  CopyMem (&Dst->FeatureFlag, &Src->FeatureFlag, sizeof (Dst->FeatureFlag));
> +
> +  Dst->ChassisHandle = GetSmbiosHandle (Src->ChassisHandle);
> +  Dst->BoardType = Src->BoardType;
> +  Dst->NumberOfContainedObjectHandles = Src->NumberOfContainedObjectHandles;
> +
> +  Handle = Dst->ContainedObjectHandles;
> +  ContainedObjectHandles = (CM_OBJECT_TOKEN *)Src->ContainedObjectHandles;
> +  for (Len = 0; Len < Src->NumberOfContainedObjectHandles; Len++) {
> +    *Handle++ = GetSmbiosHandle (*ContainedObjectHandles++);
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/** Set up the SMBIOS table of System Enclure,
> +  SMBIOS type 3
> +**/
> +EFI_STATUS
> +BuildSmbiosSystemEnclosure (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_SYSTEM_ENCLOSURE  * Src;
> +  SMBIOS_TABLE_TYPE3          * Dst;
> +  SMBIOS_TABLE_STRING         * SKUNumber;
> +  CHAR8                       * Strings;
> +  UINT8                         StrIndex;
> +  UINTN                         Len;
> +  UINTN                         Size;
> +  CONTAINED_ELEMENT           * ContainedElements;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken);
> +
> +  SKUNumber = (SMBIOS_TABLE_STRING *)(DstObject + Dst->Hdr.Length - 1);
> +
> +  Len = 0;
> +  StrIndex = 0;
> +  Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length;
> +  // Update the strings
> +  Len = SET_SMBIOS_TABLE_STRING (Manufacturer);
> +  Len = SET_SMBIOS_TABLE_STRING (Version);
> +  Len = SET_SMBIOS_TABLE_STRING (SerialNumber);
> +  Len = SET_SMBIOS_TABLE_STRING (AssetTag);
> +  Len = SetSmbiosTableString (&StrIndex, &Strings, SKUNumber, Src->SKUNumber);
> +
> +  Dst->Type = Src->Type;
> +  Size = sizeof (Dst->BootupState)
> +       + sizeof (Dst->PowerSupplyState)
> +       + sizeof (Dst->ThermalState)
> +       + sizeof (Dst->SecurityStatus)
> +       + sizeof (Dst->OemDefined[0]) * 4
> +       + sizeof (Dst->Height)
> +       + sizeof (Dst->NumberofPowerCords)
> +       + sizeof (Dst->ContainedElementCount)
> +       + sizeof (Dst->ContainedElementRecordLength);
> +  CopyMem (&Dst->BootupState, &Src->BootupState, Size);
> +
> +  ContainedElements = Dst->ContainedElements;
> +  for (Len = 0; Len < Src->ContainedElementCount; Len++) {
> +    CopyMem (ContainedElements++, Src->ContainedElements++, sizeof (CONTAINED_ELEMENT));
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** Set up the SMBIOS table of Processor Info,
> +  SMBIOS type 4
> +**/
> +EFI_STATUS
> +BuildSmbiosProcessorInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_PROCESSOR_INFO  * Src;
> +  SMBIOS_TABLE_TYPE4        * Dst;
> +  CHAR8                     * Strings;
> +  UINT8                       StrIndex;
> +  UINTN                       Len;
> +  UINTN                       Size;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken);
> +
> +  Len = 0;
> +  StrIndex = 0;
> +  Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length;
> +  // Update the strings
> +  Len = SET_SMBIOS_TABLE_STRING (Socket);
> +  Len = SET_SMBIOS_TABLE_STRING (ProcessorManufacture);
> +  Len = SET_SMBIOS_TABLE_STRING (ProcessorVersion);
> +  Len = SET_SMBIOS_TABLE_STRING (SerialNumber);
> +  Len = SET_SMBIOS_TABLE_STRING (AssetTag);
> +  Len = SET_SMBIOS_TABLE_STRING (PartNumber);
> +
> +  Dst->ProcessorType = Src->ProcessorType;
> +  Dst->ProcessorFamily = Src->ProcessorFamily;
> +
> +  CopyMem (&Dst->ProcessorId, Src->ProcessorId, sizeof (Dst->ProcessorId));
> +
> +  Size = sizeof (Dst->Voltage)
> +       + sizeof (Dst->ExternalClock)
> +       + sizeof (Dst->MaxSpeed)
> +       + sizeof (Dst->CurrentSpeed)
> +       + sizeof (Dst->Status)
> +       + sizeof (Dst->ProcessorUpgrade);
> +  CopyMem (&Dst->Voltage, &Src->Voltage, Size);
> +
> +  Dst->L1CacheHandle = GetSmbiosHandle (Src->L1CacheHandle);
> +  Dst->L2CacheHandle = GetSmbiosHandle (Src->L2CacheHandle);
> +  Dst->L3CacheHandle = GetSmbiosHandle (Src->L3CacheHandle);
> +
> +  Size = sizeof (Dst->CoreCount)
> +       + sizeof (Dst->EnabledCoreCount)
> +       + sizeof (Dst->ThreadCount)
> +       + sizeof (Dst->ProcessorCharacteristics)
> +       + sizeof (Dst->ProcessorFamily2)
> +       + sizeof (Dst->CoreCount2)
> +       + sizeof (Dst->EnabledCoreCount2)
> +       + sizeof (Dst->ThreadCount2);
> +  CopyMem (&Dst->CoreCount, &Src->CoreCount, Size);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** Set up the SMBIOS table of Cache Info,
> +  SMBIOS type 7
> +**/
> +EFI_STATUS
> +BuildSmbiosCacheInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_CACHE_INFO  * Src;
> +  SMBIOS_TABLE_TYPE7    * Dst;
> +  CHAR8                 * Strings;
> +  UINT8                   StrIndex;
> +  UINTN                   Len;
> +  UINTN                   Size;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken);
> +
> +  Len = 0;
> +  StrIndex = 0;
> +  Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length;
> +  // Update the strings
> +  Len = SET_SMBIOS_TABLE_STRING (SocketDesignation);
> +
> +  Size = sizeof (Dst->CacheConfiguration)
> +       + sizeof (Dst->MaximumCacheSize)
> +       + sizeof (Dst->InstalledSize)
> +       + sizeof (Dst->SupportedSRAMType)
> +       + sizeof (Dst->CurrentSRAMType)
> +       + sizeof (Dst->CacheSpeed)
> +       + sizeof (Dst->ErrorCorrectionType)
> +       + sizeof (Dst->SystemCacheType)
> +       + sizeof (Dst->Associativity)
> +       + sizeof (Dst->MaximumCacheSize2)
> +       + sizeof (Dst->InstalledSize2);
> +  CopyMem (&Dst->CacheConfiguration, &Src->CacheConfiguration, Size);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** Set up the SMBIOS table of Port Connector Info,
> +  SMBIOS type 8
> +**/
> +EFI_STATUS
> +BuildSmbiosPortConnectorInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_PORT_CONNECTOR_INFO   * Src;
> +  SMBIOS_TABLE_TYPE8    * Dst;
> +  CHAR8                 * Strings;
> +  UINT8                   StrIndex;
> +  UINTN                   Len;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken);
> +
> +  Len = 0;
> +  StrIndex = 0;
> +  Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length;
> +  // Update the strings
> +  Len = SET_SMBIOS_TABLE_STRING (InternalReferenceDesignator);
> +  Len = SET_SMBIOS_TABLE_STRING (ExternalReferenceDesignator);
> +
> +  Dst->InternalConnectorType = Src->InternalConnectorType;
> +  Dst->ExternalConnectorType = Src->ExternalConnectorType;
> +  Dst->PortType = Src->PortType;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/** Set up the SMBIOS table of System Slots,
> +  SMBIOS type 9
> +**/
> +EFI_STATUS
> +BuildSmbiosSystemSlots (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_SYSTEM_SLOTS  * Src;
> +  SMBIOS_TABLE_TYPE9      * Dst;
> +  CHAR8                   * Strings;
> +  UINT8                     StrIndex;
> +  UINTN                     Len;
> +  UINTN                     Size;
> +  MISC_SLOT_PEER_GROUP    * PeerGroups;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken);
> +
> +  Len = 0;
> +  StrIndex = 0;
> +  Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length;
> +  // Update the strings
> +  Len = SET_SMBIOS_TABLE_STRING (SlotDesignation);
> +
> +  Size = sizeof (Dst->SlotType)
> +       + sizeof (Dst->SlotDataBusWidth)
> +       + sizeof (Dst->CurrentUsage)
> +       + sizeof (Dst->SlotLength)
> +       + sizeof (Dst->SlotID)
> +       + sizeof (Dst->SlotCharacteristics1)
> +       + sizeof (Dst->SlotCharacteristics2)
> +       + sizeof (Dst->SegmentGroupNum)
> +       + sizeof (Dst->BusNum)
> +       + sizeof (Dst->DevFuncNum)
> +       + sizeof (Dst->DataBusWidth)
> +       + sizeof (Dst->PeerGroupingCount);
> +  CopyMem (&Dst->SlotType, &Src->SlotType, Size);
> +
> +  PeerGroups = Dst->PeerGroups;
> +  for (Len = 0; Len < Src->PeerGroupingCount; Len++) {
> +    CopyMem (PeerGroups++,  Src->PeerGroups++, sizeof (MISC_SLOT_PEER_GROUP));
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/** Set up the SMBIOS table of OEM Strings,
> +  SMBIOS type 11
> +**/
> +EFI_STATUS
> +BuildSmbiosOemStrings (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_OEM_STRINGS   * Src;
> +  SMBIOS_TABLE_TYPE11     * Dst;
> +  CONST CHAR8             * StringSrc;
> +  CHAR8                   * Strings;
> +  UINT8                     StrIndex;
> +  UINTN                     Len;
> +  UINTN                     Index;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
> +
> +  Len = 0;
> +  StrIndex = 0;
> +  Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length;
> +
> +  Dst->StringCount = Src->StringCount;
> +  StringSrc = Src->Strings;
> +  // Update the strings
> +  for (Index = 0; Index < Src->StringCount; Index++) {
> +    Len = AsciiStrSize (StringSrc);
> +    CopyMem (Strings, StringSrc, Len);
> +    Strings += Len;
> +    StringSrc += Len;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** Set up the SMBIOS table of Bios Language Info,
> +  SMBIOS type 13
> +**/
> +EFI_STATUS
> +BuildSmbiosBiosLanguageInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_BIOS_LANGUAGE_INFO  * Src;
> +  SMBIOS_TABLE_TYPE13   * Dst;
> +  CONST CHAR8           * StringSrc;
> +  CHAR8                 * Strings;
> +  UINT8                   StrIndex;
> +  UINTN                   Len;
> +  UINTN                   Index;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
> +
> +  Len = 0;
> +  StrIndex = 0;
> +  Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length;
> +
> +  Dst->Flags = Src->Flags;
> +  Dst->CurrentLanguages = Src->CurrentLanguages;
> +  Dst->InstallableLanguages = Src->InstallableLanguages;
> +  StringSrc = Src->Languages;
> +  // Update the strings
> +  for (Index = 0; Index < Src->InstallableLanguages; Index++) {
> +    Len = AsciiStrSize (StringSrc);
> +    CopyMem (Strings, StringSrc, Len);
> +    Strings += Len;
> +    StringSrc += Len;
> +  }
> +
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** Set up the SMBIOS table of System Event Log,
> +  SMBIOS type 15
> +**/
> +EFI_STATUS
> +BuildSmbiosSystemEventLog (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_SYSTEM_EVENT_LOG  * Src;
> +  SMBIOS_TABLE_TYPE15         * Dst;
> +  UINTN                         Len;
> +  EVENT_LOG_TYPE              * EventLogTypeDescriptors;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
> +
> +  // No strings
> +  Len = Dst->Hdr.Length - sizeof (Dst->Hdr) - sizeof (EVENT_LOG_TYPE);
> +  CopyMem (&Dst->LogAreaLength, &Src->LogAreaLength, Len);
> +
> +  EventLogTypeDescriptors = Dst->EventLogTypeDescriptors;
> +  for (Len = 0; Len < Src->NumberOfSupportedLogTypeDescriptors; Len++) {
> +    CopyMem (EventLogTypeDescriptors++, Src->EventLogTypeDescriptors++, sizeof (EVENT_LOG_TYPE));
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** Set up the SMBIOS table of Physical Memory Array,
> +  SMBIOS type 16
> +**/
> +EFI_STATUS
> +BuildSmbiosPhysicalMemoryArray (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_PHYSICAL_MEMORY_ARRAY   * Src;
> +  SMBIOS_TABLE_TYPE16   * Dst;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken);
> +  // No strings
> +
> +  Dst->Location = Src->Location;
> +  Dst->Use = Src->Use;
> +  Dst->MemoryErrorCorrection = Src->MemoryErrorCorrection;
> +  Dst->NumberOfMemoryDevices = Src->NumberOfMemoryDevices;
> +
> +  // Use MaximumCapacity when less than 2TB
> +  if (Src->MaximumCapacity < 0x020000000000UL) {
> +    Dst->MaximumCapacity = (Src->MaximumCapacity >> 10);
> +    if (Src->MaximumCapacity & (BIT10 - 1)) {
> +      Dst->MaximumCapacity++;
> +    }
> +    Dst->ExtendedMaximumCapacity = 0;
> +  } else {
> +    Dst->MaximumCapacity = 0x80000000;
> +    Dst->ExtendedMaximumCapacity = Src->MaximumCapacity;
> +  }
> +
> +  Dst->MemoryErrorInformationHandle = GetSmbiosHandle (Src->MemoryErrorInformationHandle);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** Set up the SMBIOS table of Memory Device,
> +  SMBIOS type 17
> +**/
> +EFI_STATUS
> +BuildSmbiosMemoryDevice (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_MEMORY_DEVICE   * Src;
> +  SMBIOS_TABLE_TYPE17   * Dst;
> +  CHAR8                 * Strings;
> +  UINT8                   StrIndex;
> +  UINTN                   Len;
> +  UINTN                   Size;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken);
> +
> +  Len = 0;
> +  StrIndex = 0;
> +  Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length;
> +  // Update the strings
> +  Len += SET_SMBIOS_TABLE_STRING (DeviceLocator);
> +  Len += SET_SMBIOS_TABLE_STRING (BankLocator);
> +  Len += SET_SMBIOS_TABLE_STRING (Manufacturer);
> +  Len += SET_SMBIOS_TABLE_STRING (SerialNumber);
> +  Len += SET_SMBIOS_TABLE_STRING (AssetTag);
> +  Len += SET_SMBIOS_TABLE_STRING (PartNumber);
> +  Len += SET_SMBIOS_TABLE_STRING (FirwareVersion);
> +
> +  Dst->MemoryArrayHandle = GetSmbiosHandle (Src->MemoryArrayHandle);
> +  Dst->MemoryErrorInformationHandle = GetSmbiosHandle (Src->MemoryErrorInformationHandle);
> +
> +  Dst->TotalWidth = Src->TotalWidth;
> +  Dst->DataWidth = Src->DataWidth;
> +  Dst->FormFactor = Src->FormFactor;
> +  Dst->DeviceSet = Src->DeviceSet;
> +  Dst->Attributes = Src->Attributes;
> +
> +  if (Src->Size < 0x0200000UL) {
> +    // Less than 32MB, so it's in 1KB
> +    Dst->Size = (Src->Size >> 10) | BIT15;
> +    if (Src->Size & (BIT10 - 1)) {
> +      Dst->Size++;
> +    }
> +    Dst->ExtendedSize = 0;
> +  } else if (Src->Size < 0x800000000UL) {
> +    // Less than 32GB, so it's in 1MB
> +    Dst->Size = (Src->Size >> 20);
> +    if (Src->Size & (BIT20 - 1)) {
> +      Dst->Size++;
> +    }
> +    Dst->ExtendedSize = 0;
> +  } else {
> +    // Equal to or greater than 32GB, so it's in 1MB
> +    Dst->Size = 0x7FFF;
> +    Dst->ExtendedSize = (Src->Size >> 20);
> +    if (Src->Size & (BIT20 - 1)) {
> +      Dst->ExtendedSize++;
> +    }
> +    // No check of BIT31 as no way to get a device in PETA
> +  }
> +
> +  if (Src->Speed < 0x10000) {
> +    // Slower than 65,536 MT/s
> +    Dst->Speed = Src->Speed;
> +    Dst->ExtendedSpeed = 0;
> +  } else {
> +    Dst->Speed = 0xFFFF;
> +    Dst->ExtendedSpeed = Src->Speed;
> +  }
> +
> +  if (Src->ConfiguredMemorySpeed < 0x10000) {
> +    // Slower than 65,536 MT/s
> +    Dst->ConfiguredMemoryClockSpeed = Src->ConfiguredMemorySpeed;
> +    Dst->ExtendedConfiguredMemorySpeed = 0;
> +  } else {
> +    Dst->ConfiguredMemoryClockSpeed = 0xFFFF;
> +    Dst->ExtendedConfiguredMemorySpeed = Src->ConfiguredMemorySpeed;
> +  }
> +
> +  Size = sizeof (Dst->MemoryType)
> +       + sizeof (Dst->TypeDetail);
> +  CopyMem (&Dst->MemoryType, &Src->MemoryType, Size);
> +
> +  Size = sizeof (Dst->MinimumVoltage)
> +       + sizeof (Dst->MaximumVoltage)
> +       + sizeof (Dst->ConfiguredVoltage)
> +       + sizeof (Dst->MemoryTechnology)
> +       + sizeof (Dst->MemoryOperatingModeCapability);
> +  CopyMem (&Dst->MinimumVoltage, &Src->MinimumVoltage, Size);
> +
> +  Size = sizeof (Dst->ModuleManufacturerID)
> +       + sizeof (Dst->ModuleProductID)
> +       + sizeof (Dst->MemorySubsystemControllerManufacturerID)
> +       + sizeof (Dst->MemorySubsystemControllerProductID)
> +       + sizeof (Dst->NonVolatileSize)
> +       + sizeof (Dst->VolatileSize)
> +       + sizeof (Dst->CacheSize)
> +       + sizeof (Dst->LogicalSize);
> +  CopyMem (&Dst->ModuleManufacturerID, &Src->ModuleManufacturerID, Size);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** Set up the SMBIOS table of Memory Array Mapped Address,
> +  SMBIOS type 19
> +**/
> +EFI_STATUS
> +BuildSmbiosMemoryArrayMappedAddress (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS   * Src;
> +  SMBIOS_TABLE_TYPE19   * Dst;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken);
> +  // No strings
> +
> +  if ((Src->StartingAddress < 0x040000000000UL) &&
> +      (Src->EndingAddress < 0x040000000000UL)) {
> +    // Lower than 4TB, then it's in 1KB
> +    Dst->StartingAddress = (Src->StartingAddress >> 10);
> +    if (Src->StartingAddress & (BIT10 -1)) {
> +      Dst->StartingAddress++;
> +    }
> +    Dst->EndingAddress = (Src->EndingAddress >> 10);
> +    if (Src->EndingAddress & (BIT10 -1)) {
> +      Dst->EndingAddress++;
> +    }
> +    Dst->ExtendedStartingAddress = 0;
> +    Dst->ExtendedEndingAddress = 0;
> +  } else {
> +    Dst->StartingAddress = 0xFFFFFFFF;
> +    Dst->EndingAddress = 0xFFFFFFFF;
> +    Dst->ExtendedStartingAddress = Src->StartingAddress;
> +    Dst->ExtendedEndingAddress = Src->EndingAddress;
> +  }
> +
> +  Dst->PartitionWidth = Src->PartitionWidth;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** Set up the SMBIOS table of System Boot Info,
> +  SMBIOS type 32
> +**/
> +EFI_STATUS
> +BuildSmbiosSystemBootInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_SYSTEM_BOOT_INFO  * Src;
> +  SMBIOS_TABLE_TYPE32         * Dst;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
> +
> +  Dst->BootStatus = Src->BootStatus;
> +  return EFI_SUCCESS;
> +}
> +
> +/** Set up the SMBIOS table of Ipmi Device Info,
> +  SMBIOS type 38
> +**/
> +EFI_STATUS
> +BuildSmbiosIpmiDeviceInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_IPMI_DEVICE_INFO  * Src;
> +  SMBIOS_TABLE_TYPE38   * Dst;
> +  UINTN                   Len;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
> +
> +  // No strings
> +  Len = Dst->Hdr.Length - sizeof (Dst->Hdr);
> +  CopyMem (&Dst->InterfaceType, &Src->InterfaceType, Len);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** Set up the SMBIOS table of Onboard Devices Extended Info,
> +  SMBIOS type 41
> +**/
> +EFI_STATUS
> +BuildSmbiosOnboardDevicesExtendedInfo (
> +  IN    UINT16            Revision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  )
> +{
> +  CM_SMBIOS_ONBOARD_DEVICES_EXTENDED_INFO   * Src;
> +  SMBIOS_TABLE_TYPE41   * Dst;
> +  CHAR8                 * Strings;
> +  UINT8                   StrIndex;
> +  UINTN                   Len;
> +  UINTN                   Size;
> +
> +  ASSERT (SrcObject != NULL);
> +  ASSERT (DstObject != NULL);
> +
> +  Src = SrcObject;
> +  Dst = DstObject;
> +  Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
> +
> +  Len = 0;
> +  StrIndex = 0;
> +  Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length;
> +  // Update strings
> +  Len += SET_SMBIOS_TABLE_STRING (ReferenceDesignation);
> +
> +  Size = sizeof (Dst->DeviceType)
> +       + sizeof (Dst->DeviceTypeInstance)
> +       + sizeof (Dst->SegmentGroupNum)
> +       + sizeof (Dst->BusNum)
> +       + sizeof (Dst->DevFuncNum);
> +  CopyMem (&Dst->DeviceType, &Src->DeviceType, Size);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.h b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.h
> new file mode 100644
> index 0000000..835ff76
> --- /dev/null
> +++ b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.h
> @@ -0,0 +1,102 @@
> +/** @file
> +  Generator of basic SMBIOS tables
> +
> +  Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
> +  Copyright (c) 2017 - 2020, ARM Limited. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef SMBIOS_BASIC_OBJECTS_H_
> +#define SMBIOS_BASIC_OBJECTS_H_
> +
> +
> +typedef EFI_STATUS (*SMBIOS_BUILD_OBJECT) (
> +  IN    UINT16            TableRevision,
> +  IN    VOID            * SrcObject,
> +  OUT   VOID            * DstObject
> +  );
> +
> +
> +#pragma pack(1)
> +
> +typedef struct {
> +  ESMBIOS_OBJECT_ID         Id;
> +  UINT16                    Size;
> +  UINT16                    Count;
> +  VOID                    * Data;
> +} CM_OBJECT_TYPE_INFO;
> +
> +// Helpful information to calculate the size of a particular SMBIOS table
> +typedef struct {
> +  SMBIOS_TYPE               Type;
> +  UINT8                     Length;
> +  UINT8                     NumStrings;
> +} SMBIOS_OBJECT_TYPE_INFO;
> +
> +typedef struct {
> +  BOOLEAN                   IsMandatory;
> +  SMBIOS_OBJECT_TYPE_INFO   SmbiosObjectInfo;
> +  CM_OBJECT_TYPE_INFO       CmObjectInfo;
> +  SMBIOS_BUILD_OBJECT       BuildObject;
> +  CONST CHAR16            * Description;
> +} SMBIOS_OBJECT_INFO;
> +
> +
> +#define CREATE_SMBIOS_OBJECT_INFO(HdrType, Mandatory, StrCnt, ObjName)        \
> +{                                                                             \
> +  .IsMandatory = (BOOLEAN)Mandatory,                                          \
> +  .CmObjectInfo = {                                                           \
> +    .Id = ESmbiosObj##ObjName,                                                \
> +    .Size = (UINT16)sizeof (struct CmSmbios##ObjName),                        \
> +  },                                                                          \
> +  .SmbiosObjectInfo = {                                                       \
> +    .Type = (SMBIOS_TYPE)HdrType,                                             \
> +    .Length = (UINT8)sizeof (SMBIOS_TABLE_TYPE##HdrType),                     \
> +    .NumStrings = (UINT16)StrCnt,                                             \
> +  },                                                                          \
> +  .BuildObject = BuildSmbios##ObjName,                                        \
> +  .Description = L"Smbios" #ObjName , \
> +}
> +
> +typedef struct {
> +  CM_OBJECT_TOKEN           RefToken;
> +  SMBIOS_HANDLE             Handle;
> +} SMBIOS_HANDLE_MAPPING;
> +
> +typedef struct {
> +  SMBIOS_HANDLE_MAPPING   * Table;
> +  SMBIOS_HANDLE             Base;
> +  UINTN                     Count;
> +} SMBIOS_OBJECT_HANDLE;
> +
> +#pragma pack()
> +
> +
> +#define SHFT_1MB_BY_64KB    (20-16)
> +#define SHFT_1GB_BY_64KB    (30-16)
> +#define MASK_1MB_BY_64KB    ((1 << SHFT_1MB_BY_64KB) - 1)
> +#define MASK_1GB_BY_64KB    ((1 << SHFT_1GB_BY_64KB) - 1)
> +
> +#define SIZE_16MB_BY_64KB   (1 << (24-16))
> +#define SIZE_16GB_BY_64KB   (1 << (34-16))
> +#define SIZE_16TB_BY_64KB   (1 << (44-16))
> +
> +
> +#define SET_EXTENDED_BIOS_ROM_SIZE(Dst, Src, BiosSize, Granule)               \
> +{                                                                             \
> +  BiosSize = (Src->BiosSize >> SHFT_##Granule##_BY_64KB);                     \
> +  BiosSize = ((Src->BiosSize & MASK_##Granule##_BY_64KB) != 0) ?              \
> +             (BiosSize + 1): (BiosSize);                                      \
> +  Dst->BiosSize = 0xFF;                                                       \
> +  Dst->ExtendedBiosSize.Size = BiosSize;                                      \
> +  Dst->ExtendedBiosSize.Unit = EFI_SMBIOS_EXTENDED_BIOS_ROM_SIZE_IN_##Granule;\
> +}
> +
> +#define SET_SMBIOS_TABLE_STRING(Variable)   \
> +  SetSmbiosTableString (&StrIndex, &Strings, &Dst->Variable, Src->Variable)
> +
> +#define GET_MAJOR_REV_NUM(Revision)         ((Revision >> 8) & 0xFF)
> +#define GET_MINOR_REV_NUM(Revision)         (Revision & 0xFF)
> +
> +#endif // SMBIOS_BASIC_OBJECTS_H_
> diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/SmbiosBasicLib.inf b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/SmbiosBasicLib.inf
> new file mode 100644
> index 0000000..e5d7104
> --- /dev/null
> +++ b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/SmbiosBasicLib.inf
> @@ -0,0 +1,39 @@
> +## @file
> +#  Basic Table Generator
> +#
> +#  Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
> +#  Copyright (c) 2017 - 2020, ARM Limited. All rights reserved.
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> +  INF_VERSION    = 0x00010019
> +  BASE_NAME      = SmbiosBasicLib
> +  FILE_GUID      = aa8a7c50-2686-40b3-920a-af898a3213ad
> +  VERSION_STRING = 1.0
> +  MODULE_TYPE    = DXE_DRIVER
> +  LIBRARY_CLASS  = NULL|DXE_DRIVER
> +  CONSTRUCTOR    = SmbiosBasicLibConstructor
> +  DESTRUCTOR     = SmbiosBasicLibDestructor
> +
> +[Sources]
> +  BasicGenerator.c
> +  BasicObjects.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  DynamicTablesPkg/DynamicTablesPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  MemoryAllocationLib
> +
> +[Pcd]
> +
> +[Protocols]
> +
> +[Guids]
> +
> diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosRawLib/RawGenerator.c b/DynamicTablesPkg/Library/Smbios/SmbiosRawLib/RawGenerator.c
> new file mode 100644
> index 0000000..7551c3f
> --- /dev/null
> +++ b/DynamicTablesPkg/Library/Smbios/SmbiosRawLib/RawGenerator.c
> @@ -0,0 +1,136 @@
> +/** @file
> +  MCFG Table Generator
> +
> +  Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Protocol/Smbios.h>
> +
> +// Module specific include files.
> +#include <SmbiosTableGenerator.h>
> +#include <ConfigurationManagerObject.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +
> +/** Construct the SMBIOS table using the SMBIOS table data provided.
> +
> +  This function invokes the Configuration Manager protocol interface
> +  to get the required hardware information for generating the SMBIOS
> +  table.
> +
> +  If this function allocates any resources then they must be freed
> +  in the FreeXXXXTableResources function.
> +
> +  @param [in]  This           Pointer to the table generator.
> +  @param [in]  SmbiosTableInfo  Pointer to the SMBIOS Table Info.
> +  @param [in]  CfgMgrProtocol Pointer to the Configuration Manager
> +                              Protocol Interface.
> +  @param [out] Table          Pointer to the constructed SMBIOS Table.
> +
> +  @retval EFI_SUCCESS           Table generated successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +BuildRawTable (
> +  IN  CONST SMBIOS_TABLE_GENERATOR                  * CONST This,
> +  IN        CM_STD_OBJ_SMBIOS_TABLE_INFO            * CONST SmbiosTableInfo,
> +  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST CfgMgrProtocol,
> +  OUT       EFI_SMBIOS_TABLE_HEADER          ** CONST Table
> +  )
> +{
> +  ASSERT (This != NULL);
> +  ASSERT (SmbiosTableInfo != NULL);
> +  ASSERT (CfgMgrProtocol != NULL);
> +  ASSERT (Table != NULL);
> +  ASSERT (SmbiosTableInfo->TableGeneratorId == This->GeneratorID);
> +  ASSERT (SmbiosTableInfo->SmbiosTableData != NULL);
> +
> +  if (SmbiosTableInfo->SmbiosTableData == NULL) {
> +    *Table = NULL;
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *Table = SmbiosTableInfo->SmbiosTableData;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/** This macro defines the Raw Generator revision.
> +*/
> +#define RAW_GENERATOR_REVISION CREATE_REVISION (1, 0)
> +
> +/** The interface for the Raw Table Generator.
> +*/
> +STATIC
> +CONST
> +SMBIOS_TABLE_GENERATOR RawGenerator = {
> +  // Generator ID
> +  CREATE_STD_SMBIOS_TABLE_GEN_ID (EStdSmbiosTableIdRaw),
> +  // Generator Description
> +  L"SMBIOS.STD.RAW.GENERATOR",
> +  // SMBIOS Table Revision supported by this Generator
> +  0,
> +  // Minimum supported SMBIOS Table Revision
> +  0,
> +  // SMBIOS Table Type
> +  // 0,
> +  // Build Table function
> +  BuildRawTable,
> +  // No additional resources are allocated by the generator.
> +  // Hence the Free Resource function is not required.
> +  NULL,
> +  // Build TableEx function
> +  NULL,
> +  // Free Table ResourceEx
> +  NULL,
> +};
> +
> +/** Register the Generator with the SMBIOS Table Factory.
> +
> +  @param [in]  ImageHandle  The handle to the image.
> +  @param [in]  SystemTable  Pointer to the System Table.
> +
> +  @retval EFI_SUCCESS           The Generator is registered.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_ALREADY_STARTED   The Generator for the Table ID
> +                                is already registered.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmbiosRawLibConstructor (
> +  IN  EFI_HANDLE           ImageHandle,
> +  IN  EFI_SYSTEM_TABLE  *  SystemTable
> +  )
> +{
> +  EFI_STATUS  Status;
> +  Status = RegisterSmbiosTableGenerator (&RawGenerator);
> +  DEBUG ((DEBUG_INFO, "RAW: Register Generator. Status = %r\n", Status));
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> +
> +/** Deregister the Generator from the SMBIOS Table Factory.
> +
> +  @param [in]  ImageHandle  The handle to the image.
> +  @param [in]  SystemTable  Pointer to the System Table.
> +
> +  @retval EFI_SUCCESS           The Generator is deregistered.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_NOT_FOUND         The Generator is not registered.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmbiosRawLibDestructor (
> +  IN  EFI_HANDLE           ImageHandle,
> +  IN  EFI_SYSTEM_TABLE  *  SystemTable
> +  )
> +{
> +  EFI_STATUS  Status;
> +  Status = DeregisterSmbiosTableGenerator (&RawGenerator);
> +  DEBUG ((DEBUG_INFO, "RAW: Deregister Generator. Status = %r\n", Status));
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosRawLib/SmbiosRawLib.inf b/DynamicTablesPkg/Library/Smbios/SmbiosRawLib/SmbiosRawLib.inf
> new file mode 100644
> index 0000000..2350d09
> --- /dev/null
> +++ b/DynamicTablesPkg/Library/Smbios/SmbiosRawLib/SmbiosRawLib.inf
> @@ -0,0 +1,36 @@
> +## @file
> +#  Raw Table Generator
> +#
> +#  Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> +  INF_VERSION    = 0x00010019
> +  BASE_NAME      = SmbiosRawLib
> +  FILE_GUID      = a6a0a14e-9de7-40a1-b97b-06ee0a992b3c
> +  VERSION_STRING = 1.0
> +  MODULE_TYPE    = DXE_DRIVER
> +  LIBRARY_CLASS  = NULL|DXE_DRIVER
> +  CONSTRUCTOR    = SmbiosRawLibConstructor
> +  DESTRUCTOR     = SmbiosRawLibDestructor
> +
> +[Sources]
> +  RawGenerator.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  DynamicTablesPkg/DynamicTablesPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +
> +[Pcd]
> +
> +[Protocols]
> +
> +[Guids]
> +
> -- 
> 2.7.4
> 
> 
> 
> 
> 
> 


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67187): https://edk2.groups.io/g/devel/message/67187
Mute This Topic: https://groups.io/mt/78072444/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list