[edk2-devel] [edk2-platforms][PATCH 19/34] JadePkg: Add SMBIOS tables support

Nhi Pham via groups.io nhi=os.amperecomputing.com at groups.io
Wed Dec 9 09:25:16 UTC 2020


From: Quan Nguyen <quan at os.amperecomputing.com>

This supports various SMBIOS tables type 0, 1, 2, 3, 4, 7, 8, 9, 11,
13, 16, 17, 19, 24 and 32.

SMBIOS Type 1, 2 and 3 are hardcoded as Host-BMC communication is not
supported yet. And, this module does not support fixup tables to reflect
changes of the system at booting time.

Signed-off-by: Quan Nguyen <quan at os.amperecomputing.com>
---
 Silicon/Ampere/AmperePkg.dec                                            |   17 +
 Platform/Ampere/JadePkg/Jade.dsc                                        |   23 +
 Platform/Ampere/JadePkg/Jade.fdf                                        |    8 +
 Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf           |   42 +
 Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf   |   42 +
 Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf |   59 ++
 Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c             |  694 +++++++++++++
 Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c     |  664 +++++++++++++
 Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c   | 1037 ++++++++++++++++++++
 9 files changed, 2586 insertions(+)

diff --git a/Silicon/Ampere/AmperePkg.dec b/Silicon/Ampere/AmperePkg.dec
index 2f349845d7de..832e9d812dba 100755
--- a/Silicon/Ampere/AmperePkg.dec
+++ b/Silicon/Ampere/AmperePkg.dec
@@ -82,3 +82,20 @@ [PcdsFixedAtBuild, PcdsDynamic]
   gAmpereTokenSpaceGuid.PcdFvMainCoreBaseAddress|0|UINT64|0xA0000002
   gAmpereTokenSpaceGuid.PcdFvMainCoreSize|0|UINT32|0xA0000003
   gAmpereTokenSpaceGuid.PcdFvBlockSize|0x00040000|UINT32|0xA0000004
+
+[PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx]
+  #
+  # SMBIOS, default or template values
+  #
+  # SMBIOS Type 0 - BIOS Information
+  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosVendor|"Ampere Computing"|VOID*|0xB0000000
+  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosVersion|"TianoCore EDKII"|VOID*|0xB0000001
+  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate|"MM/DD/YYYY"|VOID*|0xB0000002 # Must follow this MM/DD/YYYY SMBIOS date format
+
+  # SMBIOS Type 1 - System Information
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemManufacturer|"Ampere Computing"|VOID*|0xB0000003
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemProductName|"Mt Jade"|VOID*|0xB0000004
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemVersion|"0.0"|VOID*|0xB0000005
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemSerialNumber|"1234-5678-9ABC-DEFF"|VOID*|0xB0000006
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1Uuid|"FEDCBA9876543210"|VOID*|0xB0000007
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemSkuNumber|"12345678"|VOID*|0xB0000008
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index ce0127e27f6d..bb141cddcc39 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -90,6 +90,9 @@ [PcdsFixedAtBuild]
 !endif
 
 [PcdsFixedAtBuild.common]
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1MajorVersion|$(MAJOR_VER)
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1MinorVersion|$(MINOR_VER)
+
 !if $(SECURE_BOOT_ENABLE) == TRUE
   # Override the default values from SecurityPkg to ensure images
   # from all sources are verified in secure boot
@@ -98,6 +101,19 @@ [PcdsFixedAtBuild.common]
   gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
 !endif
 
+[PcdsDynamicDefault.common.DEFAULT]
+  # SMBIOS Type 0 - BIOS Information
+  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosVendor|"Ampere Computing"
+  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosVersion|"TianoCore EDKII"
+  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate|"MM/DD/YYYY"
+
+  # SMBIOS Type 1 - System Information
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemManufacturer|"Ampere Computing"
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemProductName|"Mt Jade"
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemVersion|"0.3"
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemSerialNumber|"0123-4567-89AB-CDEF"
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemSkuNumber|"01234567"
+
 [PcdsPatchableInModule]
   #
   # Console Resolution (HD mode)
@@ -130,3 +146,10 @@ [Components.common]
   # VGA ASpeed
   #
   Drivers/ASpeed/ASpeedGopBinPkg/ASpeedAst2500GopDxe.inf
+
+  # SMBIOS
+  #
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+  Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
+  Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index 100d5bf6f80c..bc618c2c6805 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -357,4 +357,12 @@ [FV.FvMain]
   INF Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
   INF RuleOverride=ACPITABLE Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
 
+  #
+  # SMBIOS
+  #
+  INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  INF Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+  INF Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
+  INF Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
+
 !include Platform/Ampere/FvRules.fdf.inc
diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
new file mode 100644
index 000000000000..32553b62cc9f
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = SmbiosCpuDxe
+  FILE_GUID                      = 4DD7C2E4-E6A6-11EA-8736-D3C56ABBB5C4
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmbiosCpuDxeEntry
+
+[Sources]
+  SmbiosCpuDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPkg/ArmPkg.dec
+  Silicon/Ampere/AmperePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/Ac01Pkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  DebugLib
+  BaseLib
+  UefiLib
+  ArmLib
+  MemoryAllocationLib
+  BaseMemoryLib
+  HobLib
+  AmpereCpuLib
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                     ## CONSUMED
+
+[Depex]
+  gEfiSmbiosProtocolGuid
diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
new file mode 100644
index 000000000000..68c692f99913
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = SmbiosMemInfoDxe
+  FILE_GUID                      = ECF38190-EBF8-11EA-B646-830715BDF83A
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmbiosMemInfoDxeEntry
+
+[Sources]
+  SmbiosMemInfoDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPkg/ArmPkg.dec
+  Silicon/Ampere/AmperePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/Ac01Pkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  DebugLib
+  BaseLib
+  UefiLib
+  ArmLib
+  MemoryAllocationLib
+  BaseMemoryLib
+  HobLib
+  AmpereCpuLib
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                     ## CONSUMED
+
+[Depex]
+  gEfiSmbiosProtocolGuid
diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
new file mode 100755
index 000000000000..2789675e1266
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
@@ -0,0 +1,59 @@
+## @file
+#
+# Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = SmbiosPlatformDxe
+  FILE_GUID                      = F0CC7D0B-CD83-4DDA-A5D4-613AB02D4E52
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmbiosPlatformDxeEntry
+
+[Sources]
+  SmbiosPlatformDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPkg/ArmPkg.dec
+  Silicon/Ampere/AmperePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/Ac01Pkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  DebugLib
+  BaseLib
+  UefiLib
+  MemoryAllocationLib
+  BaseMemoryLib
+  HobLib
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                     ## CONSUMED
+
+[Pcd]
+  # Type 0
+  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosVendor
+  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosVersion
+  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+  gArmTokenSpaceGuid.PcdFdSize
+
+  # Type 1
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemManufacturer
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemProductName
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemVersion
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemSerialNumber
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1Uuid
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1SystemSkuNumber
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1MajorVersion
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1MinorVersion
+
+[Depex]
+  gEfiSmbiosProtocolGuid
diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c
new file mode 100644
index 000000000000..fecd80aa308b
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c
@@ -0,0 +1,694 @@
+/** @file
+
+  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/ArmLib.h>
+#include <Library/HobLib.h>
+#include <Library/AmpereCpuLib.h>
+#include <Guid/SmBios.h>
+#include <Protocol/Smbios.h>
+#include <PlatformInfoHob.h>
+
+#define CPU_CACHE_LEVEL_MAX 3
+
+#define MHZ_SCALE_FACTOR 1000000
+
+#define CACHE_SIZE(x)   (UINT16) (0x8000 | (x) >> 16)
+#define CACHE_SIZE_2(x) (0x80000000 | (x) >> 16)
+
+#define TYPE4_ADDITIONAL_STRINGS                                  \
+  "SOCKET 0\0"                       /* socket type */            \
+  "Ampere Computing\0"               /* manufacturer */           \
+  "Ampere(TM) Altra(TM) Processor\0" /* processor description */  \
+  "NotSet\0"                         /* part number */
+
+#define TYPE7_ADDITIONAL_STRINGS                                  \
+  "L1 Cache\0"                       /* L1 Cache  */
+
+//
+// Type definition and contents of the default SMBIOS table.
+// This table covers only the minimum structures required by
+// the SMBIOS specification (section 6.2, version 3.0)
+//
+#pragma pack(1)
+typedef struct {
+  SMBIOS_TABLE_TYPE4 Base;
+  CHAR8              Strings[sizeof(TYPE4_ADDITIONAL_STRINGS)];
+} ARM_TYPE4;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE7 Base;
+  CHAR8              Strings[sizeof(TYPE7_ADDITIONAL_STRINGS)];
+} ARM_TYPE7;
+
+#pragma pack()
+//-------------------------------------
+//        SMBIOS Platform Common
+//-------------------------------------
+enum {
+  ADDITIONAL_STR_INDEX_1 = 1,
+  ADDITIONAL_STR_INDEX_2,
+  ADDITIONAL_STR_INDEX_3,
+  ADDITIONAL_STR_INDEX_4,
+  ADDITIONAL_STR_INDEX_5,
+  ADDITIONAL_STR_INDEX_6,
+  ADDITIONAL_STR_INDEX_7,
+  ADDITIONAL_STR_INDEX_8,
+  ADDITIONAL_STR_INDEX_9,
+  ADDITIONAL_STR_INDEX_MAX
+};
+
+// Type 4 Processor Socket 0
+STATIC ARM_TYPE4 mArmDefaultType4Sk0 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE4),           // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1, //socket type
+    3,                      //processor type CPU
+    ProcessorFamilyIndicatorFamily2, //processor family, acquire from field2
+    ADDITIONAL_STR_INDEX_2, //manufacturer
+    {{0,},{0.}},            //processor id
+    ADDITIONAL_STR_INDEX_3, //version
+    {0,0,0,0,0,1},          //voltage
+    0,                      //external clock
+    3000,                   //max speed
+    3000,                   //current speed
+    0x41,                   //status
+    ProcessorUpgradeOther,
+    0xFFFF,                 //l1 cache handle
+    0xFFFF,                 //l2 cache handle
+    0xFFFF,                 //l3 cache handle
+    0,                      //serial not set
+    0,                      //asset not set
+    ADDITIONAL_STR_INDEX_4, //part number
+    80,                     //core count in socket
+    80,                     //enabled core count in socket
+    0,                      //threads per socket
+    0xEC,                   // processor characteristics
+    ProcessorFamilyARMv8,   //ARM core
+  },
+  TYPE4_ADDITIONAL_STRINGS
+};
+
+// Type 4 Processor Socket 1
+STATIC ARM_TYPE4 mArmDefaultType4Sk1 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE4),           // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1, //socket type
+    3,                      //processor type CPU
+    ProcessorFamilyIndicatorFamily2, //processor family, acquire from field2
+    ADDITIONAL_STR_INDEX_2, //manufacturer
+    {{0,},{0.}},            //processor id
+    ADDITIONAL_STR_INDEX_3, //version
+    {0,0,0,0,0,1},          //voltage
+    0,                      //external clock
+    3000,                   //max speed
+    3000,                   //current speed
+    0x41,                   //status
+    ProcessorUpgradeOther,
+    0xFFFF,                 //l1 cache handle
+    0xFFFF,                 //l2 cache handle
+    0xFFFF,                 //l3 cache handle
+    0,                      //serial not set
+    0,                      //asset not set
+    ADDITIONAL_STR_INDEX_4, //part number
+    80,                     //core count in socket
+    80,                     //enabled core count in socket
+    0,                      //threads per socket
+    0xEC,                   // processor characteristics
+    ProcessorFamilyARMv8,   //ARM core
+  },
+  TYPE4_ADDITIONAL_STRINGS
+};
+
+// Type 7 Cache Information
+STATIC ARM_TYPE7 mArmDefaultType7Sk0L1 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    0x180,              //L1 enabled, Write Back
+    0x8001,             //64k i cache max
+    0x8001,             //64k installed
+    {0, 0, 0, 0, 0, 1}, //SRAM type
+    {0, 0, 0, 0, 0, 1}, //SRAM type
+    0,                  //unkown speed
+    CacheErrorParity,   //parity checking
+    CacheTypeUnified,   //Unified cache
+    CacheAssociativity4Way, // 4-way
+  },
+  "L1 Cache\0"
+};
+
+// Type 7 Cache Information
+STATIC ARM_TYPE7 mArmDefaultType7Sk0L2 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    0x181,              //L2 enabled, Write Back
+    0x8010,             //1M cache max
+    0x8010,             //1M installed
+    {0, 0, 0, 0, 0, 1}, //SRAM type
+    {0, 0, 0, 0, 0, 1}, //SRAM type
+    0,                  //unkown speed
+    CacheErrorSingleBit,//single bit ECC
+    CacheTypeUnified,   //Unified cache
+    CacheAssociativity8Way, //8-way
+  },
+  "L2 Cache\0"
+};
+
+// Type 7 Cache Information
+STATIC ARM_TYPE7 mArmDefaultType7Sk0L3 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    0x182,              //L3 enabled, Write Back
+    0x8200,             //32M cache max
+    0x8200,             //32M installed
+    {0, 0, 0, 0, 0, 1}, //SRAM type
+    {0, 0, 0, 0, 0, 1}, //SRAM type
+    0,                  //unkown speed
+    CacheErrorParity,   //parity checking
+    CacheTypeUnified,   //Unified cache
+    CacheAssociativity32Way, // 32-way
+  },
+  "L3 Cache\0"
+};
+
+// Type 7 Cache Information
+STATIC ARM_TYPE7 mArmDefaultType7Sk1L1 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    0x180,             //L1 enabled, Write Back
+    0x8001,            //64k i cache max
+    0x8001,            //64k installed
+    {0, 0, 0, 0, 0, 1},//SRAM type
+    {0, 0, 0, 0, 0, 1},//SRAM type
+    0,                 //unkown speed
+    CacheErrorParity,  //parity checking
+    CacheTypeUnified,  //Unified cache
+    CacheAssociativity4Way, //4-way
+  },
+  "L1 Cache\0"
+};
+
+// Type 7 Cache Information
+STATIC ARM_TYPE7 mArmDefaultType7Sk1L2 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    0x181,              //L2 enabled, Write Back
+    0x8010,             //1M cache max
+    0x8010,             //1M installed
+    {0, 0, 0, 0, 0, 1}, //SRAM type
+    {0, 0, 0, 0, 0, 1}, //SRAM type
+    0,                  //unkown speed
+    CacheErrorSingleBit,//single bit ECC
+    CacheTypeUnified,   //Unified cache
+    CacheAssociativity8Way, //8-way
+  },
+  "L2 Cache\0"
+};
+
+// Type 7 Cache Information
+STATIC ARM_TYPE7 mArmDefaultType7Sk1L3 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    0x182,              //L3 enabled, Write Back
+    0x8200,             //32M cache max
+    0x8200,             //32M installed
+    {0, 0, 0, 0, 0, 1}, //SRAM type
+    {0, 0, 0, 0, 0, 1}, //SRAM type
+    0,                  //unkown speed
+    CacheErrorParity,   //parity checking
+    CacheTypeUnified,   //Unified cache
+    CacheAssociativity32Way, // 32-way
+  },
+  "L3 Cache\0"
+};
+
+STATIC CONST VOID* DefaultCommonTables[] =
+{
+  &mArmDefaultType4Sk0,
+  &mArmDefaultType4Sk1,
+  NULL
+};
+
+STATIC CONST VOID* DefaultType7Sk0Tables[] =
+{
+  &mArmDefaultType7Sk0L1,
+  &mArmDefaultType7Sk0L2,
+  &mArmDefaultType7Sk0L3,
+  NULL
+};
+
+STATIC CONST VOID* DefaultType7Sk1Tables[] =
+{
+  &mArmDefaultType7Sk1L1,
+  &mArmDefaultType7Sk1L2,
+  &mArmDefaultType7Sk1L3,
+  NULL
+};
+
+STATIC
+UINT32
+GetCacheConfig (
+  UINTN Level
+  )
+{
+  UINT64 Val;
+  BOOLEAN SupportWB;
+  BOOLEAN SupportWT;
+
+  Val = AArch64ReadCCSIDRReg (Level);
+  SupportWT = (Val & (1 << 31)) ? TRUE : FALSE;
+  SupportWB = (Val & (1 << 30)) ? TRUE : FALSE;
+  if (SupportWT && SupportWB) {
+    return 2; /* Varies with Memory Address */
+  }
+
+  if (SupportWT) {
+    return 0;
+  }
+
+  return 1; /* WB */
+}
+
+STATIC
+UINTN
+GetStringPackSize (
+  CHAR8 *StringPack
+  )
+{
+  UINTN     StrCount;
+  CHAR8     *StrStart;
+
+  if ((*StringPack == 0) && (*(StringPack + 1) == 0)) {
+    return 0;
+  }
+
+  // String section ends in double-null (0000h)
+  for (StrCount = 0, StrStart = StringPack;
+        ((*StrStart != 0) || (*(StrStart + 1) != 0)); StrStart++, StrCount++) {};
+
+  return StrCount + 2; // Included the double NULL
+}
+
+// Update String at String number to String Pack
+EFI_STATUS
+UpdateStringPack (
+  CHAR8             *StringPack,
+  CHAR8             *String,
+  UINTN             StringNumber
+  )
+{
+  CHAR8                     *StrStart;
+  UINTN                     StrIndex;
+  UINTN                     InputStrLen;
+  UINTN                     TargetStrLen;
+  UINTN                     BufferSize;
+  CHAR8                     *Buffer;
+
+  StrStart = StringPack;
+  for (StrIndex = 1; StrIndex < StringNumber; StrStart++) {
+    // A string ends in 00h
+    if (*StrStart == 0) {
+      StrIndex++;
+    }
+    // String section ends in double-null (0000h)
+    if ((*StrStart == 0) && (*(StrStart + 1) == 0)) {
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  if (*StrStart == 0) {
+    StrStart++;
+  }
+
+  InputStrLen = AsciiStrLen (String);
+  TargetStrLen = AsciiStrLen (StrStart);
+  BufferSize = GetStringPackSize (StrStart + TargetStrLen + 1);
+
+  // Replace the String if length matched
+  // OR this is the last string
+  if (InputStrLen == TargetStrLen || (BufferSize == 0)) {
+    CopyMem (StrStart, String, InputStrLen);
+  }
+  // Otherwise, buffer is needed to apply new string
+  else {
+    Buffer = AllocateZeroPool (BufferSize);
+    if (Buffer == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    CopyMem (Buffer, StrStart + TargetStrLen + 1, BufferSize);
+    CopyMem (StrStart, String, InputStrLen + 1);
+    CopyMem (StrStart + InputStrLen + 1, Buffer, BufferSize);
+
+    FreePool (Buffer);
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+UpdateSmbiosType4 (
+  PlatformInfoHob_V2 *PlatformHob
+  )
+{
+  UINTN                       Index;
+  CHAR8                       Str[40];
+  CHAR8                       *StringPack;
+  SMBIOS_TABLE_TYPE4          *Table;
+
+  ASSERT (PlatformHob != NULL);
+
+  for (Index = 0; Index < GetNumberSupportedSockets (); Index++) {
+    if (Index == 0) {
+      Table = &mArmDefaultType4Sk0.Base;
+      StringPack = mArmDefaultType4Sk0.Strings;
+    } else {
+      Table = &mArmDefaultType4Sk1.Base;
+      StringPack = mArmDefaultType4Sk1.Strings;
+    }
+
+    AsciiSPrint (Str, sizeof (Str), "CPU %d", Index);
+    UpdateStringPack (StringPack, Str, ADDITIONAL_STR_INDEX_1);
+
+    Table->CoreCount = (UINT16) GetMaximumNumberOfCores ();
+    Table->ThreadCount = (UINT16) GetMaximumNumberOfCores ();
+    Table->EnabledCoreCount = (UINT16) (GetNumberActiveCoresPerSocket (Index));
+
+    if (Table->EnabledCoreCount) {
+      Table->CurrentSpeed = (UINT16) (PlatformHob->CpuClk / MHZ_SCALE_FACTOR);
+      Table->ExternalClock = (UINT16) (PlatformHob->PcpClk / MHZ_SCALE_FACTOR);
+      Table->MaxSpeed = (UINT16) (PlatformHob->CpuClk / MHZ_SCALE_FACTOR);
+      if (PlatformHob->TurboCapability[Index]) {
+        Table->MaxSpeed = (UINT16) (PlatformHob->TurboFrequency[Index]);
+      }
+    } else {
+      Table->CurrentSpeed = 0;
+      Table->ExternalClock = 0;
+      Table->MaxSpeed = 0;
+      Table->Status = 0;
+    }
+
+    *((UINT32*) &Table->ProcessorId) = (UINT32) ArmReadMidr ();
+    *((UINT32*) &Table->ProcessorId + 1) = 0;
+    *((UINT8*) &Table->Voltage) = 0x80 | PlatformHob->CoreVoltage[Index] / 100;
+
+    /* Type 4 Part number */
+    if (Table->EnabledCoreCount) {
+      if ((PlatformHob->ScuProductId[Index] & 0xff) == 0x01) {
+        AsciiSPrint (Str, sizeof (Str), "Q%02d-%02X",
+          PlatformHob->SkuMaxCore[Index], PlatformHob->SkuMaxTurbo[Index]);
+      }
+      else {
+        AsciiSPrint (Str, sizeof (Str), "M%02d%02X",
+          PlatformHob->SkuMaxCore[Index], PlatformHob->SkuMaxTurbo[Index]);
+      }
+
+    UpdateStringPack (StringPack, Str, ADDITIONAL_STR_INDEX_4);
+    }
+  }
+}
+
+STATIC
+VOID
+UpdateSmbiosType7 (
+  PlatformInfoHob_V2 *PlatformHob
+  )
+{
+  UINTN                       Index;
+  SMBIOS_TABLE_TYPE7          *Table;
+
+  ASSERT (PlatformHob != NULL);
+
+  for (Index = 0; Index < GetNumberSupportedSockets (); Index++) {
+    if (Index == 0) {
+      Table = &mArmDefaultType7Sk0L1.Base;
+    } else {
+      Table = &mArmDefaultType7Sk1L1.Base;
+    }
+
+    Table->Associativity = (UINT8) CpuGetAssociativity (1);
+    Table->CacheConfiguration = (1 << 7 | GetCacheConfig (1) << 8); /* Enabled, Internal, L1 */
+    Table->MaximumCacheSize  = CACHE_SIZE (CpuGetCacheSize (1));
+    Table->InstalledSize     = CACHE_SIZE (CpuGetCacheSize (1));
+    Table->MaximumCacheSize2 = CACHE_SIZE_2 (CpuGetCacheSize (1));
+    Table->InstalledSize2    = CACHE_SIZE_2 (CpuGetCacheSize (1));
+
+    if (Index == 0) {
+      Table = &mArmDefaultType7Sk0L2.Base;
+    } else {
+      Table = &mArmDefaultType7Sk1L2.Base;
+    }
+
+    Table->Associativity = (UINT8) CpuGetAssociativity (2);
+    Table->CacheConfiguration = (1 << 7 | GetCacheConfig (2) << 8 | 1); /* Enabled, Internal, L2 */
+    Table->MaximumCacheSize  = CACHE_SIZE (CpuGetCacheSize (2));
+    Table->InstalledSize     = CACHE_SIZE (CpuGetCacheSize (2));
+    Table->MaximumCacheSize2 = CACHE_SIZE_2 (CpuGetCacheSize (2));
+    Table->InstalledSize2    = CACHE_SIZE_2 (CpuGetCacheSize (2));
+
+    if (Index == 0) {
+      Table = &mArmDefaultType7Sk0L3.Base;
+    } else {
+      Table = &mArmDefaultType7Sk1L3.Base;
+    }
+
+    // CpuGetCacheSize() not return L3 size, set it to 32MB
+    Table->MaximumCacheSize  = CACHE_SIZE (32 << 20);
+    Table->InstalledSize     = CACHE_SIZE (32 << 20);
+    Table->MaximumCacheSize2 = CACHE_SIZE_2 (32 << 20);
+    Table->InstalledSize2    = CACHE_SIZE_2 (32 << 20);
+  }
+
+  if (GetNumberSupportedSockets () == 2 && GetNumberActiveCoresPerSocket (1) == 0) {
+    mArmDefaultType7Sk1L1.Base.InstalledSize = 0;
+    mArmDefaultType7Sk1L1.Base.InstalledSize2 = 0;
+    mArmDefaultType7Sk1L2.Base.InstalledSize = 0;
+    mArmDefaultType7Sk1L2.Base.InstalledSize2 = 0;
+    mArmDefaultType7Sk1L3.Base.InstalledSize = 0;
+    mArmDefaultType7Sk1L3.Base.InstalledSize2 = 0;
+  }
+
+}
+
+STATIC
+VOID
+UpdateSmbiosInfo (
+  VOID
+  )
+{
+  VOID                        *Hob;
+  PlatformInfoHob_V2          *PlatformHob;
+  CONST EFI_GUID              PlatformHobGuid = PLATFORM_INFO_HOB_GUID_V2;
+
+  /* Get the Platform HOB */
+  Hob = GetFirstGuidHob (&PlatformHobGuid);
+  ASSERT (Hob != NULL);
+  if (Hob == NULL) {
+    return;
+  }
+
+  PlatformHob = (PlatformInfoHob_V2 *) GET_GUID_HOB_DATA (Hob);
+
+  UpdateSmbiosType4 (PlatformHob);
+  UpdateSmbiosType7 (PlatformHob);
+}
+
+/**
+   Install SMBIOS Type 7 table
+
+   @param  Smbios               SMBIOS protocol.
+**/
+EFI_STATUS
+InstallType7Structures (
+  IN EFI_SMBIOS_PROTOCOL  *Smbios
+  )
+{
+  EFI_STATUS          Status = EFI_SUCCESS;
+  EFI_SMBIOS_HANDLE   SmbiosHandle;
+  SMBIOS_TABLE_TYPE4  *Type4Table;
+  CONST VOID          **Tables;
+  UINTN               Index;
+  UINTN               Level;
+
+  for ( Index = 0; Index < GetNumberSupportedSockets (); Index++ ) {
+    if ( Index == 0) {
+      Tables = DefaultType7Sk0Tables;
+      Type4Table = &mArmDefaultType4Sk0.Base;
+    } else {
+      Tables = DefaultType7Sk1Tables;
+      Type4Table = &mArmDefaultType4Sk1.Base;
+    }
+
+    for (Level = 0; Level < CPU_CACHE_LEVEL_MAX; Level++ ) {
+      SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER*) Tables[Level])->Handle;
+      Status = Smbios->Add (
+                         Smbios,
+                         NULL,
+                         &SmbiosHandle,
+                         (EFI_SMBIOS_TABLE_HEADER*) Tables[Level]
+                         );
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR,
+                "%a: adding SMBIOS type 7 Socket %d L%d cache failed\n",
+                __FUNCTION__,
+                Index,
+                Level + 1));
+        //stop adding rather than continuing
+        return Status;
+      }
+
+      // Save handle to Type 4
+      if (Level == 0) { //L1 cache
+        Type4Table->L1CacheHandle = SmbiosHandle;
+      } else if (Level == 1) { //L2 cache
+        Type4Table->L2CacheHandle = SmbiosHandle;
+      } else if (Level == 2) { //L3 cache
+        Type4Table->L3CacheHandle = SmbiosHandle;
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+   Install a whole table worth of structructures
+
+   @param  Smbios               SMBIOS protocol.
+   @param  DefaultTables        A pointer to the default SMBIOS table structure.
+**/
+EFI_STATUS
+InstallStructures (
+  IN EFI_SMBIOS_PROTOCOL  *Smbios,
+  IN CONST VOID           *DefaultTables[]
+  )
+{
+  EFI_STATUS          Status = EFI_SUCCESS;
+  EFI_SMBIOS_HANDLE   SmbiosHandle;
+  UINTN               Index;
+
+  for (Index = 0; Index < GetNumberSupportedSockets () && DefaultTables[Index] != NULL; Index++) {
+    SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER*) DefaultTables[Index])->Handle;
+    Status = Smbios->Add (
+                       Smbios,
+                       NULL,
+                       &SmbiosHandle,
+                       (EFI_SMBIOS_TABLE_HEADER*) DefaultTables[Index]
+                       );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: adding %d failed\n", __FUNCTION__, Index));
+
+      //stop adding rather than continuing
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+   Install all structures from the DefaultTables structure
+
+   @param  Smbios               SMBIOS protocol
+
+**/
+EFI_STATUS
+InstallAllStructures (
+  IN EFI_SMBIOS_PROTOCOL  *Smbios
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  UpdateSmbiosInfo ();
+
+  // Install Type 7 structures
+  InstallType7Structures (Smbios);
+
+  // Install Tables
+  Status = InstallStructures (Smbios, DefaultCommonTables);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+SmbiosCpuDxeEntry (
+  IN EFI_HANDLE             ImageHandle,
+  IN EFI_SYSTEM_TABLE       *SystemTable
+  )
+{
+  EFI_STATUS            Status;
+  EFI_SMBIOS_PROTOCOL   *Smbios;
+
+  //
+  // Find the SMBIOS protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiSmbiosProtocolGuid,
+                  NULL,
+                  (VOID**) &Smbios
+                  );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Unable to locate SMBIOS Protocol"));
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  Status = InstallAllStructures (Smbios);
+  DEBUG ((DEBUG_ERROR, "SmbiosCpu install: %r\n", Status));
+
+  return Status;
+}
diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c
new file mode 100644
index 000000000000..e4a51f20aaff
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c
@@ -0,0 +1,664 @@
+/** @file
+
+  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/ArmLib.h>
+#include <Library/HobLib.h>
+#include <Library/AmpereCpuLib.h>
+#include <Guid/SmBios.h>
+#include <Protocol/Smbios.h>
+#include <PlatformInfoHob.h>
+
+#define TYPE16_ADDITIONAL_STRINGS        \
+  "\0"                       /* no string*/
+
+#define TYPE17_ADDITIONAL_STRINGS        \
+  "Device Locator not set \0"  \
+  "Bank Locator not set \0"    \
+  "Manufacturer not set \0"    \
+  "Serial Number not set \0"   \
+  "Asset Tag not set \0"       \
+  "Part Number not set \0"     \
+
+#define TYPE19_ADDITIONAL_STRINGS        \
+  "\0"                      /* no string */
+
+//
+// Type definition and contents of the default SMBIOS table.
+// This table covers only the minimum structures required by
+// the SMBIOS specification (section 6.2, version 3.0)
+//
+#pragma pack(1)
+typedef struct {
+  SMBIOS_TABLE_TYPE16 Base;
+  CHAR8              Strings[sizeof (TYPE16_ADDITIONAL_STRINGS)];
+} ARM_TYPE16;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE17 Base;
+  CHAR8              Strings[sizeof (TYPE17_ADDITIONAL_STRINGS)];
+} ARM_TYPE17;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE19 Base;
+  CHAR8              Strings[sizeof (TYPE19_ADDITIONAL_STRINGS)];
+} ARM_TYPE19;
+
+#pragma pack()
+// Type 16 Physical Memory Array
+STATIC  ARM_TYPE16 mArmDefaultType16 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE16),          // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    MemoryArrayLocationSystemBoard,  //on motherboard
+    MemoryArrayUseSystemMemory,      //system RAM
+    MemoryErrorCorrectionMultiBitEcc,//ECC RAM
+    0x80000000,
+    0xFFFE,   //No error information structure
+    0x10,
+    0x40000000000ULL,
+  },
+  TYPE16_ADDITIONAL_STRINGS
+};
+
+// Type 17 Memory Device
+STATIC ARM_TYPE17 mArmDefaultType17 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_MEMORY_DEVICE,
+      sizeof (SMBIOS_TABLE_TYPE17),
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    0xFFFF,                         // array to which this module belongs
+    0xFFFE,                         // no errors
+    72,                             // single DIMM with ECC
+    64,                             // data width of this device (64-bits)
+    0,                              // no module installed
+    0x09,                           // DIMM
+    1,                              // part of a set
+    1,                              // device locator
+    2,                              // bank locator
+    MemoryTypeDdr4,                 // DDR4
+    {},                             // type detail
+    0,                              // ? MHz
+    3,                              // manufacturer
+    4,                              // serial
+    5,                              // asset tag
+    6,                              // part number
+    0,                              // rank
+  },
+  TYPE17_ADDITIONAL_STRINGS
+};
+
+// Type 19 Memory Array Mapped Address
+STATIC ARM_TYPE19 mArmDefaultType19 = {
+  {
+    {  // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS,
+      sizeof (SMBIOS_TABLE_TYPE19),
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    0xFFFFFFFF,// invalid, look at extended addr field
+    0xFFFFFFFF,
+    0xFFFF,    // handle
+    1,
+    0x0,
+    0x0,
+  },
+  TYPE19_ADDITIONAL_STRINGS
+};
+
+typedef struct _JEDEC_MF_ID {
+  UINT8           VendorId;
+  CHAR8           *ManufacturerString;
+} JEDEC_MF_ID;
+
+JEDEC_MF_ID Bank0Table[] = {
+  { 0x01, "AMD" },
+  { 0x04, "Fujitsu" },
+  { 0x07, "Hitachi" },
+  { 0x89, "Intel" },
+  { 0x10, "NEC" },
+  { 0x97, "Texas Instrument" },
+  { 0x98, "Toshiba" },
+  { 0x1c, "Mitsubishi" },
+  { 0x1f, "Atmel" },
+  { 0x20, "STMicroelectronics" },
+  { 0xa4, "IBM" },
+  { 0x2c, "Micron Technology" },
+  { 0xad, "SK Hynix" },
+  { 0xb0, "Sharp" },
+  { 0xb3, "IDT" },
+  { 0x3e, "Oracle" },
+  { 0xbf, "SST" },
+  { 0x40, "ProMos/Mosel" },
+  { 0xc1, "Infineon" },
+  { 0xc2, "Macronix" },
+  { 0x45, "SanDisk" },
+  { 0xce, "Samsung" },
+  { 0xda, "Winbond" },
+  { 0xe0, "LG Semi" },
+  { 0x62, "Sanyo" },
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID Bank1Table[] = {
+  { 0x98, "Kingston" },
+  { 0xba, "PNY" },
+  { 0x4f, "Transcend" },
+  { 0x7a, "Apacer" },
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID Bank2Table[] = {
+  { 0x9e, "Corsair" },
+  { 0xfe, "Elpida" },
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID Bank3Table[] = {
+  { 0x0b, "Nanya" },
+  { 0x94, "Mushkin" },
+  { 0x25, "Kingmax" },
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID Bank4Table[] = {
+  { 0xb0, "OCZ" },
+  { 0xcb, "A-DATA" },
+  { 0xcd, "G Skill" },
+  { 0xef, "Team" },
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID Bank5Table[] = {
+  { 0x02, "Patriot" },
+  { 0x9b, "Crucial" },
+  { 0x51, "Qimonda" },
+  { 0x57, "AENEON" },
+  { 0xf7, "Avant" },
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID Bank6Table[] = {
+  { 0x34, "Super Talent" },
+  { 0xd3, "Silicon Power" },
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID Bank7Table[] = {
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID *ManufacturerJedecIdBankTable[] = {
+  Bank0Table,
+  Bank1Table,
+  Bank2Table,
+  Bank3Table,
+  Bank4Table,
+  Bank5Table,
+  Bank6Table,
+  Bank7Table
+};
+
+STATIC
+UINTN
+GetStringPackSize (
+  CHAR8 *StringPack
+  )
+{
+  UINTN     StrCount;
+  CHAR8     *StrStart;
+
+  if ((*StringPack == 0) && (*(StringPack + 1) == 0)) {
+    return 0;
+  }
+
+  // String section ends in double-null (0000h)
+  for (StrCount = 0, StrStart = StringPack;
+        ((*StrStart != 0) || (*(StrStart + 1) != 0)); StrStart++, StrCount++) {};
+
+  return StrCount + 2; // Included the double NULL
+}
+
+// Update String at String number to String Pack
+EFI_STATUS
+UpdateStringPack (
+  CHAR8             *StringPack,
+  CHAR8             *String,
+  UINTN             StringNumber
+  )
+{
+  CHAR8                     *StrStart;
+  UINTN                     StrIndex;
+  UINTN                     InputStrLen;
+  UINTN                     TargetStrLen;
+  UINTN                     BufferSize;
+  CHAR8                     *Buffer;
+
+  StrStart = StringPack;
+  for (StrIndex = 1; StrIndex < StringNumber; StrStart++) {
+    // A string ends in 00h
+    if (*StrStart == 0) {
+      StrIndex++;
+    }
+    // String section ends in double-null (0000h)
+    if ((*StrStart == 0) && (*(StrStart + 1) == 0)) {
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  if (*StrStart == 0) {
+    StrStart++;
+  }
+
+  InputStrLen = AsciiStrLen (String);
+  TargetStrLen = AsciiStrLen (StrStart);
+  BufferSize = GetStringPackSize (StrStart + TargetStrLen + 1);
+
+  // Replace the String if length matched
+  // OR this is the last string
+  if ((InputStrLen == TargetStrLen) || (BufferSize == 0)) {
+    CopyMem (StrStart, String, InputStrLen);
+  }
+  // Otherwise, buffer is needed to apply new string
+  else {
+    Buffer = AllocateZeroPool (BufferSize);
+    if (Buffer == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    CopyMem (Buffer, StrStart + TargetStrLen + 1, BufferSize);
+    CopyMem (StrStart, String, InputStrLen + 1);
+    CopyMem (StrStart + InputStrLen + 1, Buffer, BufferSize);
+
+    FreePool (Buffer);
+  }
+
+  return EFI_SUCCESS;
+}
+
+UINT8
+GetMemoryType (
+  IN UINT8     *SpdData
+  )
+{
+  return (SpdData[2] == 0x08) ? 1 :   // DDR2
+         (SpdData[2] == 0x0B) ? 2 :   // DDR3
+         (SpdData[2] == 0x0C) ? 3 : 0;// DDR4
+}
+
+EFI_STATUS
+UpdateManufacturer (
+  IN VOID                    *Table,
+  IN UINT8                   *SpdData
+  )
+{
+  EFI_STATUS      Status = EFI_SUCCESS;
+  UINTN           i;
+  UINT8           Data8;
+  UINT8           MemType;
+  JEDEC_MF_ID     *IdTblPtr = NULL;
+
+  MemType = GetMemoryType (SpdData);
+
+  switch (MemType) {
+  case 1:
+    for (i = 0; i < 8; i++) {      // DDR2
+      Data8 = SpdData[64 + i];
+      if (Data8 != 0x7f) {
+        break;
+      }
+    }
+    break;
+
+  case 2:                    // DDR3
+    i = SpdData[117] & 0x7f; // Remove parity bit
+    Data8 = SpdData[118];
+    break;
+
+  case 3:                    // DDR4
+    i = SpdData[320] & 0x7f; // Remove parity bit
+    Data8 = SpdData[321];
+    break;
+
+  default:
+    return EFI_UNSUPPORTED;  // Not supported
+  }
+
+  if (i > 7) i = 7;
+  IdTblPtr = ManufacturerJedecIdBankTable[i];
+
+  // Search in Manufacturer table
+  while ((IdTblPtr->VendorId != Data8) && (IdTblPtr->VendorId != 0xff)) {
+    IdTblPtr++;
+  }
+
+  if (IdTblPtr->VendorId != 0xff) {
+    Status = UpdateStringPack (
+               ((ARM_TYPE17 *) Table)->Strings,
+               IdTblPtr->ManufacturerString,
+               ((ARM_TYPE17 *) Table)->Base.Manufacturer
+               );
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+UpdateSerialNumber (
+  IN VOID                    *Table,
+  IN UINT8                   *SpdData
+  )
+{
+  UINT8           MemType;
+  UINTN           Offset;
+  CHAR8           Str[64];
+
+  MemType = GetMemoryType (SpdData);
+
+  switch (MemType) {
+  case 1:
+    Offset = 95;
+    break;
+
+  case 2:                          // DDR3
+    Offset = 122;
+    break;
+
+  case 3:                          // DDR4
+    Offset = 325;
+    break;
+
+  default:
+    return EFI_UNSUPPORTED;        // Not supported
+  }
+
+  AsciiSPrint (Str, sizeof (Str), "%02X%02X%02X%02X",
+               SpdData[Offset], SpdData[Offset + 1],
+               SpdData[Offset + 2], SpdData[Offset + 3]);
+
+  return UpdateStringPack (((ARM_TYPE17 *) Table)->Strings, Str,
+                           ((ARM_TYPE17 *) Table)->Base.SerialNumber);
+}
+
+CHAR8
+Printable (
+  IN CHAR8 Character
+  )
+{
+  if((Character >= 0x20) && (Character <= 0x7E)) {
+    return Character;
+  }
+
+  return ' ';
+}
+
+EFI_STATUS
+UpdatePartNumber (
+  IN VOID                    *Table,
+  IN UINT8                   *SpdData
+  )
+{
+  UINT8           MemType;
+  UINTN           Offset;
+  CHAR8           Str[64];
+
+  MemType = GetMemoryType (SpdData);
+
+  switch (MemType) {
+  case 1:
+    Offset = 73;
+    break;
+
+  case 2:                          // DDR3
+    Offset = 128;
+    break;
+
+  case 3:                          // DDR4
+    Offset = 329;
+    break;
+
+  default:
+    return EFI_UNSUPPORTED;        // Not supported
+  }
+
+  AsciiSPrint (Str, sizeof (Str), "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
+               Printable (SpdData[Offset]), Printable (SpdData[Offset + 1]),
+               Printable (SpdData[Offset + 2]), Printable (SpdData[Offset + 3]),
+               Printable (SpdData[Offset + 4]), Printable (SpdData[Offset + 5]),
+               Printable (SpdData[Offset + 6]), Printable (SpdData[Offset + 7]),
+               Printable (SpdData[Offset + 8]), Printable (SpdData[Offset + 9]),
+               Printable (SpdData[Offset + 10]), Printable (SpdData[Offset + 11]),
+               Printable (SpdData[Offset + 12]), Printable (SpdData[Offset + 13]),
+               Printable (SpdData[Offset + 14]), Printable (SpdData[Offset + 15]),
+               Printable (SpdData[Offset + 16]), Printable (SpdData[Offset + 17]));
+
+  return UpdateStringPack (((ARM_TYPE17 *) Table)->Strings, Str,
+                           ((ARM_TYPE17 *) Table)->Base.PartNumber);
+}
+
+/**
+   Install SMBIOS Type 16 17 and 19 table
+
+   @param  Smbios               SMBIOS protocol.
+**/
+EFI_STATUS
+InstallMemStructures (
+  IN EFI_SMBIOS_PROTOCOL  *Smbios
+  )
+{
+  EFI_STATUS           Status = EFI_SUCCESS;
+  CONST EFI_GUID       PlatformHobGuid = PLATFORM_INFO_HOB_GUID_V2;
+  EFI_SMBIOS_HANDLE    SmbiosHandle;
+  EFI_SMBIOS_HANDLE    Type16Handle;
+  PlatformInfoHob_V2   *PlatformHob;
+  PlatformDimmV2       *Dimm;
+  CHAR8                *Table;
+  VOID                 *Hob;
+  UINTN                Index;
+  UINTN                SlotIndex;
+  UINTN                MemRegionIndex;
+  UINT64               MemorySize = 0;
+  CHAR8                Str[64];
+
+  ASSERT (Smbios != NULL);
+
+  /* Get the Platform HOB */
+  Hob = GetFirstGuidHob (&PlatformHobGuid);
+  ASSERT (Hob != NULL);
+  if (Hob == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformHob = (PlatformInfoHob_V2 *) GET_GUID_HOB_DATA (Hob);
+
+  Table = AllocateZeroPool (sizeof (ARM_TYPE17));
+  if (Table == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  for ( Index = 0; Index < GetNumberSupportedSockets (); Index++ ) {
+    // Copy template to Type 16
+    CopyMem (Table, (VOID *) &mArmDefaultType16, sizeof (ARM_TYPE16));
+
+    ((ARM_TYPE16 *) Table)->Base.MaximumCapacity = 0x80000000;
+    ((ARM_TYPE16 *) Table)->Base.ExtendedMaximumCapacity = 0x40000000000ULL; /* 4TB per socket */
+    ((ARM_TYPE16 *) Table)->Base.MemoryErrorCorrection = MemoryErrorCorrectionMultiBitEcc;
+
+    // Install Type 16 and hold the handle so that the subsequence type17/19 could use
+    Type16Handle = ((ARM_TYPE16 *) Table)->Base.Hdr.Handle;
+    Status = Smbios->Add (
+                       Smbios,
+                       NULL,
+                       &Type16Handle,
+                       (EFI_SMBIOS_TABLE_HEADER*)Table
+                       );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: adding SMBIOS type 16 socket %d failed\n", __FUNCTION__, Index));
+      FreePool (Table);
+      //stop adding rather than continuing
+      return Status;
+    }
+
+    for (SlotIndex = 0; SlotIndex < PLATFORM_DIMM_INFO_MAX_SLOT; SlotIndex++) {
+      // Copy Tempplate to Type 17
+      CopyMem (Table, (VOID *) &mArmDefaultType17, sizeof (ARM_TYPE17));
+
+      // Fill up type 17 table's content here
+      Dimm = &PlatformHob->DimmList.Dimm[SlotIndex];
+      if (Dimm->NodeId != Index) {
+        continue;
+      }
+
+      if (Dimm->Info.DimmStatus == DIMM_INSTALLED_OPERATIONAL) {
+
+        UpdateManufacturer ((VOID *) Table, Dimm->SpdData.Data);
+        UpdateSerialNumber ((VOID *) Table, Dimm->SpdData.Data);
+        UpdatePartNumber ((VOID *) Table, Dimm->SpdData.Data);
+
+        MemorySize = Dimm->Info.DimmSize * 1024;
+        if (MemorySize >= 0x7FFF) {
+          ((ARM_TYPE17 *) Table)->Base.Size = 0x7FFF;
+          ((ARM_TYPE17 *) Table)->Base.ExtendedSize = MemorySize;
+        } else {
+          ((ARM_TYPE17 *) Table)->Base.Size = (UINT16) MemorySize;
+          ((ARM_TYPE17 *) Table)->Base.ExtendedSize = 0;
+        }
+
+        ((ARM_TYPE17 *) Table)->Base.MemoryType = 0x1A; /* DDR4 */
+        ((ARM_TYPE17 *) Table)->Base.Speed = (UINT16) PlatformHob->DramInfo.MaxSpeed;
+        ((ARM_TYPE17 *) Table)->Base.ConfiguredMemoryClockSpeed = (UINT16) PlatformHob->DramInfo.MaxSpeed;
+        ((ARM_TYPE17 *) Table)->Base.ConfiguredVoltage = 1200;
+        ((ARM_TYPE17 *) Table)->Base.MinimumVoltage = 1140;
+        ((ARM_TYPE17 *) Table)->Base.MaximumVoltage = 1260;
+        ((ARM_TYPE17 *) Table)->Base.DeviceSet = 0; // None
+
+        if (Dimm->Info.DimmType == UDIMM || Dimm->Info.DimmType == SODIMM) {
+          ((ARM_TYPE17 *) Table)->Base.TypeDetail.Unbuffered = 1; /* BIT 14: unregistered */
+        } else if (Dimm->Info.DimmType == RDIMM
+                || Dimm->Info.DimmType == LRDIMM
+                || Dimm->Info.DimmType == RSODIMM) {
+          ((ARM_TYPE17 *) Table)->Base.TypeDetail.Registered = 1; /* BIT 13: registered */
+        }
+        /* FIXME: Determine if need to set technology to NVDIMM-* when supported */
+        ((ARM_TYPE17 *) Table)->Base.MemoryTechnology = 0x3; // DRAM
+      }
+      AsciiSPrint (Str, sizeof (Str), "Socket %d DIMM %d", Index, SlotIndex);
+      UpdateStringPack (((ARM_TYPE17 *) Table)->Strings, Str, ((ARM_TYPE17 *) Table)->Base.DeviceLocator);
+      AsciiSPrint (Str, sizeof (Str), "Bank %d", SlotIndex);
+      UpdateStringPack (((ARM_TYPE17 *) Table)->Strings, Str, ((ARM_TYPE17 *) Table)->Base.BankLocator);
+      AsciiSPrint (Str, sizeof (Str), "Array %d Asset Tag %d", Index, SlotIndex);
+      UpdateStringPack (((ARM_TYPE17 *) Table)->Strings, Str, ((ARM_TYPE17 *) Table)->Base.AssetTag);
+
+      // Update Type 16 handle
+      ((ARM_TYPE17 *) Table)->Base.MemoryArrayHandle = Type16Handle;
+
+      // Install structure
+      SmbiosHandle = ((ARM_TYPE17 *) Table)->Base.Hdr.Handle;
+      Status = Smbios->Add (
+                         Smbios,
+                         NULL,
+                         &SmbiosHandle,
+                         (EFI_SMBIOS_TABLE_HEADER*)Table
+                         );
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "%a: adding SMBIOS type 17 Socket %d Slot %d failed\n",
+                __FUNCTION__,
+                Index,
+                SlotIndex));
+        FreePool (Table);
+        //stop adding rather than continuing
+        return Status;
+      }
+    }
+
+    for (MemRegionIndex = 0; MemRegionIndex < PlatformHob->DramInfo.NumRegion; MemRegionIndex++) {
+      // Copy Tempplate to Type 19
+      CopyMem (Table, (VOID *) &mArmDefaultType19, sizeof (ARM_TYPE19));
+
+      if (PlatformHob->DramInfo.Node[MemRegionIndex] != Index) {
+        continue;
+      }
+
+      ((ARM_TYPE19 *) Table)->Base.StartingAddress = 0xFFFFFFFF;
+      ((ARM_TYPE19 *) Table)->Base.EndingAddress = 0xFFFFFFFF;
+      ((ARM_TYPE19 *) Table)->Base.ExtendedStartingAddress = PlatformHob->DramInfo.Base[MemRegionIndex];
+      ((ARM_TYPE19 *) Table)->Base.ExtendedEndingAddress = PlatformHob->DramInfo.Base[MemRegionIndex] +
+                                                           PlatformHob->DramInfo.Size[MemRegionIndex] - 1;
+
+      if (MemorySize != 0) {
+        ((ARM_TYPE19 *) Table)->Base.PartitionWidth = (PlatformHob->DramInfo.Size[MemRegionIndex] - 1) / MemorySize + 1;
+      }
+
+      // Update Type 16 handle
+      ((ARM_TYPE19 *) Table)->Base.MemoryArrayHandle = Type16Handle;
+
+      // Install structure
+      SmbiosHandle = ((ARM_TYPE19 *) Table)->Base.Hdr.Handle;
+      Status = Smbios->Add (
+                         Smbios,
+                         NULL,
+                         &SmbiosHandle,
+                         (EFI_SMBIOS_TABLE_HEADER*)Table
+                       );
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "%a: adding SMBIOS type 19 Socket %d MemRegion %d failed\n",
+                __FUNCTION__,
+                Index, MemRegionIndex));
+        FreePool (Table);
+        //stop adding rather than continuing
+        return Status;
+      }
+    }
+  }
+
+  FreePool (Table);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SmbiosMemInfoDxeEntry (
+  IN EFI_HANDLE             ImageHandle,
+  IN EFI_SYSTEM_TABLE       *SystemTable
+  )
+{
+  EFI_STATUS            Status;
+  EFI_SMBIOS_PROTOCOL   *Smbios;
+
+  //
+  // Find the SMBIOS protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiSmbiosProtocolGuid,
+                  NULL,
+                  (VOID**) &Smbios
+                  );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Unable to locate SMBIOS Protocol"));
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  Status = InstallMemStructures (Smbios);
+  DEBUG ((DEBUG_ERROR, "SmbiosMemInfoDxe install: %r\n", Status));
+
+  return Status;
+}
diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c
new file mode 100755
index 000000000000..74c5cc9f24ba
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c
@@ -0,0 +1,1037 @@
+/** @file
+
+  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Guid/SmBios.h>
+#include <Library/HobLib.h>
+#include <Protocol/Smbios.h>
+#include <PlatformInfoHob.h>
+
+// Type0 Data
+#define VENDOR_TEMPLATE       "Ampere Computing\0"
+#define BIOS_VERSION_TEMPLATE "TianoCore EDKII\0"
+#define RELEASE_DATE_TEMPLATE "MM/DD/YYYY\0"
+
+#define TYPE0_ADDITIONAL_STRINGS                    \
+  VENDOR_TEMPLATE              /* Vendor */         \
+  BIOS_VERSION_TEMPLATE        /* BiosVersion */    \
+  RELEASE_DATE_TEMPLATE        /* BiosReleaseDate */
+
+// Type1 Data
+#define MANUFACTURER_TEMPLATE "Ampere Computing\0"
+#define PRODUCT_NAME_TEMPLATE "Mt. Jade\0"
+#define SYS_VERSION_TEMPLATE  "PR010\0"
+#define SERIAL_TEMPLATE       "123456789ABCDEFF123456789ABCDEFF\0"
+#define SKU_TEMPLATE          "FEDCBA9876543211FEDCBA9876543211\0"
+#define FAMILY_TEMPLATE       "ARMv8\0"
+
+#define TYPE1_ADDITIONAL_STRINGS                  \
+  MANUFACTURER_TEMPLATE       /* Manufacturer */  \
+  PRODUCT_NAME_TEMPLATE       /* Product Name */  \
+  SYS_VERSION_TEMPLATE        /* Version */       \
+  SERIAL_TEMPLATE             /* Serial Number */ \
+  SKU_TEMPLATE                /* SKU Number */    \
+  FAMILY_TEMPLATE             /* Family */
+
+#define TYPE2_ADDITIONAL_STRINGS                   \
+  MANUFACTURER_TEMPLATE       /* Manufacturer */   \
+  PRODUCT_NAME_TEMPLATE       /* Product Name */   \
+  "EVT2\0"                    /* Version */        \
+  "Serial Not Set\0"          /* Serial */         \
+  "Base of Chassis\0"         /* board location */ \
+  "FF\0"                      /* Version */        \
+  "FF\0"                      /* Version */
+
+#define TYPE3_ADDITIONAL_STRINGS                 \
+  MANUFACTURER_TEMPLATE       /* Manufacturer */ \
+  "None\0"                    /* Version */      \
+  "Serial Not Set\0"          /* Serial  */      \
+  "Asset Tag Not Set\0"       /* Asset Tag */
+
+#define TYPE8_ADDITIONAL_STRINGS      \
+  "VGA1 - Rear VGA Connector\0"       \
+  "DB-15 Male (VGA)         \0"
+
+#define TYPE9_ADDITIONAL_STRINGS       \
+  "Socket 0 Riser 1 x32 - Slot 1\0"
+
+#define TYPE11_ADDITIONAL_STRINGS       \
+  "www.amperecomputing.com\0"
+
+#define TYPE13_ADDITIONAL_STRINGS       \
+  "en|US|iso8859-1\0"
+
+#define TYPE41_ADDITIONAL_STRINGS       \
+  "Onboard VGA\0"
+
+//
+// Type definition and contents of the default SMBIOS table.
+// This table covers only the minimum structures required by
+// the SMBIOS specification (section 6.2, version 3.0)
+//
+#pragma pack(1)
+typedef struct {
+  SMBIOS_TABLE_TYPE0 Base;
+  CHAR8              Strings[sizeof(TYPE0_ADDITIONAL_STRINGS)];
+} ARM_TYPE0;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE1 Base;
+  CHAR8              Strings[sizeof(TYPE1_ADDITIONAL_STRINGS)];
+} ARM_TYPE1;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE2 Base;
+  CHAR8              Strings[sizeof(TYPE2_ADDITIONAL_STRINGS)];
+} ARM_TYPE2;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE3 Base;
+  CHAR8              Strings[sizeof(TYPE3_ADDITIONAL_STRINGS)];
+} ARM_TYPE3;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE8 Base;
+  CHAR8              Strings[sizeof(TYPE8_ADDITIONAL_STRINGS)];
+} ARM_TYPE8;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE9 Base;
+  CHAR8              Strings[sizeof(TYPE9_ADDITIONAL_STRINGS)];
+} ARM_TYPE9;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE11 Base;
+  CHAR8              Strings[sizeof(TYPE11_ADDITIONAL_STRINGS)];
+} ARM_TYPE11;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE13 Base;
+  CHAR8              Strings[sizeof(TYPE13_ADDITIONAL_STRINGS)];
+} ARM_TYPE13;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE41 Base;
+  CHAR8              Strings[sizeof(TYPE41_ADDITIONAL_STRINGS)];
+} ARM_TYPE41;
+
+#pragma pack()
+
+//-------------------------------------
+//        SMBIOS Platform Common
+//-------------------------------------
+enum {
+  ADDITIONAL_STR_INDEX_1 = 1,
+  ADDITIONAL_STR_INDEX_2,
+  ADDITIONAL_STR_INDEX_3,
+  ADDITIONAL_STR_INDEX_4,
+  ADDITIONAL_STR_INDEX_5,
+  ADDITIONAL_STR_INDEX_6,
+  ADDITIONAL_STR_INDEX_MAX
+};
+
+
+// Type 0 BIOS information
+STATIC ARM_TYPE0 mArmDefaultType0 = {
+  {
+    { // Header
+      EFI_SMBIOS_TYPE_BIOS_INFORMATION, // UINT8 Type
+      sizeof(SMBIOS_TABLE_TYPE0),       // UINT8 Length, The length of the structure's string-set is not included.
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+
+    ADDITIONAL_STR_INDEX_1,     // SMBIOS_TABLE_STRING       Vendor
+    ADDITIONAL_STR_INDEX_2,     // SMBIOS_TABLE_STRING       BiosVersion
+    0,                          // UINT16                    BiosSegment
+    ADDITIONAL_STR_INDEX_3,     // SMBIOS_TABLE_STRING       BiosReleaseDate
+    0,                          // UINT8                     BiosSize
+
+    // MISC_BIOS_CHARACTERISTICS BiosCharacteristics
+    {
+      0,0,0,0,0,0,
+      1, //PCI supported
+      0,
+      1, //PNP supported
+      0,
+      1, //BIOS upgradable
+      0, 0, 0,
+      0, //Boot from CD
+      1, //selectable boot
+    },
+
+    // BIOSCharacteristicsExtensionBytes[2]
+    {
+      0,
+      0,
+    },
+
+    0,     // UINT8                     SystemBiosMajorRelease
+    0,     // UINT8                     SystemBiosMinorRelease
+
+    // If the system does not have field upgradeable embedded controller
+    // firmware, the value is 0FFh
+    0xFF,  // UINT8                     EmbeddedControllerFirmwareMajorRelease
+    0xFF   // UINT8                     EmbeddedControllerFirmwareMinorRelease
+  },
+
+  // Text strings (unformatted area)
+  TYPE0_ADDITIONAL_STRINGS
+};
+
+// Type 1 System information
+STATIC ARM_TYPE1 mArmDefaultType1 = {
+  {
+    { // Header
+      EFI_SMBIOS_TYPE_SYSTEM_INFORMATION,
+      sizeof(SMBIOS_TABLE_TYPE1),
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+
+    ADDITIONAL_STR_INDEX_1,      //Manufacturer
+    ADDITIONAL_STR_INDEX_2,      //Product Name
+    ADDITIONAL_STR_INDEX_3,      //Version
+    ADDITIONAL_STR_INDEX_4,      //Serial Number
+    { 0x12345678, 0x9ABC, 0xDEFF, { 0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xFF }},   //UUID
+    SystemWakeupTypePowerSwitch,  //Wakeup type
+    ADDITIONAL_STR_INDEX_5,       //SKU Number
+    ADDITIONAL_STR_INDEX_6,       //Family
+  },
+
+  // Text strings (unformatted)
+  TYPE1_ADDITIONAL_STRINGS
+};
+
+// Type 2 Baseboard
+STATIC ARM_TYPE2 mArmDefaultType2 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE2),           // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,    //Manufacturer
+    ADDITIONAL_STR_INDEX_2,    //Product Name
+    ADDITIONAL_STR_INDEX_3,    //Version
+    ADDITIONAL_STR_INDEX_4,    //Serial
+    0,    //Asset tag
+    {1},  //motherboard, not replaceable
+    ADDITIONAL_STR_INDEX_5,    //location of board
+    0xFFFF,     //chassis handle
+    BaseBoardTypeMotherBoard,
+    0,
+    {0},
+  },
+  TYPE2_ADDITIONAL_STRINGS
+};
+
+// Type 3 Enclosure
+STATIC CONST ARM_TYPE3 mArmDefaultType3 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE3),      // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,          //Manufacturer
+    MiscChassisTypeRackMountChassis, //Rack-mounted chassis
+    ADDITIONAL_STR_INDEX_2,          //version
+    ADDITIONAL_STR_INDEX_3,          //serial
+    ADDITIONAL_STR_INDEX_4,          //asset tag
+    ChassisStateUnknown,             //boot chassis state
+    ChassisStateSafe,                //power supply state
+    ChassisStateSafe,                //thermal state
+    ChassisSecurityStatusNone,       //security state
+    {0,0,0,0},                       //OEM defined
+    1,                               //1U height
+    2,                               //number of power cords
+    0,                               //no contained elements
+  },
+  TYPE3_ADDITIONAL_STRINGS
+};
+
+// Type 8 Port Connector Information
+STATIC CONST ARM_TYPE8  mArmDefaultType8Vga = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
+    PortConnectorTypeDB15Female,  // InternalConnectorType;
+    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
+    PortTypeOther,                // ExternalConnectorType;
+    PortTypeVideoPort,            // PortType;
+  },
+  "VGA1 - Rear VGA Connector\0" \
+  "DB-15 Male (VGA)\0"
+};
+
+// Type 8 Port Connector Information
+STATIC CONST ARM_TYPE8  mArmDefaultType8USBFront = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
+    PortConnectorTypeUsb,         // InternalConnectorType;
+    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
+    PortTypeOther,                // ExternalConnectorType;
+    PortTypeUsb,                  // PortType;
+  },
+  "Front Panel USB 3.0\0"  \
+  "USB\0"
+};
+
+// Type 8 Port Connector Information
+STATIC CONST ARM_TYPE8  mArmDefaultType8USBRear = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
+    PortConnectorTypeUsb,         // InternalConnectorType;
+    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
+    PortTypeOther,                // ExternalConnectorType;
+    PortTypeUsb,                  // PortType;
+  },
+  "Rear Panel USB 3.0\0"   \
+  "USB\0"
+};
+
+// Type 8 Port Connector Information
+STATIC CONST ARM_TYPE8  mArmDefaultType8NetRJ45 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
+    PortConnectorTypeRJ45,        // InternalConnectorType;
+    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
+    PortConnectorTypeRJ45,        // ExternalConnectorType;
+    PortTypeNetworkPort,          // PortType;
+  },
+  "RJ1 - BMC RJ45 Port\0" \
+  "RJ45 Connector\0"
+};
+
+// Type 8 Port Connector Information
+STATIC CONST ARM_TYPE8  mArmDefaultType8NetOcp = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
+    PortTypeOther,                // InternalConnectorType;
+    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
+    PortTypeOther,                // ExternalConnectorType;
+    PortTypeNetworkPort,          // PortType;
+  },
+  "OCP1 - OCP NIC 3.0 Connector\0"  \
+  "OCP NIC 3.0\0"
+};
+
+// Type 8 Port Connector Information
+STATIC CONST ARM_TYPE8  mArmDefaultType8Uart = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
+    PortTypeOther,                 // InternalConnectorType;
+    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
+    PortConnectorTypeDB9Female,    // ExternalConnectorType;
+    PortTypeSerial16550Compatible, // PortType;
+  },
+  "UART1 - BMC UART5 Connector\0"  \
+  "DB-9 female\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk0RiserX32Slot1 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth16X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, //Provides 3.3 Volts
+    {1},       //PME
+    0,
+    0,
+    0,
+  },
+  "S0 Riser 1 x32 - Slot 1\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk0RiserX32Slot2 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth8X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, //Provides 3.3 Volts
+    {1},       //PME
+    4,
+    0,
+    0,
+  },
+  "S0 Riser x32 - Slot 2\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk0RiserX32Slot3 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth8X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, //Provides 3.3 Volts
+    {1},       //PME
+    5,
+    0,
+    0,
+  },
+  "S0 Riser x32 - Slot 3\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX24Slot1 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth8X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, //Provides 3.3 Volts
+    {1},       //PME
+    7,
+    0,
+    0,
+  },
+  "S1 Riser x24 - Slot 1\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX24Slot2 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth8X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, //Provides 3.3 Volts
+    {1},       //PME
+    8,
+    0,
+    0,
+  },
+  "S1 Riser x24 - Slot 2\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX24Slot3 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth8X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, //Provides 3.3 Volts
+    {1},       //PME
+    9,
+    0,
+    0,
+  },
+  "S1 Riser x24 - Slot 3\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX8Slot1 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth8X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, //Provides 3.3 Volts
+    {1},       //PME
+    8,
+    0,
+    0,
+  },
+  "S1 Riser x8 - Slot 1\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk0OcpNic = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth16X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, //Provides 3.3 Volts
+    {1},       //PME
+    1,
+    0,
+    0,
+  },
+  "S0 OCP NIC 3.0\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk1NvmeM2Slot1 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth4X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, //Provides 3.3 Volts
+    {1},       //PME
+    5,
+    0,
+    0,
+  },
+  "S1 NVMe M.2 - Slot 1\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk1NvmeM2Slot2 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth4X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, //Provides 3.3 Volts
+    {1},       //PME
+    5,
+    0,
+    0,
+  },
+  "S1 NVMe M.2 - Slot 2\0"
+};
+
+// Type 11 OEM Strings
+STATIC ARM_TYPE11 mArmDefaultType11 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_OEM_STRINGS,   // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE11),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1
+  },
+  TYPE11_ADDITIONAL_STRINGS
+};
+
+// Type 13 BIOS Language Information
+STATIC ARM_TYPE13 mArmDefaultType13 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE13),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    1,
+    0,
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    1,
+  },
+  TYPE13_ADDITIONAL_STRINGS
+};
+
+//Type 24 Hardware Security
+STATIC SMBIOS_TABLE_TYPE24 mArmDefaultType24 = {
+  { // SMBIOS_STRUCTURE Hdr
+    EFI_SMBIOS_TYPE_HARDWARE_SECURITY, // UINT8 Type
+    sizeof (SMBIOS_TABLE_TYPE24),      // UINT8 Length
+    SMBIOS_HANDLE_PI_RESERVED,
+  },
+  0
+};
+
+// Type 32 System Boot Information
+STATIC SMBIOS_TABLE_TYPE32 mArmDefaultType32 = {
+  { // SMBIOS_STRUCTURE Hdr
+    EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION, // UINT8 Type
+    sizeof (SMBIOS_TABLE_TYPE32),            // UINT8 Length
+    SMBIOS_HANDLE_PI_RESERVED,
+  },
+  {0, 0, 0, 0, 0, 0},
+  0
+};
+
+// Type 38 IPMI Device Information
+STATIC SMBIOS_TABLE_TYPE38 mArmDefaultType38 = {
+  { // SMBIOS_STRUCTURE Hdr
+    EFI_SMBIOS_TYPE_IPMI_DEVICE_INFORMATION, // UINT8 Type
+    sizeof (SMBIOS_TABLE_TYPE38),            // UINT8 Length
+    SMBIOS_HANDLE_PI_RESERVED,
+  },
+  IPMIDeviceInfoInterfaceTypeSSIF,
+  0x20,
+  0x20,
+  0xFF,
+  0x20
+};
+
+// Type 41 Onboard Devices Extended Information
+STATIC ARM_TYPE41 mArmDefaultType41 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_ONBOARD_DEVICES_EXTENDED_INFORMATION,
+      sizeof (SMBIOS_TABLE_TYPE41),
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    1,
+    0x83,  // OnBoardDeviceExtendedTypeVideo, Enabled
+    1,
+    4,
+    2,
+    0,
+  },
+  TYPE41_ADDITIONAL_STRINGS
+};
+
+// Type 42 System Boot Information
+STATIC SMBIOS_TABLE_TYPE42 mArmDefaultType42 = {
+  { // SMBIOS_STRUCTURE Hdr
+    EFI_SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE,
+    sizeof (SMBIOS_TABLE_TYPE42),
+    SMBIOS_HANDLE_PI_RESERVED,
+  },
+  MCHostInterfaceTypeOemDefined,
+  4,
+  {0xFF, 0, 0, 0}
+};
+
+STATIC CONST VOID* DefaultCommonTables[] =
+{
+  &mArmDefaultType0,
+  &mArmDefaultType1,
+  &mArmDefaultType2,
+  &mArmDefaultType8Vga,
+  &mArmDefaultType8USBFront,
+  &mArmDefaultType8USBRear,
+  &mArmDefaultType8NetRJ45,
+  &mArmDefaultType8NetOcp,
+  &mArmDefaultType8Uart,
+  &mArmDefaultType9Sk0RiserX32Slot1,
+  &mArmDefaultType9Sk0RiserX32Slot2,
+  &mArmDefaultType9Sk0RiserX32Slot3,
+  &mArmDefaultType9Sk1RiserX24Slot1,
+  &mArmDefaultType9Sk1RiserX24Slot2,
+  &mArmDefaultType9Sk1RiserX24Slot3,
+  &mArmDefaultType9Sk1RiserX8Slot1,
+  &mArmDefaultType9Sk0OcpNic,
+  &mArmDefaultType9Sk1NvmeM2Slot1,
+  &mArmDefaultType9Sk1NvmeM2Slot2,
+  &mArmDefaultType11,
+  &mArmDefaultType13,
+  &mArmDefaultType24,
+  &mArmDefaultType32,
+  &mArmDefaultType38,
+  &mArmDefaultType41,
+  &mArmDefaultType42,
+  NULL
+};
+
+typedef struct {
+  CHAR8   MonthNameStr[4];  // example "Jan", Compiler build date, month
+  CHAR8   DigitStr[3];      // example "01", Smbios date format, month
+} MonthStringDig;
+
+STATIC MonthStringDig MonthMatch[12] = {
+  { "Jan", "01" },
+  { "Feb", "02" },
+  { "Mar", "03" },
+  { "Apr", "04" },
+  { "May", "05" },
+  { "Jun", "06" },
+  { "Jul", "07" },
+  { "Aug", "08" },
+  { "Sep", "09" },
+  { "Oct", "10" },
+  { "Nov", "11" },
+  { "Dec", "12" }
+};
+
+STATIC
+VOID
+ConstructBuildDate (
+  OUT CHAR8* DateBuf
+  )
+{
+  UINTN i;
+
+  // GCC __DATE__ format is "Feb  2 1996"
+  // If the day of the month is less than 10, it is padded with a space on the left
+  CHAR8* BuildDate = __DATE__;
+
+  // SMBIOS spec date string: MM/DD/YYYY
+  CHAR8 SmbiosDateStr[sizeof (RELEASE_DATE_TEMPLATE)] = { 0 };
+
+  SmbiosDateStr[sizeof (RELEASE_DATE_TEMPLATE) - 1] = '\0';
+
+  SmbiosDateStr[2] = '/';
+  SmbiosDateStr[5] = '/';
+
+  // Month
+  for (i = 0; i < sizeof (MonthMatch) / sizeof (MonthMatch[0]); i++) {
+    if (AsciiStrnCmp (&BuildDate[0], MonthMatch[i].MonthNameStr, AsciiStrLen (MonthMatch[i].MonthNameStr)) == 0) {
+      CopyMem (&SmbiosDateStr[0], MonthMatch[i].DigitStr, AsciiStrLen (MonthMatch[i].DigitStr));
+      break;
+    }
+  }
+
+  // Day
+  CopyMem (&SmbiosDateStr[3], &BuildDate[4], 2);
+  if (BuildDate[4] == ' ') {
+    // day is less then 10, SAPCE filed by compiler, SMBIOS requires 0
+    SmbiosDateStr[3] = '0';
+  }
+
+  // Year
+  CopyMem (&SmbiosDateStr[6], &BuildDate[7], 4);
+
+  CopyMem (DateBuf, SmbiosDateStr, AsciiStrLen (RELEASE_DATE_TEMPLATE));
+}
+
+STATIC
+UINT8
+GetBiosVerMajor (
+  VOID
+  )
+{
+  return (PcdGet8 (PcdSmbiosTables1MajorVersion));
+}
+
+STATIC
+UINT8
+GetBiosVerMinor (
+  VOID
+  )
+{
+  return (PcdGet8 (PcdSmbiosTables1MinorVersion));
+}
+
+STATIC
+EFI_STATUS
+UpdateSmbiosType0 (
+  PlatformInfoHob_V2 * PlatformHob
+  )
+{
+  EFI_STATUS                            Status        = EFI_SUCCESS;
+  MISC_BIOS_CHARACTERISTICS_EXTENSION   *MiscExt      = NULL;
+  CHAR8                                 *ReleaseDateBuf = NULL;
+  CHAR8                                 *PcdReleaseDate = NULL;
+  CHAR8                                 AsciiVersion[32];
+  UINTN                                 Index;
+
+  //
+  //  Update Type0 information
+  //
+  ReleaseDateBuf = &mArmDefaultType0.Strings[0]
+                + sizeof (VENDOR_TEMPLATE) - 1
+                + sizeof (BIOS_VERSION_TEMPLATE) - 1;
+  PcdReleaseDate = (CHAR8*) PcdGetPtr (PcdSmbiosTables0BiosReleaseDate);
+
+  if (AsciiStrnCmp (PcdReleaseDate, RELEASE_DATE_TEMPLATE, AsciiStrLen (RELEASE_DATE_TEMPLATE)) == 0) {
+    // If PCD is still template date MM/DD/YYYY, use compiler date
+    ConstructBuildDate (ReleaseDateBuf);
+  } else {
+    // PCD is updated somehow, use PCD date
+    CopyMem (ReleaseDateBuf, PcdReleaseDate, AsciiStrLen (PcdReleaseDate));
+  }
+
+  if (PcdGet32 (PcdFdSize) < SIZE_16MB) {
+    mArmDefaultType0.Base.BiosSize = (PcdGet32 (PcdFdSize) / SIZE_64KB) - 1;
+
+    mArmDefaultType0.Base.ExtendedBiosSize.Size = 0;
+    mArmDefaultType0.Base.ExtendedBiosSize.Unit = 0;
+  } else {
+    // TODO: Need to update Extended BIOS ROM Size
+    mArmDefaultType0.Base.BiosSize = 0xFF;
+
+    // As a reminder
+    ASSERT (FALSE);
+  }
+
+  // Type0 BIOS Characteristics Extension Byte 1
+  MiscExt = (MISC_BIOS_CHARACTERISTICS_EXTENSION*)&(mArmDefaultType0.Base.BIOSCharacteristicsExtensionBytes);
+
+  MiscExt->BiosReserved.AcpiIsSupported = 1;
+
+  // Type0 BIOS Characteristics Extension Byte 2
+  MiscExt->SystemReserved.BiosBootSpecIsSupported = 1;
+  MiscExt->SystemReserved.FunctionKeyNetworkBootIsSupported = 1;
+  MiscExt->SystemReserved.UefiSpecificationSupported = 1;
+
+  // Type0 BIOS Release
+  // TODO: to decide another way: If the system does not support the use of this
+  // field, the value is 0FFh
+  mArmDefaultType0.Base.SystemBiosMajorRelease = GetBiosVerMajor ();
+  mArmDefaultType0.Base.SystemBiosMinorRelease = GetBiosVerMinor ();
+
+  /* Update SMBIOS Type 0 EC Info */
+  CopyMem ((VOID *) &AsciiVersion, (VOID *) &PlatformHob->SmPmProVer,
+              sizeof (PlatformHob->SmPmProVer));
+  /* The AsciiVersion is formated as "major.minor" */
+  for (Index = 0; Index < (UINTN) AsciiStrLen (AsciiVersion); Index++) {
+    if (AsciiVersion[Index] == '.') {
+      AsciiVersion[Index] = '\0';
+      break;
+    }
+  }
+
+  mArmDefaultType0.Base.EmbeddedControllerFirmwareMajorRelease =
+    (UINT8) AsciiStrDecimalToUintn (AsciiVersion);
+  mArmDefaultType0.Base.EmbeddedControllerFirmwareMinorRelease =
+    (UINT8) AsciiStrDecimalToUintn (AsciiVersion + Index + 1);
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+InstallType3Structure (
+  IN EFI_SMBIOS_PROTOCOL  *Smbios
+  )
+{
+  EFI_STATUS          Status = EFI_SUCCESS;
+  EFI_SMBIOS_HANDLE   SmbiosHandle;
+
+  ASSERT (Smbios != NULL);
+
+  SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER*) &mArmDefaultType3)->Handle;
+  Status = Smbios->Add (
+                     Smbios,
+                     NULL,
+                     &SmbiosHandle,
+                     (EFI_SMBIOS_TABLE_HEADER*)&mArmDefaultType3
+                   );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "adding SMBIOS type 3 failed\n"));
+    //stop adding rather than continuing
+    return Status;
+  }
+
+  //Save this handle to type 2 table
+  mArmDefaultType2.Base.ChassisHandle = SmbiosHandle;
+
+  return Status;
+}
+
+/**
+   Install a whole table worth of structures
+
+   @param  Smbios               SMBIOS protocol.
+   @param  DefaultTables        A pointer to the default SMBIOS table structure.
+**/
+EFI_STATUS
+InstallStructures (
+  IN EFI_SMBIOS_PROTOCOL  *Smbios,
+  IN CONST VOID           *DefaultTables[]
+  )
+{
+  EFI_STATUS          Status = EFI_SUCCESS;
+  EFI_SMBIOS_HANDLE   SmbiosHandle;
+  UINTN               TableIndex;
+
+  ASSERT (Smbios != NULL);
+
+  for (TableIndex = 0; DefaultTables[TableIndex] != NULL; TableIndex++) {
+    SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER*) DefaultTables[TableIndex])->Handle;
+    Status = Smbios->Add (
+                       Smbios,
+                       NULL,
+                       &SmbiosHandle,
+                       (EFI_SMBIOS_TABLE_HEADER *) DefaultTables[TableIndex]
+                       );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: adding %d failed\n", __FUNCTION__, TableIndex));
+
+      //stop adding rather than continuing
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+UpdateSmbiosInfo (VOID)
+{
+  VOID                        *Hob;
+  PlatformInfoHob_V2          *PlatformHob;
+  CONST EFI_GUID              PlatformHobGuid = PLATFORM_INFO_HOB_GUID_V2;
+
+  /* Get the Platform HOB */
+  Hob = GetFirstGuidHob (&PlatformHobGuid);
+  ASSERT (Hob != NULL);
+  if (Hob == NULL) {
+    return;
+  }
+
+  PlatformHob = (PlatformInfoHob_V2 *) GET_GUID_HOB_DATA (Hob);
+
+  //
+  //  Update Type0 information
+  //
+  UpdateSmbiosType0 (PlatformHob);
+
+}
+
+/**
+   Install all structures from the DefaultTables structure
+
+   @param  Smbios               SMBIOS protocol
+
+**/
+EFI_STATUS
+InstallAllStructures (
+  IN EFI_SMBIOS_PROTOCOL  *Smbios
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  ASSERT (Smbios != NULL);
+
+  //Update SMBIOS Tables
+  UpdateSmbiosInfo ();
+
+  // Install Type 3 table
+  InstallType3Structure (Smbios);
+
+  // Install Tables
+  Status = InstallStructures (Smbios, DefaultCommonTables);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+   Installs SMBIOS information for ARM platforms
+
+   @param ImageHandle     Module's image handle
+   @param SystemTable     Pointer of EFI_SYSTEM_TABLE
+
+   @retval EFI_SUCCESS    Smbios data successfully installed
+   @retval Other          Smbios data was not installed
+
+**/
+EFI_STATUS
+EFIAPI
+SmbiosPlatformDxeEntry (
+  IN EFI_HANDLE             ImageHandle,
+  IN EFI_SYSTEM_TABLE* SystemTable
+  )
+{
+  EFI_STATUS            Status;
+  EFI_SMBIOS_PROTOCOL   *Smbios;
+
+  //
+  // Find the SMBIOS protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiSmbiosProtocolGuid,
+                  NULL,
+                  (VOID**) &Smbios
+                );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = InstallAllStructures (Smbios);
+  DEBUG ((DEBUG_ERROR, "SmbiosPlatform install - %r\n", Status));
+
+  return Status;
+}
-- 
2.17.1



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





More information about the edk2-devel-archive mailing list