public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH] DynamicTablesPkg: Add library for SMBIOS table generation
@ 2020-11-06 12:27 Irene Park
  2020-11-06 12:33 ` Irene Park
  2020-11-09 16:27 ` [edk2-devel] " Leif Lindholm
  0 siblings, 2 replies; 4+ messages in thread
From: Irene Park @ 2020-11-06 12:27 UTC (permalink / raw)
  To: devel; +Cc: Irene Park

From: Irene Park <ipark@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@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) {
+    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;
+
+///
+/// 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                  
 } 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;
 
   /// 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 (
+  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
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
+    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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] DynamicTablesPkg: Add library for SMBIOS table generation
  2020-11-06 12:27 [PATCH] DynamicTablesPkg: Add library for SMBIOS table generation Irene Park
@ 2020-11-06 12:33 ` Irene Park
  2020-11-06 13:16   ` Sami Mujawar
  2020-11-09 16:27 ` [edk2-devel] " Leif Lindholm
  1 sibling, 1 reply; 4+ messages in thread
From: Irene Park @ 2020-11-06 12:33 UTC (permalink / raw)
  To: devel@edk2.groups.io, Sami Mujawar

Hi Sami,
Would you please review the concept of this patch?
I'll update this patch with full comments later.
Thank you,
Irene

-----Original Message-----
From: Irene Park <ipark@nvidia.com> 
Sent: Friday, November 6, 2020 7:28 AM
To: devel@edk2.groups.io
Cc: Irene Park <ipark@nvidia.com>
Subject: [PATCH] DynamicTablesPkg: Add library for SMBIOS table generation

From: Irene Park <ipark@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@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) {
+    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;
+
+///
+/// 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                  
 } 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;
 
   /// 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 (
+  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
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
+    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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] DynamicTablesPkg: Add library for SMBIOS table generation
  2020-11-06 12:33 ` Irene Park
@ 2020-11-06 13:16   ` Sami Mujawar
  0 siblings, 0 replies; 4+ messages in thread
From: Sami Mujawar @ 2020-11-06 13:16 UTC (permalink / raw)
  To: Irene Park, devel@edk2.groups.io; +Cc: Matteo Carlini, Alexei Fedorov, nd

Hi Irene,

Thank you for this patch. 

Can you share your Github branch with this patch, please? That way it is easier for me to review.
Also, do you have the corresponding platform specific patches (that add SMBIOS Objects to Configuration Manager)?

Regards,

Sami Mujawar

-----Original Message-----
From: Irene Park <ipark@nvidia.com> 
Sent: 06 November 2020 12:33 PM
To: devel@edk2.groups.io; Sami Mujawar <Sami.Mujawar@arm.com>
Subject: RE: [PATCH] DynamicTablesPkg: Add library for SMBIOS table generation

Hi Sami,
Would you please review the concept of this patch?
I'll update this patch with full comments later.
Thank you,
Irene

-----Original Message-----
From: Irene Park <ipark@nvidia.com> 
Sent: Friday, November 6, 2020 7:28 AM
To: devel@edk2.groups.io
Cc: Irene Park <ipark@nvidia.com>
Subject: [PATCH] DynamicTablesPkg: Add library for SMBIOS table generation

From: Irene Park <ipark@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@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) {
+    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;
+
+///
+/// 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                  
 } 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;
 
   /// 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 (
+  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
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
+    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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [edk2-devel] [PATCH] DynamicTablesPkg: Add library for SMBIOS table generation
  2020-11-06 12:27 [PATCH] DynamicTablesPkg: Add library for SMBIOS table generation Irene Park
  2020-11-06 12:33 ` Irene Park
@ 2020-11-09 16:27 ` Leif Lindholm
  1 sibling, 0 replies; 4+ messages in thread
From: Leif Lindholm @ 2020-11-09 16:27 UTC (permalink / raw)
  To: devel, ipark; +Cc: sami.mujawar

On Fri, Nov 06, 2020 at 07:27:31 -0500, Irene Park wrote:
> From: Irene Park <ipark@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@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
> 
> 
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-11-09 16:28 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-11-06 12:27 [PATCH] DynamicTablesPkg: Add library for SMBIOS table generation Irene Park
2020-11-06 12:33 ` Irene Park
2020-11-06 13:16   ` Sami Mujawar
2020-11-09 16:27 ` [edk2-devel] " Leif Lindholm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox