public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v3 0/3] ArmPkg,MdePkg: Add Universal/Smbios and Drivers/VersionInfoPeim
@ 2020-11-11  0:17 Rebecca Cran
  2020-11-11  0:17 ` [PATCH v3 1/3] ArmPkg: Add ARM SMC Architecture functions to ArmStdSmc.h Rebecca Cran
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Rebecca Cran @ 2020-11-11  0:17 UTC (permalink / raw)
  To: devel
  Cc: Rebecca Cran, Leif Lindholm, Ard Biesheuvel, Michael D Kinney,
	Liming Gao, Zhiguang Liu

Much of the data for the SMBIOS tables is generic, and need not be
duplicated for each platform. This patch series introduces
ArmPkg/Universal/Smbios, which is largely copied from
edk2-platforms/Silicon/HiSilicon/Drivers/Smbios and generates SMBIOS
tables 0,1,2,3,4,713,32 and uses a combination of PCDs and calls into a
new OemMiscLib to get information which varies between platforms.

I plan to submit a patch against SbsaQemu to update it to use this new
functionality.

CHANGES FROM v2:

Fixed a bug in the processor characteristics handling.

Added new code to detect the cache size and architecture in a
generic way.

Removed various definitions from ArmLibPrivate.h that appear to be
obsolete.

Rebecca Cran (3):
  ArmPkg: Add ARM SMC Architecture functions to ArmStdSmc.h
  MdePkg: Update IndustryStandard/SmBios.h with processor status data
  ArmPkg: add Universal/Smbios as a generic SMBIOS library

 ArmPkg/ArmPkg.dec                             |  16 +
 .../VersionInfoPeim/VersionInfoPeim.inf       |  46 ++
 .../ProcessorSubClassDxe.inf                  |  55 ++
 .../Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf    |  89 +++
 ArmPkg/Include/Chipset/AArch64.h              |   4 +
 ArmPkg/Include/Guid/VersionInfoHobGuid.h      |  29 +
 ArmPkg/Include/IndustryStandard/ArmStdSmc.h   |  13 +
 ArmPkg/Include/Library/ArmLib.h               |   6 +
 ArmPkg/Include/Library/OemMiscLib.h           |  86 +++
 ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h    |   6 +
 ArmPkg/Library/ArmLib/ArmLibPrivate.h         | 100 ++-
 .../ProcessorSubClassDxe/ProcessorSubClass.h  |  34 +
 .../Smbios/SmbiosMiscDxe/SmbiosMisc.h         | 217 ++++++
 MdePkg/Include/IndustryStandard/SmBios.h      |  13 +
 .../Drivers/VersionInfoPeim/VersionInfoPeim.c |  90 +++
 ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c    |  15 +
 ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c          |  17 +
 .../ProcessorSubClassDxe/ProcessorSubClass.c  | 723 ++++++++++++++++++
 .../SmbiosMiscDxe/SmbiosMiscDataTable.c       |  50 ++
 .../SmbiosMiscDxe/SmbiosMiscEntryPoint.c      | 167 ++++
 .../SmbiosMiscDxe/Type00/MiscBiosVendorData.c |  99 +++
 .../Type00/MiscBiosVendorFunction.c           | 232 ++++++
 .../Type01/MiscSystemManufacturerData.c       |  43 ++
 .../Type01/MiscSystemManufacturerFunction.c   | 171 +++++
 .../Type02/MiscBaseBoardManufacturerData.c    |  51 ++
 .../MiscBaseBoardManufacturerFunction.c       | 184 +++++
 .../Type03/MiscChassisManufacturerData.c      |  58 ++
 .../Type03/MiscChassisManufacturerFunction.c  | 182 +++++
 .../MiscNumberOfInstallableLanguagesData.c    |  39 +
 ...MiscNumberOfInstallableLanguagesFunction.c | 154 ++++
 .../Type32/MiscBootInformationData.c          |  41 +
 .../Type32/MiscBootInformationFunction.c      |  66 ++
 .../Library/ArmLib/AArch64/AArch64Support.S   |   3 +
 .../Library/ArmLib/AArch64/ArmLibSupportV8.S  |   2 +-
 ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S   |   4 +
 ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm |   6 +-
 .../ProcessorSubClassStrings.uni              |  23 +
 .../SmbiosMiscDxe/SmbiosMiscLibString.uni     |  21 +
 .../SmbiosMiscDxe/Type00/MiscBiosVendor.uni   |  18 +
 .../Type01/MiscSystemManufacturer.uni         |  21 +
 .../Type02/MiscBaseBoardManufacturer.uni      |  21 +
 .../Type03/MiscChassisManufacturer.uni        |  18 +
 .../MiscNumberOfInstallableLanguages.uni      |  43 ++
 43 files changed, 3239 insertions(+), 37 deletions(-)
 create mode 100644 ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.inf
 create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
 create mode 100644 ArmPkg/Include/Guid/VersionInfoHobGuid.h
 create mode 100644 ArmPkg/Include/Library/OemMiscLib.h
 create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h
 create mode 100644 ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.c
 create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturer.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturer.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturer.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguages.uni

-- 
2.26.2


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

* [PATCH v3 1/3] ArmPkg: Add ARM SMC Architecture functions to ArmStdSmc.h
  2020-11-11  0:17 [PATCH v3 0/3] ArmPkg,MdePkg: Add Universal/Smbios and Drivers/VersionInfoPeim Rebecca Cran
@ 2020-11-11  0:17 ` Rebecca Cran
  2020-11-12 21:49   ` [edk2-devel] " Sami Mujawar
  2020-11-19 12:00   ` Leif Lindholm
  2020-11-11  0:17 ` [PATCH v3 2/3] MdePkg: Update IndustryStandard/SmBios.h with processor status data Rebecca Cran
  2020-11-11  0:17 ` [PATCH v3 3/3] ArmPkg: add Universal/Smbios as a generic SMBIOS library Rebecca Cran
  2 siblings, 2 replies; 14+ messages in thread
From: Rebecca Cran @ 2020-11-11  0:17 UTC (permalink / raw)
  To: devel
  Cc: Rebecca Cran, Leif Lindholm, Ard Biesheuvel, Michael D Kinney,
	Liming Gao, Zhiguang Liu

The ARM SMC Architecture functions were missing from ArmStdSmc.h.
Add them, based on the SMC Calling Convention version 1.2 specification.

Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
---
 ArmPkg/Include/IndustryStandard/ArmStdSmc.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/ArmPkg/Include/IndustryStandard/ArmStdSmc.h b/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
index 3509eb680f18..90f32c2249cd 100644
--- a/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
+++ b/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
@@ -1,5 +1,6 @@
 /** @file
 *
+*  Copyright (c) 2020, NUVIA Inc. All rights reserved.
 *  Copyright (c) 2012-2017, ARM Limited. All rights reserved.
 *
 *  SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -52,6 +53,18 @@
 #define ARM_SMC_MM_RET_DENIED              -3
 #define ARM_SMC_MM_RET_NO_MEMORY           -4
 
+// ARM Architecture Calls
+#define ARM_SMC_ID_ARCH_VERSION      0x80000000
+#define ARM_SMC_ID_ARCH_FEATURES     0x80000001
+#define ARM_SMC_ID_ARCH_SOC_ID       0x80000002
+#define ARM_SMC_ID_ARCH_WORKAROUND_1 0x80008000
+#define ARM_SMC_ID_ARCH_WORKAROUND_2 0x80007FFF
+
+#define ARM_SMC_ARCH_RET_SUCCESS            0
+#define ARM_SMC_ARCH_RET_NOT_SUPPORTED     -1
+#define ARM_SMC_ARCH_RET_NOT_REQUIRED      -2
+#define ARM_SMC_ARCH_RET_INVALID_PARAMETER -3
+
 /*
  * Power State Coordination Interface (PSCI) calls cover a subset of the
  * Standard Service Call range.
-- 
2.26.2


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

* [PATCH v3 2/3] MdePkg: Update IndustryStandard/SmBios.h with processor status data
  2020-11-11  0:17 [PATCH v3 0/3] ArmPkg,MdePkg: Add Universal/Smbios and Drivers/VersionInfoPeim Rebecca Cran
  2020-11-11  0:17 ` [PATCH v3 1/3] ArmPkg: Add ARM SMC Architecture functions to ArmStdSmc.h Rebecca Cran
@ 2020-11-11  0:17 ` Rebecca Cran
  2020-11-11  1:18   ` 回复: " gaoliming
                     ` (2 more replies)
  2020-11-11  0:17 ` [PATCH v3 3/3] ArmPkg: add Universal/Smbios as a generic SMBIOS library Rebecca Cran
  2 siblings, 3 replies; 14+ messages in thread
From: Rebecca Cran @ 2020-11-11  0:17 UTC (permalink / raw)
  To: devel
  Cc: Rebecca Cran, Leif Lindholm, Ard Biesheuvel, Michael D Kinney,
	Liming Gao, Zhiguang Liu

Add a bitfield that describes the structure of the byte in the Status
field of the SMBIOS Type 4 Processor Information table.

Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
---
 MdePkg/Include/IndustryStandard/SmBios.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/MdePkg/Include/IndustryStandard/SmBios.h b/MdePkg/Include/IndustryStandard/SmBios.h
index 1ee01645679a..bb4a3a8dc0d3 100644
--- a/MdePkg/Include/IndustryStandard/SmBios.h
+++ b/MdePkg/Include/IndustryStandard/SmBios.h
@@ -875,6 +875,19 @@ typedef struct {
   UINT16  ProcessorReserved2             :6;
 } PROCESSOR_CHARACTERISTIC_FLAGS;
 
+///
+/// Processor Information - Status
+///
+typedef union {
+  struct {
+    UINT8 CpuStatus       :3; // Indicates the status of the processor.
+    UINT8 Reserved1       :3; // Reserved for future use. Should be set to zero.
+    UINT8 SocketPopulated :1; // Indicates if the processor socket is populated or not.
+    UINT8 Reserved2       :1; // Reserved for future use. Should be set to zero.
+  } Bits;
+  UINT8 Data;
+} PROCESSOR_STATUS_DATA;
+
 typedef struct {
   PROCESSOR_SIGNATURE     Signature;
   PROCESSOR_FEATURE_FLAGS FeatureFlags;
-- 
2.26.2


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

* [PATCH v3 3/3] ArmPkg: add Universal/Smbios as a generic SMBIOS library
  2020-11-11  0:17 [PATCH v3 0/3] ArmPkg,MdePkg: Add Universal/Smbios and Drivers/VersionInfoPeim Rebecca Cran
  2020-11-11  0:17 ` [PATCH v3 1/3] ArmPkg: Add ARM SMC Architecture functions to ArmStdSmc.h Rebecca Cran
  2020-11-11  0:17 ` [PATCH v3 2/3] MdePkg: Update IndustryStandard/SmBios.h with processor status data Rebecca Cran
@ 2020-11-11  0:17 ` Rebecca Cran
  2020-11-16 13:43   ` [edk2-devel] " Sami Mujawar
  2020-11-19 12:58   ` Leif Lindholm
  2 siblings, 2 replies; 14+ messages in thread
From: Rebecca Cran @ 2020-11-11  0:17 UTC (permalink / raw)
  To: devel
  Cc: Rebecca Cran, Leif Lindholm, Ard Biesheuvel, Michael D Kinney,
	Liming Gao, Zhiguang Liu

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=ASCII, Size: 128373 bytes --]

Much of the data for the SMBIOS tables is generic, and need not be
duplicated for each platform.

Adapt code from edk2-platforms/Silicon/HiSilicon/Drivers/Smbios and
edk2-platforms/Silicon/HiSilicon/Drivers/VersionInfoPeim, making them
generic, and place them into edk2/ArmPkg/Universal/Smbios and
edk2/ArmPkg/Drivers/VersionInfoPeim respectively.

They depend on each platform implementing an OemMiscLib that provides
OEM specific information such as CPU and cache information.

The VersionInfoPeim generates the release date from the build time, and
fetches the version string from PcdFirmwareVersionString.

Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
---
 ArmPkg/ArmPkg.dec                             |  16 +
 .../VersionInfoPeim/VersionInfoPeim.inf       |  46 ++
 .../ProcessorSubClassDxe.inf                  |  55 ++
 .../Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf    |  89 +++
 ArmPkg/Include/Chipset/AArch64.h              |   4 +
 ArmPkg/Include/Guid/VersionInfoHobGuid.h      |  29 +
 ArmPkg/Include/Library/ArmLib.h               |   6 +
 ArmPkg/Include/Library/OemMiscLib.h           |  86 +++
 ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h    |   6 +
 ArmPkg/Library/ArmLib/ArmLibPrivate.h         | 100 ++-
 .../ProcessorSubClassDxe/ProcessorSubClass.h  |  34 +
 .../Smbios/SmbiosMiscDxe/SmbiosMisc.h         | 217 ++++++
 .../Drivers/VersionInfoPeim/VersionInfoPeim.c |  90 +++
 ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c    |  15 +
 ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c          |  17 +
 .../ProcessorSubClassDxe/ProcessorSubClass.c  | 723 ++++++++++++++++++
 .../SmbiosMiscDxe/SmbiosMiscDataTable.c       |  50 ++
 .../SmbiosMiscDxe/SmbiosMiscEntryPoint.c      | 167 ++++
 .../SmbiosMiscDxe/Type00/MiscBiosVendorData.c |  99 +++
 .../Type00/MiscBiosVendorFunction.c           | 232 ++++++
 .../Type01/MiscSystemManufacturerData.c       |  43 ++
 .../Type01/MiscSystemManufacturerFunction.c   | 171 +++++
 .../Type02/MiscBaseBoardManufacturerData.c    |  51 ++
 .../MiscBaseBoardManufacturerFunction.c       | 184 +++++
 .../Type03/MiscChassisManufacturerData.c      |  58 ++
 .../Type03/MiscChassisManufacturerFunction.c  | 182 +++++
 .../MiscNumberOfInstallableLanguagesData.c    |  39 +
 ...MiscNumberOfInstallableLanguagesFunction.c | 154 ++++
 .../Type32/MiscBootInformationData.c          |  41 +
 .../Type32/MiscBootInformationFunction.c      |  66 ++
 .../Library/ArmLib/AArch64/AArch64Support.S   |   3 +
 .../Library/ArmLib/AArch64/ArmLibSupportV8.S  |   2 +-
 ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S   |   4 +
 ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm |   6 +-
 .../ProcessorSubClassStrings.uni              |  23 +
 .../SmbiosMiscDxe/SmbiosMiscLibString.uni     |  21 +
 .../SmbiosMiscDxe/Type00/MiscBiosVendor.uni   |  18 +
 .../Type01/MiscSystemManufacturer.uni         |  21 +
 .../Type02/MiscBaseBoardManufacturer.uni      |  21 +
 .../Type03/MiscChassisManufacturer.uni        |  18 +
 .../MiscNumberOfInstallableLanguages.uni      |  43 ++
 41 files changed, 3213 insertions(+), 37 deletions(-)
 create mode 100644 ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.inf
 create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
 create mode 100644 ArmPkg/Include/Guid/VersionInfoHobGuid.h
 create mode 100644 ArmPkg/Include/Library/OemMiscLib.h
 create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h
 create mode 100644 ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.c
 create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturer.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturer.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturer.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguages.uni

diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index eaf1072d9ef3..64cfb7dc65e3 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -45,6 +45,8 @@ [Guids.common]
   # Include/Guid/ArmMpCoreInfo.h
   gArmMpCoreInfoGuid = { 0xa4ee0728, 0xe5d7, 0x4ac5,  {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} }
 
+  gVersionInfoHobGuid = { 0xe13a14c, 0x859c, 0x4f22, {0x82, 0xbd, 0x18, 0xe, 0xe1, 0x42, 0x12, 0xbf } }
+
 [Protocols.common]
   ## Arm System Control and Management Interface(SCMI) Base protocol
   ## ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h
@@ -115,6 +117,20 @@ [PcdsFixedAtBuild.common]
   # The Primary Core is ClusterId[0] & CoreId[0]
   gArmTokenSpaceGuid.PcdArmPrimaryCore|0|UINT32|0x00000037
 
+  #
+  # SMBIOS PCDs
+  #
+  gArmTokenSpaceGuid.PcdSystemProductName|L""|VOID*|0x30000053
+  gArmTokenSpaceGuid.PcdSystemVersion|L""|VOID*|0x30000054
+  gArmTokenSpaceGuid.PcdBaseBoardManufacturer|L""|VOID*|0x30000055
+  gArmTokenSpaceGuid.PcdBaseBoardProductName|L""|VOID*|0x30000056
+  gArmTokenSpaceGuid.PcdBaseBoardVersion|L""|VOID*|0x30000057
+  gArmTokenSpaceGuid.PcdProcessorManufacturer|L""|VOID*|0x30000071
+  gArmTokenSpaceGuid.PcdProcessorVersion|L""|VOID*|0x30000072
+  gArmTokenSpaceGuid.PcdProcessorSerialNumber|L""|VOID*|0x30000073
+  gArmTokenSpaceGuid.PcdProcessorAssetTag|L""|VOID*|0x30000074
+  gArmTokenSpaceGuid.PcdProcessorPartNumber|L""|VOID*|0x30000075
+
   #
   # ARM L2x0 PCDs
   #
diff --git a/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.inf b/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.inf
new file mode 100644
index 000000000000..c813dd84de4c
--- /dev/null
+++ b/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.inf
@@ -0,0 +1,46 @@
+#/** @file
+#
+#    Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2016, Linaro Limited. All rights reserved.
+#
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 1.29
+  BASE_NAME                      = VersionInfoPeim
+  FILE_GUID                      = 3d45d0a0-4ded-4c01-b16f-2b3007c1fbe2
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = VersionInfoEntry
+
+[Sources.common]
+  VersionInfoPeim.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  PcdLib
+  PeimEntryPoint
+  PrintLib
+  SerialPortLib
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+
+[Guids]
+  gVersionInfoHobGuid
+
+[Depex]
+  TRUE
+
+[BuildOptions]
+
diff --git a/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
new file mode 100644
index 000000000000..715f66912983
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
@@ -0,0 +1,55 @@
+#/** @file
+#
+#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2015, Linaro Limited. All rights reserved.
+#
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+
+[Defines]
+  INF_VERSION                    = 1.29
+  BASE_NAME                      = ProcessorSubClass
+  FILE_GUID                      = f3fe0e33-ea38-4069-9fb5-be23407207c7
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = ProcessorSubClassEntryPoint
+
+[Sources]
+  ProcessorSubClass.c
+  ProcessorSubClassStrings.uni
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  ArmSmcLib
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  HiiLib
+  IoLib
+  MemoryAllocationLib
+  OemMiscLib
+  PcdLib
+  PrintLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdProcessorManufacturer
+  gArmTokenSpaceGuid.PcdProcessorVersion
+  gArmTokenSpaceGuid.PcdProcessorSerialNumber
+  gArmTokenSpaceGuid.PcdProcessorAssetTag
+  gArmTokenSpaceGuid.PcdProcessorPartNumber
+
+[Guids]
+
+
+[Depex]
+  gEfiSmbiosProtocolGuid
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
new file mode 100644
index 000000000000..1954f7207267
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
@@ -0,0 +1,89 @@
+## @file
+# Component description file for SmbiosMisc instance.
+#
+# Parses the MiscSubclassDataTable and reports any generated data to the DataHub.
+#  All .uni file who tagged with "ToolCode="DUMMY"" in following file list is included by
+#  MiscSubclassDriver.uni file, the StrGather tool will expand MiscSubclassDriver.uni file
+#  and parse all .uni file.
+# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+# Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+# Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+##
+
+
+[Defines]
+  INF_VERSION                    = 1.29
+  BASE_NAME                      = SmbiosMiscDxe
+  FILE_GUID                      = 7e5e26d4-0be9-401f-b5e1-1c2bda7ca777
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmbiosMiscEntryPoint
+
+[Sources]
+  SmbiosMisc.h
+  SmbiosMiscDataTable.c
+  SmbiosMiscEntryPoint.c
+  SmbiosMiscLibString.uni
+  Type00/MiscBiosVendorData.c
+  Type00/MiscBiosVendorFunction.c
+  Type01/MiscSystemManufacturerData.c
+  Type01/MiscSystemManufacturerFunction.c
+  Type02/MiscBaseBoardManufacturerData.c
+  Type02/MiscBaseBoardManufacturerFunction.c
+  Type03/MiscChassisManufacturerData.c
+  Type03/MiscChassisManufacturerFunction.c
+  Type13/MiscNumberOfInstallableLanguagesData.c
+  Type13/MiscNumberOfInstallableLanguagesFunction.c
+  Type32/MiscBootInformationData.c
+  Type32/MiscBootInformationFunction.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  PcdLib
+  HiiLib
+  HobLib
+  MemoryAllocationLib
+  OemMiscLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdFdSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareReleaseDateString
+  gArmTokenSpaceGuid.PcdSystemProductName
+  gArmTokenSpaceGuid.PcdSystemVersion
+  gArmTokenSpaceGuid.PcdBaseBoardManufacturer
+  gArmTokenSpaceGuid.PcdBaseBoardProductName
+  gArmTokenSpaceGuid.PcdBaseBoardVersion
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang
+
+[Guids]
+  gEfiGenericVariableGuid
+  gVersionInfoHobGuid
+
+[Depex]
+  gEfiSmbiosProtocolGuid
+
+
diff --git a/ArmPkg/Include/Chipset/AArch64.h b/ArmPkg/Include/Chipset/AArch64.h
index 0ade5cce91c3..7c2b592f92ee 100644
--- a/ArmPkg/Include/Chipset/AArch64.h
+++ b/ArmPkg/Include/Chipset/AArch64.h
@@ -112,6 +112,10 @@
 #define ARM_VECTOR_LOW_A32_FIQ  0x700
 #define ARM_VECTOR_LOW_A32_SERR 0x780
 
+// The ID_AA64MMFR2_EL1 register was added in ARMv8.2. Since we
+// build for ARMv8.0, we need to define the register here.
+#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
+
 #define VECTOR_BASE(tbl)          \
   .section .text.##tbl##,"ax";    \
   .align 11;                      \
diff --git a/ArmPkg/Include/Guid/VersionInfoHobGuid.h b/ArmPkg/Include/Guid/VersionInfoHobGuid.h
new file mode 100644
index 000000000000..9eeb0a5f7482
--- /dev/null
+++ b/ArmPkg/Include/Guid/VersionInfoHobGuid.h
@@ -0,0 +1,29 @@
+/** @file
+*
+*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2016, Linaro Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#ifndef _VERSION_INFO_HOB_GUID_H_
+#define _VERSION_INFO_HOB_GUID_H_
+
+// {0E13A14C-859C-4f22-82BD-180EE14212BF}
+#define VERSION_INFO_HOB_GUID \
+  {0xe13a14c, 0x859c, 0x4f22, {0x82, 0xbd, 0x18, 0xe, 0xe1, 0x42, 0x12, 0xbf}}
+
+extern GUID gVersionInfoHobGuid;
+
+#pragma pack(1)
+
+typedef struct {
+  EFI_TIME BuildTime;
+  CHAR16   String[1];
+} VERSION_INFO;
+
+#pragma pack()
+
+#endif
+
diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h
index 5a27b7c2fc27..4a740b6ca298 100644
--- a/ArmPkg/Include/Library/ArmLib.h
+++ b/ArmPkg/Include/Library/ArmLib.h
@@ -132,6 +132,12 @@ ArmIsArchTimerImplemented (
   VOID
   );
 
+UINTN
+EFIAPI
+ArmIsCcidxImplemented (
+  VOID
+  );
+
 UINTN
 EFIAPI
 ArmReadIdPfr0 (
diff --git a/ArmPkg/Include/Library/OemMiscLib.h b/ArmPkg/Include/Library/OemMiscLib.h
new file mode 100644
index 000000000000..78dc70426e24
--- /dev/null
+++ b/ArmPkg/Include/Library/OemMiscLib.h
@@ -0,0 +1,86 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, Linaro Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+
+#ifndef OEM_MISC_LIB_H
+#define OEM_MISC_LIB_H
+
+#include <Uefi.h>
+#include <IndustryStandard/SmBios.h>
+
+typedef enum
+{
+  CPU_CACHE_L1 = 0,
+  CPU_CACHE_L2,
+  CPU_CACHE_L3,
+  CPU_CACHE_L4,
+  CPU_CACHE_L5,
+  CPU_CACHE_L6,
+  CPU_CACHE_L7
+} CPU_CACHE_LEVEL;
+
+typedef struct
+{
+  UINT8 Voltage;
+  UINT16 CurrentSpeed;
+  UINT16 MaxSpeed;
+  UINT16 ExternalClock;
+  UINT16 CoreCount;
+  UINT16 CoresEnabled;
+  UINT16 ThreadCount;
+} MISC_PROCESSOR_DATA;
+
+typedef enum {
+    ProductNameType01,
+    SerialNumType01,
+    UuidType01,
+    SystemManufacturerType01,
+    AssertTagType02,
+    SrNumType02,
+    BoardManufacturerType02,
+    AssetTagType03,
+    SrNumType03,
+    VersionType03,
+    ChassisTypeType03 ,
+    ManufacturerType03,
+} GET_INFO_BMC_OFFSET;
+
+UINTN OemGetCpuFreq (UINT8 Socket);
+
+BOOLEAN
+OemGetProcessorInformation (
+  IN UINTN ProcessorNumber,
+  IN OUT PROCESSOR_STATUS_DATA *ProcessorStatus,
+  IN OUT PROCESSOR_CHARACTERISTIC_FLAGS *ProcessorCharacteristics,
+  IN OUT MISC_PROCESSOR_DATA *MiscProcessorData
+  );
+
+BOOLEAN OemGetCacheInformation (
+  IN UINT8 CacheLevel,
+  IN OUT SMBIOS_TABLE_TYPE7 *SmbiosCacheTable
+  );
+
+UINT8 OemGetProcessorMaxSockets (VOID);
+
+UINTN PlatformGetCpuFreq (IN UINT8 Socket);
+
+UINTN PlatformGetCoreCount (VOID);
+
+EFI_STATUS OemGetChassisType(OUT UINT8 *ChassisType);
+
+BOOLEAN OemIsSocketPresent (UINTN Socket);
+
+VOID
+UpdateSmbiosInfo (
+  IN EFI_HII_HANDLE mHiiHandle,
+  IN EFI_STRING_ID TokenToUpdate,
+  IN UINT8 Offset
+  );
+
+#endif // OEM_MISC_LIB_H
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
index b2c8a8ea0b84..d6bcfc3b82ae 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
@@ -35,5 +35,11 @@ ArmCleanInvalidateDataCacheEntryBySetWay (
   IN  UINTN   SetWayFormat
   );
 
+UINTN
+EFIAPI
+ArmReadIdMmfr2 (
+  VOID
+  );
+
 #endif // __AARCH64_LIB_H__
 
diff --git a/ArmPkg/Library/ArmLib/ArmLibPrivate.h b/ArmPkg/Library/ArmLib/ArmLibPrivate.h
index 2e90739eb858..d57c80edb572 100644
--- a/ArmPkg/Library/ArmLib/ArmLibPrivate.h
+++ b/ArmPkg/Library/ArmLib/ArmLibPrivate.h
@@ -9,46 +9,76 @@
 #ifndef __ARM_LIB_PRIVATE_H__
 #define __ARM_LIB_PRIVATE_H__
 
-#define CACHE_SIZE_4_KB             (3UL)
-#define CACHE_SIZE_8_KB             (4UL)
-#define CACHE_SIZE_16_KB            (5UL)
-#define CACHE_SIZE_32_KB            (6UL)
-#define CACHE_SIZE_64_KB            (7UL)
-#define CACHE_SIZE_128_KB           (8UL)
+typedef union {
+  struct {
+    UINT32    InD           :1;
+    UINT32    Level         :3;
+    UINT32    TnD           :1;
+    UINT32    Reserved      :27;
+  } Bits;
+  UINT32 Data;
+} CSSELR_DATA;
 
-#define CACHE_ASSOCIATIVITY_DIRECT  (0UL)
-#define CACHE_ASSOCIATIVITY_4_WAY   (2UL)
-#define CACHE_ASSOCIATIVITY_8_WAY   (3UL)
+typedef enum
+{
+  CSSELR_CACHE_TYPE_DATA_OR_UNIFIED = 0,
+  CSSELR_CACHE_TYPE_INSTRUCTION = 1
+} CSSELR_CACHE_TYPE;
 
-#define CACHE_PRESENT               (0UL)
-#define CACHE_NOT_PRESENT           (1UL)
+typedef union {
+  struct {
+    UINT64    LineSize           :3;
+    UINT64    Associativity      :10;
+    UINT64    NumSets            :15;
+    UINT64    Unknown            :4;
+    UINT64    Reserved           :32;
+  } BitsNonCcidx;
+  struct {
+    UINT64    LineSize           :3;
+    UINT64    Associativity      :21;
+    UINT64    Reserved1          :8;
+    UINT64    NumSets            :24;
+    UINT64    Reserved2          :8;
+  } BitsCcidx;
+  UINT64 Data;
+} CCSIDR_DATA;
 
-#define CACHE_LINE_LENGTH_32_BYTES  (2UL)
+typedef union {
+  struct {
+    UINT32 NumSets               :24;
+    UINT32 Reserved              :8;
+  } Bits;
+  UINT32 Data;
+} CSSIDR2_DATA;
 
-#define SIZE_FIELD_TO_CACHE_SIZE(x)           (((x) >> 6) & 0x0F)
-#define SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(x)  (((x) >> 3) & 0x07)
-#define SIZE_FIELD_TO_CACHE_PRESENCE(x)       (((x) >> 2) & 0x01)
-#define SIZE_FIELD_TO_CACHE_LINE_LENGTH(x)    (((x) >> 0) & 0x03)
+// The lower 32 bits are the same for both AARCH32 and AARCH64
+// so we can use the same structure for both.
+typedef union {
+  struct {
+    UINT32    Ctype1   : 3;
+    UINT32    Ctype2   : 3;
+    UINT32    Ctype3   : 3;
+    UINT32    Ctype4   : 3;
+    UINT32    Ctype5   : 3;
+    UINT32    Ctype6   : 3;
+    UINT32    Ctype7   : 3;
+    UINT32    LoUIS    : 3;
+    UINT32    LoC      : 3;
+    UINT32    LoUU     : 3;
+    UINT32    Icb      : 3;
+  } Bits;
+  UINT32 Data;
+} CLIDR_DATA;
 
-#define DATA_CACHE_SIZE_FIELD(x)              (((x) >> 12) & 0x0FFF)
-#define INSTRUCTION_CACHE_SIZE_FIELD(x)       (((x) >>  0) & 0x0FFF)
+typedef enum {
+  CLIDR_CACHE_TYPE_NONE = 0,
+  CLIDR_CACHE_TYPE_INSTRUCTION_ONLY = 1,
+  CLIDR_CACHE_TYPE_DATA_ONLY = 2,
+  CLIDR_CACHE_TYPE_SEPARATE = 3,
+  CLIDR_CACHE_TYPE_UNIFIED = 4
+} CLIDR_CACHE_TYPE;
 
-#define DATA_CACHE_SIZE(x)                    (SIZE_FIELD_TO_CACHE_SIZE(DATA_CACHE_SIZE_FIELD(x)))
-#define DATA_CACHE_ASSOCIATIVITY(x)           (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(DATA_CACHE_SIZE_FIELD(x)))
-#define DATA_CACHE_PRESENT(x)                 (SIZE_FIELD_TO_CACHE_PRESENCE(DATA_CACHE_SIZE_FIELD(x)))
-#define DATA_CACHE_LINE_LENGTH(x)             (SIZE_FIELD_TO_CACHE_LINE_LENGTH(DATA_CACHE_SIZE_FIELD(x)))
-
-#define INSTRUCTION_CACHE_SIZE(x)             (SIZE_FIELD_TO_CACHE_SIZE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
-#define INSTRUCTION_CACHE_ASSOCIATIVITY(x)    (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(INSTRUCTION_CACHE_SIZE_FIELD(x)))
-#define INSTRUCTION_CACHE_PRESENT(x)          (SIZE_FIELD_TO_CACHE_PRESENCE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
-#define INSTRUCTION_CACHE_LINE_LENGTH(x)      (SIZE_FIELD_TO_CACHE_LINE_LENGTH(INSTRUCTION_CACHE_SIZE_FIELD(x)))
-
-#define CACHE_TYPE(x)                         (((x) >> 25) & 0x0F)
-#define CACHE_TYPE_WRITE_BACK                 (0x0EUL)
-
-#define CACHE_ARCHITECTURE(x)                 (((x) >> 24) & 0x01)
-#define CACHE_ARCHITECTURE_UNIFIED            (0UL)
-#define CACHE_ARCHITECTURE_SEPARATE           (1UL)
+#define CLIDR_GET_CACHE_TYPE(x, level) ((x >> (3 * level)) & 0b111)
 
 VOID
 CPSRMaskInsert (
@@ -61,7 +91,7 @@ CPSRRead (
   VOID
   );
 
-UINT32
+UINTN
 ReadCCSIDR (
   IN UINT32 CSSELR
   );
diff --git a/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h
new file mode 100644
index 000000000000..a8a4ab2b1beb
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h
@@ -0,0 +1,34 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, Linaro Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#ifndef PROCESSOR_SUBCLASS_DRIVER_H
+#define PROCESSOR_SUBCLASS_DRIVER_H
+
+#include <Uefi.h>
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/ArmStdSmc.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmSmcLib.h>
+#include <Library/ArmLib/ArmLibPrivate.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HiiLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/OemMiscLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+extern UINT8 ProcessorSubClassStrings[];
+
+#endif // PROCESSOR_SUBCLASS_DRIVER_H
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h
new file mode 100644
index 000000000000..80c77517fabc
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h
@@ -0,0 +1,217 @@
+/**@file
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  SmbiosMisc.h
+
+Abstract:
+
+  Header file for the SmbiosMisc Driver.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#ifndef SMBIOS_MISC_DRIVER_H
+#define SMBIOS_MISC_DRIVER_H
+
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/HiiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/DebugMask.h>
+#include <Library/OemMiscLib.h>
+
+#include <Library/PrintLib.h>
+
+//
+// Data table entry update function.
+//
+typedef EFI_STATUS (EFIAPI EFI_MISC_SMBIOS_DATA_FUNCTION) (
+  IN  VOID                 *RecordData,
+  IN  EFI_SMBIOS_PROTOCOL  *Smbios
+  );
+
+
+//
+// Data table entry definition.
+//
+typedef struct {
+  //
+  // intermediate input data for SMBIOS record
+  //
+  VOID                              *RecordData;
+  EFI_MISC_SMBIOS_DATA_FUNCTION     *Function;
+} EFI_MISC_SMBIOS_DATA_TABLE;
+
+
+//
+// Data Table extern definitions.
+//
+#define MISC_SMBIOS_TABLE_EXTERNS(NAME1, NAME2, NAME3) \
+extern NAME1 NAME2 ## Data; \
+extern EFI_MISC_SMBIOS_DATA_FUNCTION NAME3 ## Function;
+
+
+//
+// Data Table entries
+//
+
+#define MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(NAME1, NAME2) \
+{ \
+  & NAME1 ## Data, \
+    NAME2 ## Function \
+}
+
+
+//
+// Global definition macros.
+//
+#define MISC_SMBIOS_TABLE_DATA(NAME1, NAME2) \
+  NAME1 NAME2 ## Data
+
+#define MISC_SMBIOS_TABLE_FUNCTION(NAME2) \
+  EFI_STATUS EFIAPI NAME2 ## Function( \
+  IN  VOID                  *RecordData, \
+  IN  EFI_SMBIOS_PROTOCOL   *Smbios \
+  )
+
+//
+// Data Table Array Entries
+//
+extern EFI_HII_HANDLE               mHiiHandle;
+
+typedef struct _EFI_TYPE11_OEM_STRING{
+  UINT8                               Offset;
+  EFI_STRING_ID                       RefOemDefineString;
+} EFI_TYPE11_OEM_STRING;
+
+typedef struct _EFI_TYPE12_SYSTEM_CONFIGURATION_OPTIONS_STRING{
+  UINT8                               Offset;
+  EFI_STRING_ID                       RefType12SystemConfigurationOptionsString;
+} EFI_TYPE12_SYSTEM_CONFIGURATION_OPTIONS_STRING;
+
+typedef struct _EFI_TYPE13_BIOS_LANGUAGE_INFORMATION_STRING{
+  UINT8                               *LanguageSignature;
+  EFI_STRING_ID                       InstallableLanguageLongString;
+  EFI_STRING_ID                       InstallableLanguageAbbreviateString;
+} EFI_TYPE13_BIOS_LANGUAGE_INFORMATION_STRING;
+
+typedef struct _EFI_TYPE40_ADDITIONAL_INFORMATION_ENTRY{
+  UINT8           RefType;
+  UINT8           RefOffset;
+  EFI_STRING_ID   RefString;
+  UINT8           Value;
+} EFI_TYPE40_ADDITIONAL_INFORMATION_ENTRY;
+
+typedef enum {
+  STRING,
+  DATA,
+} OEM_DEFINE_TYPE;
+
+typedef struct {
+  OEM_DEFINE_TYPE                Type;
+  UINTN                          Token;
+  UINTN                          DataSize;
+} OEM_DEFINE_INFO_STRING;
+
+typedef struct {
+  OEM_DEFINE_TYPE                Type;
+  UINTN                          DataAddress;
+  UINTN                          DataSize;
+} OEM_DEFINE_INFO_DATA;
+
+typedef union {
+  OEM_DEFINE_INFO_STRING         DefineString;
+  OEM_DEFINE_INFO_DATA           DefineData;
+} EFI_OEM_DEFINE_ARRAY;
+
+typedef struct _DMI_STRING_STRUCTURE {
+  UINT8                                 Type;
+  UINT8                                 Offset;
+  UINT8                                 Valid;
+  UINT16                                Length;
+  UINT8                                 String[1]; // Variable length field
+} DMI_STRING_STRUCTURE;
+
+typedef struct {
+  UINT8                                 Type;           // The SMBIOS structure type
+  UINT8                                 FixedOffset;    // The offset of the string reference
+                                                        // within the structure's fixed data.
+} DMI_UPDATABLE_STRING;
+
+EFI_STATUS
+FindString (
+  IN UINT8                              Type,
+  IN UINT8                              Offset,
+  IN EFI_STRING_ID                      TokenToUpdate
+);
+
+EFI_STATUS
+FindUuid (
+  EFI_GUID                    *Uuid
+);
+
+EFI_STATUS
+StringToBiosVeriosn (
+  IN  EFI_STRING_ID                     BiosVersionToken,
+  OUT UINT8                             *MajorVersion,
+  OUT UINT8                             *MinorVersion
+);
+
+
+/**
+ Logs SMBIOS record.
+
+ @param [in]   Buffer         Pointer to the data buffer.
+ @param [in]   SmbiosHandle   Pointer for retrieve handle.
+
+**/
+EFI_STATUS
+LogSmbiosData (
+  IN       UINT8                      *Buffer,
+  IN  OUT  EFI_SMBIOS_HANDLE          *SmbiosHandle
+  );
+
+/**
+ Get Link Type Handle.
+
+ @param [in]   SmbiosType     Get this Type from SMBIOS table
+ @param [out]  HandleArray    Pointer to Hadndler array with has been free by caller
+ @param [out]  HandleCount    Pointer to Hadndler Counter
+
+**/
+VOID
+GetLinkTypeHandle(
+  IN  UINT8                 SmbiosType,
+  OUT UINT16                **HandleArray,
+  OUT UINTN                 *HandleCount
+  );
+
+//
+// Data Table Array
+//
+extern EFI_MISC_SMBIOS_DATA_TABLE   mSmbiosMiscDataTable[];
+
+//
+// Data Table Array Entries
+//
+extern UINTN                        mSmbiosMiscDataTableEntries;
+
+extern UINT8                        SmbiosMiscDxeStrings[];
+
+
+
+#endif // SMBIOS_MISC_DRIVER_H
diff --git a/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.c b/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.c
new file mode 100644
index 000000000000..5b5dc47e7ea9
--- /dev/null
+++ b/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.c
@@ -0,0 +1,90 @@
+/** @file
+*
+*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2016, Linaro Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <Uefi.h>
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrintLib.h>
+#include <Library/SerialPortLib.h>
+
+#include <Guid/VersionInfoHobGuid.h>
+
+struct MonthDescription {
+  CONST CHAR8* MonthStr;
+  UINT32    MonthInt;
+} gMonthDescription[] = {
+  { "Jan", 1 },
+  { "Feb", 2 },
+  { "Mar", 3 },
+  { "Apr", 4 },
+  { "May", 5 },
+  { "Jun", 6 },
+  { "Jul", 7 },
+  { "Aug", 8 },
+  { "Sep", 9 },
+  { "Oct", 10 },
+  { "Nov", 11 },
+  { "Dec", 12 },
+  { "???", 1 },  // Use 1 as default month
+};
+
+VOID GetReleaseTime (EFI_TIME *Time)
+{
+  CONST CHAR8      *ReleaseDate = __DATE__;
+  CONST CHAR8      *ReleaseTime = __TIME__;
+  UINTN            i;
+
+  for (i = 0;i < 12;i++) {
+    if (AsciiStrnCmp (ReleaseDate, gMonthDescription[i].MonthStr, 3) == 0) {
+      break;
+    }
+  }
+
+  Time->Month = gMonthDescription[i].MonthInt;
+  Time->Day = AsciiStrDecimalToUintn(ReleaseDate+4);
+  Time->Year = AsciiStrDecimalToUintn(ReleaseDate+7);
+  Time->Hour = AsciiStrDecimalToUintn(ReleaseTime);
+  Time->Minute = AsciiStrDecimalToUintn(ReleaseTime+3);
+  Time->Second = AsciiStrDecimalToUintn(ReleaseTime+6);
+
+  return;
+}
+
+EFI_STATUS
+EFIAPI
+VersionInfoEntry (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  VERSION_INFO *VersionInfo;
+  EFI_TIME Time = {0};
+  CONST CHAR16 *ReleaseString =
+    (CHAR16 *) FixedPcdGetPtr (PcdFirmwareVersionString);
+
+  GetReleaseTime (&Time);
+
+  VersionInfo = BuildGuidHob (&gVersionInfoHobGuid,
+                      sizeof (VERSION_INFO) -
+                      sizeof (VersionInfo->String) +
+                      StrSize (ReleaseString));
+  if (VersionInfo == NULL) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%d] Build HOB failed!\n", __FILE__, __LINE__));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  CopyMem (&VersionInfo->BuildTime, &Time, sizeof (EFI_TIME));
+  CopyMem (VersionInfo->String, ReleaseString, StrSize (ReleaseString));
+
+  return EFI_SUCCESS;
+}
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
index 3fbd591192e2..134fe56cb387 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
@@ -71,3 +71,18 @@ ArmCleanDataCache (
   ArmDataSynchronizationBarrier ();
   AArch64DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
 }
+
+UINTN
+EFIAPI
+ArmIsCcidxImplemented (
+  VOID
+  )
+{
+  UINTN Mmfr2;
+
+  Mmfr2 = ArmReadIdMmfr2 ();
+  if (((Mmfr2 >> 20) & 0xF) == 1)
+    return 1;
+
+  return 0;
+}
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
index 2c4a23e1a1b2..4466e39dcc28 100644
--- a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
+++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
@@ -71,3 +71,20 @@ ArmCleanDataCache (
   ArmDataSynchronizationBarrier ();
   ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
 }
+
+UINTN
+EFIAPI
+ArmIsCcidxImplemented (
+  VOID
+  )
+{
+  UINTN Mmfr4;
+  
+  Mmfr4 = ArmReadIdMmfr4 ();
+  if (((Mmfr4 >> 24) & 0xF) == 1) {
+    return 1;
+  }
+
+  return 0;
+}
+
diff --git a/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c
new file mode 100644
index 000000000000..2b29945ce966
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c
@@ -0,0 +1,723 @@
+/** @file
+*
+*  Copyright (c) 2020, NUVIA Inc. All rights reserved.
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, Linaro Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include "ProcessorSubClass.h"
+
+EFI_HII_HANDLE                  mHiiHandle;
+
+EFI_SMBIOS_PROTOCOL             *mSmbios;
+
+SMBIOS_TABLE_TYPE4   mSmbiosProcessorTable[] = {
+  //CPU0
+  {
+    {                                               //Header
+      EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION,          //Type
+      sizeof (SMBIOS_TABLE_TYPE4),                    //Length
+      0                                               //Handle
+    },
+    1,                                              //Socket
+    CentralProcessor,                               //ProcessorType
+    ProcessorFamilyIndicatorFamily2,                //ProcessorFamily
+    2,                                              //ProcessorManufacture
+    {                                               //ProcessorId
+      {                                               //Signature
+        0
+      },
+      {                                               //FeatureFlags
+        0
+      }
+    },
+    3,                                              //ProcessorVersion
+    {                                               //Voltage
+      0
+    },
+    0,                                              //ExternalClock
+    0,                                              //MaxSpeed
+    0,                                              //CurrentSpeed
+    0,                                              //Status
+    ProcessorUpgradeUnknown,                        //ProcessorUpgrade
+    0xFFFF,                                         //L1CacheHandle
+    0xFFFF,                                         //L2CacheHandle
+    0xFFFF,                                         //L3CacheHandle
+    4,                                              //SerialNumber
+    5,                                              //AssetTag
+    6,                                              //PartNumber
+    0,                                              //CoreCount
+    0,                                              //EnabledCoreCount
+    0,                                              //ThreadCount
+    0,                                              //ProcessorCharacteristics
+    ProcessorFamilyARM,                             //ProcessorFamily2
+    0,                                              //CoreCount2
+    0,                                              //EnabledCoreCount2
+    0                                               //ThreadCount2
+  },
+
+  //CPU1
+  {
+    {                                               //Header
+      EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION,          //Type
+      sizeof (SMBIOS_TABLE_TYPE4),                    //Length
+      0                                               //Handle
+    },
+    1,                                              //Socket
+    CentralProcessor,                               //ProcessorType
+    ProcessorFamilyIndicatorFamily2,                //ProcessorFamily
+    2,                                              //ProcessorManufacture
+    {                                               //ProcessorId
+      {                                               //Signature
+        0
+      },
+      {                                               //FeatureFlags
+        0
+      }
+    },
+    3,                                              //ProcessorVersion
+    {                                               //Voltage
+      0
+    },
+    0,                                              //ExternalClock
+    0,                                              //MaxSpeed
+    0,                                              //CurrentSpeed
+    0,                                              //Status
+    ProcessorUpgradeUnknown,                        //ProcessorUpgrade
+    0xFFFF,                                         //L1CacheHandle
+    0xFFFF,                                         //L2CacheHandle
+    0xFFFF,                                         //L3CacheHandle
+    4,                                              //SerialNumber
+    5,                                              //AssetTag
+    6,                                              //PartNumber
+    0,                                              //CoreCount
+    0,                                              //EnabledCoreCount
+    0,                                              //ThreadCount
+    0,                                              //ProcessorCharacteristics
+    ProcessorFamilyARMv8,                           //ProcessorFamily2
+    0,                                              //CoreCount2
+    0,                                              //EnabledCoreCount2
+    0                                               //ThreadCount2
+  }
+};
+
+
+UINT16
+GetCpuFrequency (
+  IN  UINT8 ProcessorNumber
+)
+{
+  return (UINT16)(PlatformGetCpuFreq (ProcessorNumber)/1000/1000);
+}
+
+UINTN
+GetCacheSocketStr (
+  IN  UINT8     CacheLevel,
+  IN  UINT8     CacheSubLevel,
+  OUT CHAR16    *CacheSocketStr
+  )
+{
+  UINTN CacheSocketStrLen;
+
+  if (CacheLevel == CPU_CACHE_L1 && CacheSubLevel == 0) {
+    CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Instruction Cache", CacheLevel + 1);
+  } else if (CacheLevel == CPU_CACHE_L1 && CacheSubLevel == 1) {
+    CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Data Cache", CacheLevel + 1);
+  } else {
+    CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Cache", CacheLevel + 1);
+  }
+
+  return CacheSocketStrLen;
+}
+
+/**
+  Add Type 7 SMBIOS Record for Cache Information.
+
+  @param[in]    ProcessorNumber     Processor number of specified processor.
+  @param[out]   L1CacheHandle       Pointer to the handle of the L1 Cache SMBIOS record.
+  @param[out]   L2CacheHandle       Pointer to the handle of the L2 Cache SMBIOS record.
+  @param[out]   L3CacheHandle       Pointer to the handle of the L3 Cache SMBIOS record.
+
+**/
+EFI_STATUS
+AddSmbiosCacheTypeTable (
+  IN UINTN                  ProcessorNumber,
+  OUT EFI_SMBIOS_HANDLE     *L1CacheHandle,
+  OUT EFI_SMBIOS_HANDLE     *L2CacheHandle,
+  OUT EFI_SMBIOS_HANDLE     *L3CacheHandle
+  )
+{
+  EFI_STATUS                  Status;
+  SMBIOS_TABLE_TYPE7          *Type7Record;
+  EFI_SMBIOS_HANDLE           SmbiosHandle;
+  UINTN                       TableSize;
+  UINT8                       CacheLevel;
+  UINT8                       CacheSubLevel;
+  CHAR8                       *OptionalStrStart;
+  EFI_STRING                  CacheSocketStr;
+  UINTN                       CacheSocketStrLen;
+  UINTN                       StringBufferSize;
+
+  CLIDR_DATA                  Clidr;
+  CSSELR_DATA                 Csselr;
+  CCSIDR_DATA                 Ccsidr;
+
+  UINT16                      CacheSize16;
+  UINT32                      CacheSize32;
+  UINT64                      CacheSize64;
+  BOOLEAN                     CcidxSupported;
+  UINT32                      Associativity;
+  UINT8                       MaxCacheLevel;
+
+  CONST UINT8                 MAX_ARM_CACHE_LEVEL = 7;
+
+  Status = EFI_SUCCESS;
+
+  MaxCacheLevel = 0;
+
+  // Read the CLIDR register to find out what caches are present.
+  Clidr.Data = ReadCLIDR ();
+
+  // Get the cache type for the L1 cache. If it's 0, there are no caches.
+  if (CLIDR_GET_CACHE_TYPE (Clidr.Data, 0) == CLIDR_CACHE_TYPE_NONE) {
+    return EFI_SUCCESS;
+  }
+
+  for (CacheLevel = 1; CacheLevel < MAX_ARM_CACHE_LEVEL; CacheLevel++) {
+    if (CLIDR_GET_CACHE_TYPE (Clidr.Data, CacheLevel) == CLIDR_CACHE_TYPE_NONE) {
+      MaxCacheLevel = CacheLevel;
+      break;
+    }
+  }
+
+  CcidxSupported = ArmIsCcidxImplemented ();
+
+  for (CacheLevel = 0; CacheLevel < MaxCacheLevel; CacheLevel++)
+  {
+    Type7Record = NULL;
+
+    CLIDR_CACHE_TYPE CacheType = CLIDR_GET_CACHE_TYPE (Clidr.Data, CacheLevel);
+
+    // At each level of cache, we can have a single type (unified, instruction or data),
+    // or two types - separate data and instruction caches. If we have separate
+    // instruction and data caches, then on the first iteration (CacheSubLevel = 0)
+    // process the instruction cache.
+    for (CacheSubLevel = 0; CacheSubLevel <= 1; CacheSubLevel++) {
+      // If there's no separate data/instruction cache, skip the second iteration
+      if (CacheSubLevel > 0 && CacheType != CLIDR_CACHE_TYPE_SEPARATE) {
+        continue;
+      }
+
+      // Allocate and fetch the cache description+++
+      StringBufferSize = sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH;
+      CacheSocketStr = AllocateZeroPool (StringBufferSize);
+      if (CacheSocketStr == NULL) {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto Exit;
+      }
+
+      CacheSocketStrLen = GetCacheSocketStr (CacheLevel, CacheSubLevel, CacheSocketStr);
+
+      TableSize = sizeof (SMBIOS_TABLE_TYPE7) + CacheSocketStrLen + 1 + 1;
+      Type7Record = AllocateZeroPool (TableSize);
+      if (Type7Record == NULL) {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto Exit;
+      }
+
+      Type7Record->Hdr.Type = EFI_SMBIOS_TYPE_CACHE_INFORMATION;
+      Type7Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE7);
+      Type7Record->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
+
+      Type7Record->SocketDesignation = 1;
+
+      Type7Record->SupportedSRAMType.Unknown = 1;
+      Type7Record->CurrentSRAMType.Unknown = 1;
+      Type7Record->CacheSpeed = 0;
+      Type7Record->ErrorCorrectionType = CacheErrorUnknown;
+
+      Csselr.Data = 0;
+      Csselr.Bits.Level = CacheLevel;
+
+      if (CacheSubLevel == 0) {
+        if (CacheType == CLIDR_CACHE_TYPE_INSTRUCTION_ONLY ||
+            CacheType == CLIDR_CACHE_TYPE_SEPARATE) {
+          Csselr.Bits.InD = CSSELR_CACHE_TYPE_INSTRUCTION; // Instruction cache
+          Type7Record->SystemCacheType = CacheTypeInstruction;
+        } else {
+          Csselr.Bits.InD = CSSELR_CACHE_TYPE_DATA_OR_UNIFIED;
+          if (CacheType == CLIDR_CACHE_TYPE_DATA_ONLY) {
+            Type7Record->SystemCacheType = CacheTypeData;
+          } else {
+            Type7Record->SystemCacheType = CacheTypeUnified;
+          }
+        }
+      } else {
+        Type7Record->SystemCacheType = CacheTypeData;
+        Csselr.Bits.InD = CSSELR_CACHE_TYPE_DATA_OR_UNIFIED;
+      }
+
+      // Read the CCSIDR register to get the cache architecture
+      Ccsidr.Data = ReadCCSIDR (Csselr.Data);
+
+      if (CcidxSupported) {
+        CacheSize64 = (UINT64)(1 << (Ccsidr.BitsCcidx.LineSize + 4)) * (Ccsidr.BitsCcidx.Associativity + 1) * (Ccsidr.BitsCcidx.NumSets + 1);
+        Associativity = Ccsidr.BitsCcidx.Associativity;
+      } else {
+        CacheSize64 = (1 << (Ccsidr.BitsNonCcidx.LineSize + 4)) * (Ccsidr.BitsNonCcidx.Associativity + 1) * (Ccsidr.BitsNonCcidx.NumSets + 1);
+        Associativity = Ccsidr.BitsNonCcidx.Associativity;
+      }
+
+      CacheSize64 /= 1024; // Minimum granularity is 1K
+
+      // Encode the cache size into the format SMBIOS wants
+      if (CacheSize64 < MAX_INT16) {
+        CacheSize16 = CacheSize64;
+        CacheSize32 = CacheSize16;
+      } else if ((CacheSize64 / 64) < MAX_INT16) {
+        CacheSize16 = (1 << 15) | (CacheSize64 / 64);
+        CacheSize32 = CacheSize16;
+      } else {
+        if ((CacheSize64 / 1024) <= 2047) {
+          CacheSize32 = CacheSize64;
+        } else {
+          CacheSize32 = (1 << 31) | (CacheSize64 / 64);
+        }
+
+        CacheSize16 = -1;
+      }
+
+      Type7Record->Associativity = Associativity + 1;
+      Type7Record->MaximumCacheSize = CacheSize16;
+      Type7Record->InstalledSize = CacheSize16;
+      Type7Record->MaximumCacheSize2 = CacheSize32;
+      Type7Record->InstalledSize2 = CacheSize32;
+
+      switch (Associativity + 1) {
+        case 2:
+          Type7Record->Associativity = CacheAssociativity2Way;
+          break;
+        case 4:
+          Type7Record->Associativity = CacheAssociativity4Way;
+          break;
+        case 8:
+          Type7Record->Associativity = CacheAssociativity8Way;
+          break;
+        case 16:
+          Type7Record->Associativity = CacheAssociativity16Way;
+          break;
+        case 12:
+          Type7Record->Associativity = CacheAssociativity12Way;
+          break;
+        case 24:
+          Type7Record->Associativity = CacheAssociativity24Way;
+          break;
+        case 32:
+          Type7Record->Associativity = CacheAssociativity32Way;
+          break;
+        case 48:
+          Type7Record->Associativity = CacheAssociativity48Way;
+          break;
+        case 64:
+          Type7Record->Associativity = CacheAssociativity64Way;
+          break;
+        case 20:
+          Type7Record->Associativity = CacheAssociativity20Way;
+          break;
+        default:
+          Type7Record->Associativity = CacheAssociativityOther;
+          break;
+      }
+
+      Type7Record->CacheConfiguration = (3 << 8) | (1 << 7) | (3 << 5) | (0 << 3) | CacheLevel;
+
+      // Allow the platform to fill in other information such as speed, SRAM type etc.
+      if (!OemGetCacheInformation (CacheLevel, Type7Record)) {
+        continue;
+      }
+
+      OptionalStrStart = (CHAR8 *) (Type7Record + 1);
+      UnicodeStrToAsciiStrS (CacheSocketStr, OptionalStrStart, CacheSocketStrLen + 1);
+
+      SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+      // Finally, install the table
+      Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)Type7Record);
+      if (EFI_ERROR (Status)) {
+        goto Exit;
+      }
+
+      // Config L1/L2/L3 Cache Handle
+      switch (CacheLevel) {
+        case CPU_CACHE_L1:
+          *L1CacheHandle = SmbiosHandle;
+          break;
+        case CPU_CACHE_L2:
+          *L2CacheHandle = SmbiosHandle;
+          break;
+        case CPU_CACHE_L3:
+          *L3CacheHandle = SmbiosHandle;
+          break;
+        default:
+            break;
+      }
+Exit:
+      if (Type7Record != NULL)
+      {
+        FreePool (Type7Record);
+      }
+      if (CacheSocketStr != NULL)
+      {
+        FreePool (CacheSocketStr);
+        CacheSocketStr = NULL;
+      }
+    }
+  }
+
+  return Status;
+}
+
+/**
+  Add Type 4 SMBIOS Record for Processor Information.
+
+  @param[in]    ProcessorNumber     Processor number of specified processor.
+
+**/
+EFI_STATUS
+AddSmbiosProcessorTypeTable (
+  IN UINTN                  ProcessorNumber
+  )
+{
+  EFI_STATUS                  Status;
+  SMBIOS_TABLE_TYPE4          *Type4Record;
+  EFI_SMBIOS_HANDLE           SmbiosHandle;
+  EFI_SMBIOS_HANDLE           L1CacheHandle;
+  EFI_SMBIOS_HANDLE           L2CacheHandle;
+  EFI_SMBIOS_HANDLE           L3CacheHandle;
+
+  CHAR8                       *OptionalStrStart;
+  UINT8                       *LegacyVoltage;
+  EFI_STRING_ID               ProcessorManu;
+  EFI_STRING_ID               ProcessorVersion;
+  EFI_STRING_ID               SerialNumber;
+  EFI_STRING_ID               AssetTag;
+  EFI_STRING_ID               PartNumber;
+  EFI_STRING                  ProcessorSocketStr;
+  EFI_STRING                  ProcessorManuStr;
+  EFI_STRING                  ProcessorVersionStr;
+  EFI_STRING                  SerialNumberStr;
+  EFI_STRING                  AssetTagStr;
+  EFI_STRING                  PartNumberStr;
+  UINTN                       ProcessorSocketStrLen;
+  UINTN                       ProcessorManuStrLen;
+  UINTN                       ProcessorVersionStrLen;
+  UINTN                       SerialNumberStrLen;
+  UINTN                       AssetTagStrLen;
+  UINTN                       PartNumberStrLen;
+  UINTN                       StringBufferSize;
+  UINTN                       TotalSize;
+
+  PROCESSOR_STATUS_DATA       ProcessorStatus = {{0}};
+  MISC_PROCESSOR_DATA         MiscProcessorData;
+
+  ARM_SMC_ARGS                Args;
+  BOOLEAN                     Arm64SocIdSupported = FALSE;
+  int                         Jep106Code;
+  int                         SocRevision;
+  int                         SmcCallStatus;
+  UINT64                      *ProcessorId;
+
+  Type4Record         = NULL;
+  ProcessorManuStr    = NULL;
+  ProcessorVersionStr = NULL;
+  SerialNumberStr     = NULL;
+  AssetTagStr         = NULL;
+  PartNumberStr       = NULL;
+
+
+  MiscProcessorData.Voltage             = 0;
+  MiscProcessorData.CurrentSpeed        = 0;
+  MiscProcessorData.CoreCount           = 0;
+  MiscProcessorData.CoresEnabled        = 0;
+  MiscProcessorData.ThreadCount         = 0;
+  L1CacheHandle       = 0xFFFF;
+  L2CacheHandle       = 0xFFFF;
+  L3CacheHandle       = 0xFFFF;
+
+  ProcessorManu       = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+  ProcessorVersion    = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+  SerialNumber        = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+  AssetTag            = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+  PartNumber          = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+
+  BOOLEAN Populated = OemGetProcessorInformation (ProcessorNumber,
+                                                  &ProcessorStatus,
+                                                  (PROCESSOR_CHARACTERISTIC_FLAGS*)&mSmbiosProcessorTable[ProcessorNumber].ProcessorCharacteristics,
+                                                  &MiscProcessorData);
+  if (Populated)
+  {
+    Status = AddSmbiosCacheTypeTable (ProcessorNumber, &L1CacheHandle,
+                                      &L2CacheHandle, &L3CacheHandle);
+
+    ProcessorManu       = STRING_TOKEN (STR_PROCESSOR_MANUFACTURE);
+    ProcessorVersion    = STRING_TOKEN (STR_PROCESSOR_VERSION);
+    SerialNumber        = STRING_TOKEN (STR_PROCESSOR_SERIAL_NUMBER);
+    AssetTag            = STRING_TOKEN (STR_PROCESSOR_ASSET_TAG);
+    PartNumber          = STRING_TOKEN (STR_PROCESSOR_PART_NUMBER);
+
+    ProcessorManuStr = (CHAR16 *) PcdGetPtr (PcdProcessorManufacturer);
+
+    if (StrLen (ProcessorManuStr) > 0)
+    {
+      HiiSetString (mHiiHandle, ProcessorManu, ProcessorManuStr, NULL);
+    }
+
+    ProcessorVersionStr = (CHAR16 *) PcdGetPtr (PcdProcessorVersion);
+
+    if (StrLen (ProcessorVersionStr) > 0)
+    {
+      HiiSetString (mHiiHandle, ProcessorVersion, ProcessorVersionStr, NULL);
+    }
+
+    SerialNumberStr = (CHAR16 *) PcdGetPtr (PcdProcessorSerialNumber);
+
+    if (StrLen (SerialNumberStr) > 0)
+    {
+      HiiSetString (mHiiHandle, SerialNumber, SerialNumberStr, NULL);
+    }
+
+    AssetTagStr = (CHAR16 *) PcdGetPtr (PcdProcessorAssetTag);
+
+    if (StrLen (AssetTagStr) > 0)
+    {
+      HiiSetString (mHiiHandle, AssetTag, AssetTagStr, NULL);
+    }
+
+    PartNumberStr = (CHAR16 *) PcdGetPtr (PcdProcessorPartNumber);
+
+    if (StrLen (PartNumberStr) > 0)
+    {
+      HiiSetString (mHiiHandle, PartNumber, PartNumberStr, NULL);
+    }
+  }
+
+  // Processor Socket Designation
+  StringBufferSize = sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH;
+  ProcessorSocketStr = AllocateZeroPool (StringBufferSize);
+  if (ProcessorSocketStr == NULL)
+  {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  ProcessorSocketStrLen = UnicodeSPrint (ProcessorSocketStr, StringBufferSize, L"CPU%02d", ProcessorNumber + 1);
+
+  // Processor Manufacture
+  ProcessorManuStr = HiiGetPackageString (&gEfiCallerIdGuid, ProcessorManu, NULL);
+  ProcessorManuStrLen = StrLen (ProcessorManuStr);
+
+  // Processor Version
+  ProcessorVersionStr = HiiGetPackageString (&gEfiCallerIdGuid, ProcessorVersion, NULL);
+  ProcessorVersionStrLen = StrLen (ProcessorVersionStr);
+
+  // Serial Number
+  SerialNumberStr = HiiGetPackageString (&gEfiCallerIdGuid, SerialNumber, NULL);
+  SerialNumberStrLen = StrLen (SerialNumberStr);
+
+  // Asset Tag
+  AssetTagStr = HiiGetPackageString (&gEfiCallerIdGuid, AssetTag, NULL);
+  AssetTagStrLen = StrLen (AssetTagStr);
+
+  // Part Number
+  PartNumberStr = HiiGetPackageString (&gEfiCallerIdGuid, PartNumber, NULL);
+  PartNumberStrLen = StrLen (PartNumberStr);
+
+  TotalSize = sizeof (SMBIOS_TABLE_TYPE4) + ProcessorSocketStrLen + 1 +
+                                            ProcessorManuStrLen + 1 +
+                                            ProcessorVersionStrLen + 1 +
+                                            SerialNumberStrLen + 1 +
+                                            AssetTagStrLen + 1 +
+                                            PartNumberStrLen + 1 + 1;
+  Type4Record = AllocateZeroPool (TotalSize);
+  if (Type4Record == NULL)
+  {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  (VOID)CopyMem (Type4Record, &mSmbiosProcessorTable[ProcessorNumber], sizeof (SMBIOS_TABLE_TYPE4));
+
+  LegacyVoltage = (UINT8*)&Type4Record->Voltage;
+
+  *LegacyVoltage                          = MiscProcessorData.Voltage;
+  Type4Record->CurrentSpeed               = MiscProcessorData.CurrentSpeed;
+  Type4Record->MaxSpeed                   = MiscProcessorData.MaxSpeed;
+  Type4Record->Status                     = ProcessorStatus.Data;
+  Type4Record->L1CacheHandle              = L1CacheHandle;
+  Type4Record->L2CacheHandle              = L2CacheHandle;
+  Type4Record->L3CacheHandle              = L3CacheHandle;
+  Type4Record->CoreCount                  = MiscProcessorData.CoreCount;
+  Type4Record->CoreCount2                 = MiscProcessorData.CoreCount;
+  Type4Record->EnabledCoreCount           = MiscProcessorData.CoresEnabled;
+  Type4Record->EnabledCoreCount2          = MiscProcessorData.CoresEnabled;
+  Type4Record->ThreadCount                = MiscProcessorData.ThreadCount;
+  Type4Record->ThreadCount2               = MiscProcessorData.ThreadCount;
+
+  Type4Record->ExternalClock              = (UINT16)(ArmReadCntFrq () / 1000 / 1000);
+
+  ProcessorId = (UINT64 *)&Type4Record->ProcessorId;
+
+  Args.Arg0 = ARM_SMC_ID_ARCH_VERSION;
+  ArmCallSmc (&Args);
+  SmcCallStatus = (int)Args.Arg0;
+
+  if (SmcCallStatus < 0 || (SmcCallStatus >> 16) >= 1) {
+    Args.Arg0 = ARM_SMC_ID_ARCH_FEATURES;
+    Args.Arg1 = ARM_SMC_ID_ARCH_SOC_ID;
+    ArmCallSmc (&Args);
+
+    if (Args.Arg0 >= 0) {
+      PROCESSOR_CHARACTERISTIC_FLAGS *ProcessorCharacteristicFlags = (PROCESSOR_CHARACTERISTIC_FLAGS*)&Type4Record->ProcessorCharacteristics;
+      Args.Arg0 = ARM_SMC_ID_ARCH_SOC_ID;
+      Args.Arg1 = 0;
+      ArmCallSmc (&Args);
+      SmcCallStatus = (int)Args.Arg0;
+
+      if (SmcCallStatus >= 0) {
+        Arm64SocIdSupported = TRUE;
+        ProcessorCharacteristicFlags->ProcessorArm64SocId = 1;
+        Jep106Code = (int)Args.Arg0;
+      } else {
+        ProcessorCharacteristicFlags->ProcessorArm64SocId  = 0;
+      }
+      Args.Arg0 = ARM_SMC_ID_ARCH_SOC_ID;
+      Args.Arg1 = 1;
+      ArmCallSmc (&Args);
+      SmcCallStatus = (int)Args.Arg0;
+
+      if (SmcCallStatus >= 0) {
+        SocRevision = (int)Args.Arg0;
+      }
+    }
+  }
+
+  if (Arm64SocIdSupported) {
+    *ProcessorId = ((UINT64)Jep106Code << 32) | SocRevision;
+  } else {
+    *ProcessorId = ArmReadMidr ();
+  }
+
+  UINTN MainIdRegister = ArmReadMidr ();
+  if (((MainIdRegister >> 16) & 0xF) < 8) {
+    Type4Record->ProcessorFamily2 = ProcessorFamilyARM;
+  } else {
+    if (sizeof (VOID*) == 4) {
+      Type4Record->ProcessorFamily2 = ProcessorFamilyARMv7;
+    } else {
+      Type4Record->ProcessorFamily2 = ProcessorFamilyARMv8;
+    }
+  }
+
+  OptionalStrStart = (CHAR8 *) (Type4Record + 1);
+  UnicodeStrToAsciiStrS (ProcessorSocketStr, OptionalStrStart, ProcessorSocketStrLen + 1);
+  UnicodeStrToAsciiStrS (ProcessorManuStr, OptionalStrStart + ProcessorSocketStrLen + 1, ProcessorManuStrLen + 1);
+  UnicodeStrToAsciiStrS (ProcessorVersionStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1, ProcessorVersionStrLen + 1);
+  UnicodeStrToAsciiStrS (SerialNumberStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1, SerialNumberStrLen + 1);
+  UnicodeStrToAsciiStrS (AssetTagStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1 + SerialNumberStrLen + 1, AssetTagStrLen + 1);
+  UnicodeStrToAsciiStrS (PartNumberStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1 + SerialNumberStrLen + 1 + AssetTagStrLen + 1, PartNumberStrLen + 1);
+
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)Type4Record);
+  if (EFI_ERROR (Status))
+  {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type04 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+  }
+  FreePool (Type4Record);
+
+Exit:
+  if (ProcessorSocketStr != NULL)
+  {
+    FreePool (ProcessorSocketStr);
+  }
+  if (ProcessorManuStr != NULL)
+  {
+    FreePool (ProcessorManuStr);
+  }
+  if (ProcessorVersionStr != NULL)
+  {
+    FreePool (ProcessorVersionStr);
+  }
+  if (SerialNumberStr != NULL)
+  {
+    FreePool (SerialNumberStr);
+  }
+  if (AssetTagStr != NULL)
+  {
+    FreePool (AssetTagStr);
+  }
+  if (PartNumberStr != NULL)
+  {
+    FreePool (PartNumberStr);
+  }
+
+  return Status;
+}
+
+/**
+  Standard EFI driver point.  This driver locates the ProcessorConfigurationData Variable,
+  if it exists, add the related SMBIOS tables by PI SMBIOS protocol.
+
+  @param  ImageHandle     Handle for the image of this driver
+  @param  SystemTable     Pointer to the EFI System Table
+
+  @retval  EFI_SUCCESS    The data was successfully stored.
+
+**/
+EFI_STATUS
+EFIAPI
+ProcessorSubClassEntryPoint(
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                      Status;
+  UINT32                          SocketIndex;
+
+  //
+  // Locate dependent protocols
+  //
+  Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&mSmbios);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol.  %r\n", Status));
+    return Status;
+  }
+
+  //
+  // Add our default strings to the HII database. They will be modified later.
+  //
+  mHiiHandle = HiiAddPackages (
+              &gEfiCallerIdGuid,
+              NULL,
+              ProcessorSubClassStrings,
+              NULL,
+              NULL
+              );
+  if (mHiiHandle == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Add SMBIOS tables for populated sockets.
+  //
+  for (SocketIndex = 0; SocketIndex < OemGetProcessorMaxSockets(); SocketIndex++) {
+    Status = AddSmbiosProcessorTypeTable (SocketIndex);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Add Processor Type Table Failed!  %r.\n", Status));
+      return Status;
+    }
+  }
+
+  return Status;
+}
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c
new file mode 100644
index 000000000000..eff045383991
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c
@@ -0,0 +1,50 @@
+/**@file
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  SmbiosMiscDataTable.c
+
+Abstract:
+
+  This file provides SMBIOS Misc Type.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE0,  MiscBiosVendor, MiscBiosVendor)
+  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE1,  MiscSystemManufacturer, MiscSystemManufacturer)
+  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE3,  MiscChassisManufacturer, MiscChassisManufacturer)
+  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE2,  MiscBaseBoardManufacturer, MiscBaseBoardManufacturer)
+  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE13, MiscNumberOfInstallableLanguages, MiscNumberOfInstallableLanguages)
+  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE32, MiscBootInformation, MiscBootInformation)
+
+
+EFI_MISC_SMBIOS_DATA_TABLE mSmbiosMiscDataTable[] = {
+  // Type0
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscBiosVendor, MiscBiosVendor),
+  // Type1
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscSystemManufacturer, MiscSystemManufacturer),
+  // Type3
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscChassisManufacturer, MiscChassisManufacturer),
+  // Type2
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscBaseBoardManufacturer, MiscBaseBoardManufacturer),
+  // Type13
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscNumberOfInstallableLanguages, MiscNumberOfInstallableLanguages),
+  // Type32
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscBootInformation, MiscBootInformation),
+};
+
+
+//
+// Number of Data Table entries.
+//
+UINTN mSmbiosMiscDataTableEntries =
+  (sizeof (mSmbiosMiscDataTable)) / sizeof (EFI_MISC_SMBIOS_DATA_TABLE);
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
new file mode 100644
index 000000000000..fe81367d1c28
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
@@ -0,0 +1,167 @@
+/**@file
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  SmbiosMiscEntryPoint.c
+
+Abstract:
+
+  This driver parses the mSmbiosMiscDataTable structure and reports
+  any generated data using SMBIOS protocol.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+#define MAX_HANDLE_COUNT  0x10
+
+EFI_HANDLE              mImageHandle;
+EFI_HII_HANDLE          mHiiHandle;
+EFI_SMBIOS_PROTOCOL     *mSmbios = NULL;
+
+/**
+  Standard EFI driver point.  This driver parses the mSmbiosMiscDataTable
+  structure and reports any generated data using SMBIOS protocol.
+
+  @param  ImageHandle     Handle for the image of this driver
+  @param  SystemTable     Pointer to the EFI System Table
+
+  @retval  EFI_SUCCESS    The data was successfully stored.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbiosMiscEntryPoint(
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  UINTN                Index;
+  EFI_STATUS           EfiStatus;
+  EFI_SMBIOS_PROTOCOL  *Smbios;
+
+  mImageHandle = ImageHandle;
+
+  EfiStatus = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
+  if (EFI_ERROR (EfiStatus)) {
+    DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol.  %r\n", EfiStatus));
+    return EfiStatus;
+  }
+
+  mSmbios = Smbios;
+
+  mHiiHandle = HiiAddPackages (
+                  &gEfiCallerIdGuid,
+                  mImageHandle,
+                  SmbiosMiscDxeStrings,
+                  NULL
+                  );
+  if (mHiiHandle == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  for (Index = 0; Index < mSmbiosMiscDataTableEntries; ++Index) {
+    //
+    // If the entry have a function pointer, just log the data.
+    //
+    if (mSmbiosMiscDataTable[Index].Function != NULL) {
+      EfiStatus = (*mSmbiosMiscDataTable[Index].Function)(
+          mSmbiosMiscDataTable[Index].RecordData,
+          Smbios
+          );
+
+      if (EFI_ERROR(EfiStatus)) {
+        DEBUG ((DEBUG_ERROR, "Misc smbios store error.  Index=%d, ReturnStatus=%r\n", Index, EfiStatus));
+        return EfiStatus;
+      }
+    }
+  }
+
+  return EfiStatus;
+}
+
+
+/**
+  Logs SMBIOS record.
+
+  @param  Buffer                The data for the fixed portion of the SMBIOS record. The format of the record is
+                                determined by EFI_SMBIOS_TABLE_HEADER.Type. The size of the formatted area is defined
+                                by EFI_SMBIOS_TABLE_HEADER.Length and either followed by a double-null (0x0000) or
+                                a set of null terminated strings and a null.
+  @param  SmbiosHandle          A unique handle will be assigned to the SMBIOS record.
+
+  @retval EFI_SUCCESS           Record was added.
+  @retval EFI_OUT_OF_RESOURCES  Record was not added due to lack of system resources.
+
+**/
+EFI_STATUS
+LogSmbiosData (
+  IN       UINT8                      *Buffer,
+  IN  OUT  EFI_SMBIOS_HANDLE          *SmbiosHandle
+  )
+{
+  EFI_STATUS         Status;
+
+  *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+
+  Status = mSmbios->Add (
+                   mSmbios,
+                   NULL,
+                   SmbiosHandle,
+                   (EFI_SMBIOS_TABLE_HEADER *)Buffer
+                   );
+
+  return Status;
+}
+
+
+VOID
+GetLinkTypeHandle(
+  IN  UINT8                 SmbiosType,
+  OUT UINT16                **HandleArray,
+  OUT UINTN                 *HandleCount
+  )
+{
+  EFI_STATUS                       Status;
+  EFI_SMBIOS_HANDLE                SmbiosHandle;
+  EFI_SMBIOS_TABLE_HEADER          *LinkTypeData = NULL;
+
+  if (mSmbios == NULL) {
+    return;
+  }
+
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+
+  *HandleArray = AllocateZeroPool (sizeof(UINT16) * MAX_HANDLE_COUNT);
+  if (*HandleArray == NULL) {
+    DEBUG ((DEBUG_ERROR, "HandleArray allocate memory resource failed.\n"));
+    return;
+  }
+
+  *HandleCount = 0;
+
+  while(1) {
+    Status = mSmbios->GetNext (
+                        mSmbios,
+                        &SmbiosHandle,
+                        &SmbiosType,
+                        &LinkTypeData,
+                        NULL
+                        );
+
+    if (!EFI_ERROR (Status)) {
+      (*HandleArray)[*HandleCount] = LinkTypeData->Handle;
+      (*HandleCount)++;
+    } else {
+      break;
+    }
+  }
+}
+
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorData.c
new file mode 100644
index 000000000000..d9a1ed418428
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorData.c
@@ -0,0 +1,99 @@
+/*++
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscBiosVendorData.c
+
+Abstract:
+
+  This file provides Smbios Type0 Data
+
+Based on the files under Nt32Pkg/MiscSubClassPlatformDxe/
+
+**/
+
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE0, MiscBiosVendor) = {
+  {                                          //Hdr
+    EFI_SMBIOS_TYPE_BIOS_INFORMATION,          // Type,
+    0,                                         // Length,
+    0                                          // Handle
+  },
+  1,                                         //Vendor
+  2,                                         //BiosVersion
+  0xE000,                                    //BiosSegment
+  3,                                         //BiosReleaseDate
+  0,                                         //BiosSize
+  {                                          //BiosCharacteristics
+    0,                                         // Reserved                          :2
+    0,                                         // Unknown                           :1
+    0,                                         // BiosCharacteristicsNotSupported   :1
+    0,                                         // IsaIsSupported                    :1
+    0,                                         // McaIsSupported                    :1
+    0,                                         // EisaIsSupported                   :1
+    1,                                         // PciIsSupported                    :1
+    0,                                         // PcmciaIsSupported                 :1
+    1,                                         // PlugAndPlayIsSupported            :1
+    0,                                         // ApmIsSupported                    :1
+    1,                                         // BiosIsUpgradable                  :1
+    1,                                         // BiosShadowingAllowed              :1
+    0,                                         // VlVesaIsSupported                 :1
+    0,                                         // EscdSupportIsAvailable            :1
+    1,                                         // BootFromCdIsSupported             :1
+    1,                                         // SelectableBootIsSupported         :1
+    0,                                         // RomBiosIsSocketed                 :1
+    0,                                         // BootFromPcmciaIsSupported         :1
+    1,                                         // EDDSpecificationIsSupported       :1
+    0,                                         // JapaneseNecFloppyIsSupported      :1
+    0,                                         // JapaneseToshibaFloppyIsSupported  :1
+    0,                                         // Floppy525_360IsSupported          :1
+    0,                                         // Floppy525_12IsSupported           :1
+    0,                                         // Floppy35_720IsSupported           :1
+    0,                                         // Floppy35_288IsSupported           :1
+    0,                                         // PrintScreenIsSupported            :1
+    0,                                         // Keyboard8042IsSupported           :1
+    0,                                         // SerialIsSupported                 :1
+    0,                                         // PrinterIsSupported                :1
+    0,                                         // CgaMonoIsSupported                :1
+    0,                                         // NecPc98                           :1
+    0                                          // ReservedForVendor                 :32
+  },
+
+  {
+    0x03,                                        //BIOSCharacteristicsExtensionBytes[0]
+    //  {                                          //BiosReserved
+    //    1,                                         // AcpiIsSupported                   :1
+    //    1,                                         // UsbLegacyIsSupported              :1
+    //    0,                                         // AgpIsSupported                    :1
+    //    0,                                         // I20BootIsSupported                :1
+    //    0,                                         // Ls120BootIsSupported              :1
+    //    0,                                         // AtapiZipDriveBootIsSupported      :1
+    //    0,                                         // Boot1394IsSupported               :1
+    //    0                                          // SmartBatteryIsSupported           :1
+    //  },
+    0x0D                                         //BIOSCharacteristicsExtensionBytes[1]
+    //  {                                          //SystemReserved
+    //    1,                                         //BiosBootSpecIsSupported            :1
+    //    0,                                         //FunctionKeyNetworkBootIsSupported  :1
+    //    1,                                         //TargetContentDistributionEnabled   :1
+    //    1,                                         //UefiSpecificationSupported         :1
+    //    0,                                         //VirtualMachineSupported            :1
+    //    0                                          //ExtensionByte2Reserved             :3
+    //  },
+  },
+  0xFF,                                        //SystemBiosMajorRelease;
+  0xFF,                                        //SystemBiosMinorRelease;
+  0xFF,                                     //EmbeddedControllerFirmwareMajorRelease;
+  0xFF                                      //EmbeddedControllerFirmwareMinorRelease;
+};
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c
new file mode 100644
index 000000000000..2f6b35d80266
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c
@@ -0,0 +1,232 @@
+/** @file
+
+  Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+  Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  MiscBiosVendorData.c
+
+Abstract:
+
+  This driver parses the mMiscSubclassDataTable structure and reports
+  any generated data to the DataHub.
+
+Based on the files under Nt32Pkg/MiscSubClassPlatformDxe/
+
+--*/
+
+//
+#include "SmbiosMisc.h"
+#include <Library/HobLib.h>
+#include <Guid/VersionInfoHobGuid.h>
+
+
+/**
+  Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k'
+  as the unit.
+
+  @param  Value              Pointer to Base2_Data
+
+  @retval
+
+**/
+UINT8
+Base2ToByteWith64KUnit (
+  IN  UINTN  Value
+  )
+{
+  UINT8 Size;
+
+  Size = Value / SIZE_64KB + (Value % SIZE_64KB + SIZE_64KB - 1) / SIZE_64KB;
+
+  return Size;
+}
+
+
+/**
+
+**/
+VOID *
+GetBiosReleaseDate (
+  VOID
+  )
+{
+  CHAR16                  *ReleaseDate = NULL;
+  VERSION_INFO            *Version;
+  VOID                    *Hob;
+
+  ReleaseDate = AllocateZeroPool ((sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH);
+  if (ReleaseDate == NULL) {
+      return NULL;
+  }
+
+  Hob = GetFirstGuidHob (&gVersionInfoHobGuid);
+  if (Hob == NULL) {
+    DEBUG ((DEBUG_ERROR, "[%a:%d] Version info HOB not found!\n", __FUNCTION__, __LINE__));
+    return NULL;
+  }
+
+  Version = GET_GUID_HOB_DATA (Hob);
+  (VOID)UnicodeSPrintAsciiFormat (ReleaseDate,
+                        (sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH,
+                        "%02d/%02d/%4d",
+                        Version->BuildTime.Month,
+                        Version->BuildTime.Day,
+                        Version->BuildTime.Year
+                        );
+
+  return ReleaseDate;
+}
+
+VOID *
+GetBiosVersion (
+  VOID
+  )
+{
+  VERSION_INFO            *Version;
+  VOID                    *Hob;
+
+  Hob = GetFirstGuidHob (&gVersionInfoHobGuid);
+  if (Hob == NULL) {
+    DEBUG ((DEBUG_ERROR, "[%a:%d] Version info HOB not found!\n", __FUNCTION__, __LINE__));
+    return NULL;
+  }
+
+  Version = GET_GUID_HOB_DATA (Hob);
+  return Version->String;
+}
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscBiosVendor (Type 0).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscBiosVendor)
+{
+  CHAR8                 *OptionalStrStart;
+  UINTN                 VendorStrLen;
+  UINTN                 VerStrLen;
+  UINTN                 DateStrLen;
+  UINTN                 BiosPhysicalSizeHexValue;
+  CHAR16                *Vendor;
+  CHAR16                *Version;
+  CHAR16                *ReleaseDate;
+  CHAR16                *Char16String;
+  EFI_STATUS            Status;
+  EFI_STRING_ID         TokenToUpdate;
+  EFI_STRING_ID         TokenToGet;
+  SMBIOS_TABLE_TYPE0    *SmbiosRecord;
+  EFI_SMBIOS_HANDLE     SmbiosHandle;
+  SMBIOS_TABLE_TYPE0    *InputData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InputData = (SMBIOS_TABLE_TYPE0 *)RecordData;
+
+  Vendor = (CHAR16 *) PcdGetPtr (PcdFirmwareVendor);
+
+  if (StrLen (Vendor) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
+    HiiSetString (mHiiHandle, TokenToUpdate, Vendor, NULL);
+  }
+
+  Version = GetBiosVersion();
+
+  if (StrLen (Version) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
+    HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
+  } else {
+    Version = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
+    if (StrLen (Version) > 0) {
+      TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
+      HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
+    }
+  }
+
+  Char16String = GetBiosReleaseDate ();
+  if (StrLen(Char16String) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
+    HiiSetString (mHiiHandle, TokenToUpdate, Char16String, NULL);
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
+  Vendor = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  VendorStrLen = StrLen (Vendor);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION);
+  Version = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  VerStrLen = StrLen (Version);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
+  ReleaseDate = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  DateStrLen = StrLen (ReleaseDate);
+
+  //
+  // Now update the BiosPhysicalSize
+  //
+  BiosPhysicalSizeHexValue = FixedPcdGet32 (PcdFdSize);
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);
+  if (SmbiosRecord == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE0));
+
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE0);
+  SmbiosRecord->BiosSegment = (UINT16)(FixedPcdGet32 (PcdFdBaseAddress) / SIZE_64KB);
+  SmbiosRecord->BiosSize = Base2ToByteWith64KUnit (BiosPhysicalSizeHexValue) - 1;
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStrS (Vendor, OptionalStrStart, VendorStrLen + 1);
+  UnicodeStrToAsciiStrS (Version, OptionalStrStart + VendorStrLen + 1, VerStrLen + 1);
+  UnicodeStrToAsciiStrS (ReleaseDate, OptionalStrStart + VendorStrLen + 1 + VerStrLen + 1, DateStrLen + 1);
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+  if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type00 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+  }
+
+  FreePool (SmbiosRecord);
+
+Exit:
+  if (Vendor != NULL) {
+    FreePool (Vendor);
+  }
+
+  if (Version != NULL) {
+    FreePool (Version);
+  }
+
+  if (ReleaseDate != NULL) {
+    FreePool (ReleaseDate);
+  }
+
+  if (Char16String != NULL) {
+    FreePool (Char16String);
+  }
+
+  return Status;
+}
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerData.c
new file mode 100644
index 000000000000..8752dbd73132
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerData.c
@@ -0,0 +1,43 @@
+/*++
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscSystemManufacturerData.c
+
+Abstract:
+
+  This file provides Smbios Type1 Data
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+
+**/
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) System Manufacturer data.
+//
+MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE1, MiscSystemManufacturer) = {
+  {                                               // Hdr
+    EFI_SMBIOS_TYPE_SYSTEM_INFORMATION,             // Type,
+    0,                                              // Length,
+    0                                               // Handle
+  },
+  1,                                              // Manufacturer
+  2,                                              // ProductName
+  3,                                              // Version
+  4,                                              // SerialNumber
+  {                                               // Uuid
+    0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+  },
+  SystemWakeupTypePowerSwitch,                    // SystemWakeupType
+  5,                                              // SKUNumber,
+  6                                               // Family
+};
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerFunction.c
new file mode 100644
index 000000000000..2f96ce90575e
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerFunction.c
@@ -0,0 +1,171 @@
+/*++
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscSystemManufacturerFunction.c
+
+Abstract:
+
+  This driver parses the mMiscSubclassDataTable structure and reports
+  any generated data to smbios.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+
+**/
+
+#include "SmbiosMisc.h"
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscSystemManufacturer (Type 1).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscSystemManufacturer)
+{
+  CHAR8                           *OptionalStrStart;
+  UINTN                           ManuStrLen;
+  UINTN                           VerStrLen;
+  UINTN                           PdNameStrLen;
+  UINTN                           SerialNumStrLen;
+  UINTN                           SKUNumStrLen;
+  UINTN                           FamilyStrLen;
+  EFI_STRING                      Manufacturer;
+  EFI_STRING                      ProductName;
+  EFI_STRING                      Version;
+  EFI_STRING                      SerialNumber;
+  EFI_STRING                      SKUNumber;
+  EFI_STRING                      Family;
+  EFI_STRING_ID                   TokenToGet;
+  EFI_SMBIOS_HANDLE               SmbiosHandle;
+  SMBIOS_TABLE_TYPE1              *SmbiosRecord;
+  SMBIOS_TABLE_TYPE1              *InputData;
+  EFI_STATUS                      Status;
+  EFI_STRING_ID                   TokenToUpdate;
+  CHAR16                          *Product;
+  CHAR16                          *pVersion;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InputData = (SMBIOS_TABLE_TYPE1 *)RecordData;
+
+  Product = (CHAR16 *) PcdGetPtr (PcdSystemProductName);
+  if (StrLen (Product) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
+    HiiSetString (mHiiHandle, TokenToUpdate, Product, NULL);
+  }
+
+  pVersion = (CHAR16 *) PcdGetPtr (PcdSystemVersion);
+  if (StrLen (pVersion) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
+    HiiSetString (mHiiHandle, TokenToUpdate, pVersion, NULL);
+  }
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_SYSTEM_SERIAL_NUMBER), SerialNumType01);
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER), SystemManufacturerType01);
+
+  TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER);
+  Manufacturer = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  ManuStrLen   = StrLen (Manufacturer);
+
+  TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
+  ProductName  = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  PdNameStrLen = StrLen (ProductName);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
+  Version    = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  VerStrLen  = StrLen (Version);
+
+  TokenToGet      = STRING_TOKEN (STR_MISC_SYSTEM_SERIAL_NUMBER);
+  SerialNumber    = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  SerialNumStrLen = StrLen (SerialNumber);
+
+  TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_SKU_NUMBER);
+  SKUNumber    = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  SKUNumStrLen = StrLen (SKUNumber);
+
+  TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_FAMILY);
+  Family       = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  FamilyStrLen = StrLen (Family);
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen      + 1
+                                                                + PdNameStrLen    + 1
+                                                                + VerStrLen       + 1
+                                                                + SerialNumStrLen + 1
+                                                                + SKUNumStrLen    + 1
+                                                                + FamilyStrLen    + 1 + 1);
+
+  if (SmbiosRecord == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE1));
+
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE1);
+
+  SmbiosRecord->Uuid = InputData->Uuid;
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStrS (Manufacturer, OptionalStrStart, ManuStrLen + 1);
+  UnicodeStrToAsciiStrS (ProductName,  OptionalStrStart + ManuStrLen + 1, PdNameStrLen + 1);
+  UnicodeStrToAsciiStrS (Version,      OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1, VerStrLen + 1);
+  UnicodeStrToAsciiStrS (SerialNumber, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1, SerialNumStrLen + 1);
+  UnicodeStrToAsciiStrS (SKUNumber, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1, SKUNumStrLen + 1);
+  UnicodeStrToAsciiStrS (Family, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SKUNumStrLen + 1, FamilyStrLen + 1);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type01 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+  }
+
+  FreePool (SmbiosRecord);
+
+Exit:
+  if (Manufacturer != NULL) {
+    FreePool (Manufacturer);
+  }
+
+  if (ProductName != NULL) {
+    FreePool (ProductName);
+  }
+
+  if (Version != NULL) {
+    FreePool (Version);
+  }
+
+  if (SerialNumber != NULL) {
+    FreePool (SerialNumber);
+  }
+
+  if (SKUNumber != NULL) {
+    FreePool (SKUNumber);
+  }
+
+  if (Family != NULL) {
+    FreePool (Family);
+  }
+
+  return 0;
+}
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerData.c
new file mode 100644
index 000000000000..ed55d87310e2
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerData.c
@@ -0,0 +1,51 @@
+/*++
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscBaseBoardManufacturerData.c
+
+Abstract:
+
+  This file provide OEM to define Smbios Type2 Data
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+//
+// Static (possibly build generated) Chassis Manufacturer data.
+//
+MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE2, MiscBaseBoardManufacturer) = {
+  {                                                       // Hdr
+    EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION,                // Type,
+    0,                                                    // Length,
+    0                                                     // Handle
+  },
+  1,                                                      // BaseBoardManufacturer
+  2,                                                      // BaseBoardProductName
+  3,                                                      // BaseBoardVersion
+  4,                                                      // BaseBoardSerialNumber
+  5,                                                      // BaseBoardAssetTag
+  {                                                       // FeatureFlag
+    1,                                                    // Motherboard           :1
+    0,                                                    // RequiresDaughterCard  :1
+    0,                                                    // Removable             :1
+    1,                                                    // Replaceable           :1
+    0,                                                    // HotSwappable          :1
+    0                                                     // Reserved              :3
+  },
+  6,                                                      // BaseBoardChassisLocation
+  0,                                                      // ChassisHandle;
+  BaseBoardTypeMotherBoard,                               // BoardType;
+  0,                                                      // NumberOfContainedObjectHandles;
+  {
+    0
+  }                                                       // ContainedObjectHandles[1];
+};
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerFunction.c
new file mode 100644
index 000000000000..0528651068c7
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerFunction.c
@@ -0,0 +1,184 @@
+/** @file
+
+  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+  Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscBaseBoardManufacturerFunction.c
+
+Abstract:
+
+  This driver parses the mSmbiosMiscDataTable structure and reports
+  any generated data using SMBIOS protocol.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+
+/**
+  This function makes basic board manufacturer to the contents of the
+  Misc Base Board Manufacturer (Type 2).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscBaseBoardManufacturer)
+{
+  CHAR8                             *OptionalStrStart;
+  UINTN                             ManuStrLen;
+  UINTN                             ProductNameStrLen;
+  UINTN                             VerStrLen;
+  UINTN                             SerialNumStrLen;
+  UINTN                             AssetTagStrLen;
+  UINTN                             ChassisLocaStrLen;
+  UINTN                             HandleCount = 0;
+  UINT16                            *HandleArray = NULL;
+  CHAR16                            *BaseBoardManufacturer;
+  CHAR16                            *BaseBoardProductName;
+  CHAR16                            *Version;
+  EFI_STRING                        SerialNumber;
+  EFI_STRING                        AssetTag;
+  EFI_STRING                        ChassisLocation;
+  EFI_STRING_ID                     TokenToGet;
+  EFI_SMBIOS_HANDLE                 SmbiosHandle;
+  SMBIOS_TABLE_TYPE2                *SmbiosRecord;
+  SMBIOS_TABLE_TYPE2                *InputData = NULL;
+  EFI_STATUS                        Status;
+
+  EFI_STRING_ID                     TokenToUpdate;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InputData = (SMBIOS_TABLE_TYPE2*)RecordData;
+
+  BaseBoardManufacturer = (CHAR16 *) PcdGetPtr (PcdBaseBoardManufacturer);
+  if (StrLen (BaseBoardManufacturer) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BASE_BOARD_MANUFACTURER);
+    HiiSetString (mHiiHandle, TokenToUpdate, BaseBoardManufacturer, NULL);
+  }
+
+  BaseBoardProductName = (CHAR16 *) PcdGetPtr (PcdBaseBoardProductName);
+  if (StrLen (BaseBoardProductName) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BASE_BOARD_PRODUCT_NAME);
+    HiiSetString (mHiiHandle, TokenToUpdate, BaseBoardProductName, NULL);
+  }
+
+  Version = (CHAR16 *) PcdGetPtr (PcdBaseBoardVersion);
+  if (StrLen (Version) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BASE_BOARD_VERSION);
+    HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
+  }
+
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_BASE_BOARD_ASSET_TAG), AssertTagType02);
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_BASE_BOARD_SERIAL_NUMBER), SrNumType02);
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_BASE_BOARD_MANUFACTURER), BoardManufacturerType02);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_MANUFACTURER);
+  BaseBoardManufacturer = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  ManuStrLen = StrLen (BaseBoardManufacturer);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_PRODUCT_NAME);
+  BaseBoardProductName = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  ProductNameStrLen = StrLen (BaseBoardProductName);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_VERSION);
+  Version = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  VerStrLen = StrLen (Version);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_SERIAL_NUMBER);
+  SerialNumber = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  SerialNumStrLen = StrLen (SerialNumber);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_ASSET_TAG);
+  AssetTag = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  AssetTagStrLen = StrLen (AssetTag);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_CHASSIS_LOCATION);
+  ChassisLocation = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  ChassisLocaStrLen = StrLen (ChassisLocation);
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE2) + ManuStrLen        + 1
+                                                                + ProductNameStrLen + 1
+                                                                + VerStrLen         + 1
+                                                                + SerialNumStrLen   + 1
+                                                                + AssetTagStrLen    + 1
+                                                                + ChassisLocaStrLen + 1 + 1);
+  if (SmbiosRecord == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE2));
+  SmbiosRecord->Hdr.Length        = sizeof (SMBIOS_TABLE_TYPE2);
+
+  //
+  //  Update Contained objects Handle
+  //
+  SmbiosRecord->NumberOfContainedObjectHandles = 0;
+  GetLinkTypeHandle (EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE, &HandleArray, &HandleCount);
+  if (HandleCount) {
+    SmbiosRecord->ChassisHandle = HandleArray[0];
+  }
+
+  FreePool(HandleArray);
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStrS (BaseBoardManufacturer, OptionalStrStart, ManuStrLen + 1);
+  UnicodeStrToAsciiStrS (BaseBoardProductName, OptionalStrStart + ManuStrLen + 1, ProductNameStrLen + 1);
+  UnicodeStrToAsciiStrS (Version, OptionalStrStart + ManuStrLen + 1 + ProductNameStrLen + 1, VerStrLen + 1);
+  UnicodeStrToAsciiStrS (SerialNumber, OptionalStrStart + ManuStrLen + 1 + ProductNameStrLen + 1 + VerStrLen + 1, SerialNumStrLen + 1);
+  UnicodeStrToAsciiStrS (AssetTag, OptionalStrStart + ManuStrLen + 1 + ProductNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1, AssetTagStrLen + 1);
+  UnicodeStrToAsciiStrS (ChassisLocation, OptionalStrStart + ManuStrLen + 1 + ProductNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssetTagStrLen + 1, ChassisLocaStrLen + 1);
+
+  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type02 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+  }
+
+  FreePool (SmbiosRecord);
+
+Exit:
+  if (BaseBoardManufacturer != NULL) {
+    FreePool (BaseBoardManufacturer);
+  }
+
+  if (BaseBoardProductName != NULL) {
+    FreePool (BaseBoardProductName);
+  }
+
+  if (Version != NULL) {
+    FreePool (Version);
+  }
+
+  if (SerialNumber != NULL) {
+    FreePool (SerialNumber);
+  }
+
+  if (AssetTag != NULL) {
+    FreePool (AssetTag);
+  }
+
+  if (ChassisLocation != NULL) {
+    FreePool (ChassisLocation);
+  }
+
+  return 0;
+}
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerData.c
new file mode 100644
index 000000000000..25d1413ed873
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerData.c
@@ -0,0 +1,58 @@
+/*++
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscChassisManufacturerData.c
+
+Abstract:
+
+  This file provides Smbios Type3 Data
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Chassis Manufacturer data.
+//
+MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE3, MiscChassisManufacturer) = {
+  {                                                       // Hdr
+    EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE  ,                   // Type,
+    0,                                                    // Length,
+    0                                                     // Handle
+  },
+  1,                                                      // Manufactrurer
+  MiscChassisTypeMainServerChassis,                       // Type
+  2,                                                      // Version
+  3,                                                      // SerialNumber
+  4,                                                      // AssetTag
+  ChassisStateSafe,                                       // BootupState
+  ChassisStateSafe,                                       // PowerSupplyState
+  ChassisStateSafe,                                       // ThermalState
+  ChassisSecurityStatusNone,                              // SecurityState
+  {
+    0,                                                    // OemDefined[0]
+    0,                                                    // OemDefined[1]
+    0,                                                    // OemDefined[2]
+    0                                                     // OemDefined[3]
+  },
+  2,                                                      // Height
+  1,                                                      // NumberofPowerCords
+  0,                                                      // ContainedElementCount
+  0,                                                      // ContainedElementRecordLength
+  {                                                       // ContainedElements[0]
+    {
+      0,                                                    // ContainedElementType
+      0,                                                    // ContainedElementMinimum
+      0                                                     // ContainedElementMaximum
+    }
+  }
+};
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerFunction.c
new file mode 100644
index 000000000000..84b4aaaeb89d
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerFunction.c
@@ -0,0 +1,182 @@
+/** @file
+
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscChassisManufacturerFunction.c
+
+Abstract:
+
+  This driver parses the mMiscSubclassDataTable structure and reports
+  any generated data to smbios.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+UINT8
+GetChassisType (
+  VOID
+  )
+{
+  EFI_STATUS                      Status;
+  UINT8                           ChassisType;
+
+  Status = OemGetChassisType (&ChassisType);
+  if (EFI_ERROR (Status)) {
+    return 0;
+  }
+
+  return ChassisType;
+}
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscChassisManufacturer (Type 3).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscChassisManufacturer)
+{
+  CHAR8                           *OptionalStrStart;
+  UINTN                           ManuStrLen;
+  UINTN                           VerStrLen;
+  UINTN                           AssertTagStrLen;
+  UINTN                           SerialNumStrLen;
+  UINTN                           ChaNumStrLen;
+  EFI_STRING                      Manufacturer;
+  EFI_STRING                      Version;
+  EFI_STRING                      SerialNumber;
+  EFI_STRING                      AssertTag;
+  EFI_STRING                      ChassisSkuNumber;
+  EFI_STRING_ID                   TokenToGet;
+  EFI_SMBIOS_HANDLE               SmbiosHandle;
+  SMBIOS_TABLE_TYPE3              *SmbiosRecord;
+  SMBIOS_TABLE_TYPE3              *InputData;
+  EFI_STATUS                      Status;
+
+  UINT8                           ContainedElementCount;
+  CONTAINED_ELEMENT               ContainedElements = {0};
+  UINT8                           ExtendLength = 0;
+
+  UINT8                           ChassisType;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InputData = (SMBIOS_TABLE_TYPE3 *)RecordData;
+
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_CHASSIS_ASSET_TAG), AssetTagType03);
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_CHASSIS_SERIAL_NUMBER), SrNumType03);
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_CHASSIS_VERSION), VersionType03);
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_CHASSIS_MANUFACTURER), ManufacturerType03);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_MANUFACTURER);
+  Manufacturer = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  ManuStrLen = StrLen (Manufacturer);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_VERSION);
+  Version = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  VerStrLen = StrLen (Version);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_SERIAL_NUMBER);
+  SerialNumber = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  SerialNumStrLen = StrLen (SerialNumber);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_ASSET_TAG);
+  AssertTag = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  AssertTagStrLen = StrLen (AssertTag);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_SKU_NUMBER);
+  ChassisSkuNumber = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  ChaNumStrLen = StrLen (ChassisSkuNumber);
+
+  ContainedElementCount = InputData->ContainedElementCount;
+
+  if (ContainedElementCount > 1) {
+    ExtendLength = (ContainedElementCount - 1) * sizeof (CONTAINED_ELEMENT);
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE3) + ExtendLength    + 1
+                                                                + ManuStrLen      + 1
+                                                                + VerStrLen       + 1
+                                                                + SerialNumStrLen + 1
+                                                                + AssertTagStrLen + 1
+                                                                + ChaNumStrLen    + 1 + 1);
+  if (SmbiosRecord == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE3));
+
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE3) + ExtendLength + 1;
+
+  ChassisType = GetChassisType ();
+  if (ChassisType != 0) {
+    SmbiosRecord->Type  = ChassisType;
+  }
+
+  //ContainedElements
+  (VOID)CopyMem (SmbiosRecord + 1, &ContainedElements, ExtendLength);
+
+  //ChassisSkuNumber
+  *((UINT8 *)SmbiosRecord + sizeof (SMBIOS_TABLE_TYPE3) + ExtendLength) = 5;
+
+  OptionalStrStart = (CHAR8 *)((UINT8 *)SmbiosRecord + sizeof (SMBIOS_TABLE_TYPE3) + ExtendLength + 1);
+  UnicodeStrToAsciiStrS (Manufacturer,     OptionalStrStart, ManuStrLen + 1);
+  UnicodeStrToAsciiStrS (Version, OptionalStrStart + ManuStrLen + 1, VerStrLen + 1);
+  UnicodeStrToAsciiStrS (SerialNumber, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1, SerialNumStrLen + 1);
+  UnicodeStrToAsciiStrS (AssertTag, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1, AssertTagStrLen + 1);
+  UnicodeStrToAsciiStrS (ChassisSkuNumber, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1 + SerialNumStrLen +1 + AssertTagStrLen + 1, ChaNumStrLen + 1);
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type03 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+  }
+
+  FreePool (SmbiosRecord);
+
+Exit:
+  if (Manufacturer != NULL) {
+    FreePool (Manufacturer);
+  }
+
+  if (Version != NULL) {
+    FreePool (Version);
+  }
+
+  if (SerialNumber != NULL) {
+    FreePool (SerialNumber);
+  }
+
+  if (AssertTag != NULL) {
+    FreePool (AssertTag);
+  }
+
+  if (ChassisSkuNumber != NULL) {
+    FreePool (ChassisSkuNumber);
+  }
+
+  return 0;
+}
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesData.c
new file mode 100644
index 000000000000..fa4c574a82c5
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesData.c
@@ -0,0 +1,39 @@
+/**@file
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscNumberOfInstallableLanguagesData.c
+
+Abstract:
+
+  This file provides Smbios Type13 Data
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+
+MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE13, MiscNumberOfInstallableLanguages) =
+{
+  {                                                     // Hdr
+    EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION,            // Type,
+    0,                                                    // Length,
+    0                                                     // Handle
+  },
+  0,                                                    // InstallableLanguages
+  0,                                                    // Flags
+  {
+    0                                                   // Reserved[15]
+  },
+  1                                                     // CurrentLanguage
+};
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesFunction.c
new file mode 100644
index 000000000000..dc360aa74cea
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesFunction.c
@@ -0,0 +1,154 @@
+/** @file
+
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+/**
+  Get next language from language code list (with separator ';').
+
+  @param  LangCode       Input: point to first language in the list. On
+                         Otput: point to next language in the list, or
+                                NULL if no more language in the list.
+  @param  Lang           The first language in the list.
+
+**/
+VOID
+EFIAPI
+GetNextLanguage (
+  IN OUT CHAR8      **LangCode,
+  OUT CHAR8         *Lang
+  )
+{
+  UINTN  Index;
+  CHAR8  *StringPtr;
+
+  if (LangCode == NULL || *LangCode == NULL || Lang == NULL) {
+    return;
+  }
+
+  Index     = 0;
+  StringPtr = *LangCode;
+  while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
+    Index++;
+  }
+
+  (VOID)CopyMem (Lang, StringPtr, Index);
+  Lang[Index] = 0;
+
+  if (StringPtr[Index] == ';') {
+    Index++;
+  }
+  *LangCode = StringPtr + Index;
+}
+
+/**
+  This function returns the number of supported languages on HiiHandle.
+
+  @param   HiiHandle    The HII package list handle.
+
+  @retval  The number of supported languages.
+
+**/
+UINT16
+EFIAPI
+GetSupportedLanguageNumber (
+  IN EFI_HII_HANDLE    HiiHandle
+  )
+{
+  CHAR8   *Lang;
+  CHAR8   *Languages;
+  CHAR8   *LanguageString;
+  UINT16  LangNumber;
+
+  Languages = HiiGetSupportedLanguages (HiiHandle);
+  if (Languages == NULL) {
+    return 0;
+  }
+
+  LangNumber = 0;
+  Lang = AllocatePool (AsciiStrSize (Languages));
+  if (Lang != NULL) {
+    LanguageString = Languages;
+    while (*LanguageString != 0) {
+      GetNextLanguage (&LanguageString, Lang);
+      LangNumber++;
+    }
+    FreePool (Lang);
+  }
+  FreePool (Languages);
+  return LangNumber;
+}
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscNumberOfInstallableLanguages (Type 13).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscNumberOfInstallableLanguages)
+{
+  UINTN                                     LangStrLen;
+  CHAR8                                     CurrentLang[SMBIOS_STRING_MAX_LENGTH + 1];
+  CHAR8                                     *OptionalStrStart;
+  EFI_STATUS                                Status;
+  EFI_SMBIOS_HANDLE                         SmbiosHandle;
+  SMBIOS_TABLE_TYPE13                       *SmbiosRecord;
+  SMBIOS_TABLE_TYPE13                       *InputData = NULL;;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InputData = (SMBIOS_TABLE_TYPE13 *)RecordData;
+
+  InputData->InstallableLanguages = GetSupportedLanguageNumber (mHiiHandle);
+
+  //
+  // Try to check if current langcode matches with the langcodes in installed languages
+  //
+  ZeroMem (CurrentLang, SMBIOS_STRING_MAX_LENGTH - 1);
+  (VOID)AsciiStrCpyS (CurrentLang, SMBIOS_STRING_MAX_LENGTH - 1, "en|US|iso8859-1");
+  LangStrLen = AsciiStrLen (CurrentLang);
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1);
+  if (SmbiosRecord == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE13));
+
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE13);
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  (VOID)AsciiStrCpyS (OptionalStrStart, SMBIOS_STRING_MAX_LENGTH - 1, CurrentLang);
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type13 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+  }
+
+  FreePool (SmbiosRecord);
+  return Status;
+}
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationData.c
new file mode 100644
index 000000000000..c00225a54005
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationData.c
@@ -0,0 +1,41 @@
+/**@file
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscBootInformationData.c
+
+Abstract:
+
+  This driver parses the mMiscSubclassDataTable structure and reports
+  any generated data to the DataHub.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE32, MiscBootInformation) = {
+  {                                                     // Hdr
+    EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION,              // Type,
+    0,                                                    // Length,
+    0                                                     // Handle
+  },
+  {                                                     // Reserved[6]
+    0,
+    0,
+    0,
+    0,
+    0,
+    0
+  },
+  BootInformationStatusNoError                          // BootInformationStatus
+};
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationFunction.c
new file mode 100644
index 000000000000..25da6de1bfa6
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationFunction.c
@@ -0,0 +1,66 @@
+/** @file
+  boot information boot time changes.
+  SMBIOS type 32.
+
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscBootInformation (Type 32).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+
+MISC_SMBIOS_TABLE_FUNCTION(MiscBootInformation)
+{
+  EFI_STATUS                         Status;
+  EFI_SMBIOS_HANDLE                  SmbiosHandle;
+  SMBIOS_TABLE_TYPE32                *SmbiosRecord;
+  SMBIOS_TABLE_TYPE32                *InputData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InputData = (SMBIOS_TABLE_TYPE32 *)RecordData;
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE32) + 1 + 1);
+  if (SmbiosRecord == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE32));
+
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE32);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type32 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+  }
+
+  FreePool (SmbiosRecord);
+  return Status;
+}
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
index 199374ff59e3..874bc2866ac3 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
@@ -424,6 +424,9 @@ ASM_FUNC(ArmCallWFI)
   wfi
   ret
 
+ASM_FUNC(ArmReadIdMmfr2)
+  mrs   x0, ID_AA64MMFR2_EL1           // read EL1 MMFR2
+  ret
 
 ASM_FUNC(ArmReadMpidr)
   mrs   x0, mpidr_el1           // read EL1 MPIDR
diff --git a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
index 0e8d21e2264f..0ae75e4cb9f9 100644
--- a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
+++ b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
@@ -84,7 +84,7 @@ ASM_FUNC(ArmDisableAllExceptions)
   ret
 
 
-// UINT32
+// UINTN
 // ReadCCSIDR (
 //   IN UINT32 CSSELR
 //   )
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
index 01c91b10fcb7..39fdb0155065 100644
--- a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
+++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
@@ -60,6 +60,10 @@ ASM_FUNC(ArmDisableInterrupts)
   isb
   bx      LR
 
+ASM_FUNC(ArmReadIdMmfr4):
+  mrc    p15,0,r0,c0,c2,6     @ Read ID_MMFR4 Register
+  bx     lr
+
 // UINT32
 // ReadCCSIDR (
 //   IN UINT32 CSSELR
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm
index 26ffa331b929..d1bbb0a0fc98 100644
--- a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm
+++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm
@@ -64,7 +64,11 @@
   isb
   bx      LR
 
-// UINT32
+ RVCT_ASM_EXPORT ArmReadIdMmfr4
+  mrc    p15,0,r0,c0,c2,6     ; Read ID_MMFR2 Register
+  bx
+
+// UINTN
 // ReadCCSIDR (
 //   IN UINT32 CSSELR
 //   )
diff --git a/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni
new file mode 100644
index 000000000000..0f55beb95276
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni
@@ -0,0 +1,23 @@
+///// @file
+//
+//  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+//  Copyright (c) 2015, Linaro Limited. All rights reserved.
+//
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+/////
+
+/=#
+
+#langdef en-US "English"
+
+//
+// Processor Information
+//
+#string STR_PROCESSOR_SOCKET_DESIGNATION    #language en-US  "Not Specified"
+#string STR_PROCESSOR_MANUFACTURE           #language en-US  "Not Specified"
+#string STR_PROCESSOR_VERSION               #language en-US  "Not Specified"
+#string STR_PROCESSOR_SERIAL_NUMBER         #language en-US  "Not Specified"
+#string STR_PROCESSOR_ASSET_TAG             #language en-US  "Not Specified"
+#string STR_PROCESSOR_PART_NUMBER           #language en-US  "Not Specified"
+#string STR_PROCESSOR_UNKNOWN               #language en-US  "Unknown"
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni
new file mode 100644
index 000000000000..7a82e520904e
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni
@@ -0,0 +1,21 @@
+// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+// --*/
+
+
+/=#
+
+#langdef en-US "English"
+
+#include "./Type00/MiscBiosVendor.uni"
+#include "./Type01/MiscSystemManufacturer.uni"
+#include "./Type02/MiscBaseBoardManufacturer.uni"
+#include "./Type03/MiscChassisManufacturer.uni"
+#include "./Type13/MiscNumberOfInstallableLanguages.uni"
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni
new file mode 100644
index 000000000000..cf14e477d260
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni
@@ -0,0 +1,18 @@
+// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+// --*/
+
+/=#
+
+#string STR_MISC_BIOS_VENDOR           #language en-US  "Not Specified"
+#string STR_MISC_BIOS_VERSION          #language en-US  "Not Specified"
+#string STR_MISC_BIOS_RELEASE_DATE     #language en-US  "Not Specified"
+#string STR_MISC_BIOS_VENDOR           #language en-US  "Not Specified"
+#string STR_MISC_BIOS_RELEASE_DATE     #language en-US  "01/01/2020"
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturer.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturer.uni
new file mode 100644
index 000000000000..417a5986c79e
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturer.uni
@@ -0,0 +1,21 @@
+// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+// --*/
+
+/=#
+
+#string STR_MISC_SYSTEM_MANUFACTURER   #language en-US  "Not Specified"
+#string STR_MISC_SYSTEM_PRODUCT_NAME   #language en-US  "Not Specified"
+#string STR_MISC_SYSTEM_PRODUCT_NAME   #language en-US  "Not Specified"
+#string STR_MISC_SYSTEM_VERSION        #language en-US  "Not Specified"
+#string STR_MISC_SYSTEM_VERSION        #language en-US  "Not Specified"
+#string STR_MISC_SYSTEM_SERIAL_NUMBER  #language en-US  "Not Specified"
+#string STR_MISC_SYSTEM_SKU_NUMBER     #language en-US  "Not Specified"
+#string STR_MISC_SYSTEM_FAMILY         #language en-US  "Not Specified"
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturer.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturer.uni
new file mode 100644
index 000000000000..96398d837752
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturer.uni
@@ -0,0 +1,21 @@
+// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+// --*/
+
+/=#
+
+#string STR_MISC_BASE_BOARD_MANUFACTURER     #language en-US  "Not Specified"
+#string STR_MISC_BASE_BOARD_PRODUCT_NAME     #language en-US  "Not Specified"
+#string STR_MISC_BASE_BOARD_PRODUCT_NAME     #language en-US  "Not Specified"
+#string STR_MISC_BASE_BOARD_VERSION          #language en-US  "Not Specified"
+#string STR_MISC_BASE_BOARD_VERSION          #language en-US  "Not Specified"
+#string STR_MISC_BASE_BOARD_SERIAL_NUMBER    #language en-US  "Not Specified"
+#string STR_MISC_BASE_BOARD_ASSET_TAG        #language en-US  "Not Specified"
+#string STR_MISC_BASE_BOARD_CHASSIS_LOCATION #language en-US  "Not Specified"
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturer.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturer.uni
new file mode 100644
index 000000000000..a2b9500f94c5
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturer.uni
@@ -0,0 +1,18 @@
+// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+// --*/
+
+/=#
+
+#string STR_MISC_CHASSIS_MANUFACTURER  #language en-US  "Not Specified"
+#string STR_MISC_CHASSIS_VERSION       #language en-US  "Not Specified"
+#string STR_MISC_CHASSIS_SERIAL_NUMBER #language en-US  "Not Specified"
+#string STR_MISC_CHASSIS_ASSET_TAG     #language en-US  "Not Specified"
+#string STR_MISC_CHASSIS_SKU_NUMBER    #language en-US  "Not Specified"
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguages.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguages.uni
new file mode 100644
index 000000000000..559003369f21
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguages.uni
@@ -0,0 +1,43 @@
+// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+// --*/
+
+/=#
+
+/=#
+//
+// Language String (Long Format)
+//
+#string STR_MISC_BIOS_LANGUAGES_ENG_LONG        #language en-US  "en|US|iso8859-1"
+#string STR_MISC_BIOS_LANGUAGES_FRA_LONG        #language en-US  "fr|CA|iso8859-1"
+#string STR_MISC_BIOS_LANGUAGES_CHN_LONG        #language en-US  "zh|TW|unicode"
+#string STR_MISC_BIOS_LANGUAGES_JPN_LONG        #language en-US  "ja|JP|unicode"
+#string STR_MISC_BIOS_LANGUAGES_ITA_LONG        #language en-US  "it|IT|iso8859-1"
+#string STR_MISC_BIOS_LANGUAGES_SPA_LONG        #language en-US  "es|ES|iso8859-1"
+#string STR_MISC_BIOS_LANGUAGES_GER_LONG        #language en-US  "de|DE|iso8859-1"
+#string STR_MISC_BIOS_LANGUAGES_POR_LONG        #language en-US  "pt|PT|iso8859-1"
+
+
+//
+// Language String (Abbreviated Format)
+//
+#string STR_MISC_BIOS_LANGUAGES_ENG_ABBREVIATE  #language en-US  "enUS"
+#string STR_MISC_BIOS_LANGUAGES_FRA_ABBREVIATE  #language en-US  "frCA"
+#string STR_MISC_BIOS_LANGUAGES_CHN_ABBREVIATE  #language en-US  "zhTW"
+#string STR_MISC_BIOS_LANGUAGES_JPN_ABBREVIATE  #language en-US  "jaJP"
+#string STR_MISC_BIOS_LANGUAGES_ITA_ABBREVIATE  #language en-US  "itIT"
+#string STR_MISC_BIOS_LANGUAGES_SPA_ABBREVIATE  #language en-US  "esES"
+#string STR_MISC_BIOS_LANGUAGES_GER_ABBREVIATE  #language en-US  "deDE"
+#string STR_MISC_BIOS_LANGUAGES_POR_ABBREVIATE  #language en-US  "ptPT"
+
+#string STR_MISC_BIOS_LANGUAGES_SIMPLECH_ABBREVIATE  #language en-US  "zhCN"
+#string STR_MISC_BIOS_LANGUAGES_SIMPLECH_LONG        #language en-US  "zh|CN|unicode"
+
+
-- 
2.26.2


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

* 回复: [PATCH v3 2/3] MdePkg: Update IndustryStandard/SmBios.h with processor status data
  2020-11-11  0:17 ` [PATCH v3 2/3] MdePkg: Update IndustryStandard/SmBios.h with processor status data Rebecca Cran
@ 2020-11-11  1:18   ` gaoliming
  2020-11-13 11:25   ` [edk2-devel] " Sami Mujawar
  2020-11-19 12:05   ` Leif Lindholm
  2 siblings, 0 replies; 14+ messages in thread
From: gaoliming @ 2020-11-11  1:18 UTC (permalink / raw)
  To: 'Rebecca Cran', devel
  Cc: 'Leif Lindholm', 'Ard Biesheuvel',
	'Michael D Kinney', 'Zhiguang Liu'

This change follows SmBios spec. It is ok to me. Reviewed-by: Liming Gao
<gaoliming@byosoft.com.cn>

> -----邮件原件-----
> 发件人: Rebecca Cran <rebecca@nuviainc.com>
> 发送时间: 2020年11月11日 8:18
> 收件人: devel@edk2.groups.io
> 抄送: Rebecca Cran <rebecca@nuviainc.com>; Leif Lindholm
> <leif@nuviainc.com>; Ard Biesheuvel <ard.biesheuvel@arm.com>; Michael D
> Kinney <michael.d.kinney@intel.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>
> 主题: [PATCH v3 2/3] MdePkg: Update IndustryStandard/SmBios.h with
> processor status data
> 
> Add a bitfield that describes the structure of the byte in the Status
> field of the SMBIOS Type 4 Processor Information table.
> 
> Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
> ---
>  MdePkg/Include/IndustryStandard/SmBios.h | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/MdePkg/Include/IndustryStandard/SmBios.h
> b/MdePkg/Include/IndustryStandard/SmBios.h
> index 1ee01645679a..bb4a3a8dc0d3 100644
> --- a/MdePkg/Include/IndustryStandard/SmBios.h
> +++ b/MdePkg/Include/IndustryStandard/SmBios.h
> @@ -875,6 +875,19 @@ typedef struct {
>    UINT16  ProcessorReserved2             :6;
>  } PROCESSOR_CHARACTERISTIC_FLAGS;
> 
> +///
> +/// Processor Information - Status
> +///
> +typedef union {
> +  struct {
> +    UINT8 CpuStatus       :3; // Indicates the status of the processor.
> +    UINT8 Reserved1       :3; // Reserved for future use. Should be set
> to zero.
> +    UINT8 SocketPopulated :1; // Indicates if the processor socket is
> populated or not.
> +    UINT8 Reserved2       :1; // Reserved for future use. Should be set
> to zero.
> +  } Bits;
> +  UINT8 Data;
> +} PROCESSOR_STATUS_DATA;
> +
>  typedef struct {
>    PROCESSOR_SIGNATURE     Signature;
>    PROCESSOR_FEATURE_FLAGS FeatureFlags;
> --
> 2.26.2




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

* Re: [edk2-devel] [PATCH v3 1/3] ArmPkg: Add ARM SMC Architecture functions to ArmStdSmc.h
  2020-11-11  0:17 ` [PATCH v3 1/3] ArmPkg: Add ARM SMC Architecture functions to ArmStdSmc.h Rebecca Cran
@ 2020-11-12 21:49   ` Sami Mujawar
  2020-11-19 12:00   ` Leif Lindholm
  1 sibling, 0 replies; 14+ messages in thread
From: Sami Mujawar @ 2020-11-12 21:49 UTC (permalink / raw)
  To: devel@edk2.groups.io, rebecca@nuviainc.com
  Cc: Leif Lindholm, Ard Biesheuvel, Michael D Kinney, Liming Gao,
	Zhiguang Liu

Hi Rebecca,

Thank you for this patch.

Please find my response inline marked [SAMI].

Otherwise this patch looks good to me.

Regards,

Sami Mujawar

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Rebecca Cran via groups.io
Sent: 11 November 2020 12:18 AM
To: devel@edk2.groups.io
Cc: Rebecca Cran <rebecca@nuviainc.com>; Leif Lindholm <leif@nuviainc.com>; Ard Biesheuvel <Ard.Biesheuvel@arm.com>; Michael D Kinney <michael.d.kinney@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>
Subject: [edk2-devel] [PATCH v3 1/3] ArmPkg: Add ARM SMC Architecture functions to ArmStdSmc.h

The ARM SMC Architecture functions were missing from ArmStdSmc.h.
Add them, based on the SMC Calling Convention version 1.2 specification.

Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
---
 ArmPkg/Include/IndustryStandard/ArmStdSmc.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/ArmPkg/Include/IndustryStandard/ArmStdSmc.h b/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
index 3509eb680f18..90f32c2249cd 100644
--- a/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
+++ b/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
@@ -1,5 +1,6 @@
 /** @file
 *
+*  Copyright (c) 2020, NUVIA Inc. All rights reserved.
 *  Copyright (c) 2012-2017, ARM Limited. All rights reserved.
 *
 *  SPDX-License-Identifier: BSD-2-Clause-Patent

[SAMI] Can you add a reference to the SMCCC 1.2 spec in the file header, please?  Something like:

@par Revision Reference:
  - SMC Calling Convention version 1.2
    (https://developer.arm.com/documentation/den0028/latest)

[/SAMI]

@@ -52,6 +53,18 @@
 #define ARM_SMC_MM_RET_DENIED              -3
 #define ARM_SMC_MM_RET_NO_MEMORY           -4

+// ARM Architecture Calls
+#define ARM_SMC_ID_ARCH_VERSION      0x80000000
+#define ARM_SMC_ID_ARCH_FEATURES     0x80000001
+#define ARM_SMC_ID_ARCH_SOC_ID       0x80000002
+#define ARM_SMC_ID_ARCH_WORKAROUND_1 0x80008000
+#define ARM_SMC_ID_ARCH_WORKAROUND_2 0x80007FFF
+
+#define ARM_SMC_ARCH_RET_SUCCESS            0
+#define ARM_SMC_ARCH_RET_NOT_SUPPORTED     -1
+#define ARM_SMC_ARCH_RET_NOT_REQUIRED      -2
+#define ARM_SMC_ARCH_RET_INVALID_PARAMETER -3
+
 /*
  * Power State Coordination Interface (PSCI) calls cover a subset of the
  * Standard Service Call range.
--
2.26.2






IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

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

* Re: [edk2-devel] [PATCH v3 2/3] MdePkg: Update IndustryStandard/SmBios.h with processor status data
  2020-11-11  0:17 ` [PATCH v3 2/3] MdePkg: Update IndustryStandard/SmBios.h with processor status data Rebecca Cran
  2020-11-11  1:18   ` 回复: " gaoliming
@ 2020-11-13 11:25   ` Sami Mujawar
  2020-11-19 12:05   ` Leif Lindholm
  2 siblings, 0 replies; 14+ messages in thread
From: Sami Mujawar @ 2020-11-13 11:25 UTC (permalink / raw)
  To: devel@edk2.groups.io, rebecca@nuviainc.com
  Cc: Leif Lindholm, Ard Biesheuvel, Michael D Kinney, Liming Gao,
	Zhiguang Liu

Hi Rebecca,

Please find my response inline marked [SAMI].

With that changed:
Acked-by: Sami Mujawar <sami.mujawar@arm.com>

Regards,

Sami Mujawar

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Rebecca Cran via groups.io
Sent: 11 November 2020 12:18 AM
To: devel@edk2.groups.io
Cc: Rebecca Cran <rebecca@nuviainc.com>; Leif Lindholm <leif@nuviainc.com>; Ard Biesheuvel <Ard.Biesheuvel@arm.com>; Michael D Kinney <michael.d.kinney@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>
Subject: [edk2-devel] [PATCH v3 2/3] MdePkg: Update IndustryStandard/SmBios.h with processor status data

Add a bitfield that describes the structure of the byte in the Status
field of the SMBIOS Type 4 Processor Information table.

Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
---
 MdePkg/Include/IndustryStandard/SmBios.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/MdePkg/Include/IndustryStandard/SmBios.h b/MdePkg/Include/IndustryStandard/SmBios.h
index 1ee01645679a..bb4a3a8dc0d3 100644
--- a/MdePkg/Include/IndustryStandard/SmBios.h
+++ b/MdePkg/Include/IndustryStandard/SmBios.h
@@ -875,6 +875,19 @@ typedef struct {
   UINT16  ProcessorReserved2             :6;
 } PROCESSOR_CHARACTERISTIC_FLAGS;

+///
+/// Processor Information - Status
+///
+typedef union {
+  struct {
+    UINT8 CpuStatus       :3; // Indicates the status of the processor.

[SAMI] Please use ///< doxygen comment style. [/SAMI]

+    UINT8 Reserved1       :3; // Reserved for future use. Should be set to zero.

[SAMI] IMO, 'Must be set to zero' would be better. [/SAMI]

+    UINT8 SocketPopulated :1; // Indicates if the processor socket is populated or not.
+    UINT8 Reserved2       :1; // Reserved for future use. Should be set to zero.
+  } Bits;
+  UINT8 Data;
+} PROCESSOR_STATUS_DATA;
+
 typedef struct {
   PROCESSOR_SIGNATURE     Signature;
   PROCESSOR_FEATURE_FLAGS FeatureFlags;
--
2.26.2






IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

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

* Re: [edk2-devel] [PATCH v3 3/3] ArmPkg: add Universal/Smbios as a generic SMBIOS library
  2020-11-11  0:17 ` [PATCH v3 3/3] ArmPkg: add Universal/Smbios as a generic SMBIOS library Rebecca Cran
@ 2020-11-16 13:43   ` Sami Mujawar
  2020-11-17  3:27     ` Rebecca Cran
  2020-11-19 12:58   ` Leif Lindholm
  1 sibling, 1 reply; 14+ messages in thread
From: Sami Mujawar @ 2020-11-16 13:43 UTC (permalink / raw)
  To: devel@edk2.groups.io, rebecca@nuviainc.com
  Cc: Leif Lindholm, Ard Biesheuvel, Michael D Kinney, Liming Gao,
	Zhiguang Liu, nd

Hi Rebecca,

I have reviewed the following files from this patch and my responses are inline marked [SAMI].
  ArmPkg/Include/Chipset/AArch64.h
  ArmPkg/Include/Library/ArmLib.h
  ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
  ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
  ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
  ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
  ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
  ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm
  ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
  ArmPkg/Library/ArmLib/ArmLibPrivate.h

Is it possible to split this patch into smaller patches, please? It will then be easier to review the remaining files.

Regards,

Sami Mujawar

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Rebecca Cran via groups.io
Sent: 11 November 2020 12:18 AM
To: devel@edk2.groups.io
Cc: Rebecca Cran <rebecca@nuviainc.com>; Leif Lindholm <leif@nuviainc.com>; Ard Biesheuvel <Ard.Biesheuvel@arm.com>; Michael D Kinney <michael.d.kinney@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>
Subject: [edk2-devel] [PATCH v3 3/3] ArmPkg: add Universal/Smbios as a generic SMBIOS library

Much of the data for the SMBIOS tables is generic, and need not be
duplicated for each platform.

Adapt code from edk2-platforms/Silicon/HiSilicon/Drivers/Smbios and
edk2-platforms/Silicon/HiSilicon/Drivers/VersionInfoPeim, making them
generic, and place them into edk2/ArmPkg/Universal/Smbios and
edk2/ArmPkg/Drivers/VersionInfoPeim respectively.

They depend on each platform implementing an OemMiscLib that provides
OEM specific information such as CPU and cache information.

The VersionInfoPeim generates the release date from the build time, and
fetches the version string from PcdFirmwareVersionString.

Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
---
 ArmPkg/ArmPkg.dec                             |  16 +
 .../VersionInfoPeim/VersionInfoPeim.inf       |  46 ++
 .../ProcessorSubClassDxe.inf                  |  55 ++
 .../Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf    |  89 +++
 ArmPkg/Include/Chipset/AArch64.h              |   4 +
 ArmPkg/Include/Guid/VersionInfoHobGuid.h      |  29 +
 ArmPkg/Include/Library/ArmLib.h               |   6 +
 ArmPkg/Include/Library/OemMiscLib.h           |  86 +++
 ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h    |   6 +
 ArmPkg/Library/ArmLib/ArmLibPrivate.h         | 100 ++-
 .../ProcessorSubClassDxe/ProcessorSubClass.h  |  34 +
 .../Smbios/SmbiosMiscDxe/SmbiosMisc.h         | 217 ++++++
 .../Drivers/VersionInfoPeim/VersionInfoPeim.c |  90 +++
 ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c    |  15 +
 ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c          |  17 +
 .../ProcessorSubClassDxe/ProcessorSubClass.c  | 723 ++++++++++++++++++
 .../SmbiosMiscDxe/SmbiosMiscDataTable.c       |  50 ++
 .../SmbiosMiscDxe/SmbiosMiscEntryPoint.c      | 167 ++++
 .../SmbiosMiscDxe/Type00/MiscBiosVendorData.c |  99 +++
 .../Type00/MiscBiosVendorFunction.c           | 232 ++++++
 .../Type01/MiscSystemManufacturerData.c       |  43 ++
 .../Type01/MiscSystemManufacturerFunction.c   | 171 +++++
 .../Type02/MiscBaseBoardManufacturerData.c    |  51 ++
 .../MiscBaseBoardManufacturerFunction.c       | 184 +++++
 .../Type03/MiscChassisManufacturerData.c      |  58 ++
 .../Type03/MiscChassisManufacturerFunction.c  | 182 +++++
 .../MiscNumberOfInstallableLanguagesData.c    |  39 +
 ...MiscNumberOfInstallableLanguagesFunction.c | 154 ++++
 .../Type32/MiscBootInformationData.c          |  41 +
 .../Type32/MiscBootInformationFunction.c      |  66 ++
 .../Library/ArmLib/AArch64/AArch64Support.S   |   3 +
 .../Library/ArmLib/AArch64/ArmLibSupportV8.S  |   2 +-
 ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S   |   4 +
 ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm |   6 +-
 .../ProcessorSubClassStrings.uni              |  23 +
 .../SmbiosMiscDxe/SmbiosMiscLibString.uni     |  21 +
 .../SmbiosMiscDxe/Type00/MiscBiosVendor.uni   |  18 +
 .../Type01/MiscSystemManufacturer.uni         |  21 +
 .../Type02/MiscBaseBoardManufacturer.uni      |  21 +
 .../Type03/MiscChassisManufacturer.uni        |  18 +
 .../MiscNumberOfInstallableLanguages.uni      |  43 ++
 41 files changed, 3213 insertions(+), 37 deletions(-)
 create mode 100644 ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.inf
 create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
 create mode 100644 ArmPkg/Include/Guid/VersionInfoHobGuid.h
 create mode 100644 ArmPkg/Include/Library/OemMiscLib.h
 create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h
 create mode 100644 ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.c
 create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationData.c
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationFunction.c
 create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturer.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturer.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturer.uni
 create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguages.uni

diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index eaf1072d9ef3..64cfb7dc65e3 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -45,6 +45,8 @@ [Guids.common]
   # Include/Guid/ArmMpCoreInfo.h
   gArmMpCoreInfoGuid = { 0xa4ee0728, 0xe5d7, 0x4ac5,  {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} }
 
+  gVersionInfoHobGuid = { 0xe13a14c, 0x859c, 0x4f22, {0x82, 0xbd, 0x18, 0xe, 0xe1, 0x42, 0x12, 0xbf } }
+
 [Protocols.common]
   ## Arm System Control and Management Interface(SCMI) Base protocol
   ## ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h
@@ -115,6 +117,20 @@ [PcdsFixedAtBuild.common]
   # The Primary Core is ClusterId[0] & CoreId[0]
   gArmTokenSpaceGuid.PcdArmPrimaryCore|0|UINT32|0x00000037
 
+  #
+  # SMBIOS PCDs
+  #
+  gArmTokenSpaceGuid.PcdSystemProductName|L""|VOID*|0x30000053
+  gArmTokenSpaceGuid.PcdSystemVersion|L""|VOID*|0x30000054
+  gArmTokenSpaceGuid.PcdBaseBoardManufacturer|L""|VOID*|0x30000055
+  gArmTokenSpaceGuid.PcdBaseBoardProductName|L""|VOID*|0x30000056
+  gArmTokenSpaceGuid.PcdBaseBoardVersion|L""|VOID*|0x30000057
+  gArmTokenSpaceGuid.PcdProcessorManufacturer|L""|VOID*|0x30000071
+  gArmTokenSpaceGuid.PcdProcessorVersion|L""|VOID*|0x30000072
+  gArmTokenSpaceGuid.PcdProcessorSerialNumber|L""|VOID*|0x30000073
+  gArmTokenSpaceGuid.PcdProcessorAssetTag|L""|VOID*|0x30000074
+  gArmTokenSpaceGuid.PcdProcessorPartNumber|L""|VOID*|0x30000075
+
   #
   # ARM L2x0 PCDs
   #
diff --git a/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.inf b/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.inf
new file mode 100644
index 000000000000..c813dd84de4c
--- /dev/null
+++ b/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.inf
@@ -0,0 +1,46 @@
+#/** @file
+#
+#    Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2016, Linaro Limited. All rights reserved.
+#
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 1.29
+  BASE_NAME                      = VersionInfoPeim
+  FILE_GUID                      = 3d45d0a0-4ded-4c01-b16f-2b3007c1fbe2
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = VersionInfoEntry
+
+[Sources.common]
+  VersionInfoPeim.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  PcdLib
+  PeimEntryPoint
+  PrintLib
+  SerialPortLib
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+
+[Guids]
+  gVersionInfoHobGuid
+
+[Depex]
+  TRUE
+
+[BuildOptions]
+
diff --git a/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
new file mode 100644
index 000000000000..715f66912983
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
@@ -0,0 +1,55 @@
+#/** @file
+#
+#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+#    Copyright (c) 2015, Linaro Limited. All rights reserved.
+#
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+
+[Defines]
+  INF_VERSION                    = 1.29
+  BASE_NAME                      = ProcessorSubClass
+  FILE_GUID                      = f3fe0e33-ea38-4069-9fb5-be23407207c7
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = ProcessorSubClassEntryPoint
+
+[Sources]
+  ProcessorSubClass.c
+  ProcessorSubClassStrings.uni
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  ArmSmcLib
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  HiiLib
+  IoLib
+  MemoryAllocationLib
+  OemMiscLib
+  PcdLib
+  PrintLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdProcessorManufacturer
+  gArmTokenSpaceGuid.PcdProcessorVersion
+  gArmTokenSpaceGuid.PcdProcessorSerialNumber
+  gArmTokenSpaceGuid.PcdProcessorAssetTag
+  gArmTokenSpaceGuid.PcdProcessorPartNumber
+
+[Guids]
+
+
+[Depex]
+  gEfiSmbiosProtocolGuid
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
new file mode 100644
index 000000000000..1954f7207267
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
@@ -0,0 +1,89 @@
+## @file
+# Component description file for SmbiosMisc instance.
+#
+# Parses the MiscSubclassDataTable and reports any generated data to the DataHub.
+#  All .uni file who tagged with "ToolCode="DUMMY"" in following file list is included by
+#  MiscSubclassDriver.uni file, the StrGather tool will expand MiscSubclassDriver.uni file
+#  and parse all .uni file.
+# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+# Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+# Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+##
+
+
+[Defines]
+  INF_VERSION                    = 1.29
+  BASE_NAME                      = SmbiosMiscDxe
+  FILE_GUID                      = 7e5e26d4-0be9-401f-b5e1-1c2bda7ca777
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmbiosMiscEntryPoint
+
+[Sources]
+  SmbiosMisc.h
+  SmbiosMiscDataTable.c
+  SmbiosMiscEntryPoint.c
+  SmbiosMiscLibString.uni
+  Type00/MiscBiosVendorData.c
+  Type00/MiscBiosVendorFunction.c
+  Type01/MiscSystemManufacturerData.c
+  Type01/MiscSystemManufacturerFunction.c
+  Type02/MiscBaseBoardManufacturerData.c
+  Type02/MiscBaseBoardManufacturerFunction.c
+  Type03/MiscChassisManufacturerData.c
+  Type03/MiscChassisManufacturerFunction.c
+  Type13/MiscNumberOfInstallableLanguagesData.c
+  Type13/MiscNumberOfInstallableLanguagesFunction.c
+  Type32/MiscBootInformationData.c
+  Type32/MiscBootInformationFunction.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  PcdLib
+  HiiLib
+  HobLib
+  MemoryAllocationLib
+  OemMiscLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdFdSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareReleaseDateString
+  gArmTokenSpaceGuid.PcdSystemProductName
+  gArmTokenSpaceGuid.PcdSystemVersion
+  gArmTokenSpaceGuid.PcdBaseBoardManufacturer
+  gArmTokenSpaceGuid.PcdBaseBoardProductName
+  gArmTokenSpaceGuid.PcdBaseBoardVersion
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang
+
+[Guids]
+  gEfiGenericVariableGuid
+  gVersionInfoHobGuid
+
+[Depex]
+  gEfiSmbiosProtocolGuid
+
+
diff --git a/ArmPkg/Include/Chipset/AArch64.h b/ArmPkg/Include/Chipset/AArch64.h
index 0ade5cce91c3..7c2b592f92ee 100644
--- a/ArmPkg/Include/Chipset/AArch64.h
+++ b/ArmPkg/Include/Chipset/AArch64.h
@@ -112,6 +112,10 @@
 #define ARM_VECTOR_LOW_A32_FIQ  0x700
 #define ARM_VECTOR_LOW_A32_SERR 0x780
 
+// The ID_AA64MMFR2_EL1 register was added in ARMv8.2. Since we
+// build for ARMv8.0, we need to define the register here.
+#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
+

[SAMI] I think this file could be a separate patch by itself. e.g something like 'Add register encoding definition for Memory Model Feature Register 2'. 
No other comments for this file.
[/SAMI]

 #define VECTOR_BASE(tbl)          \
   .section .text.##tbl##,"ax";    \
   .align 11;                      \
diff --git a/ArmPkg/Include/Guid/VersionInfoHobGuid.h b/ArmPkg/Include/Guid/VersionInfoHobGuid.h
new file mode 100644
index 000000000000..9eeb0a5f7482
--- /dev/null
+++ b/ArmPkg/Include/Guid/VersionInfoHobGuid.h
@@ -0,0 +1,29 @@
+/** @file
+*
+*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2016, Linaro Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#ifndef _VERSION_INFO_HOB_GUID_H_
+#define _VERSION_INFO_HOB_GUID_H_
+
+// {0E13A14C-859C-4f22-82BD-180EE14212BF}
+#define VERSION_INFO_HOB_GUID \
+  {0xe13a14c, 0x859c, 0x4f22, {0x82, 0xbd, 0x18, 0xe, 0xe1, 0x42, 0x12, 0xbf}}
+
+extern GUID gVersionInfoHobGuid;
+
+#pragma pack(1)
+
+typedef struct {
+  EFI_TIME BuildTime;
+  CHAR16   String[1];
+} VERSION_INFO;
+
+#pragma pack()
+
+#endif
+
diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h
index 5a27b7c2fc27..4a740b6ca298 100644
--- a/ArmPkg/Include/Library/ArmLib.h
+++ b/ArmPkg/Include/Library/ArmLib.h
@@ -132,6 +132,12 @@ ArmIsArchTimerImplemented (
   VOID
   );
 
+UINTN
+EFIAPI
+ArmIsCcidxImplemented (
+  VOID
+  );
+
[SAMI] This could be a separate patch along with ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
e.g. 'Add helper to read CCIDX status'.
[/SAMI]

 UINTN
 EFIAPI
 ArmReadIdPfr0 (
diff --git a/ArmPkg/Include/Library/OemMiscLib.h b/ArmPkg/Include/Library/OemMiscLib.h
new file mode 100644
index 000000000000..78dc70426e24
--- /dev/null
+++ b/ArmPkg/Include/Library/OemMiscLib.h
@@ -0,0 +1,86 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, Linaro Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+
+#ifndef OEM_MISC_LIB_H
+#define OEM_MISC_LIB_H
+
+#include <Uefi.h>
+#include <IndustryStandard/SmBios.h>
+
+typedef enum
+{
+  CPU_CACHE_L1 = 0,
+  CPU_CACHE_L2,
+  CPU_CACHE_L3,
+  CPU_CACHE_L4,
+  CPU_CACHE_L5,
+  CPU_CACHE_L6,
+  CPU_CACHE_L7
+} CPU_CACHE_LEVEL;
+
+typedef struct
+{
+  UINT8 Voltage;
+  UINT16 CurrentSpeed;
+  UINT16 MaxSpeed;
+  UINT16 ExternalClock;
+  UINT16 CoreCount;
+  UINT16 CoresEnabled;
+  UINT16 ThreadCount;
+} MISC_PROCESSOR_DATA;
+
+typedef enum {
+    ProductNameType01,
+    SerialNumType01,
+    UuidType01,
+    SystemManufacturerType01,
+    AssertTagType02,
+    SrNumType02,
+    BoardManufacturerType02,
+    AssetTagType03,
+    SrNumType03,
+    VersionType03,
+    ChassisTypeType03 ,
+    ManufacturerType03,
+} GET_INFO_BMC_OFFSET;
+
+UINTN OemGetCpuFreq (UINT8 Socket);
+
+BOOLEAN
+OemGetProcessorInformation (
+  IN UINTN ProcessorNumber,
+  IN OUT PROCESSOR_STATUS_DATA *ProcessorStatus,
+  IN OUT PROCESSOR_CHARACTERISTIC_FLAGS *ProcessorCharacteristics,
+  IN OUT MISC_PROCESSOR_DATA *MiscProcessorData
+  );
+
+BOOLEAN OemGetCacheInformation (
+  IN UINT8 CacheLevel,
+  IN OUT SMBIOS_TABLE_TYPE7 *SmbiosCacheTable
+  );
+
+UINT8 OemGetProcessorMaxSockets (VOID);
+
+UINTN PlatformGetCpuFreq (IN UINT8 Socket);
+
+UINTN PlatformGetCoreCount (VOID);
+
+EFI_STATUS OemGetChassisType(OUT UINT8 *ChassisType);
+
+BOOLEAN OemIsSocketPresent (UINTN Socket);
+
+VOID
+UpdateSmbiosInfo (
+  IN EFI_HII_HANDLE mHiiHandle,
+  IN EFI_STRING_ID TokenToUpdate,
+  IN UINT8 Offset
+  );
+
+#endif // OEM_MISC_LIB_H
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
index b2c8a8ea0b84..d6bcfc3b82ae 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
@@ -35,5 +35,11 @@ ArmCleanInvalidateDataCacheEntryBySetWay (
   IN  UINTN   SetWayFormat
   );
 
+UINTN
+EFIAPI
+ArmReadIdMmfr2 (
+  VOID
+  );
+

[SAMI] This could be a separate patch e.g. 'Add helper to read MMFR2'
[/SAMI]

 #endif // __AARCH64_LIB_H__
 
diff --git a/ArmPkg/Library/ArmLib/ArmLibPrivate.h b/ArmPkg/Library/ArmLib/ArmLibPrivate.h
index 2e90739eb858..d57c80edb572 100644
--- a/ArmPkg/Library/ArmLib/ArmLibPrivate.h
+++ b/ArmPkg/Library/ArmLib/ArmLibPrivate.h
@@ -9,46 +9,76 @@
 #ifndef __ARM_LIB_PRIVATE_H__
 #define __ARM_LIB_PRIVATE_H__
 
-#define CACHE_SIZE_4_KB             (3UL)
-#define CACHE_SIZE_8_KB             (4UL)
-#define CACHE_SIZE_16_KB            (5UL)
-#define CACHE_SIZE_32_KB            (6UL)
-#define CACHE_SIZE_64_KB            (7UL)
-#define CACHE_SIZE_128_KB           (8UL)
+typedef union {
+  struct {
+    UINT32    InD           :1;
+    UINT32    Level         :3;
+    UINT32    TnD           :1;
+    UINT32    Reserved      :27;
+  } Bits;
+  UINT32 Data;
+} CSSELR_DATA;

[SAMI] Please add doxygen style documentation for the structure and its fields.
[/SAMI]
 

-#define CACHE_ASSOCIATIVITY_DIRECT  (0UL)
-#define CACHE_ASSOCIATIVITY_4_WAY   (2UL)
-#define CACHE_ASSOCIATIVITY_8_WAY   (3UL)
+typedef enum
+{
+  CSSELR_CACHE_TYPE_DATA_OR_UNIFIED = 0,
+  CSSELR_CACHE_TYPE_INSTRUCTION = 1
+} CSSELR_CACHE_TYPE;

[SAMI] I am all in favour of using enums. Is it possible to update the enums to confirm to the edk2 coding standard, please?
The elements of the enumerated type must follow the data and function naming convention. 
Please see https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/5_source_files/56_declarations_and_types#5-6-2-2-enumerated-types
[/SAMI]
 
-#define CACHE_PRESENT               (0UL)
-#define CACHE_NOT_PRESENT           (1UL)
+typedef union {
+  struct {
+    UINT64    LineSize           :3;
+    UINT64    Associativity      :10;
+    UINT64    NumSets            :15;
+    UINT64    Unknown            :4;
+    UINT64    Reserved           :32;
+  } BitsNonCcidx;
+  struct {
+    UINT64    LineSize           :3;
+    UINT64    Associativity      :21;
+    UINT64    Reserved1          :8;
+    UINT64    NumSets            :24;
+    UINT64    Reserved2          :8;
+  } BitsCcidx;
+  UINT64 Data;
+} CCSIDR_DATA;
 
-#define CACHE_LINE_LENGTH_32_BYTES  (2UL)
+typedef union {
+  struct {
+    UINT32 NumSets               :24;
+    UINT32 Reserved              :8;
+  } Bits;
+  UINT32 Data;
+} CSSIDR2_DATA;
 
-#define SIZE_FIELD_TO_CACHE_SIZE(x)           (((x) >> 6) & 0x0F)
-#define SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(x)  (((x) >> 3) & 0x07)
-#define SIZE_FIELD_TO_CACHE_PRESENCE(x)       (((x) >> 2) & 0x01)
-#define SIZE_FIELD_TO_CACHE_LINE_LENGTH(x)    (((x) >> 0) & 0x03)
+// The lower 32 bits are the same for both AARCH32 and AARCH64
+// so we can use the same structure for both.
+typedef union {
+  struct {
+    UINT32    Ctype1   : 3;
+    UINT32    Ctype2   : 3;
+    UINT32    Ctype3   : 3;
+    UINT32    Ctype4   : 3;
+    UINT32    Ctype5   : 3;
+    UINT32    Ctype6   : 3;
+    UINT32    Ctype7   : 3;
+    UINT32    LoUIS    : 3;
+    UINT32    LoC      : 3;
+    UINT32    LoUU     : 3;
+    UINT32    Icb      : 3;
+  } Bits;
+  UINT32 Data;
+} CLIDR_DATA;
 
-#define DATA_CACHE_SIZE_FIELD(x)              (((x) >> 12) & 0x0FFF)
-#define INSTRUCTION_CACHE_SIZE_FIELD(x)       (((x) >>  0) & 0x0FFF)
+typedef enum {
+  CLIDR_CACHE_TYPE_NONE = 0,
+  CLIDR_CACHE_TYPE_INSTRUCTION_ONLY = 1,
+  CLIDR_CACHE_TYPE_DATA_ONLY = 2,
+  CLIDR_CACHE_TYPE_SEPARATE = 3,
+  CLIDR_CACHE_TYPE_UNIFIED = 4
+} CLIDR_CACHE_TYPE;
 
-#define DATA_CACHE_SIZE(x)                    (SIZE_FIELD_TO_CACHE_SIZE(DATA_CACHE_SIZE_FIELD(x)))
-#define DATA_CACHE_ASSOCIATIVITY(x)           (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(DATA_CACHE_SIZE_FIELD(x)))
-#define DATA_CACHE_PRESENT(x)                 (SIZE_FIELD_TO_CACHE_PRESENCE(DATA_CACHE_SIZE_FIELD(x)))
-#define DATA_CACHE_LINE_LENGTH(x)             (SIZE_FIELD_TO_CACHE_LINE_LENGTH(DATA_CACHE_SIZE_FIELD(x)))
-
-#define INSTRUCTION_CACHE_SIZE(x)             (SIZE_FIELD_TO_CACHE_SIZE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
-#define INSTRUCTION_CACHE_ASSOCIATIVITY(x)    (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(INSTRUCTION_CACHE_SIZE_FIELD(x)))
-#define INSTRUCTION_CACHE_PRESENT(x)          (SIZE_FIELD_TO_CACHE_PRESENCE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
-#define INSTRUCTION_CACHE_LINE_LENGTH(x)      (SIZE_FIELD_TO_CACHE_LINE_LENGTH(INSTRUCTION_CACHE_SIZE_FIELD(x)))
-
-#define CACHE_TYPE(x)                         (((x) >> 25) & 0x0F)
-#define CACHE_TYPE_WRITE_BACK                 (0x0EUL)
-
-#define CACHE_ARCHITECTURE(x)                 (((x) >> 24) & 0x01)
-#define CACHE_ARCHITECTURE_UNIFIED            (0UL)
-#define CACHE_ARCHITECTURE_SEPARATE           (1UL)
+#define CLIDR_GET_CACHE_TYPE(x, level) ((x >> (3 * level)) & 0b111)
 
 VOID
 CPSRMaskInsert (
@@ -61,7 +91,7 @@ CPSRRead (
   VOID
   );
 
-UINT32
+UINTN
 ReadCCSIDR (
   IN UINT32 CSSELR
   );
diff --git a/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h
new file mode 100644
index 000000000000..a8a4ab2b1beb
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h
@@ -0,0 +1,34 @@
+/** @file
+*
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, Linaro Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#ifndef PROCESSOR_SUBCLASS_DRIVER_H
+#define PROCESSOR_SUBCLASS_DRIVER_H
+
+#include <Uefi.h>
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/ArmStdSmc.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmSmcLib.h>
+#include <Library/ArmLib/ArmLibPrivate.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HiiLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/OemMiscLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+extern UINT8 ProcessorSubClassStrings[];
+
+#endif // PROCESSOR_SUBCLASS_DRIVER_H
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h
new file mode 100644
index 000000000000..80c77517fabc
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h
@@ -0,0 +1,217 @@
+/**@file
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  SmbiosMisc.h
+
+Abstract:
+
+  Header file for the SmbiosMisc Driver.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#ifndef SMBIOS_MISC_DRIVER_H
+#define SMBIOS_MISC_DRIVER_H
+
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/HiiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/DebugMask.h>
+#include <Library/OemMiscLib.h>
+
+#include <Library/PrintLib.h>
+
+//
+// Data table entry update function.
+//
+typedef EFI_STATUS (EFIAPI EFI_MISC_SMBIOS_DATA_FUNCTION) (
+  IN  VOID                 *RecordData,
+  IN  EFI_SMBIOS_PROTOCOL  *Smbios
+  );
+
+
+//
+// Data table entry definition.
+//
+typedef struct {
+  //
+  // intermediate input data for SMBIOS record
+  //
+  VOID                              *RecordData;
+  EFI_MISC_SMBIOS_DATA_FUNCTION     *Function;
+} EFI_MISC_SMBIOS_DATA_TABLE;
+
+
+//
+// Data Table extern definitions.
+//
+#define MISC_SMBIOS_TABLE_EXTERNS(NAME1, NAME2, NAME3) \
+extern NAME1 NAME2 ## Data; \
+extern EFI_MISC_SMBIOS_DATA_FUNCTION NAME3 ## Function;
+
+
+//
+// Data Table entries
+//
+
+#define MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(NAME1, NAME2) \
+{ \
+  & NAME1 ## Data, \
+    NAME2 ## Function \
+}
+
+
+//
+// Global definition macros.
+//
+#define MISC_SMBIOS_TABLE_DATA(NAME1, NAME2) \
+  NAME1 NAME2 ## Data
+
+#define MISC_SMBIOS_TABLE_FUNCTION(NAME2) \
+  EFI_STATUS EFIAPI NAME2 ## Function( \
+  IN  VOID                  *RecordData, \
+  IN  EFI_SMBIOS_PROTOCOL   *Smbios \
+  )
+
+//
+// Data Table Array Entries
+//
+extern EFI_HII_HANDLE               mHiiHandle;
+
+typedef struct _EFI_TYPE11_OEM_STRING{
+  UINT8                               Offset;
+  EFI_STRING_ID                       RefOemDefineString;
+} EFI_TYPE11_OEM_STRING;
+
+typedef struct _EFI_TYPE12_SYSTEM_CONFIGURATION_OPTIONS_STRING{
+  UINT8                               Offset;
+  EFI_STRING_ID                       RefType12SystemConfigurationOptionsString;
+} EFI_TYPE12_SYSTEM_CONFIGURATION_OPTIONS_STRING;
+
+typedef struct _EFI_TYPE13_BIOS_LANGUAGE_INFORMATION_STRING{
+  UINT8                               *LanguageSignature;
+  EFI_STRING_ID                       InstallableLanguageLongString;
+  EFI_STRING_ID                       InstallableLanguageAbbreviateString;
+} EFI_TYPE13_BIOS_LANGUAGE_INFORMATION_STRING;
+
+typedef struct _EFI_TYPE40_ADDITIONAL_INFORMATION_ENTRY{
+  UINT8           RefType;
+  UINT8           RefOffset;
+  EFI_STRING_ID   RefString;
+  UINT8           Value;
+} EFI_TYPE40_ADDITIONAL_INFORMATION_ENTRY;
+
+typedef enum {
+  STRING,
+  DATA,
+} OEM_DEFINE_TYPE;
+
+typedef struct {
+  OEM_DEFINE_TYPE                Type;
+  UINTN                          Token;
+  UINTN                          DataSize;
+} OEM_DEFINE_INFO_STRING;
+
+typedef struct {
+  OEM_DEFINE_TYPE                Type;
+  UINTN                          DataAddress;
+  UINTN                          DataSize;
+} OEM_DEFINE_INFO_DATA;
+
+typedef union {
+  OEM_DEFINE_INFO_STRING         DefineString;
+  OEM_DEFINE_INFO_DATA           DefineData;
+} EFI_OEM_DEFINE_ARRAY;
+
+typedef struct _DMI_STRING_STRUCTURE {
+  UINT8                                 Type;
+  UINT8                                 Offset;
+  UINT8                                 Valid;
+  UINT16                                Length;
+  UINT8                                 String[1]; // Variable length field
+} DMI_STRING_STRUCTURE;
+
+typedef struct {
+  UINT8                                 Type;           // The SMBIOS structure type
+  UINT8                                 FixedOffset;    // The offset of the string reference
+                                                        // within the structure's fixed data.
+} DMI_UPDATABLE_STRING;
+
+EFI_STATUS
+FindString (
+  IN UINT8                              Type,
+  IN UINT8                              Offset,
+  IN EFI_STRING_ID                      TokenToUpdate
+);
+
+EFI_STATUS
+FindUuid (
+  EFI_GUID                    *Uuid
+);
+
+EFI_STATUS
+StringToBiosVeriosn (
+  IN  EFI_STRING_ID                     BiosVersionToken,
+  OUT UINT8                             *MajorVersion,
+  OUT UINT8                             *MinorVersion
+);
+
+
+/**
+ Logs SMBIOS record.
+
+ @param [in]   Buffer         Pointer to the data buffer.
+ @param [in]   SmbiosHandle   Pointer for retrieve handle.
+
+**/
+EFI_STATUS
+LogSmbiosData (
+  IN       UINT8                      *Buffer,
+  IN  OUT  EFI_SMBIOS_HANDLE          *SmbiosHandle
+  );
+
+/**
+ Get Link Type Handle.
+
+ @param [in]   SmbiosType     Get this Type from SMBIOS table
+ @param [out]  HandleArray    Pointer to Hadndler array with has been free by caller
+ @param [out]  HandleCount    Pointer to Hadndler Counter
+
+**/
+VOID
+GetLinkTypeHandle(
+  IN  UINT8                 SmbiosType,
+  OUT UINT16                **HandleArray,
+  OUT UINTN                 *HandleCount
+  );
+
+//
+// Data Table Array
+//
+extern EFI_MISC_SMBIOS_DATA_TABLE   mSmbiosMiscDataTable[];
+
+//
+// Data Table Array Entries
+//
+extern UINTN                        mSmbiosMiscDataTableEntries;
+
+extern UINT8                        SmbiosMiscDxeStrings[];
+
+
+
+#endif // SMBIOS_MISC_DRIVER_H
diff --git a/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.c b/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.c
new file mode 100644
index 000000000000..5b5dc47e7ea9
--- /dev/null
+++ b/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.c
@@ -0,0 +1,90 @@
+/** @file
+*
+*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2016, Linaro Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <Uefi.h>
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrintLib.h>
+#include <Library/SerialPortLib.h>
+
+#include <Guid/VersionInfoHobGuid.h>
+
+struct MonthDescription {
+  CONST CHAR8* MonthStr;
+  UINT32    MonthInt;
+} gMonthDescription[] = {
+  { "Jan", 1 },
+  { "Feb", 2 },
+  { "Mar", 3 },
+  { "Apr", 4 },
+  { "May", 5 },
+  { "Jun", 6 },
+  { "Jul", 7 },
+  { "Aug", 8 },
+  { "Sep", 9 },
+  { "Oct", 10 },
+  { "Nov", 11 },
+  { "Dec", 12 },
+  { "???", 1 },  // Use 1 as default month
+};
+
+VOID GetReleaseTime (EFI_TIME *Time)
+{
+  CONST CHAR8      *ReleaseDate = __DATE__;
+  CONST CHAR8      *ReleaseTime = __TIME__;
+  UINTN            i;
+
+  for (i = 0;i < 12;i++) {
+    if (AsciiStrnCmp (ReleaseDate, gMonthDescription[i].MonthStr, 3) == 0) {
+      break;
+    }
+  }
+
+  Time->Month = gMonthDescription[i].MonthInt;
+  Time->Day = AsciiStrDecimalToUintn(ReleaseDate+4);
+  Time->Year = AsciiStrDecimalToUintn(ReleaseDate+7);
+  Time->Hour = AsciiStrDecimalToUintn(ReleaseTime);
+  Time->Minute = AsciiStrDecimalToUintn(ReleaseTime+3);
+  Time->Second = AsciiStrDecimalToUintn(ReleaseTime+6);
+
+  return;
+}
+
+EFI_STATUS
+EFIAPI
+VersionInfoEntry (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  VERSION_INFO *VersionInfo;
+  EFI_TIME Time = {0};
+  CONST CHAR16 *ReleaseString =
+    (CHAR16 *) FixedPcdGetPtr (PcdFirmwareVersionString);
+
+  GetReleaseTime (&Time);
+
+  VersionInfo = BuildGuidHob (&gVersionInfoHobGuid,
+                      sizeof (VERSION_INFO) -
+                      sizeof (VersionInfo->String) +
+                      StrSize (ReleaseString));
+  if (VersionInfo == NULL) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%d] Build HOB failed!\n", __FILE__, __LINE__));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  CopyMem (&VersionInfo->BuildTime, &Time, sizeof (EFI_TIME));
+  CopyMem (VersionInfo->String, ReleaseString, StrSize (ReleaseString));
+
+  return EFI_SUCCESS;
+}
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
index 3fbd591192e2..134fe56cb387 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
@@ -71,3 +71,18 @@ ArmCleanDataCache (
   ArmDataSynchronizationBarrier ();
   AArch64DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
 }
+
+UINTN
+EFIAPI
+ArmIsCcidxImplemented (
+  VOID
+  )

[SAMI] Would return type BOOL be more suitable here? 
This could be combined with changes in ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c to create a separate patch.
[/SAMI]

+{
+  UINTN Mmfr2;
+
+  Mmfr2 = ArmReadIdMmfr2 ();
+  if (((Mmfr2 >> 20) & 0xF) == 1)
+    return 1;
+
+  return 0;

[SAMI] This could be changed to:
  return (((Mmfr4 >> 24) & 0xF) == 1) ? TRUE: FALSE;
[/SAMI]

+}
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
index 2c4a23e1a1b2..4466e39dcc28 100644
--- a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
+++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
@@ -71,3 +71,20 @@ ArmCleanDataCache (
   ArmDataSynchronizationBarrier ();
   ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
 }
+
+UINTN
+EFIAPI
+ArmIsCcidxImplemented (
+  VOID
+  )
+{
+  UINTN Mmfr4;
+
+  Mmfr4 = ArmReadIdMmfr4 ();
+  if (((Mmfr4 >> 24) & 0xF) == 1) {
+    return 1;
+  }
+
+  return 0;
+}

[SAMI] Same comments as for ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
[/SAMI]

+
diff --git a/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c
new file mode 100644
index 000000000000..2b29945ce966
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c
@@ -0,0 +1,723 @@
+/** @file
+*
+*  Copyright (c) 2020, NUVIA Inc. All rights reserved.
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2015, Linaro Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include "ProcessorSubClass.h"
+
+EFI_HII_HANDLE                  mHiiHandle;
+
+EFI_SMBIOS_PROTOCOL             *mSmbios;
+
+SMBIOS_TABLE_TYPE4   mSmbiosProcessorTable[] = {
+  //CPU0
+  {
+    {                                               //Header
+      EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION,          //Type
+      sizeof (SMBIOS_TABLE_TYPE4),                    //Length
+      0                                               //Handle
+    },
+    1,                                              //Socket
+    CentralProcessor,                               //ProcessorType
+    ProcessorFamilyIndicatorFamily2,                //ProcessorFamily
+    2,                                              //ProcessorManufacture
+    {                                               //ProcessorId
+      {                                               //Signature
+        0
+      },
+      {                                               //FeatureFlags
+        0
+      }
+    },
+    3,                                              //ProcessorVersion
+    {                                               //Voltage
+      0
+    },
+    0,                                              //ExternalClock
+    0,                                              //MaxSpeed
+    0,                                              //CurrentSpeed
+    0,                                              //Status
+    ProcessorUpgradeUnknown,                        //ProcessorUpgrade
+    0xFFFF,                                         //L1CacheHandle
+    0xFFFF,                                         //L2CacheHandle
+    0xFFFF,                                         //L3CacheHandle
+    4,                                              //SerialNumber
+    5,                                              //AssetTag
+    6,                                              //PartNumber
+    0,                                              //CoreCount
+    0,                                              //EnabledCoreCount
+    0,                                              //ThreadCount
+    0,                                              //ProcessorCharacteristics
+    ProcessorFamilyARM,                             //ProcessorFamily2
+    0,                                              //CoreCount2
+    0,                                              //EnabledCoreCount2
+    0                                               //ThreadCount2
+  },
+
+  //CPU1
+  {
+    {                                               //Header
+      EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION,          //Type
+      sizeof (SMBIOS_TABLE_TYPE4),                    //Length
+      0                                               //Handle
+    },
+    1,                                              //Socket
+    CentralProcessor,                               //ProcessorType
+    ProcessorFamilyIndicatorFamily2,                //ProcessorFamily
+    2,                                              //ProcessorManufacture
+    {                                               //ProcessorId
+      {                                               //Signature
+        0
+      },
+      {                                               //FeatureFlags
+        0
+      }
+    },
+    3,                                              //ProcessorVersion
+    {                                               //Voltage
+      0
+    },
+    0,                                              //ExternalClock
+    0,                                              //MaxSpeed
+    0,                                              //CurrentSpeed
+    0,                                              //Status
+    ProcessorUpgradeUnknown,                        //ProcessorUpgrade
+    0xFFFF,                                         //L1CacheHandle
+    0xFFFF,                                         //L2CacheHandle
+    0xFFFF,                                         //L3CacheHandle
+    4,                                              //SerialNumber
+    5,                                              //AssetTag
+    6,                                              //PartNumber
+    0,                                              //CoreCount
+    0,                                              //EnabledCoreCount
+    0,                                              //ThreadCount
+    0,                                              //ProcessorCharacteristics
+    ProcessorFamilyARMv8,                           //ProcessorFamily2
+    0,                                              //CoreCount2
+    0,                                              //EnabledCoreCount2
+    0                                               //ThreadCount2
+  }
+};
+
+
+UINT16
+GetCpuFrequency (
+  IN  UINT8 ProcessorNumber
+)
+{
+  return (UINT16)(PlatformGetCpuFreq (ProcessorNumber)/1000/1000);
+}
+
+UINTN
+GetCacheSocketStr (
+  IN  UINT8     CacheLevel,
+  IN  UINT8     CacheSubLevel,
+  OUT CHAR16    *CacheSocketStr
+  )
+{
+  UINTN CacheSocketStrLen;
+
+  if (CacheLevel == CPU_CACHE_L1 && CacheSubLevel == 0) {
+    CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Instruction Cache", CacheLevel + 1);
+  } else if (CacheLevel == CPU_CACHE_L1 && CacheSubLevel == 1) {
+    CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Data Cache", CacheLevel + 1);
+  } else {
+    CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Cache", CacheLevel + 1);
+  }
+
+  return CacheSocketStrLen;
+}
+
+/**
+  Add Type 7 SMBIOS Record for Cache Information.
+
+  @param[in]    ProcessorNumber     Processor number of specified processor.
+  @param[out]   L1CacheHandle       Pointer to the handle of the L1 Cache SMBIOS record.
+  @param[out]   L2CacheHandle       Pointer to the handle of the L2 Cache SMBIOS record.
+  @param[out]   L3CacheHandle       Pointer to the handle of the L3 Cache SMBIOS record.
+
+**/
+EFI_STATUS
+AddSmbiosCacheTypeTable (
+  IN UINTN                  ProcessorNumber,
+  OUT EFI_SMBIOS_HANDLE     *L1CacheHandle,
+  OUT EFI_SMBIOS_HANDLE     *L2CacheHandle,
+  OUT EFI_SMBIOS_HANDLE     *L3CacheHandle
+  )
+{
+  EFI_STATUS                  Status;
+  SMBIOS_TABLE_TYPE7          *Type7Record;
+  EFI_SMBIOS_HANDLE           SmbiosHandle;
+  UINTN                       TableSize;
+  UINT8                       CacheLevel;
+  UINT8                       CacheSubLevel;
+  CHAR8                       *OptionalStrStart;
+  EFI_STRING                  CacheSocketStr;
+  UINTN                       CacheSocketStrLen;
+  UINTN                       StringBufferSize;
+
+  CLIDR_DATA                  Clidr;
+  CSSELR_DATA                 Csselr;
+  CCSIDR_DATA                 Ccsidr;
+
+  UINT16                      CacheSize16;
+  UINT32                      CacheSize32;
+  UINT64                      CacheSize64;
+  BOOLEAN                     CcidxSupported;
+  UINT32                      Associativity;
+  UINT8                       MaxCacheLevel;
+
+  CONST UINT8                 MAX_ARM_CACHE_LEVEL = 7;
+
+  Status = EFI_SUCCESS;
+
+  MaxCacheLevel = 0;
+
+  // Read the CLIDR register to find out what caches are present.
+  Clidr.Data = ReadCLIDR ();
+
+  // Get the cache type for the L1 cache. If it's 0, there are no caches.
+  if (CLIDR_GET_CACHE_TYPE (Clidr.Data, 0) == CLIDR_CACHE_TYPE_NONE) {
+    return EFI_SUCCESS;
+  }
+
+  for (CacheLevel = 1; CacheLevel < MAX_ARM_CACHE_LEVEL; CacheLevel++) {
+    if (CLIDR_GET_CACHE_TYPE (Clidr.Data, CacheLevel) == CLIDR_CACHE_TYPE_NONE) {
+      MaxCacheLevel = CacheLevel;
+      break;
+    }
+  }
+
+  CcidxSupported = ArmIsCcidxImplemented ();
+
+  for (CacheLevel = 0; CacheLevel < MaxCacheLevel; CacheLevel++)
+  {
+    Type7Record = NULL;
+
+    CLIDR_CACHE_TYPE CacheType = CLIDR_GET_CACHE_TYPE (Clidr.Data, CacheLevel);
+
+    // At each level of cache, we can have a single type (unified, instruction or data),
+    // or two types - separate data and instruction caches. If we have separate
+    // instruction and data caches, then on the first iteration (CacheSubLevel = 0)
+    // process the instruction cache.
+    for (CacheSubLevel = 0; CacheSubLevel <= 1; CacheSubLevel++) {
+      // If there's no separate data/instruction cache, skip the second iteration
+      if (CacheSubLevel > 0 && CacheType != CLIDR_CACHE_TYPE_SEPARATE) {
+        continue;
+      }
+
+      // Allocate and fetch the cache description+++
+      StringBufferSize = sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH;
+      CacheSocketStr = AllocateZeroPool (StringBufferSize);
+      if (CacheSocketStr == NULL) {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto Exit;
+      }
+
+      CacheSocketStrLen = GetCacheSocketStr (CacheLevel, CacheSubLevel, CacheSocketStr);
+
+      TableSize = sizeof (SMBIOS_TABLE_TYPE7) + CacheSocketStrLen + 1 + 1;
+      Type7Record = AllocateZeroPool (TableSize);
+      if (Type7Record == NULL) {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto Exit;
+      }
+
+      Type7Record->Hdr.Type = EFI_SMBIOS_TYPE_CACHE_INFORMATION;
+      Type7Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE7);
+      Type7Record->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
+
+      Type7Record->SocketDesignation = 1;
+
+      Type7Record->SupportedSRAMType.Unknown = 1;
+      Type7Record->CurrentSRAMType.Unknown = 1;
+      Type7Record->CacheSpeed = 0;
+      Type7Record->ErrorCorrectionType = CacheErrorUnknown;
+
+      Csselr.Data = 0;
+      Csselr.Bits.Level = CacheLevel;
+
+      if (CacheSubLevel == 0) {
+        if (CacheType == CLIDR_CACHE_TYPE_INSTRUCTION_ONLY ||
+            CacheType == CLIDR_CACHE_TYPE_SEPARATE) {
+          Csselr.Bits.InD = CSSELR_CACHE_TYPE_INSTRUCTION; // Instruction cache
+          Type7Record->SystemCacheType = CacheTypeInstruction;
+        } else {
+          Csselr.Bits.InD = CSSELR_CACHE_TYPE_DATA_OR_UNIFIED;
+          if (CacheType == CLIDR_CACHE_TYPE_DATA_ONLY) {
+            Type7Record->SystemCacheType = CacheTypeData;
+          } else {
+            Type7Record->SystemCacheType = CacheTypeUnified;
+          }
+        }
+      } else {
+        Type7Record->SystemCacheType = CacheTypeData;
+        Csselr.Bits.InD = CSSELR_CACHE_TYPE_DATA_OR_UNIFIED;
+      }
+
+      // Read the CCSIDR register to get the cache architecture
+      Ccsidr.Data = ReadCCSIDR (Csselr.Data);
+
+      if (CcidxSupported) {
+        CacheSize64 = (UINT64)(1 << (Ccsidr.BitsCcidx.LineSize + 4)) * (Ccsidr.BitsCcidx.Associativity + 1) * (Ccsidr.BitsCcidx.NumSets + 1);
+        Associativity = Ccsidr.BitsCcidx.Associativity;
+      } else {
+        CacheSize64 = (1 << (Ccsidr.BitsNonCcidx.LineSize + 4)) * (Ccsidr.BitsNonCcidx.Associativity + 1) * (Ccsidr.BitsNonCcidx.NumSets + 1);
+        Associativity = Ccsidr.BitsNonCcidx.Associativity;
+      }
+
+      CacheSize64 /= 1024; // Minimum granularity is 1K
+
+      // Encode the cache size into the format SMBIOS wants
+      if (CacheSize64 < MAX_INT16) {
+        CacheSize16 = CacheSize64;
+        CacheSize32 = CacheSize16;
+      } else if ((CacheSize64 / 64) < MAX_INT16) {
+        CacheSize16 = (1 << 15) | (CacheSize64 / 64);
+        CacheSize32 = CacheSize16;
+      } else {
+        if ((CacheSize64 / 1024) <= 2047) {
+          CacheSize32 = CacheSize64;
+        } else {
+          CacheSize32 = (1 << 31) | (CacheSize64 / 64);
+        }
+
+        CacheSize16 = -1;
+      }
+
+      Type7Record->Associativity = Associativity + 1;
+      Type7Record->MaximumCacheSize = CacheSize16;
+      Type7Record->InstalledSize = CacheSize16;
+      Type7Record->MaximumCacheSize2 = CacheSize32;
+      Type7Record->InstalledSize2 = CacheSize32;
+
+      switch (Associativity + 1) {
+        case 2:
+          Type7Record->Associativity = CacheAssociativity2Way;
+          break;
+        case 4:
+          Type7Record->Associativity = CacheAssociativity4Way;
+          break;
+        case 8:
+          Type7Record->Associativity = CacheAssociativity8Way;
+          break;
+        case 16:
+          Type7Record->Associativity = CacheAssociativity16Way;
+          break;
+        case 12:
+          Type7Record->Associativity = CacheAssociativity12Way;
+          break;
+        case 24:
+          Type7Record->Associativity = CacheAssociativity24Way;
+          break;
+        case 32:
+          Type7Record->Associativity = CacheAssociativity32Way;
+          break;
+        case 48:
+          Type7Record->Associativity = CacheAssociativity48Way;
+          break;
+        case 64:
+          Type7Record->Associativity = CacheAssociativity64Way;
+          break;
+        case 20:
+          Type7Record->Associativity = CacheAssociativity20Way;
+          break;
+        default:
+          Type7Record->Associativity = CacheAssociativityOther;
+          break;
+      }
+
+      Type7Record->CacheConfiguration = (3 << 8) | (1 << 7) | (3 << 5) | (0 << 3) | CacheLevel;
+
+      // Allow the platform to fill in other information such as speed, SRAM type etc.
+      if (!OemGetCacheInformation (CacheLevel, Type7Record)) {
+        continue;
+      }
+
+      OptionalStrStart = (CHAR8 *) (Type7Record + 1);
+      UnicodeStrToAsciiStrS (CacheSocketStr, OptionalStrStart, CacheSocketStrLen + 1);
+
+      SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+      // Finally, install the table
+      Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)Type7Record);
+      if (EFI_ERROR (Status)) {
+        goto Exit;
+      }
+
+      // Config L1/L2/L3 Cache Handle
+      switch (CacheLevel) {
+        case CPU_CACHE_L1:
+          *L1CacheHandle = SmbiosHandle;
+          break;
+        case CPU_CACHE_L2:
+          *L2CacheHandle = SmbiosHandle;
+          break;
+        case CPU_CACHE_L3:
+          *L3CacheHandle = SmbiosHandle;
+          break;
+        default:
+            break;
+      }
+Exit:
+      if (Type7Record != NULL)
+      {
+        FreePool (Type7Record);
+      }
+      if (CacheSocketStr != NULL)
+      {
+        FreePool (CacheSocketStr);
+        CacheSocketStr = NULL;
+      }
+    }
+  }
+
+  return Status;
+}
+
+/**
+  Add Type 4 SMBIOS Record for Processor Information.
+
+  @param[in]    ProcessorNumber     Processor number of specified processor.
+
+**/
+EFI_STATUS
+AddSmbiosProcessorTypeTable (
+  IN UINTN                  ProcessorNumber
+  )
+{
+  EFI_STATUS                  Status;
+  SMBIOS_TABLE_TYPE4          *Type4Record;
+  EFI_SMBIOS_HANDLE           SmbiosHandle;
+  EFI_SMBIOS_HANDLE           L1CacheHandle;
+  EFI_SMBIOS_HANDLE           L2CacheHandle;
+  EFI_SMBIOS_HANDLE           L3CacheHandle;
+
+  CHAR8                       *OptionalStrStart;
+  UINT8                       *LegacyVoltage;
+  EFI_STRING_ID               ProcessorManu;
+  EFI_STRING_ID               ProcessorVersion;
+  EFI_STRING_ID               SerialNumber;
+  EFI_STRING_ID               AssetTag;
+  EFI_STRING_ID               PartNumber;
+  EFI_STRING                  ProcessorSocketStr;
+  EFI_STRING                  ProcessorManuStr;
+  EFI_STRING                  ProcessorVersionStr;
+  EFI_STRING                  SerialNumberStr;
+  EFI_STRING                  AssetTagStr;
+  EFI_STRING                  PartNumberStr;
+  UINTN                       ProcessorSocketStrLen;
+  UINTN                       ProcessorManuStrLen;
+  UINTN                       ProcessorVersionStrLen;
+  UINTN                       SerialNumberStrLen;
+  UINTN                       AssetTagStrLen;
+  UINTN                       PartNumberStrLen;
+  UINTN                       StringBufferSize;
+  UINTN                       TotalSize;
+
+  PROCESSOR_STATUS_DATA       ProcessorStatus = {{0}};
+  MISC_PROCESSOR_DATA         MiscProcessorData;
+
+  ARM_SMC_ARGS                Args;
+  BOOLEAN                     Arm64SocIdSupported = FALSE;
+  int                         Jep106Code;
+  int                         SocRevision;
+  int                         SmcCallStatus;
+  UINT64                      *ProcessorId;
+
+  Type4Record         = NULL;
+  ProcessorManuStr    = NULL;
+  ProcessorVersionStr = NULL;
+  SerialNumberStr     = NULL;
+  AssetTagStr         = NULL;
+  PartNumberStr       = NULL;
+
+
+  MiscProcessorData.Voltage             = 0;
+  MiscProcessorData.CurrentSpeed        = 0;
+  MiscProcessorData.CoreCount           = 0;
+  MiscProcessorData.CoresEnabled        = 0;
+  MiscProcessorData.ThreadCount         = 0;
+  L1CacheHandle       = 0xFFFF;
+  L2CacheHandle       = 0xFFFF;
+  L3CacheHandle       = 0xFFFF;
+
+  ProcessorManu       = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+  ProcessorVersion    = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+  SerialNumber        = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+  AssetTag            = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+  PartNumber          = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
+
+  BOOLEAN Populated = OemGetProcessorInformation (ProcessorNumber,
+                                                  &ProcessorStatus,
+                                                  (PROCESSOR_CHARACTERISTIC_FLAGS*)&mSmbiosProcessorTable[ProcessorNumber].ProcessorCharacteristics,
+                                                  &MiscProcessorData);
+  if (Populated)
+  {
+    Status = AddSmbiosCacheTypeTable (ProcessorNumber, &L1CacheHandle,
+                                      &L2CacheHandle, &L3CacheHandle);
+
+    ProcessorManu       = STRING_TOKEN (STR_PROCESSOR_MANUFACTURE);
+    ProcessorVersion    = STRING_TOKEN (STR_PROCESSOR_VERSION);
+    SerialNumber        = STRING_TOKEN (STR_PROCESSOR_SERIAL_NUMBER);
+    AssetTag            = STRING_TOKEN (STR_PROCESSOR_ASSET_TAG);
+    PartNumber          = STRING_TOKEN (STR_PROCESSOR_PART_NUMBER);
+
+    ProcessorManuStr = (CHAR16 *) PcdGetPtr (PcdProcessorManufacturer);
+
+    if (StrLen (ProcessorManuStr) > 0)
+    {
+      HiiSetString (mHiiHandle, ProcessorManu, ProcessorManuStr, NULL);
+    }
+
+    ProcessorVersionStr = (CHAR16 *) PcdGetPtr (PcdProcessorVersion);
+
+    if (StrLen (ProcessorVersionStr) > 0)
+    {
+      HiiSetString (mHiiHandle, ProcessorVersion, ProcessorVersionStr, NULL);
+    }
+
+    SerialNumberStr = (CHAR16 *) PcdGetPtr (PcdProcessorSerialNumber);
+
+    if (StrLen (SerialNumberStr) > 0)
+    {
+      HiiSetString (mHiiHandle, SerialNumber, SerialNumberStr, NULL);
+    }
+
+    AssetTagStr = (CHAR16 *) PcdGetPtr (PcdProcessorAssetTag);
+
+    if (StrLen (AssetTagStr) > 0)
+    {
+      HiiSetString (mHiiHandle, AssetTag, AssetTagStr, NULL);
+    }
+
+    PartNumberStr = (CHAR16 *) PcdGetPtr (PcdProcessorPartNumber);
+
+    if (StrLen (PartNumberStr) > 0)
+    {
+      HiiSetString (mHiiHandle, PartNumber, PartNumberStr, NULL);
+    }
+  }
+
+  // Processor Socket Designation
+  StringBufferSize = sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH;
+  ProcessorSocketStr = AllocateZeroPool (StringBufferSize);
+  if (ProcessorSocketStr == NULL)
+  {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  ProcessorSocketStrLen = UnicodeSPrint (ProcessorSocketStr, StringBufferSize, L"CPU%02d", ProcessorNumber + 1);
+
+  // Processor Manufacture
+  ProcessorManuStr = HiiGetPackageString (&gEfiCallerIdGuid, ProcessorManu, NULL);
+  ProcessorManuStrLen = StrLen (ProcessorManuStr);
+
+  // Processor Version
+  ProcessorVersionStr = HiiGetPackageString (&gEfiCallerIdGuid, ProcessorVersion, NULL);
+  ProcessorVersionStrLen = StrLen (ProcessorVersionStr);
+
+  // Serial Number
+  SerialNumberStr = HiiGetPackageString (&gEfiCallerIdGuid, SerialNumber, NULL);
+  SerialNumberStrLen = StrLen (SerialNumberStr);
+
+  // Asset Tag
+  AssetTagStr = HiiGetPackageString (&gEfiCallerIdGuid, AssetTag, NULL);
+  AssetTagStrLen = StrLen (AssetTagStr);
+
+  // Part Number
+  PartNumberStr = HiiGetPackageString (&gEfiCallerIdGuid, PartNumber, NULL);
+  PartNumberStrLen = StrLen (PartNumberStr);
+
+  TotalSize = sizeof (SMBIOS_TABLE_TYPE4) + ProcessorSocketStrLen + 1 +
+                                            ProcessorManuStrLen + 1 +
+                                            ProcessorVersionStrLen + 1 +
+                                            SerialNumberStrLen + 1 +
+                                            AssetTagStrLen + 1 +
+                                            PartNumberStrLen + 1 + 1;
+  Type4Record = AllocateZeroPool (TotalSize);
+  if (Type4Record == NULL)
+  {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  (VOID)CopyMem (Type4Record, &mSmbiosProcessorTable[ProcessorNumber], sizeof (SMBIOS_TABLE_TYPE4));
+
+  LegacyVoltage = (UINT8*)&Type4Record->Voltage;
+
+  *LegacyVoltage                          = MiscProcessorData.Voltage;
+  Type4Record->CurrentSpeed               = MiscProcessorData.CurrentSpeed;
+  Type4Record->MaxSpeed                   = MiscProcessorData.MaxSpeed;
+  Type4Record->Status                     = ProcessorStatus.Data;
+  Type4Record->L1CacheHandle              = L1CacheHandle;
+  Type4Record->L2CacheHandle              = L2CacheHandle;
+  Type4Record->L3CacheHandle              = L3CacheHandle;
+  Type4Record->CoreCount                  = MiscProcessorData.CoreCount;
+  Type4Record->CoreCount2                 = MiscProcessorData.CoreCount;
+  Type4Record->EnabledCoreCount           = MiscProcessorData.CoresEnabled;
+  Type4Record->EnabledCoreCount2          = MiscProcessorData.CoresEnabled;
+  Type4Record->ThreadCount                = MiscProcessorData.ThreadCount;
+  Type4Record->ThreadCount2               = MiscProcessorData.ThreadCount;
+
+  Type4Record->ExternalClock              = (UINT16)(ArmReadCntFrq () / 1000 / 1000);
+
+  ProcessorId = (UINT64 *)&Type4Record->ProcessorId;
+
+  Args.Arg0 = ARM_SMC_ID_ARCH_VERSION;
+  ArmCallSmc (&Args);
+  SmcCallStatus = (int)Args.Arg0;
+
+  if (SmcCallStatus < 0 || (SmcCallStatus >> 16) >= 1) {
+    Args.Arg0 = ARM_SMC_ID_ARCH_FEATURES;
+    Args.Arg1 = ARM_SMC_ID_ARCH_SOC_ID;
+    ArmCallSmc (&Args);
+
+    if (Args.Arg0 >= 0) {
+      PROCESSOR_CHARACTERISTIC_FLAGS *ProcessorCharacteristicFlags = (PROCESSOR_CHARACTERISTIC_FLAGS*)&Type4Record->ProcessorCharacteristics;
+      Args.Arg0 = ARM_SMC_ID_ARCH_SOC_ID;
+      Args.Arg1 = 0;
+      ArmCallSmc (&Args);
+      SmcCallStatus = (int)Args.Arg0;
+
+      if (SmcCallStatus >= 0) {
+        Arm64SocIdSupported = TRUE;
+        ProcessorCharacteristicFlags->ProcessorArm64SocId = 1;
+        Jep106Code = (int)Args.Arg0;
+      } else {
+        ProcessorCharacteristicFlags->ProcessorArm64SocId  = 0;
+      }
+      Args.Arg0 = ARM_SMC_ID_ARCH_SOC_ID;
+      Args.Arg1 = 1;
+      ArmCallSmc (&Args);
+      SmcCallStatus = (int)Args.Arg0;
+
+      if (SmcCallStatus >= 0) {
+        SocRevision = (int)Args.Arg0;
+      }
+    }
+  }
+
+  if (Arm64SocIdSupported) {
+    *ProcessorId = ((UINT64)Jep106Code << 32) | SocRevision;
+  } else {
+    *ProcessorId = ArmReadMidr ();
+  }
+
+  UINTN MainIdRegister = ArmReadMidr ();
+  if (((MainIdRegister >> 16) & 0xF) < 8) {
+    Type4Record->ProcessorFamily2 = ProcessorFamilyARM;
+  } else {
+    if (sizeof (VOID*) == 4) {
+      Type4Record->ProcessorFamily2 = ProcessorFamilyARMv7;
+    } else {
+      Type4Record->ProcessorFamily2 = ProcessorFamilyARMv8;
+    }
+  }
+
+  OptionalStrStart = (CHAR8 *) (Type4Record + 1);
+  UnicodeStrToAsciiStrS (ProcessorSocketStr, OptionalStrStart, ProcessorSocketStrLen + 1);
+  UnicodeStrToAsciiStrS (ProcessorManuStr, OptionalStrStart + ProcessorSocketStrLen + 1, ProcessorManuStrLen + 1);
+  UnicodeStrToAsciiStrS (ProcessorVersionStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1, ProcessorVersionStrLen + 1);
+  UnicodeStrToAsciiStrS (SerialNumberStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1, SerialNumberStrLen + 1);
+  UnicodeStrToAsciiStrS (AssetTagStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1 + SerialNumberStrLen + 1, AssetTagStrLen + 1);
+  UnicodeStrToAsciiStrS (PartNumberStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1 + SerialNumberStrLen + 1 + AssetTagStrLen + 1, PartNumberStrLen + 1);
+
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)Type4Record);
+  if (EFI_ERROR (Status))
+  {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type04 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+  }
+  FreePool (Type4Record);
+
+Exit:
+  if (ProcessorSocketStr != NULL)
+  {
+    FreePool (ProcessorSocketStr);
+  }
+  if (ProcessorManuStr != NULL)
+  {
+    FreePool (ProcessorManuStr);
+  }
+  if (ProcessorVersionStr != NULL)
+  {
+    FreePool (ProcessorVersionStr);
+  }
+  if (SerialNumberStr != NULL)
+  {
+    FreePool (SerialNumberStr);
+  }
+  if (AssetTagStr != NULL)
+  {
+    FreePool (AssetTagStr);
+  }
+  if (PartNumberStr != NULL)
+  {
+    FreePool (PartNumberStr);
+  }
+
+  return Status;
+}
+
+/**
+  Standard EFI driver point.  This driver locates the ProcessorConfigurationData Variable,
+  if it exists, add the related SMBIOS tables by PI SMBIOS protocol.
+
+  @param  ImageHandle     Handle for the image of this driver
+  @param  SystemTable     Pointer to the EFI System Table
+
+  @retval  EFI_SUCCESS    The data was successfully stored.
+
+**/
+EFI_STATUS
+EFIAPI
+ProcessorSubClassEntryPoint(
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                      Status;
+  UINT32                          SocketIndex;
+
+  //
+  // Locate dependent protocols
+  //
+  Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&mSmbios);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol.  %r\n", Status));
+    return Status;
+  }
+
+  //
+  // Add our default strings to the HII database. They will be modified later.
+  //
+  mHiiHandle = HiiAddPackages (
+              &gEfiCallerIdGuid,
+              NULL,
+              ProcessorSubClassStrings,
+              NULL,
+              NULL
+              );
+  if (mHiiHandle == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Add SMBIOS tables for populated sockets.
+  //
+  for (SocketIndex = 0; SocketIndex < OemGetProcessorMaxSockets(); SocketIndex++) {
+    Status = AddSmbiosProcessorTypeTable (SocketIndex);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Add Processor Type Table Failed!  %r.\n", Status));
+      return Status;
+    }
+  }
+
+  return Status;
+}
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c
new file mode 100644
index 000000000000..eff045383991
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c
@@ -0,0 +1,50 @@
+/**@file
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  SmbiosMiscDataTable.c
+
+Abstract:
+
+  This file provides SMBIOS Misc Type.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE0,  MiscBiosVendor, MiscBiosVendor)
+  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE1,  MiscSystemManufacturer, MiscSystemManufacturer)
+  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE3,  MiscChassisManufacturer, MiscChassisManufacturer)
+  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE2,  MiscBaseBoardManufacturer, MiscBaseBoardManufacturer)
+  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE13, MiscNumberOfInstallableLanguages, MiscNumberOfInstallableLanguages)
+  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE32, MiscBootInformation, MiscBootInformation)
+
+
+EFI_MISC_SMBIOS_DATA_TABLE mSmbiosMiscDataTable[] = {
+  // Type0
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscBiosVendor, MiscBiosVendor),
+  // Type1
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscSystemManufacturer, MiscSystemManufacturer),
+  // Type3
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscChassisManufacturer, MiscChassisManufacturer),
+  // Type2
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscBaseBoardManufacturer, MiscBaseBoardManufacturer),
+  // Type13
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscNumberOfInstallableLanguages, MiscNumberOfInstallableLanguages),
+  // Type32
+  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscBootInformation, MiscBootInformation),
+};
+
+
+//
+// Number of Data Table entries.
+//
+UINTN mSmbiosMiscDataTableEntries =
+  (sizeof (mSmbiosMiscDataTable)) / sizeof (EFI_MISC_SMBIOS_DATA_TABLE);
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
new file mode 100644
index 000000000000..fe81367d1c28
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
@@ -0,0 +1,167 @@
+/**@file
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  SmbiosMiscEntryPoint.c
+
+Abstract:
+
+  This driver parses the mSmbiosMiscDataTable structure and reports
+  any generated data using SMBIOS protocol.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+#define MAX_HANDLE_COUNT  0x10
+
+EFI_HANDLE              mImageHandle;
+EFI_HII_HANDLE          mHiiHandle;
+EFI_SMBIOS_PROTOCOL     *mSmbios = NULL;
+
+/**
+  Standard EFI driver point.  This driver parses the mSmbiosMiscDataTable
+  structure and reports any generated data using SMBIOS protocol.
+
+  @param  ImageHandle     Handle for the image of this driver
+  @param  SystemTable     Pointer to the EFI System Table
+
+  @retval  EFI_SUCCESS    The data was successfully stored.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbiosMiscEntryPoint(
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  UINTN                Index;
+  EFI_STATUS           EfiStatus;
+  EFI_SMBIOS_PROTOCOL  *Smbios;
+
+  mImageHandle = ImageHandle;
+
+  EfiStatus = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
+  if (EFI_ERROR (EfiStatus)) {
+    DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol.  %r\n", EfiStatus));
+    return EfiStatus;
+  }
+
+  mSmbios = Smbios;
+
+  mHiiHandle = HiiAddPackages (
+                  &gEfiCallerIdGuid,
+                  mImageHandle,
+                  SmbiosMiscDxeStrings,
+                  NULL
+                  );
+  if (mHiiHandle == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  for (Index = 0; Index < mSmbiosMiscDataTableEntries; ++Index) {
+    //
+    // If the entry have a function pointer, just log the data.
+    //
+    if (mSmbiosMiscDataTable[Index].Function != NULL) {
+      EfiStatus = (*mSmbiosMiscDataTable[Index].Function)(
+          mSmbiosMiscDataTable[Index].RecordData,
+          Smbios
+          );
+
+      if (EFI_ERROR(EfiStatus)) {
+        DEBUG ((DEBUG_ERROR, "Misc smbios store error.  Index=%d, ReturnStatus=%r\n", Index, EfiStatus));
+        return EfiStatus;
+      }
+    }
+  }
+
+  return EfiStatus;
+}
+
+
+/**
+  Logs SMBIOS record.
+
+  @param  Buffer                The data for the fixed portion of the SMBIOS record. The format of the record is
+                                determined by EFI_SMBIOS_TABLE_HEADER.Type. The size of the formatted area is defined
+                                by EFI_SMBIOS_TABLE_HEADER.Length and either followed by a double-null (0x0000) or
+                                a set of null terminated strings and a null.
+  @param  SmbiosHandle          A unique handle will be assigned to the SMBIOS record.
+
+  @retval EFI_SUCCESS           Record was added.
+  @retval EFI_OUT_OF_RESOURCES  Record was not added due to lack of system resources.
+
+**/
+EFI_STATUS
+LogSmbiosData (
+  IN       UINT8                      *Buffer,
+  IN  OUT  EFI_SMBIOS_HANDLE          *SmbiosHandle
+  )
+{
+  EFI_STATUS         Status;
+
+  *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+
+  Status = mSmbios->Add (
+                   mSmbios,
+                   NULL,
+                   SmbiosHandle,
+                   (EFI_SMBIOS_TABLE_HEADER *)Buffer
+                   );
+
+  return Status;
+}
+
+
+VOID
+GetLinkTypeHandle(
+  IN  UINT8                 SmbiosType,
+  OUT UINT16                **HandleArray,
+  OUT UINTN                 *HandleCount
+  )
+{
+  EFI_STATUS                       Status;
+  EFI_SMBIOS_HANDLE                SmbiosHandle;
+  EFI_SMBIOS_TABLE_HEADER          *LinkTypeData = NULL;
+
+  if (mSmbios == NULL) {
+    return;
+  }
+
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+
+  *HandleArray = AllocateZeroPool (sizeof(UINT16) * MAX_HANDLE_COUNT);
+  if (*HandleArray == NULL) {
+    DEBUG ((DEBUG_ERROR, "HandleArray allocate memory resource failed.\n"));
+    return;
+  }
+
+  *HandleCount = 0;
+
+  while(1) {
+    Status = mSmbios->GetNext (
+                        mSmbios,
+                        &SmbiosHandle,
+                        &SmbiosType,
+                        &LinkTypeData,
+                        NULL
+                        );
+
+    if (!EFI_ERROR (Status)) {
+      (*HandleArray)[*HandleCount] = LinkTypeData->Handle;
+      (*HandleCount)++;
+    } else {
+      break;
+    }
+  }
+}
+
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorData.c
new file mode 100644
index 000000000000..d9a1ed418428
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorData.c
@@ -0,0 +1,99 @@
+/*++
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscBiosVendorData.c
+
+Abstract:
+
+  This file provides Smbios Type0 Data
+
+Based on the files under Nt32Pkg/MiscSubClassPlatformDxe/
+
+**/
+
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE0, MiscBiosVendor) = {
+  {                                          //Hdr
+    EFI_SMBIOS_TYPE_BIOS_INFORMATION,          // Type,
+    0,                                         // Length,
+    0                                          // Handle
+  },
+  1,                                         //Vendor
+  2,                                         //BiosVersion
+  0xE000,                                    //BiosSegment
+  3,                                         //BiosReleaseDate
+  0,                                         //BiosSize
+  {                                          //BiosCharacteristics
+    0,                                         // Reserved                          :2
+    0,                                         // Unknown                           :1
+    0,                                         // BiosCharacteristicsNotSupported   :1
+    0,                                         // IsaIsSupported                    :1
+    0,                                         // McaIsSupported                    :1
+    0,                                         // EisaIsSupported                   :1
+    1,                                         // PciIsSupported                    :1
+    0,                                         // PcmciaIsSupported                 :1
+    1,                                         // PlugAndPlayIsSupported            :1
+    0,                                         // ApmIsSupported                    :1
+    1,                                         // BiosIsUpgradable                  :1
+    1,                                         // BiosShadowingAllowed              :1
+    0,                                         // VlVesaIsSupported                 :1
+    0,                                         // EscdSupportIsAvailable            :1
+    1,                                         // BootFromCdIsSupported             :1
+    1,                                         // SelectableBootIsSupported         :1
+    0,                                         // RomBiosIsSocketed                 :1
+    0,                                         // BootFromPcmciaIsSupported         :1
+    1,                                         // EDDSpecificationIsSupported       :1
+    0,                                         // JapaneseNecFloppyIsSupported      :1
+    0,                                         // JapaneseToshibaFloppyIsSupported  :1
+    0,                                         // Floppy525_360IsSupported          :1
+    0,                                         // Floppy525_12IsSupported           :1
+    0,                                         // Floppy35_720IsSupported           :1
+    0,                                         // Floppy35_288IsSupported           :1
+    0,                                         // PrintScreenIsSupported            :1
+    0,                                         // Keyboard8042IsSupported           :1
+    0,                                         // SerialIsSupported                 :1
+    0,                                         // PrinterIsSupported                :1
+    0,                                         // CgaMonoIsSupported                :1
+    0,                                         // NecPc98                           :1
+    0                                          // ReservedForVendor                 :32
+  },
+
+  {
+    0x03,                                        //BIOSCharacteristicsExtensionBytes[0]
+    //  {                                          //BiosReserved
+    //    1,                                         // AcpiIsSupported                   :1
+    //    1,                                         // UsbLegacyIsSupported              :1
+    //    0,                                         // AgpIsSupported                    :1
+    //    0,                                         // I20BootIsSupported                :1
+    //    0,                                         // Ls120BootIsSupported              :1
+    //    0,                                         // AtapiZipDriveBootIsSupported      :1
+    //    0,                                         // Boot1394IsSupported               :1
+    //    0                                          // SmartBatteryIsSupported           :1
+    //  },
+    0x0D                                         //BIOSCharacteristicsExtensionBytes[1]
+    //  {                                          //SystemReserved
+    //    1,                                         //BiosBootSpecIsSupported            :1
+    //    0,                                         //FunctionKeyNetworkBootIsSupported  :1
+    //    1,                                         //TargetContentDistributionEnabled   :1
+    //    1,                                         //UefiSpecificationSupported         :1
+    //    0,                                         //VirtualMachineSupported            :1
+    //    0                                          //ExtensionByte2Reserved             :3
+    //  },
+  },
+  0xFF,                                        //SystemBiosMajorRelease;
+  0xFF,                                        //SystemBiosMinorRelease;
+  0xFF,                                     //EmbeddedControllerFirmwareMajorRelease;
+  0xFF                                      //EmbeddedControllerFirmwareMinorRelease;
+};
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c
new file mode 100644
index 000000000000..2f6b35d80266
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c
@@ -0,0 +1,232 @@
+/** @file
+
+  Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+  Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+Module Name:
+
+  MiscBiosVendorData.c
+
+Abstract:
+
+  This driver parses the mMiscSubclassDataTable structure and reports
+  any generated data to the DataHub.
+
+Based on the files under Nt32Pkg/MiscSubClassPlatformDxe/
+
+--*/
+
+//
+#include "SmbiosMisc.h"
+#include <Library/HobLib.h>
+#include <Guid/VersionInfoHobGuid.h>
+
+
+/**
+  Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k'
+  as the unit.
+
+  @param  Value              Pointer to Base2_Data
+
+  @retval
+
+**/
+UINT8
+Base2ToByteWith64KUnit (
+  IN  UINTN  Value
+  )
+{
+  UINT8 Size;
+
+  Size = Value / SIZE_64KB + (Value % SIZE_64KB + SIZE_64KB - 1) / SIZE_64KB;
+
+  return Size;
+}
+
+
+/**
+
+**/
+VOID *
+GetBiosReleaseDate (
+  VOID
+  )
+{
+  CHAR16                  *ReleaseDate = NULL;
+  VERSION_INFO            *Version;
+  VOID                    *Hob;
+
+  ReleaseDate = AllocateZeroPool ((sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH);
+  if (ReleaseDate == NULL) {
+      return NULL;
+  }
+
+  Hob = GetFirstGuidHob (&gVersionInfoHobGuid);
+  if (Hob == NULL) {
+    DEBUG ((DEBUG_ERROR, "[%a:%d] Version info HOB not found!\n", __FUNCTION__, __LINE__));
+    return NULL;
+  }
+
+  Version = GET_GUID_HOB_DATA (Hob);
+  (VOID)UnicodeSPrintAsciiFormat (ReleaseDate,
+                        (sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH,
+                        "%02d/%02d/%4d",
+                        Version->BuildTime.Month,
+                        Version->BuildTime.Day,
+                        Version->BuildTime.Year
+                        );
+
+  return ReleaseDate;
+}
+
+VOID *
+GetBiosVersion (
+  VOID
+  )
+{
+  VERSION_INFO            *Version;
+  VOID                    *Hob;
+
+  Hob = GetFirstGuidHob (&gVersionInfoHobGuid);
+  if (Hob == NULL) {
+    DEBUG ((DEBUG_ERROR, "[%a:%d] Version info HOB not found!\n", __FUNCTION__, __LINE__));
+    return NULL;
+  }
+
+  Version = GET_GUID_HOB_DATA (Hob);
+  return Version->String;
+}
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscBiosVendor (Type 0).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscBiosVendor)
+{
+  CHAR8                 *OptionalStrStart;
+  UINTN                 VendorStrLen;
+  UINTN                 VerStrLen;
+  UINTN                 DateStrLen;
+  UINTN                 BiosPhysicalSizeHexValue;
+  CHAR16                *Vendor;
+  CHAR16                *Version;
+  CHAR16                *ReleaseDate;
+  CHAR16                *Char16String;
+  EFI_STATUS            Status;
+  EFI_STRING_ID         TokenToUpdate;
+  EFI_STRING_ID         TokenToGet;
+  SMBIOS_TABLE_TYPE0    *SmbiosRecord;
+  EFI_SMBIOS_HANDLE     SmbiosHandle;
+  SMBIOS_TABLE_TYPE0    *InputData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InputData = (SMBIOS_TABLE_TYPE0 *)RecordData;
+
+  Vendor = (CHAR16 *) PcdGetPtr (PcdFirmwareVendor);
+
+  if (StrLen (Vendor) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
+    HiiSetString (mHiiHandle, TokenToUpdate, Vendor, NULL);
+  }
+
+  Version = GetBiosVersion();
+
+  if (StrLen (Version) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
+    HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
+  } else {
+    Version = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
+    if (StrLen (Version) > 0) {
+      TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
+      HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
+    }
+  }
+
+  Char16String = GetBiosReleaseDate ();
+  if (StrLen(Char16String) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
+    HiiSetString (mHiiHandle, TokenToUpdate, Char16String, NULL);
+  }
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
+  Vendor = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  VendorStrLen = StrLen (Vendor);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION);
+  Version = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  VerStrLen = StrLen (Version);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
+  ReleaseDate = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  DateStrLen = StrLen (ReleaseDate);
+
+  //
+  // Now update the BiosPhysicalSize
+  //
+  BiosPhysicalSizeHexValue = FixedPcdGet32 (PcdFdSize);
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);
+  if (SmbiosRecord == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE0));
+
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE0);
+  SmbiosRecord->BiosSegment = (UINT16)(FixedPcdGet32 (PcdFdBaseAddress) / SIZE_64KB);
+  SmbiosRecord->BiosSize = Base2ToByteWith64KUnit (BiosPhysicalSizeHexValue) - 1;
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStrS (Vendor, OptionalStrStart, VendorStrLen + 1);
+  UnicodeStrToAsciiStrS (Version, OptionalStrStart + VendorStrLen + 1, VerStrLen + 1);
+  UnicodeStrToAsciiStrS (ReleaseDate, OptionalStrStart + VendorStrLen + 1 + VerStrLen + 1, DateStrLen + 1);
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+  if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type00 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+  }
+
+  FreePool (SmbiosRecord);
+
+Exit:
+  if (Vendor != NULL) {
+    FreePool (Vendor);
+  }
+
+  if (Version != NULL) {
+    FreePool (Version);
+  }
+
+  if (ReleaseDate != NULL) {
+    FreePool (ReleaseDate);
+  }
+
+  if (Char16String != NULL) {
+    FreePool (Char16String);
+  }
+
+  return Status;
+}
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerData.c
new file mode 100644
index 000000000000..8752dbd73132
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerData.c
@@ -0,0 +1,43 @@
+/*++
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscSystemManufacturerData.c
+
+Abstract:
+
+  This file provides Smbios Type1 Data
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+
+**/
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) System Manufacturer data.
+//
+MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE1, MiscSystemManufacturer) = {
+  {                                               // Hdr
+    EFI_SMBIOS_TYPE_SYSTEM_INFORMATION,             // Type,
+    0,                                              // Length,
+    0                                               // Handle
+  },
+  1,                                              // Manufacturer
+  2,                                              // ProductName
+  3,                                              // Version
+  4,                                              // SerialNumber
+  {                                               // Uuid
+    0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+  },
+  SystemWakeupTypePowerSwitch,                    // SystemWakeupType
+  5,                                              // SKUNumber,
+  6                                               // Family
+};
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerFunction.c
new file mode 100644
index 000000000000..2f96ce90575e
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerFunction.c
@@ -0,0 +1,171 @@
+/*++
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscSystemManufacturerFunction.c
+
+Abstract:
+
+  This driver parses the mMiscSubclassDataTable structure and reports
+  any generated data to smbios.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+
+**/
+
+#include "SmbiosMisc.h"
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscSystemManufacturer (Type 1).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscSystemManufacturer)
+{
+  CHAR8                           *OptionalStrStart;
+  UINTN                           ManuStrLen;
+  UINTN                           VerStrLen;
+  UINTN                           PdNameStrLen;
+  UINTN                           SerialNumStrLen;
+  UINTN                           SKUNumStrLen;
+  UINTN                           FamilyStrLen;
+  EFI_STRING                      Manufacturer;
+  EFI_STRING                      ProductName;
+  EFI_STRING                      Version;
+  EFI_STRING                      SerialNumber;
+  EFI_STRING                      SKUNumber;
+  EFI_STRING                      Family;
+  EFI_STRING_ID                   TokenToGet;
+  EFI_SMBIOS_HANDLE               SmbiosHandle;
+  SMBIOS_TABLE_TYPE1              *SmbiosRecord;
+  SMBIOS_TABLE_TYPE1              *InputData;
+  EFI_STATUS                      Status;
+  EFI_STRING_ID                   TokenToUpdate;
+  CHAR16                          *Product;
+  CHAR16                          *pVersion;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InputData = (SMBIOS_TABLE_TYPE1 *)RecordData;
+
+  Product = (CHAR16 *) PcdGetPtr (PcdSystemProductName);
+  if (StrLen (Product) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
+    HiiSetString (mHiiHandle, TokenToUpdate, Product, NULL);
+  }
+
+  pVersion = (CHAR16 *) PcdGetPtr (PcdSystemVersion);
+  if (StrLen (pVersion) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
+    HiiSetString (mHiiHandle, TokenToUpdate, pVersion, NULL);
+  }
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_SYSTEM_SERIAL_NUMBER), SerialNumType01);
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER), SystemManufacturerType01);
+
+  TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER);
+  Manufacturer = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  ManuStrLen   = StrLen (Manufacturer);
+
+  TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
+  ProductName  = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  PdNameStrLen = StrLen (ProductName);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
+  Version    = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  VerStrLen  = StrLen (Version);
+
+  TokenToGet      = STRING_TOKEN (STR_MISC_SYSTEM_SERIAL_NUMBER);
+  SerialNumber    = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  SerialNumStrLen = StrLen (SerialNumber);
+
+  TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_SKU_NUMBER);
+  SKUNumber    = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  SKUNumStrLen = StrLen (SKUNumber);
+
+  TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_FAMILY);
+  Family       = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  FamilyStrLen = StrLen (Family);
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen      + 1
+                                                                + PdNameStrLen    + 1
+                                                                + VerStrLen       + 1
+                                                                + SerialNumStrLen + 1
+                                                                + SKUNumStrLen    + 1
+                                                                + FamilyStrLen    + 1 + 1);
+
+  if (SmbiosRecord == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE1));
+
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE1);
+
+  SmbiosRecord->Uuid = InputData->Uuid;
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStrS (Manufacturer, OptionalStrStart, ManuStrLen + 1);
+  UnicodeStrToAsciiStrS (ProductName,  OptionalStrStart + ManuStrLen + 1, PdNameStrLen + 1);
+  UnicodeStrToAsciiStrS (Version,      OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1, VerStrLen + 1);
+  UnicodeStrToAsciiStrS (SerialNumber, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1, SerialNumStrLen + 1);
+  UnicodeStrToAsciiStrS (SKUNumber, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1, SKUNumStrLen + 1);
+  UnicodeStrToAsciiStrS (Family, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SKUNumStrLen + 1, FamilyStrLen + 1);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type01 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+  }
+
+  FreePool (SmbiosRecord);
+
+Exit:
+  if (Manufacturer != NULL) {
+    FreePool (Manufacturer);
+  }
+
+  if (ProductName != NULL) {
+    FreePool (ProductName);
+  }
+
+  if (Version != NULL) {
+    FreePool (Version);
+  }
+
+  if (SerialNumber != NULL) {
+    FreePool (SerialNumber);
+  }
+
+  if (SKUNumber != NULL) {
+    FreePool (SKUNumber);
+  }
+
+  if (Family != NULL) {
+    FreePool (Family);
+  }
+
+  return 0;
+}
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerData.c
new file mode 100644
index 000000000000..ed55d87310e2
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerData.c
@@ -0,0 +1,51 @@
+/*++
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscBaseBoardManufacturerData.c
+
+Abstract:
+
+  This file provide OEM to define Smbios Type2 Data
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+//
+// Static (possibly build generated) Chassis Manufacturer data.
+//
+MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE2, MiscBaseBoardManufacturer) = {
+  {                                                       // Hdr
+    EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION,                // Type,
+    0,                                                    // Length,
+    0                                                     // Handle
+  },
+  1,                                                      // BaseBoardManufacturer
+  2,                                                      // BaseBoardProductName
+  3,                                                      // BaseBoardVersion
+  4,                                                      // BaseBoardSerialNumber
+  5,                                                      // BaseBoardAssetTag
+  {                                                       // FeatureFlag
+    1,                                                    // Motherboard           :1
+    0,                                                    // RequiresDaughterCard  :1
+    0,                                                    // Removable             :1
+    1,                                                    // Replaceable           :1
+    0,                                                    // HotSwappable          :1
+    0                                                     // Reserved              :3
+  },
+  6,                                                      // BaseBoardChassisLocation
+  0,                                                      // ChassisHandle;
+  BaseBoardTypeMotherBoard,                               // BoardType;
+  0,                                                      // NumberOfContainedObjectHandles;
+  {
+    0
+  }                                                       // ContainedObjectHandles[1];
+};
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerFunction.c
new file mode 100644
index 000000000000..0528651068c7
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerFunction.c
@@ -0,0 +1,184 @@
+/** @file
+
+  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+  Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscBaseBoardManufacturerFunction.c
+
+Abstract:
+
+  This driver parses the mSmbiosMiscDataTable structure and reports
+  any generated data using SMBIOS protocol.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+
+/**
+  This function makes basic board manufacturer to the contents of the
+  Misc Base Board Manufacturer (Type 2).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscBaseBoardManufacturer)
+{
+  CHAR8                             *OptionalStrStart;
+  UINTN                             ManuStrLen;
+  UINTN                             ProductNameStrLen;
+  UINTN                             VerStrLen;
+  UINTN                             SerialNumStrLen;
+  UINTN                             AssetTagStrLen;
+  UINTN                             ChassisLocaStrLen;
+  UINTN                             HandleCount = 0;
+  UINT16                            *HandleArray = NULL;
+  CHAR16                            *BaseBoardManufacturer;
+  CHAR16                            *BaseBoardProductName;
+  CHAR16                            *Version;
+  EFI_STRING                        SerialNumber;
+  EFI_STRING                        AssetTag;
+  EFI_STRING                        ChassisLocation;
+  EFI_STRING_ID                     TokenToGet;
+  EFI_SMBIOS_HANDLE                 SmbiosHandle;
+  SMBIOS_TABLE_TYPE2                *SmbiosRecord;
+  SMBIOS_TABLE_TYPE2                *InputData = NULL;
+  EFI_STATUS                        Status;
+
+  EFI_STRING_ID                     TokenToUpdate;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InputData = (SMBIOS_TABLE_TYPE2*)RecordData;
+
+  BaseBoardManufacturer = (CHAR16 *) PcdGetPtr (PcdBaseBoardManufacturer);
+  if (StrLen (BaseBoardManufacturer) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BASE_BOARD_MANUFACTURER);
+    HiiSetString (mHiiHandle, TokenToUpdate, BaseBoardManufacturer, NULL);
+  }
+
+  BaseBoardProductName = (CHAR16 *) PcdGetPtr (PcdBaseBoardProductName);
+  if (StrLen (BaseBoardProductName) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BASE_BOARD_PRODUCT_NAME);
+    HiiSetString (mHiiHandle, TokenToUpdate, BaseBoardProductName, NULL);
+  }
+
+  Version = (CHAR16 *) PcdGetPtr (PcdBaseBoardVersion);
+  if (StrLen (Version) > 0) {
+    TokenToUpdate = STRING_TOKEN (STR_MISC_BASE_BOARD_VERSION);
+    HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
+  }
+
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_BASE_BOARD_ASSET_TAG), AssertTagType02);
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_BASE_BOARD_SERIAL_NUMBER), SrNumType02);
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_BASE_BOARD_MANUFACTURER), BoardManufacturerType02);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_MANUFACTURER);
+  BaseBoardManufacturer = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  ManuStrLen = StrLen (BaseBoardManufacturer);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_PRODUCT_NAME);
+  BaseBoardProductName = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  ProductNameStrLen = StrLen (BaseBoardProductName);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_VERSION);
+  Version = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  VerStrLen = StrLen (Version);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_SERIAL_NUMBER);
+  SerialNumber = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  SerialNumStrLen = StrLen (SerialNumber);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_ASSET_TAG);
+  AssetTag = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  AssetTagStrLen = StrLen (AssetTag);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_CHASSIS_LOCATION);
+  ChassisLocation = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  ChassisLocaStrLen = StrLen (ChassisLocation);
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE2) + ManuStrLen        + 1
+                                                                + ProductNameStrLen + 1
+                                                                + VerStrLen         + 1
+                                                                + SerialNumStrLen   + 1
+                                                                + AssetTagStrLen    + 1
+                                                                + ChassisLocaStrLen + 1 + 1);
+  if (SmbiosRecord == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE2));
+  SmbiosRecord->Hdr.Length        = sizeof (SMBIOS_TABLE_TYPE2);
+
+  //
+  //  Update Contained objects Handle
+  //
+  SmbiosRecord->NumberOfContainedObjectHandles = 0;
+  GetLinkTypeHandle (EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE, &HandleArray, &HandleCount);
+  if (HandleCount) {
+    SmbiosRecord->ChassisHandle = HandleArray[0];
+  }
+
+  FreePool(HandleArray);
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  UnicodeStrToAsciiStrS (BaseBoardManufacturer, OptionalStrStart, ManuStrLen + 1);
+  UnicodeStrToAsciiStrS (BaseBoardProductName, OptionalStrStart + ManuStrLen + 1, ProductNameStrLen + 1);
+  UnicodeStrToAsciiStrS (Version, OptionalStrStart + ManuStrLen + 1 + ProductNameStrLen + 1, VerStrLen + 1);
+  UnicodeStrToAsciiStrS (SerialNumber, OptionalStrStart + ManuStrLen + 1 + ProductNameStrLen + 1 + VerStrLen + 1, SerialNumStrLen + 1);
+  UnicodeStrToAsciiStrS (AssetTag, OptionalStrStart + ManuStrLen + 1 + ProductNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1, AssetTagStrLen + 1);
+  UnicodeStrToAsciiStrS (ChassisLocation, OptionalStrStart + ManuStrLen + 1 + ProductNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssetTagStrLen + 1, ChassisLocaStrLen + 1);
+
+  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type02 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+  }
+
+  FreePool (SmbiosRecord);
+
+Exit:
+  if (BaseBoardManufacturer != NULL) {
+    FreePool (BaseBoardManufacturer);
+  }
+
+  if (BaseBoardProductName != NULL) {
+    FreePool (BaseBoardProductName);
+  }
+
+  if (Version != NULL) {
+    FreePool (Version);
+  }
+
+  if (SerialNumber != NULL) {
+    FreePool (SerialNumber);
+  }
+
+  if (AssetTag != NULL) {
+    FreePool (AssetTag);
+  }
+
+  if (ChassisLocation != NULL) {
+    FreePool (ChassisLocation);
+  }
+
+  return 0;
+}
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerData.c
new file mode 100644
index 000000000000..25d1413ed873
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerData.c
@@ -0,0 +1,58 @@
+/*++
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscChassisManufacturerData.c
+
+Abstract:
+
+  This file provides Smbios Type3 Data
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Chassis Manufacturer data.
+//
+MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE3, MiscChassisManufacturer) = {
+  {                                                       // Hdr
+    EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE  ,                   // Type,
+    0,                                                    // Length,
+    0                                                     // Handle
+  },
+  1,                                                      // Manufactrurer
+  MiscChassisTypeMainServerChassis,                       // Type
+  2,                                                      // Version
+  3,                                                      // SerialNumber
+  4,                                                      // AssetTag
+  ChassisStateSafe,                                       // BootupState
+  ChassisStateSafe,                                       // PowerSupplyState
+  ChassisStateSafe,                                       // ThermalState
+  ChassisSecurityStatusNone,                              // SecurityState
+  {
+    0,                                                    // OemDefined[0]
+    0,                                                    // OemDefined[1]
+    0,                                                    // OemDefined[2]
+    0                                                     // OemDefined[3]
+  },
+  2,                                                      // Height
+  1,                                                      // NumberofPowerCords
+  0,                                                      // ContainedElementCount
+  0,                                                      // ContainedElementRecordLength
+  {                                                       // ContainedElements[0]
+    {
+      0,                                                    // ContainedElementType
+      0,                                                    // ContainedElementMinimum
+      0                                                     // ContainedElementMaximum
+    }
+  }
+};
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerFunction.c
new file mode 100644
index 000000000000..84b4aaaeb89d
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerFunction.c
@@ -0,0 +1,182 @@
+/** @file
+
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscChassisManufacturerFunction.c
+
+Abstract:
+
+  This driver parses the mMiscSubclassDataTable structure and reports
+  any generated data to smbios.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+UINT8
+GetChassisType (
+  VOID
+  )
+{
+  EFI_STATUS                      Status;
+  UINT8                           ChassisType;
+
+  Status = OemGetChassisType (&ChassisType);
+  if (EFI_ERROR (Status)) {
+    return 0;
+  }
+
+  return ChassisType;
+}
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscChassisManufacturer (Type 3).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscChassisManufacturer)
+{
+  CHAR8                           *OptionalStrStart;
+  UINTN                           ManuStrLen;
+  UINTN                           VerStrLen;
+  UINTN                           AssertTagStrLen;
+  UINTN                           SerialNumStrLen;
+  UINTN                           ChaNumStrLen;
+  EFI_STRING                      Manufacturer;
+  EFI_STRING                      Version;
+  EFI_STRING                      SerialNumber;
+  EFI_STRING                      AssertTag;
+  EFI_STRING                      ChassisSkuNumber;
+  EFI_STRING_ID                   TokenToGet;
+  EFI_SMBIOS_HANDLE               SmbiosHandle;
+  SMBIOS_TABLE_TYPE3              *SmbiosRecord;
+  SMBIOS_TABLE_TYPE3              *InputData;
+  EFI_STATUS                      Status;
+
+  UINT8                           ContainedElementCount;
+  CONTAINED_ELEMENT               ContainedElements = {0};
+  UINT8                           ExtendLength = 0;
+
+  UINT8                           ChassisType;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InputData = (SMBIOS_TABLE_TYPE3 *)RecordData;
+
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_CHASSIS_ASSET_TAG), AssetTagType03);
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_CHASSIS_SERIAL_NUMBER), SrNumType03);
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_CHASSIS_VERSION), VersionType03);
+  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_CHASSIS_MANUFACTURER), ManufacturerType03);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_MANUFACTURER);
+  Manufacturer = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  ManuStrLen = StrLen (Manufacturer);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_VERSION);
+  Version = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  VerStrLen = StrLen (Version);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_SERIAL_NUMBER);
+  SerialNumber = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  SerialNumStrLen = StrLen (SerialNumber);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_ASSET_TAG);
+  AssertTag = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  AssertTagStrLen = StrLen (AssertTag);
+
+  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_SKU_NUMBER);
+  ChassisSkuNumber = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
+  ChaNumStrLen = StrLen (ChassisSkuNumber);
+
+  ContainedElementCount = InputData->ContainedElementCount;
+
+  if (ContainedElementCount > 1) {
+    ExtendLength = (ContainedElementCount - 1) * sizeof (CONTAINED_ELEMENT);
+  }
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE3) + ExtendLength    + 1
+                                                                + ManuStrLen      + 1
+                                                                + VerStrLen       + 1
+                                                                + SerialNumStrLen + 1
+                                                                + AssertTagStrLen + 1
+                                                                + ChaNumStrLen    + 1 + 1);
+  if (SmbiosRecord == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE3));
+
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE3) + ExtendLength + 1;
+
+  ChassisType = GetChassisType ();
+  if (ChassisType != 0) {
+    SmbiosRecord->Type  = ChassisType;
+  }
+
+  //ContainedElements
+  (VOID)CopyMem (SmbiosRecord + 1, &ContainedElements, ExtendLength);
+
+  //ChassisSkuNumber
+  *((UINT8 *)SmbiosRecord + sizeof (SMBIOS_TABLE_TYPE3) + ExtendLength) = 5;
+
+  OptionalStrStart = (CHAR8 *)((UINT8 *)SmbiosRecord + sizeof (SMBIOS_TABLE_TYPE3) + ExtendLength + 1);
+  UnicodeStrToAsciiStrS (Manufacturer,     OptionalStrStart, ManuStrLen + 1);
+  UnicodeStrToAsciiStrS (Version, OptionalStrStart + ManuStrLen + 1, VerStrLen + 1);
+  UnicodeStrToAsciiStrS (SerialNumber, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1, SerialNumStrLen + 1);
+  UnicodeStrToAsciiStrS (AssertTag, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1, AssertTagStrLen + 1);
+  UnicodeStrToAsciiStrS (ChassisSkuNumber, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1 + SerialNumStrLen +1 + AssertTagStrLen + 1, ChaNumStrLen + 1);
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type03 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+  }
+
+  FreePool (SmbiosRecord);
+
+Exit:
+  if (Manufacturer != NULL) {
+    FreePool (Manufacturer);
+  }
+
+  if (Version != NULL) {
+    FreePool (Version);
+  }
+
+  if (SerialNumber != NULL) {
+    FreePool (SerialNumber);
+  }
+
+  if (AssertTag != NULL) {
+    FreePool (AssertTag);
+  }
+
+  if (ChassisSkuNumber != NULL) {
+    FreePool (ChassisSkuNumber);
+  }
+
+  return 0;
+}
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesData.c
new file mode 100644
index 000000000000..fa4c574a82c5
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesData.c
@@ -0,0 +1,39 @@
+/**@file
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscNumberOfInstallableLanguagesData.c
+
+Abstract:
+
+  This file provides Smbios Type13 Data
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+
+MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE13, MiscNumberOfInstallableLanguages) =
+{
+  {                                                     // Hdr
+    EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION,            // Type,
+    0,                                                    // Length,
+    0                                                     // Handle
+  },
+  0,                                                    // InstallableLanguages
+  0,                                                    // Flags
+  {
+    0                                                   // Reserved[15]
+  },
+  1                                                     // CurrentLanguage
+};
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesFunction.c
new file mode 100644
index 000000000000..dc360aa74cea
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesFunction.c
@@ -0,0 +1,154 @@
+/** @file
+
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+/**
+  Get next language from language code list (with separator ';').
+
+  @param  LangCode       Input: point to first language in the list. On
+                         Otput: point to next language in the list, or
+                                NULL if no more language in the list.
+  @param  Lang           The first language in the list.
+
+**/
+VOID
+EFIAPI
+GetNextLanguage (
+  IN OUT CHAR8      **LangCode,
+  OUT CHAR8         *Lang
+  )
+{
+  UINTN  Index;
+  CHAR8  *StringPtr;
+
+  if (LangCode == NULL || *LangCode == NULL || Lang == NULL) {
+    return;
+  }
+
+  Index     = 0;
+  StringPtr = *LangCode;
+  while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
+    Index++;
+  }
+
+  (VOID)CopyMem (Lang, StringPtr, Index);
+  Lang[Index] = 0;
+
+  if (StringPtr[Index] == ';') {
+    Index++;
+  }
+  *LangCode = StringPtr + Index;
+}
+
+/**
+  This function returns the number of supported languages on HiiHandle.
+
+  @param   HiiHandle    The HII package list handle.
+
+  @retval  The number of supported languages.
+
+**/
+UINT16
+EFIAPI
+GetSupportedLanguageNumber (
+  IN EFI_HII_HANDLE    HiiHandle
+  )
+{
+  CHAR8   *Lang;
+  CHAR8   *Languages;
+  CHAR8   *LanguageString;
+  UINT16  LangNumber;
+
+  Languages = HiiGetSupportedLanguages (HiiHandle);
+  if (Languages == NULL) {
+    return 0;
+  }
+
+  LangNumber = 0;
+  Lang = AllocatePool (AsciiStrSize (Languages));
+  if (Lang != NULL) {
+    LanguageString = Languages;
+    while (*LanguageString != 0) {
+      GetNextLanguage (&LanguageString, Lang);
+      LangNumber++;
+    }
+    FreePool (Lang);
+  }
+  FreePool (Languages);
+  return LangNumber;
+}
+
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscNumberOfInstallableLanguages (Type 13).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscNumberOfInstallableLanguages)
+{
+  UINTN                                     LangStrLen;
+  CHAR8                                     CurrentLang[SMBIOS_STRING_MAX_LENGTH + 1];
+  CHAR8                                     *OptionalStrStart;
+  EFI_STATUS                                Status;
+  EFI_SMBIOS_HANDLE                         SmbiosHandle;
+  SMBIOS_TABLE_TYPE13                       *SmbiosRecord;
+  SMBIOS_TABLE_TYPE13                       *InputData = NULL;;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InputData = (SMBIOS_TABLE_TYPE13 *)RecordData;
+
+  InputData->InstallableLanguages = GetSupportedLanguageNumber (mHiiHandle);
+
+  //
+  // Try to check if current langcode matches with the langcodes in installed languages
+  //
+  ZeroMem (CurrentLang, SMBIOS_STRING_MAX_LENGTH - 1);
+  (VOID)AsciiStrCpyS (CurrentLang, SMBIOS_STRING_MAX_LENGTH - 1, "en|US|iso8859-1");
+  LangStrLen = AsciiStrLen (CurrentLang);
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1);
+  if (SmbiosRecord == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE13));
+
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE13);
+
+  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+  (VOID)AsciiStrCpyS (OptionalStrStart, SMBIOS_STRING_MAX_LENGTH - 1, CurrentLang);
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type13 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+  }
+
+  FreePool (SmbiosRecord);
+  return Status;
+}
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationData.c
new file mode 100644
index 000000000000..c00225a54005
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationData.c
@@ -0,0 +1,41 @@
+/**@file
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MiscBootInformationData.c
+
+Abstract:
+
+  This driver parses the mMiscSubclassDataTable structure and reports
+  any generated data to the DataHub.
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE32, MiscBootInformation) = {
+  {                                                     // Hdr
+    EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION,              // Type,
+    0,                                                    // Length,
+    0                                                     // Handle
+  },
+  {                                                     // Reserved[6]
+    0,
+    0,
+    0,
+    0,
+    0,
+    0
+  },
+  BootInformationStatusNoError                          // BootInformationStatus
+};
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationFunction.c
new file mode 100644
index 000000000000..25da6de1bfa6
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationFunction.c
@@ -0,0 +1,66 @@
+/** @file
+  boot information boot time changes.
+  SMBIOS type 32.
+
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+**/
+
+#include "SmbiosMisc.h"
+
+/**
+  This function makes boot time changes to the contents of the
+  MiscBootInformation (Type 32).
+
+  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
+
+**/
+
+MISC_SMBIOS_TABLE_FUNCTION(MiscBootInformation)
+{
+  EFI_STATUS                         Status;
+  EFI_SMBIOS_HANDLE                  SmbiosHandle;
+  SMBIOS_TABLE_TYPE32                *SmbiosRecord;
+  SMBIOS_TABLE_TYPE32                *InputData;
+
+  //
+  // First check for invalid parameters.
+  //
+  if (RecordData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InputData = (SMBIOS_TABLE_TYPE32 *)RecordData;
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE32) + 1 + 1);
+  if (SmbiosRecord == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE32));
+
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE32);
+
+  //
+  // Now we have got the full smbios record, call smbios protocol to add this record.
+  //
+  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type32 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
+  }
+
+  FreePool (SmbiosRecord);
+  return Status;
+}
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
index 199374ff59e3..874bc2866ac3 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
@@ -424,6 +424,9 @@ ASM_FUNC(ArmCallWFI)
   wfi
   ret
 
+ASM_FUNC(ArmReadIdMmfr2)
+  mrs   x0, ID_AA64MMFR2_EL1           // read EL1 MMFR2
+  ret
 
 ASM_FUNC(ArmReadMpidr)
   mrs   x0, mpidr_el1           // read EL1 MPIDR
diff --git a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
index 0e8d21e2264f..0ae75e4cb9f9 100644
--- a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
+++ b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
@@ -84,7 +84,7 @@ ASM_FUNC(ArmDisableAllExceptions)
   ret
 
 
-// UINT32
+// UINTN
 // ReadCCSIDR (
 //   IN UINT32 CSSELR
 //   )
[SAMI] This could be a separate patch. [/SAMI]

diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
index 01c91b10fcb7..39fdb0155065 100644
--- a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
+++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
@@ -60,6 +60,10 @@ ASM_FUNC(ArmDisableInterrupts)
   isb
   bx      LR
 
+ASM_FUNC(ArmReadIdMmfr4):
+  mrc    p15,0,r0,c0,c2,6     @ Read ID_MMFR4 Register
+  bx     lr
+
[SAMI] This can be a separate patch along with ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm
  e.g. Add helper to read MMFR4
[/SAMI]

 // UINT32
 // ReadCCSIDR (
 //   IN UINT32 CSSELR
[SAMI] Is it possible to find and replace the declaration/comments for ReadCCSIDR to reflect the change from UINT32->UINTN, please?
[/SAMI]

diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm
index 26ffa331b929..d1bbb0a0fc98 100644
--- a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm
+++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm
@@ -64,7 +64,11 @@
   isb
   bx      LR
 
-// UINT32
+ RVCT_ASM_EXPORT ArmReadIdMmfr4
+  mrc    p15,0,r0,c0,c2,6     ; Read ID_MMFR2 Register

[SAMI] The comment should be ID_MMFR4
[/SAMI]

+  bx

[SAMI] This should be 'bx     LR'.
[/SAMI]

+
+// UINTN
 // ReadCCSIDR (
 //   IN UINT32 CSSELR
 //   )
diff --git a/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni
new file mode 100644
index 000000000000..0f55beb95276
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni
@@ -0,0 +1,23 @@
+???///// @file
+//
+//  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+//  Copyright (c) 2015, Linaro Limited. All rights reserved.
+//
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+/////
+
+/=#
+
+#langdef en-US "English"
+
+//
+// Processor Information
+//
+#string STR_PROCESSOR_SOCKET_DESIGNATION    #language en-US  "Not Specified"
+#string STR_PROCESSOR_MANUFACTURE           #language en-US  "Not Specified"
+#string STR_PROCESSOR_VERSION               #language en-US  "Not Specified"
+#string STR_PROCESSOR_SERIAL_NUMBER         #language en-US  "Not Specified"
+#string STR_PROCESSOR_ASSET_TAG             #language en-US  "Not Specified"
+#string STR_PROCESSOR_PART_NUMBER           #language en-US  "Not Specified"
+#string STR_PROCESSOR_UNKNOWN               #language en-US  "Unknown"
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni
new file mode 100644
index 000000000000..7a82e520904e
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni
@@ -0,0 +1,21 @@
+???// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+// --*/
+
+
+/=#
+
+#langdef en-US "English"
+
+#include "./Type00/MiscBiosVendor.uni"
+#include "./Type01/MiscSystemManufacturer.uni"
+#include "./Type02/MiscBaseBoardManufacturer.uni"
+#include "./Type03/MiscChassisManufacturer.uni"
+#include "./Type13/MiscNumberOfInstallableLanguages.uni"
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni
new file mode 100644
index 000000000000..cf14e477d260
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni
@@ -0,0 +1,18 @@
+???// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+// --*/
+
+/=#
+
+#string STR_MISC_BIOS_VENDOR           #language en-US  "Not Specified"
+#string STR_MISC_BIOS_VERSION          #language en-US  "Not Specified"
+#string STR_MISC_BIOS_RELEASE_DATE     #language en-US  "Not Specified"
+#string STR_MISC_BIOS_VENDOR           #language en-US  "Not Specified"
+#string STR_MISC_BIOS_RELEASE_DATE     #language en-US  "01/01/2020"
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturer.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturer.uni
new file mode 100644
index 000000000000..417a5986c79e
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturer.uni
@@ -0,0 +1,21 @@
+???// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+// --*/
+
+/=#
+
+#string STR_MISC_SYSTEM_MANUFACTURER   #language en-US  "Not Specified"
+#string STR_MISC_SYSTEM_PRODUCT_NAME   #language en-US  "Not Specified"
+#string STR_MISC_SYSTEM_PRODUCT_NAME   #language en-US  "Not Specified"
+#string STR_MISC_SYSTEM_VERSION        #language en-US  "Not Specified"
+#string STR_MISC_SYSTEM_VERSION        #language en-US  "Not Specified"
+#string STR_MISC_SYSTEM_SERIAL_NUMBER  #language en-US  "Not Specified"
+#string STR_MISC_SYSTEM_SKU_NUMBER     #language en-US  "Not Specified"
+#string STR_MISC_SYSTEM_FAMILY         #language en-US  "Not Specified"
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturer.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturer.uni
new file mode 100644
index 000000000000..96398d837752
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturer.uni
@@ -0,0 +1,21 @@
+???// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+// --*/
+
+/=#
+
+#string STR_MISC_BASE_BOARD_MANUFACTURER     #language en-US  "Not Specified"
+#string STR_MISC_BASE_BOARD_PRODUCT_NAME     #language en-US  "Not Specified"
+#string STR_MISC_BASE_BOARD_PRODUCT_NAME     #language en-US  "Not Specified"
+#string STR_MISC_BASE_BOARD_VERSION          #language en-US  "Not Specified"
+#string STR_MISC_BASE_BOARD_VERSION          #language en-US  "Not Specified"
+#string STR_MISC_BASE_BOARD_SERIAL_NUMBER    #language en-US  "Not Specified"
+#string STR_MISC_BASE_BOARD_ASSET_TAG        #language en-US  "Not Specified"
+#string STR_MISC_BASE_BOARD_CHASSIS_LOCATION #language en-US  "Not Specified"
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturer.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturer.uni
new file mode 100644
index 000000000000..a2b9500f94c5
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturer.uni
@@ -0,0 +1,18 @@
+???// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+// --*/
+
+/=#
+
+#string STR_MISC_CHASSIS_MANUFACTURER  #language en-US  "Not Specified"
+#string STR_MISC_CHASSIS_VERSION       #language en-US  "Not Specified"
+#string STR_MISC_CHASSIS_SERIAL_NUMBER #language en-US  "Not Specified"
+#string STR_MISC_CHASSIS_ASSET_TAG     #language en-US  "Not Specified"
+#string STR_MISC_CHASSIS_SKU_NUMBER    #language en-US  "Not Specified"
diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguages.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguages.uni
new file mode 100644
index 000000000000..559003369f21
--- /dev/null
+++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguages.uni
@@ -0,0 +1,43 @@
+???// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
+// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
+// --*/
+
+/=#
+
+/=#
+//
+// Language String (Long Format)
+//
+#string STR_MISC_BIOS_LANGUAGES_ENG_LONG        #language en-US  "en|US|iso8859-1"
+#string STR_MISC_BIOS_LANGUAGES_FRA_LONG        #language en-US  "fr|CA|iso8859-1"
+#string STR_MISC_BIOS_LANGUAGES_CHN_LONG        #language en-US  "zh|TW|unicode"
+#string STR_MISC_BIOS_LANGUAGES_JPN_LONG        #language en-US  "ja|JP|unicode"
+#string STR_MISC_BIOS_LANGUAGES_ITA_LONG        #language en-US  "it|IT|iso8859-1"
+#string STR_MISC_BIOS_LANGUAGES_SPA_LONG        #language en-US  "es|ES|iso8859-1"
+#string STR_MISC_BIOS_LANGUAGES_GER_LONG        #language en-US  "de|DE|iso8859-1"
+#string STR_MISC_BIOS_LANGUAGES_POR_LONG        #language en-US  "pt|PT|iso8859-1"
+
+
+//
+// Language String (Abbreviated Format)
+//
+#string STR_MISC_BIOS_LANGUAGES_ENG_ABBREVIATE  #language en-US  "enUS"
+#string STR_MISC_BIOS_LANGUAGES_FRA_ABBREVIATE  #language en-US  "frCA"
+#string STR_MISC_BIOS_LANGUAGES_CHN_ABBREVIATE  #language en-US  "zhTW"
+#string STR_MISC_BIOS_LANGUAGES_JPN_ABBREVIATE  #language en-US  "jaJP"
+#string STR_MISC_BIOS_LANGUAGES_ITA_ABBREVIATE  #language en-US  "itIT"
+#string STR_MISC_BIOS_LANGUAGES_SPA_ABBREVIATE  #language en-US  "esES"
+#string STR_MISC_BIOS_LANGUAGES_GER_ABBREVIATE  #language en-US  "deDE"
+#string STR_MISC_BIOS_LANGUAGES_POR_ABBREVIATE  #language en-US  "ptPT"
+
+#string STR_MISC_BIOS_LANGUAGES_SIMPLECH_ABBREVIATE  #language en-US  "zhCN"
+#string STR_MISC_BIOS_LANGUAGES_SIMPLECH_LONG        #language en-US  "zh|CN|unicode"
+
+
-- 
2.26.2







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

* Re: [edk2-devel] [PATCH v3 3/3] ArmPkg: add Universal/Smbios as a generic SMBIOS library
  2020-11-16 13:43   ` [edk2-devel] " Sami Mujawar
@ 2020-11-17  3:27     ` Rebecca Cran
  0 siblings, 0 replies; 14+ messages in thread
From: Rebecca Cran @ 2020-11-17  3:27 UTC (permalink / raw)
  To: Sami Mujawar, devel@edk2.groups.io
  Cc: Leif Lindholm, Ard Biesheuvel, Michael D Kinney, Liming Gao,
	Zhiguang Liu, nd

On 11/16/20 6:43 AM, Sami Mujawar wrote:

> I have reviewed the following files from this patch and my responses are inline marked [SAMI].
>    ArmPkg/Include/Chipset/AArch64.h
>    ArmPkg/Include/Library/ArmLib.h
>    ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
>    ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
>    ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
>    ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
>    ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
>    ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm
>    ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
>    ArmPkg/Library/ArmLib/ArmLibPrivate.h
>
> Is it possible to split this patch into smaller patches, please? It will then be easier to review the remaining files.

Thanks! I've split the patch into much smaller changes and incorporated 
your fixes. I'll send out a v4 soon.


-- 
Rebecca Cran


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

* Re: [PATCH v3 1/3] ArmPkg: Add ARM SMC Architecture functions to ArmStdSmc.h
  2020-11-11  0:17 ` [PATCH v3 1/3] ArmPkg: Add ARM SMC Architecture functions to ArmStdSmc.h Rebecca Cran
  2020-11-12 21:49   ` [edk2-devel] " Sami Mujawar
@ 2020-11-19 12:00   ` Leif Lindholm
  1 sibling, 0 replies; 14+ messages in thread
From: Leif Lindholm @ 2020-11-19 12:00 UTC (permalink / raw)
  To: Rebecca Cran
  Cc: devel, Ard Biesheuvel, Michael D Kinney, Liming Gao, Zhiguang Liu

On Tue, Nov 10, 2020 at 17:17:46 -0700, Rebecca Cran wrote:
> The ARM SMC Architecture functions were missing from ArmStdSmc.h.
> Add them, based on the SMC Calling Convention version 1.2 specification.
> 
> Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
> ---
>  ArmPkg/Include/IndustryStandard/ArmStdSmc.h | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/ArmPkg/Include/IndustryStandard/ArmStdSmc.h b/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
> index 3509eb680f18..90f32c2249cd 100644
> --- a/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
> +++ b/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
> @@ -1,5 +1,6 @@
>  /** @file
>  *
> +*  Copyright (c) 2020, NUVIA Inc. All rights reserved.
>  *  Copyright (c) 2012-2017, ARM Limited. All rights reserved.
>  *
>  *  SPDX-License-Identifier: BSD-2-Clause-Patent
> @@ -52,6 +53,18 @@
>  #define ARM_SMC_MM_RET_DENIED              -3
>  #define ARM_SMC_MM_RET_NO_MEMORY           -4
>  
> +// ARM Architecture Calls
> +#define ARM_SMC_ID_ARCH_VERSION      0x80000000

This one does not actually contain "ARCH" in the spec, and it
references SMCCC version speficically.

> +#define ARM_SMC_ID_ARCH_FEATURES     0x80000001
> +#define ARM_SMC_ID_ARCH_SOC_ID       0x80000002
> +#define ARM_SMC_ID_ARCH_WORKAROUND_1 0x80008000
> +#define ARM_SMC_ID_ARCH_WORKAROUND_2 0x80007FFF

TF-A defines this whole block as:

#define SMCCC_VERSION                   U(0x80000000)
#define SMCCC_ARCH_FEATURES             U(0x80000001)
#define SMCCC_ARCH_SOC_ID               U(0x80000002)
#define SMCCC_ARCH_WORKAROUND_1         U(0x80008000)
#define SMCCC_ARCH_WORKAROUND_2         U(0x80007FFF)

I think I prefer these shorter versions, which also addresses the
abovementioned comment. (Not the U() bit, that's TF-A idiom.)

> +#define ARM_SMC_ARCH_RET_SUCCESS            0
> +#define ARM_SMC_ARCH_RET_NOT_SUPPORTED     -1
> +#define ARM_SMC_ARCH_RET_NOT_REQUIRED      -2
> +#define ARM_SMC_ARCH_RET_INVALID_PARAMETER -3

And these as:

#define SMC_ARCH_CALL_SUCCESS           0
#define SMC_ARCH_CALL_NOT_SUPPORTED     -1
#define SMC_ARCH_CALL_NOT_REQUIRED      -2
#define SMC_ARCH_CALL_INVAL_PARAM       -3

Not sure I prefer these, but I think we cold drop the ARM_ prefix.

/
    Leif


> +
>  /*
>   * Power State Coordination Interface (PSCI) calls cover a subset of the
>   * Standard Service Call range.
> -- 
> 2.26.2
> 

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

* Re: [PATCH v3 2/3] MdePkg: Update IndustryStandard/SmBios.h with processor status data
  2020-11-11  0:17 ` [PATCH v3 2/3] MdePkg: Update IndustryStandard/SmBios.h with processor status data Rebecca Cran
  2020-11-11  1:18   ` 回复: " gaoliming
  2020-11-13 11:25   ` [edk2-devel] " Sami Mujawar
@ 2020-11-19 12:05   ` Leif Lindholm
  2 siblings, 0 replies; 14+ messages in thread
From: Leif Lindholm @ 2020-11-19 12:05 UTC (permalink / raw)
  To: Rebecca Cran
  Cc: devel, Ard Biesheuvel, Michael D Kinney, Liming Gao, Zhiguang Liu

On Tue, Nov 10, 2020 at 17:17:47 -0700, Rebecca Cran wrote:
> Add a bitfield that describes the structure of the byte in the Status
> field of the SMBIOS Type 4 Processor Information table.
> 
> Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>

Reviewed-by: Leif Lindholm <leif@nuviainc.com>

> ---
>  MdePkg/Include/IndustryStandard/SmBios.h | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/MdePkg/Include/IndustryStandard/SmBios.h b/MdePkg/Include/IndustryStandard/SmBios.h
> index 1ee01645679a..bb4a3a8dc0d3 100644
> --- a/MdePkg/Include/IndustryStandard/SmBios.h
> +++ b/MdePkg/Include/IndustryStandard/SmBios.h
> @@ -875,6 +875,19 @@ typedef struct {
>    UINT16  ProcessorReserved2             :6;
>  } PROCESSOR_CHARACTERISTIC_FLAGS;
>  
> +///
> +/// Processor Information - Status
> +///
> +typedef union {
> +  struct {
> +    UINT8 CpuStatus       :3; // Indicates the status of the processor.
> +    UINT8 Reserved1       :3; // Reserved for future use. Should be set to zero.
> +    UINT8 SocketPopulated :1; // Indicates if the processor socket is populated or not.
> +    UINT8 Reserved2       :1; // Reserved for future use. Should be set to zero.
> +  } Bits;
> +  UINT8 Data;
> +} PROCESSOR_STATUS_DATA;
> +
>  typedef struct {
>    PROCESSOR_SIGNATURE     Signature;
>    PROCESSOR_FEATURE_FLAGS FeatureFlags;
> -- 
> 2.26.2
> 

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

* Re: [PATCH v3 3/3] ArmPkg: add Universal/Smbios as a generic SMBIOS library
  2020-11-11  0:17 ` [PATCH v3 3/3] ArmPkg: add Universal/Smbios as a generic SMBIOS library Rebecca Cran
  2020-11-16 13:43   ` [edk2-devel] " Sami Mujawar
@ 2020-11-19 12:58   ` Leif Lindholm
  2020-12-07  4:59     ` Rebecca Cran
  1 sibling, 1 reply; 14+ messages in thread
From: Leif Lindholm @ 2020-11-19 12:58 UTC (permalink / raw)
  To: Rebecca Cran
  Cc: devel, Ard Biesheuvel, Michael D Kinney, Liming Gao, Zhiguang Liu

On Tue, Nov 10, 2020 at 17:17:48 -0700, Rebecca Cran wrote:
> Much of the data for the SMBIOS tables is generic, and need not be
> duplicated for each platform.
> 
> Adapt code from edk2-platforms/Silicon/HiSilicon/Drivers/Smbios and
> edk2-platforms/Silicon/HiSilicon/Drivers/VersionInfoPeim, making them
> generic, and place them into edk2/ArmPkg/Universal/Smbios and
> edk2/ArmPkg/Drivers/VersionInfoPeim respectively.
> 
> They depend on each platform implementing an OemMiscLib that provides
> OEM specific information such as CPU and cache information.
> 
> The VersionInfoPeim generates the release date from the build time, and
> fetches the version string from PcdFirmwareVersionString.
> 
> Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
> ---
>  ArmPkg/ArmPkg.dec                             |  16 +
>  .../VersionInfoPeim/VersionInfoPeim.inf       |  46 ++
>  .../ProcessorSubClassDxe.inf                  |  55 ++
>  .../Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf    |  89 +++
>  ArmPkg/Include/Chipset/AArch64.h              |   4 +
>  ArmPkg/Include/Guid/VersionInfoHobGuid.h      |  29 +
>  ArmPkg/Include/Library/ArmLib.h               |   6 +
>  ArmPkg/Include/Library/OemMiscLib.h           |  86 +++
>  ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h    |   6 +
>  ArmPkg/Library/ArmLib/ArmLibPrivate.h         | 100 ++-
>  .../ProcessorSubClassDxe/ProcessorSubClass.h  |  34 +
>  .../Smbios/SmbiosMiscDxe/SmbiosMisc.h         | 217 ++++++
>  .../Drivers/VersionInfoPeim/VersionInfoPeim.c |  90 +++
>  ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c    |  15 +
>  ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c          |  17 +
>  .../ProcessorSubClassDxe/ProcessorSubClass.c  | 723 ++++++++++++++++++
>  .../SmbiosMiscDxe/SmbiosMiscDataTable.c       |  50 ++
>  .../SmbiosMiscDxe/SmbiosMiscEntryPoint.c      | 167 ++++
>  .../SmbiosMiscDxe/Type00/MiscBiosVendorData.c |  99 +++
>  .../Type00/MiscBiosVendorFunction.c           | 232 ++++++
>  .../Type01/MiscSystemManufacturerData.c       |  43 ++
>  .../Type01/MiscSystemManufacturerFunction.c   | 171 +++++
>  .../Type02/MiscBaseBoardManufacturerData.c    |  51 ++
>  .../MiscBaseBoardManufacturerFunction.c       | 184 +++++
>  .../Type03/MiscChassisManufacturerData.c      |  58 ++
>  .../Type03/MiscChassisManufacturerFunction.c  | 182 +++++
>  .../MiscNumberOfInstallableLanguagesData.c    |  39 +
>  ...MiscNumberOfInstallableLanguagesFunction.c | 154 ++++
>  .../Type32/MiscBootInformationData.c          |  41 +
>  .../Type32/MiscBootInformationFunction.c      |  66 ++
>  .../Library/ArmLib/AArch64/AArch64Support.S   |   3 +
>  .../Library/ArmLib/AArch64/ArmLibSupportV8.S  |   2 +-
>  ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S   |   4 +
>  ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm |   6 +-
>  .../ProcessorSubClassStrings.uni              |  23 +
>  .../SmbiosMiscDxe/SmbiosMiscLibString.uni     |  21 +
>  .../SmbiosMiscDxe/Type00/MiscBiosVendor.uni   |  18 +
>  .../Type01/MiscSystemManufacturer.uni         |  21 +
>  .../Type02/MiscBaseBoardManufacturer.uni      |  21 +
>  .../Type03/MiscChassisManufacturer.uni        |  18 +
>  .../MiscNumberOfInstallableLanguages.uni      |  43 ++
>  41 files changed, 3213 insertions(+), 37 deletions(-)

Please use --stat=1000 --stat-graph-width=20 when generating
patches, to avoid above ellipses.

>  create mode 100644 ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.inf
>  create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
>  create mode 100644 ArmPkg/Include/Guid/VersionInfoHobGuid.h
>  create mode 100644 ArmPkg/Include/Library/OemMiscLib.h
>  create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h
>  create mode 100644 ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.c
>  create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorData.c
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerData.c
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerFunction.c
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerData.c
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerFunction.c
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerData.c
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerFunction.c
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesData.c
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesFunction.c
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationData.c
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationFunction.c
>  create mode 100644 ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturer.uni
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturer.uni
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturer.uni
>  create mode 100644 ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguages.uni
> 
> diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
> index eaf1072d9ef3..64cfb7dc65e3 100644
> --- a/ArmPkg/ArmPkg.dec
> +++ b/ArmPkg/ArmPkg.dec
> @@ -45,6 +45,8 @@ [Guids.common]
>    # Include/Guid/ArmMpCoreInfo.h
>    gArmMpCoreInfoGuid = { 0xa4ee0728, 0xe5d7, 0x4ac5,  {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} }
>  
> +  gVersionInfoHobGuid = { 0xe13a14c, 0x859c, 0x4f22, {0x82, 0xbd, 0x18, 0xe, 0xe1, 0x42, 0x12, 0xbf } }

What version? FirmwareVersion? Would make sense to be explicit in the
name.

> +
>  [Protocols.common]
>    ## Arm System Control and Management Interface(SCMI) Base protocol
>    ## ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h
> @@ -115,6 +117,20 @@ [PcdsFixedAtBuild.common]
>    # The Primary Core is ClusterId[0] & CoreId[0]
>    gArmTokenSpaceGuid.PcdArmPrimaryCore|0|UINT32|0x00000037
>  
> +  #
> +  # SMBIOS PCDs
> +  #
> +  gArmTokenSpaceGuid.PcdSystemProductName|L""|VOID*|0x30000053
> +  gArmTokenSpaceGuid.PcdSystemVersion|L""|VOID*|0x30000054
> +  gArmTokenSpaceGuid.PcdBaseBoardManufacturer|L""|VOID*|0x30000055
> +  gArmTokenSpaceGuid.PcdBaseBoardProductName|L""|VOID*|0x30000056
> +  gArmTokenSpaceGuid.PcdBaseBoardVersion|L""|VOID*|0x30000057
> +  gArmTokenSpaceGuid.PcdProcessorManufacturer|L""|VOID*|0x30000071
> +  gArmTokenSpaceGuid.PcdProcessorVersion|L""|VOID*|0x30000072
> +  gArmTokenSpaceGuid.PcdProcessorSerialNumber|L""|VOID*|0x30000073
> +  gArmTokenSpaceGuid.PcdProcessorAssetTag|L""|VOID*|0x30000074
> +  gArmTokenSpaceGuid.PcdProcessorPartNumber|L""|VOID*|0x30000075
> +
>    #
>    # ARM L2x0 PCDs
>    #
> diff --git a/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.inf b/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.inf
> new file mode 100644
> index 000000000000..c813dd84de4c
> --- /dev/null
> +++ b/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.inf
> @@ -0,0 +1,46 @@
> +#/** @file
> +#
> +#    Copyright (c) 2016, Hisilicon Limited. All rights reserved.
> +#    Copyright (c) 2016, Linaro Limited. All rights reserved.
> +#
> +#    SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#**/
> +
> +[Defines]
> +  INF_VERSION                    = 1.29
> +  BASE_NAME                      = VersionInfoPeim
> +  FILE_GUID                      = 3d45d0a0-4ded-4c01-b16f-2b3007c1fbe2
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = VersionInfoEntry
> +
> +[Sources.common]
> +  VersionInfoPeim.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  HobLib
> +  PcdLib
> +  PeimEntryPoint
> +  PrintLib
> +  SerialPortLib
> +
> +[Pcd]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
> +
> +[Guids]
> +  gVersionInfoHobGuid
> +
> +[Depex]
> +  TRUE
> +
> +[BuildOptions]
> +
> diff --git a/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
> new file mode 100644
> index 000000000000..715f66912983
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
> @@ -0,0 +1,55 @@
> +#/** @file
> +#
> +#    Copyright (c) 2015, Hisilicon Limited. All rights reserved.
> +#    Copyright (c) 2015, Linaro Limited. All rights reserved.
> +#
> +#    SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#**/
> +
> +
> +[Defines]
> +  INF_VERSION                    = 1.29
> +  BASE_NAME                      = ProcessorSubClass
> +  FILE_GUID                      = f3fe0e33-ea38-4069-9fb5-be23407207c7
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = ProcessorSubClassEntryPoint
> +
> +[Sources]
> +  ProcessorSubClass.c
> +  ProcessorSubClassStrings.uni
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> +  ArmSmcLib
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  HiiLib
> +  IoLib
> +  MemoryAllocationLib
> +  OemMiscLib
> +  PcdLib
> +  PrintLib
> +  UefiDriverEntryPoint
> +
> +[Protocols]
> +  gEfiSmbiosProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
> +
> +[Pcd]
> +  gArmTokenSpaceGuid.PcdProcessorManufacturer
> +  gArmTokenSpaceGuid.PcdProcessorVersion
> +  gArmTokenSpaceGuid.PcdProcessorSerialNumber
> +  gArmTokenSpaceGuid.PcdProcessorAssetTag
> +  gArmTokenSpaceGuid.PcdProcessorPartNumber
> +
> +[Guids]
> +
> +
> +[Depex]
> +  gEfiSmbiosProtocolGuid
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
> new file mode 100644
> index 000000000000..1954f7207267
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
> @@ -0,0 +1,89 @@
> +## @file
> +# Component description file for SmbiosMisc instance.
> +#
> +# Parses the MiscSubclassDataTable and reports any generated data to the DataHub.
> +#  All .uni file who tagged with "ToolCode="DUMMY"" in following file list is included by
> +#  MiscSubclassDriver.uni file, the StrGather tool will expand MiscSubclassDriver.uni file
> +#  and parse all .uni file.
> +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +# Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +# Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +##
> +
> +
> +[Defines]
> +  INF_VERSION                    = 1.29
> +  BASE_NAME                      = SmbiosMiscDxe

Proper capitalisation is SmBios. Please get rid of any occurrences of
Smbios in the patch, including file names. (sorry)

> +  FILE_GUID                      = 7e5e26d4-0be9-401f-b5e1-1c2bda7ca777
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = SmbiosMiscEntryPoint
> +
> +[Sources]
> +  SmbiosMisc.h
> +  SmbiosMiscDataTable.c
> +  SmbiosMiscEntryPoint.c
> +  SmbiosMiscLibString.uni
> +  Type00/MiscBiosVendorData.c
> +  Type00/MiscBiosVendorFunction.c
> +  Type01/MiscSystemManufacturerData.c
> +  Type01/MiscSystemManufacturerFunction.c
> +  Type02/MiscBaseBoardManufacturerData.c
> +  Type02/MiscBaseBoardManufacturerFunction.c
> +  Type03/MiscChassisManufacturerData.c
> +  Type03/MiscChassisManufacturerFunction.c
> +  Type13/MiscNumberOfInstallableLanguagesData.c
> +  Type13/MiscNumberOfInstallableLanguagesFunction.c
> +  Type32/MiscBootInformationData.c
> +  Type32/MiscBootInformationFunction.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  DevicePathLib
> +  PcdLib
> +  HiiLib
> +  HobLib
> +  MemoryAllocationLib
> +  OemMiscLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +
> +[Protocols]
> +  gEfiSmbiosProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
> +
> +[Pcd]
> +  gArmTokenSpaceGuid.PcdFdSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareReleaseDateString
> +  gArmTokenSpaceGuid.PcdSystemProductName
> +  gArmTokenSpaceGuid.PcdSystemVersion
> +  gArmTokenSpaceGuid.PcdBaseBoardManufacturer
> +  gArmTokenSpaceGuid.PcdBaseBoardProductName
> +  gArmTokenSpaceGuid.PcdBaseBoardVersion
> +  gArmTokenSpaceGuid.PcdFdBaseAddress
> +
> +  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang
> +
> +[Guids]
> +  gEfiGenericVariableGuid
> +  gVersionInfoHobGuid
> +
> +[Depex]
> +  gEfiSmbiosProtocolGuid
> +
> +
> diff --git a/ArmPkg/Include/Chipset/AArch64.h b/ArmPkg/Include/Chipset/AArch64.h
> index 0ade5cce91c3..7c2b592f92ee 100644
> --- a/ArmPkg/Include/Chipset/AArch64.h
> +++ b/ArmPkg/Include/Chipset/AArch64.h
> @@ -112,6 +112,10 @@
>  #define ARM_VECTOR_LOW_A32_FIQ  0x700
>  #define ARM_VECTOR_LOW_A32_SERR 0x780
>  
> +// The ID_AA64MMFR2_EL1 register was added in ARMv8.2. Since we
> +// build for ARMv8.0, we need to define the register here.
> +#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
> +
>  #define VECTOR_BASE(tbl)          \
>    .section .text.##tbl##,"ax";    \
>    .align 11;                      \
> diff --git a/ArmPkg/Include/Guid/VersionInfoHobGuid.h b/ArmPkg/Include/Guid/VersionInfoHobGuid.h
> new file mode 100644
> index 000000000000..9eeb0a5f7482
> --- /dev/null
> +++ b/ArmPkg/Include/Guid/VersionInfoHobGuid.h
> @@ -0,0 +1,29 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
> +*  Copyright (c) 2016, Linaro Limited. All rights reserved.
> +*
> +*  SPDX-License-Identifier: BSD-2-Clause-Patent
> +*
> +**/
> +
> +#ifndef _VERSION_INFO_HOB_GUID_H_
> +#define _VERSION_INFO_HOB_GUID_H_

No leading _ in macros.

> +
> +// {0E13A14C-859C-4f22-82BD-180EE14212BF}
> +#define VERSION_INFO_HOB_GUID \
> +  {0xe13a14c, 0x859c, 0x4f22, {0x82, 0xbd, 0x18, 0xe, 0xe1, 0x42, 0x12, 0xbf}}
> +
> +extern GUID gVersionInfoHobGuid;
> +
> +#pragma pack(1)
> +
> +typedef struct {
> +  EFI_TIME BuildTime;
> +  CHAR16   String[1];
> +} VERSION_INFO;
> +
> +#pragma pack()
> +
> +#endif
> +
> diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h
> index 5a27b7c2fc27..4a740b6ca298 100644
> --- a/ArmPkg/Include/Library/ArmLib.h
> +++ b/ArmPkg/Include/Library/ArmLib.h
> @@ -132,6 +132,12 @@ ArmIsArchTimerImplemented (
>    VOID
>    );
>  
> +UINTN
> +EFIAPI
> +ArmIsCcidxImplemented (
> +  VOID
> +  );
> +
>  UINTN
>  EFIAPI
>  ArmReadIdPfr0 (
> diff --git a/ArmPkg/Include/Library/OemMiscLib.h b/ArmPkg/Include/Library/OemMiscLib.h
> new file mode 100644
> index 000000000000..78dc70426e24
> --- /dev/null
> +++ b/ArmPkg/Include/Library/OemMiscLib.h
> @@ -0,0 +1,86 @@
> +/** @file
> +*
> +*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
> +*  Copyright (c) 2015, Linaro Limited. All rights reserved.
> +*
> +*  SPDX-License-Identifier: BSD-2-Clause-Patent
> +*
> +**/
> +
> +
> +#ifndef OEM_MISC_LIB_H
> +#define OEM_MISC_LIB_H
> +
> +#include <Uefi.h>
> +#include <IndustryStandard/SmBios.h>
> +
> +typedef enum
> +{
> +  CPU_CACHE_L1 = 0,
> +  CPU_CACHE_L2,
> +  CPU_CACHE_L3,
> +  CPU_CACHE_L4,
> +  CPU_CACHE_L5,
> +  CPU_CACHE_L6,
> +  CPU_CACHE_L7
> +} CPU_CACHE_LEVEL;
> +
> +typedef struct
> +{
> +  UINT8 Voltage;
> +  UINT16 CurrentSpeed;
> +  UINT16 MaxSpeed;
> +  UINT16 ExternalClock;
> +  UINT16 CoreCount;
> +  UINT16 CoresEnabled;
> +  UINT16 ThreadCount;
> +} MISC_PROCESSOR_DATA;
> +
> +typedef enum {
> +    ProductNameType01,
> +    SerialNumType01,
> +    UuidType01,
> +    SystemManufacturerType01,
> +    AssertTagType02,
> +    SrNumType02,
> +    BoardManufacturerType02,
> +    AssetTagType03,
> +    SrNumType03,
> +    VersionType03,
> +    ChassisTypeType03 ,
> +    ManufacturerType03,
> +} GET_INFO_BMC_OFFSET;
> +
> +UINTN OemGetCpuFreq (UINT8 Socket);
> +
> +BOOLEAN
> +OemGetProcessorInformation (
> +  IN UINTN ProcessorNumber,
> +  IN OUT PROCESSOR_STATUS_DATA *ProcessorStatus,
> +  IN OUT PROCESSOR_CHARACTERISTIC_FLAGS *ProcessorCharacteristics,
> +  IN OUT MISC_PROCESSOR_DATA *MiscProcessorData
> +  );
> +
> +BOOLEAN OemGetCacheInformation (
> +  IN UINT8 CacheLevel,
> +  IN OUT SMBIOS_TABLE_TYPE7 *SmbiosCacheTable
> +  );
> +
> +UINT8 OemGetProcessorMaxSockets (VOID);
> +
> +UINTN PlatformGetCpuFreq (IN UINT8 Socket);

Where is this function defined?

> +
> +UINTN PlatformGetCoreCount (VOID);
> +
> +EFI_STATUS OemGetChassisType(OUT UINT8 *ChassisType);
> +
> +BOOLEAN OemIsSocketPresent (UINTN Socket);
> +
> +VOID
> +UpdateSmbiosInfo (
> +  IN EFI_HII_HANDLE mHiiHandle,
> +  IN EFI_STRING_ID TokenToUpdate,
> +  IN UINT8 Offset
> +  );
> +
> +#endif // OEM_MISC_LIB_H
> diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
> index b2c8a8ea0b84..d6bcfc3b82ae 100644
> --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
> +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
> @@ -35,5 +35,11 @@ ArmCleanInvalidateDataCacheEntryBySetWay (
>    IN  UINTN   SetWayFormat
>    );
>  
> +UINTN
> +EFIAPI
> +ArmReadIdMmfr2 (
> +  VOID
> +  );
> +
>  #endif // __AARCH64_LIB_H__
>  
> diff --git a/ArmPkg/Library/ArmLib/ArmLibPrivate.h b/ArmPkg/Library/ArmLib/ArmLibPrivate.h
> index 2e90739eb858..d57c80edb572 100644
> --- a/ArmPkg/Library/ArmLib/ArmLibPrivate.h
> +++ b/ArmPkg/Library/ArmLib/ArmLibPrivate.h

Changes to this file in general seem to be removing unused(?) existing
cache-related macros and adding (architectural) special
purposeregister descriptions as replacements. This feels like two
separate changes (and hence patches).

> @@ -9,46 +9,76 @@
>  #ifndef __ARM_LIB_PRIVATE_H__
>  #define __ARM_LIB_PRIVATE_H__
>  
> -#define CACHE_SIZE_4_KB             (3UL)
> -#define CACHE_SIZE_8_KB             (4UL)
> -#define CACHE_SIZE_16_KB            (5UL)
> -#define CACHE_SIZE_32_KB            (6UL)
> -#define CACHE_SIZE_64_KB            (7UL)
> -#define CACHE_SIZE_128_KB           (8UL)
> +typedef union {
> +  struct {
> +    UINT32    InD           :1;
> +    UINT32    Level         :3;
> +    UINT32    TnD           :1;
> +    UINT32    Reserved      :27;
> +  } Bits;
> +  UINT32 Data;
> +} CSSELR_DATA;
>  
> -#define CACHE_ASSOCIATIVITY_DIRECT  (0UL)
> -#define CACHE_ASSOCIATIVITY_4_WAY   (2UL)
> -#define CACHE_ASSOCIATIVITY_8_WAY   (3UL)
> +typedef enum
> +{
> +  CSSELR_CACHE_TYPE_DATA_OR_UNIFIED = 0,
> +  CSSELR_CACHE_TYPE_INSTRUCTION = 1
> +} CSSELR_CACHE_TYPE;
>  
> -#define CACHE_PRESENT               (0UL)
> -#define CACHE_NOT_PRESENT           (1UL)
> +typedef union {
> +  struct {
> +    UINT64    LineSize           :3;
> +    UINT64    Associativity      :10;
> +    UINT64    NumSets            :15;
> +    UINT64    Unknown            :4;
> +    UINT64    Reserved           :32;
> +  } BitsNonCcidx;
> +  struct {
> +    UINT64    LineSize           :3;
> +    UINT64    Associativity      :21;
> +    UINT64    Reserved1          :8;
> +    UINT64    NumSets            :24;
> +    UINT64    Reserved2          :8;
> +  } BitsCcidx;
> +  UINT64 Data;
> +} CCSIDR_DATA;
>  
> -#define CACHE_LINE_LENGTH_32_BYTES  (2UL)
> +typedef union {
> +  struct {
> +    UINT32 NumSets               :24;
> +    UINT32 Reserved              :8;
> +  } Bits;
> +  UINT32 Data;
> +} CSSIDR2_DATA;
>  
> -#define SIZE_FIELD_TO_CACHE_SIZE(x)           (((x) >> 6) & 0x0F)
> -#define SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(x)  (((x) >> 3) & 0x07)
> -#define SIZE_FIELD_TO_CACHE_PRESENCE(x)       (((x) >> 2) & 0x01)
> -#define SIZE_FIELD_TO_CACHE_LINE_LENGTH(x)    (((x) >> 0) & 0x03)
> +// The lower 32 bits are the same for both AARCH32 and AARCH64
> +// so we can use the same structure for both.
> +typedef union {
> +  struct {
> +    UINT32    Ctype1   : 3;
> +    UINT32    Ctype2   : 3;
> +    UINT32    Ctype3   : 3;
> +    UINT32    Ctype4   : 3;
> +    UINT32    Ctype5   : 3;
> +    UINT32    Ctype6   : 3;
> +    UINT32    Ctype7   : 3;
> +    UINT32    LoUIS    : 3;
> +    UINT32    LoC      : 3;
> +    UINT32    LoUU     : 3;
> +    UINT32    Icb      : 3;
> +  } Bits;
> +  UINT32 Data;
> +} CLIDR_DATA;
>  
> -#define DATA_CACHE_SIZE_FIELD(x)              (((x) >> 12) & 0x0FFF)
> -#define INSTRUCTION_CACHE_SIZE_FIELD(x)       (((x) >>  0) & 0x0FFF)
> +typedef enum {
> +  CLIDR_CACHE_TYPE_NONE = 0,
> +  CLIDR_CACHE_TYPE_INSTRUCTION_ONLY = 1,
> +  CLIDR_CACHE_TYPE_DATA_ONLY = 2,
> +  CLIDR_CACHE_TYPE_SEPARATE = 3,
> +  CLIDR_CACHE_TYPE_UNIFIED = 4
> +} CLIDR_CACHE_TYPE;
>  
> -#define DATA_CACHE_SIZE(x)                    (SIZE_FIELD_TO_CACHE_SIZE(DATA_CACHE_SIZE_FIELD(x)))
> -#define DATA_CACHE_ASSOCIATIVITY(x)           (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(DATA_CACHE_SIZE_FIELD(x)))
> -#define DATA_CACHE_PRESENT(x)                 (SIZE_FIELD_TO_CACHE_PRESENCE(DATA_CACHE_SIZE_FIELD(x)))
> -#define DATA_CACHE_LINE_LENGTH(x)             (SIZE_FIELD_TO_CACHE_LINE_LENGTH(DATA_CACHE_SIZE_FIELD(x)))
> -
> -#define INSTRUCTION_CACHE_SIZE(x)             (SIZE_FIELD_TO_CACHE_SIZE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
> -#define INSTRUCTION_CACHE_ASSOCIATIVITY(x)    (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(INSTRUCTION_CACHE_SIZE_FIELD(x)))
> -#define INSTRUCTION_CACHE_PRESENT(x)          (SIZE_FIELD_TO_CACHE_PRESENCE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
> -#define INSTRUCTION_CACHE_LINE_LENGTH(x)      (SIZE_FIELD_TO_CACHE_LINE_LENGTH(INSTRUCTION_CACHE_SIZE_FIELD(x)))
> -
> -#define CACHE_TYPE(x)                         (((x) >> 25) & 0x0F)
> -#define CACHE_TYPE_WRITE_BACK                 (0x0EUL)
> -
> -#define CACHE_ARCHITECTURE(x)                 (((x) >> 24) & 0x01)
> -#define CACHE_ARCHITECTURE_UNIFIED            (0UL)
> -#define CACHE_ARCHITECTURE_SEPARATE           (1UL)
> +#define CLIDR_GET_CACHE_TYPE(x, level) ((x >> (3 * level)) & 0b111)
>  
>  VOID
>  CPSRMaskInsert (
> @@ -61,7 +91,7 @@ CPSRRead (
>    VOID
>    );
>  
> -UINT32
> +UINTN
>  ReadCCSIDR (
>    IN UINT32 CSSELR
>    );
> diff --git a/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h
> new file mode 100644
> index 000000000000..a8a4ab2b1beb
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.h
> @@ -0,0 +1,34 @@
> +/** @file
> +*
> +*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
> +*  Copyright (c) 2015, Linaro Limited. All rights reserved.
> +*
> +*  SPDX-License-Identifier: BSD-2-Clause-Patent
> +*
> +**/
> +
> +#ifndef PROCESSOR_SUBCLASS_DRIVER_H
> +#define PROCESSOR_SUBCLASS_DRIVER_H
> +
> +#include <Uefi.h>
> +#include <Protocol/Smbios.h>
> +#include <IndustryStandard/ArmStdSmc.h>
> +#include <IndustryStandard/SmBios.h>
> +#include <Library/ArmLib.h>
> +#include <Library/ArmSmcLib.h>
> +#include <Library/ArmLib/ArmLibPrivate.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/OemMiscLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +
> +extern UINT8 ProcessorSubClassStrings[];
> +
> +#endif // PROCESSOR_SUBCLASS_DRIVER_H
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h
> new file mode 100644
> index 000000000000..80c77517fabc
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h
> @@ -0,0 +1,217 @@
> +/**@file
> +
> +Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  SmbiosMisc.h
> +
> +Abstract:
> +
> +  Header file for the SmbiosMisc Driver.
> +
> +Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +**/
> +
> +#ifndef SMBIOS_MISC_DRIVER_H
> +#define SMBIOS_MISC_DRIVER_H
> +
> +#include <Protocol/Smbios.h>
> +#include <IndustryStandard/SmBios.h>
> +#include <Library/HiiLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Guid/DebugMask.h>
> +#include <Library/OemMiscLib.h>
> +
> +#include <Library/PrintLib.h>
> +
> +//
> +// Data table entry update function.
> +//
> +typedef EFI_STATUS (EFIAPI EFI_MISC_SMBIOS_DATA_FUNCTION) (
> +  IN  VOID                 *RecordData,
> +  IN  EFI_SMBIOS_PROTOCOL  *Smbios
> +  );
> +
> +
> +//
> +// Data table entry definition.
> +//
> +typedef struct {
> +  //
> +  // intermediate input data for SMBIOS record
> +  //
> +  VOID                              *RecordData;
> +  EFI_MISC_SMBIOS_DATA_FUNCTION     *Function;
> +} EFI_MISC_SMBIOS_DATA_TABLE;
> +
> +
> +//
> +// Data Table extern definitions.
> +//
> +#define MISC_SMBIOS_TABLE_EXTERNS(NAME1, NAME2, NAME3) \
> +extern NAME1 NAME2 ## Data; \
> +extern EFI_MISC_SMBIOS_DATA_FUNCTION NAME3 ## Function;
> +
> +
> +//
> +// Data Table entries
> +//
> +
> +#define MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(NAME1, NAME2) \
> +{ \
> +  & NAME1 ## Data, \

Eew.
This is quite possibly very useful, but that '&' made me swear out
loud. Add a comment describing how this is used further down?

> +    NAME2 ## Function \
> +}
> +
> +
> +//
> +// Global definition macros.
> +//
> +#define MISC_SMBIOS_TABLE_DATA(NAME1, NAME2) \
> +  NAME1 NAME2 ## Data
> +
> +#define MISC_SMBIOS_TABLE_FUNCTION(NAME2) \
> +  EFI_STATUS EFIAPI NAME2 ## Function( \
> +  IN  VOID                  *RecordData, \
> +  IN  EFI_SMBIOS_PROTOCOL   *Smbios \
> +  )
> +
> +//
> +// Data Table Array Entries
> +//
> +extern EFI_HII_HANDLE               mHiiHandle;
> +
> +typedef struct _EFI_TYPE11_OEM_STRING{
> +  UINT8                               Offset;
> +  EFI_STRING_ID                       RefOemDefineString;
> +} EFI_TYPE11_OEM_STRING;
> +
> +typedef struct _EFI_TYPE12_SYSTEM_CONFIGURATION_OPTIONS_STRING{
> +  UINT8                               Offset;
> +  EFI_STRING_ID                       RefType12SystemConfigurationOptionsString;
> +} EFI_TYPE12_SYSTEM_CONFIGURATION_OPTIONS_STRING;
> +
> +typedef struct _EFI_TYPE13_BIOS_LANGUAGE_INFORMATION_STRING{
> +  UINT8                               *LanguageSignature;
> +  EFI_STRING_ID                       InstallableLanguageLongString;
> +  EFI_STRING_ID                       InstallableLanguageAbbreviateString;
> +} EFI_TYPE13_BIOS_LANGUAGE_INFORMATION_STRING;
> +
> +typedef struct _EFI_TYPE40_ADDITIONAL_INFORMATION_ENTRY{
> +  UINT8           RefType;
> +  UINT8           RefOffset;
> +  EFI_STRING_ID   RefString;
> +  UINT8           Value;
> +} EFI_TYPE40_ADDITIONAL_INFORMATION_ENTRY;
> +
> +typedef enum {
> +  STRING,
> +  DATA,
> +} OEM_DEFINE_TYPE;
> +
> +typedef struct {
> +  OEM_DEFINE_TYPE                Type;
> +  UINTN                          Token;
> +  UINTN                          DataSize;
> +} OEM_DEFINE_INFO_STRING;
> +
> +typedef struct {
> +  OEM_DEFINE_TYPE                Type;
> +  UINTN                          DataAddress;
> +  UINTN                          DataSize;
> +} OEM_DEFINE_INFO_DATA;
> +
> +typedef union {
> +  OEM_DEFINE_INFO_STRING         DefineString;
> +  OEM_DEFINE_INFO_DATA           DefineData;
> +} EFI_OEM_DEFINE_ARRAY;
> +
> +typedef struct _DMI_STRING_STRUCTURE {
> +  UINT8                                 Type;
> +  UINT8                                 Offset;
> +  UINT8                                 Valid;
> +  UINT16                                Length;
> +  UINT8                                 String[1]; // Variable length field
> +} DMI_STRING_STRUCTURE;
> +
> +typedef struct {
> +  UINT8                                 Type;           // The SMBIOS structure type
> +  UINT8                                 FixedOffset;    // The offset of the string reference
> +                                                        // within the structure's fixed data.
> +} DMI_UPDATABLE_STRING;
> +
> +EFI_STATUS
> +FindString (
> +  IN UINT8                              Type,
> +  IN UINT8                              Offset,
> +  IN EFI_STRING_ID                      TokenToUpdate
> +);
> +
> +EFI_STATUS
> +FindUuid (
> +  EFI_GUID                    *Uuid
> +);
> +
> +EFI_STATUS
> +StringToBiosVeriosn (
> +  IN  EFI_STRING_ID                     BiosVersionToken,
> +  OUT UINT8                             *MajorVersion,
> +  OUT UINT8                             *MinorVersion
> +);
> +
> +
> +/**
> + Logs SMBIOS record.
> +
> + @param [in]   Buffer         Pointer to the data buffer.
> + @param [in]   SmbiosHandle   Pointer for retrieve handle.
> +
> +**/
> +EFI_STATUS
> +LogSmbiosData (
> +  IN       UINT8                      *Buffer,
> +  IN  OUT  EFI_SMBIOS_HANDLE          *SmbiosHandle
> +  );
> +
> +/**
> + Get Link Type Handle.
> +
> + @param [in]   SmbiosType     Get this Type from SMBIOS table
> + @param [out]  HandleArray    Pointer to Hadndler array with has been free by caller
> + @param [out]  HandleCount    Pointer to Hadndler Counter
> +
> +**/
> +VOID
> +GetLinkTypeHandle(
> +  IN  UINT8                 SmbiosType,
> +  OUT UINT16                **HandleArray,
> +  OUT UINTN                 *HandleCount
> +  );
> +
> +//
> +// Data Table Array
> +//
> +extern EFI_MISC_SMBIOS_DATA_TABLE   mSmbiosMiscDataTable[];
> +
> +//
> +// Data Table Array Entries
> +//
> +extern UINTN                        mSmbiosMiscDataTableEntries;
> +
> +extern UINT8                        SmbiosMiscDxeStrings[];

Should also have m-prefix?

> +
> +
> +
> +#endif // SMBIOS_MISC_DRIVER_H
> diff --git a/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.c b/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.c
> new file mode 100644
> index 000000000000..5b5dc47e7ea9
> --- /dev/null
> +++ b/ArmPkg/Drivers/VersionInfoPeim/VersionInfoPeim.c
> @@ -0,0 +1,90 @@
> +/** @file
> +*
> +*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
> +*  Copyright (c) 2016, Linaro Limited. All rights reserved.
> +*
> +*  SPDX-License-Identifier: BSD-2-Clause-Patent
> +*
> +**/
> +
> +#include <Uefi.h>
> +#include <PiPei.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/SerialPortLib.h>
> +
> +#include <Guid/VersionInfoHobGuid.h>
> +
> +struct MonthDescription {
> +  CONST CHAR8* MonthStr;
> +  UINT32    MonthInt;
> +} gMonthDescription[] = {

Not used in any other file - use m prefix over g?

> +  { "Jan", 1 },
> +  { "Feb", 2 },
> +  { "Mar", 3 },
> +  { "Apr", 4 },
> +  { "May", 5 },
> +  { "Jun", 6 },
> +  { "Jul", 7 },
> +  { "Aug", 8 },
> +  { "Sep", 9 },
> +  { "Oct", 10 },
> +  { "Nov", 11 },
> +  { "Dec", 12 },
> +  { "???", 1 },  // Use 1 as default month
> +};
> +
> +VOID GetReleaseTime (EFI_TIME *Time)
> +{
> +  CONST CHAR8      *ReleaseDate = __DATE__;
> +  CONST CHAR8      *ReleaseTime = __TIME__;
> +  UINTN            i;
> +
> +  for (i = 0;i < 12;i++) {
> +    if (AsciiStrnCmp (ReleaseDate, gMonthDescription[i].MonthStr, 3) == 0) {
> +      break;
> +    }
> +  }
> +
> +  Time->Month = gMonthDescription[i].MonthInt;
> +  Time->Day = AsciiStrDecimalToUintn(ReleaseDate+4);
> +  Time->Year = AsciiStrDecimalToUintn(ReleaseDate+7);
> +  Time->Hour = AsciiStrDecimalToUintn(ReleaseTime);
> +  Time->Minute = AsciiStrDecimalToUintn(ReleaseTime+3);
> +  Time->Second = AsciiStrDecimalToUintn(ReleaseTime+6);
> +
> +  return;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +VersionInfoEntry (
> +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  )
> +{
> +  VERSION_INFO *VersionInfo;
> +  EFI_TIME Time = {0};
> +  CONST CHAR16 *ReleaseString =
> +    (CHAR16 *) FixedPcdGetPtr (PcdFirmwareVersionString);

No space after cast.

> +
> +  GetReleaseTime (&Time);
> +
> +  VersionInfo = BuildGuidHob (&gVersionInfoHobGuid,
> +                      sizeof (VERSION_INFO) -
> +                      sizeof (VersionInfo->String) +
> +                      StrSize (ReleaseString));

Indentation looks wrong.

> +  if (VersionInfo == NULL) {
> +    DEBUG ((DEBUG_ERROR, "[%a]:[%d] Build HOB failed!\n", __FILE__, __LINE__));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  CopyMem (&VersionInfo->BuildTime, &Time, sizeof (EFI_TIME));
> +  CopyMem (VersionInfo->String, ReleaseString, StrSize (ReleaseString));
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
> index 3fbd591192e2..134fe56cb387 100644
> --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
> +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
> @@ -71,3 +71,18 @@ ArmCleanDataCache (
>    ArmDataSynchronizationBarrier ();
>    AArch64DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
>  }
> +
> +UINTN
> +EFIAPI
> +ArmIsCcidxImplemented (
> +  VOID
> +  )
> +{
> +  UINTN Mmfr2;
> +
> +  Mmfr2 = ArmReadIdMmfr2 ();
> +  if (((Mmfr2 >> 20) & 0xF) == 1)
> +    return 1;
> +
> +  return 0;
> +}
> diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
> index 2c4a23e1a1b2..4466e39dcc28 100644
> --- a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
> +++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
> @@ -71,3 +71,20 @@ ArmCleanDataCache (
>    ArmDataSynchronizationBarrier ();
>    ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
>  }
> +
> +UINTN
> +EFIAPI
> +ArmIsCcidxImplemented (
> +  VOID
> +  )
> +{
> +  UINTN Mmfr4;
> +  
> +  Mmfr4 = ArmReadIdMmfr4 ();
> +  if (((Mmfr4 >> 24) & 0xF) == 1) {
> +    return 1;
> +  }
> +
> +  return 0;
> +}
> +
> diff --git a/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c
> new file mode 100644
> index 000000000000..2b29945ce966
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c
> @@ -0,0 +1,723 @@
> +/** @file
> +*
> +*  Copyright (c) 2020, NUVIA Inc. All rights reserved.
> +*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
> +*  Copyright (c) 2015, Linaro Limited. All rights reserved.
> +*
> +*  SPDX-License-Identifier: BSD-2-Clause-Patent
> +*
> +**/
> +
> +#include "ProcessorSubClass.h"
> +
> +EFI_HII_HANDLE                  mHiiHandle;
> +
> +EFI_SMBIOS_PROTOCOL             *mSmbios;
> +
> +SMBIOS_TABLE_TYPE4   mSmbiosProcessorTable[] = {
> +  //CPU0
> +  {
> +    {                                               //Header
> +      EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION,          //Type
> +      sizeof (SMBIOS_TABLE_TYPE4),                    //Length
> +      0                                               //Handle
> +    },
> +    1,                                              //Socket
> +    CentralProcessor,                               //ProcessorType
> +    ProcessorFamilyIndicatorFamily2,                //ProcessorFamily
> +    2,                                              //ProcessorManufacture
> +    {                                               //ProcessorId
> +      {                                               //Signature
> +        0
> +      },
> +      {                                               //FeatureFlags
> +        0
> +      }
> +    },
> +    3,                                              //ProcessorVersion
> +    {                                               //Voltage
> +      0
> +    },
> +    0,                                              //ExternalClock
> +    0,                                              //MaxSpeed
> +    0,                                              //CurrentSpeed
> +    0,                                              //Status
> +    ProcessorUpgradeUnknown,                        //ProcessorUpgrade
> +    0xFFFF,                                         //L1CacheHandle
> +    0xFFFF,                                         //L2CacheHandle
> +    0xFFFF,                                         //L3CacheHandle
> +    4,                                              //SerialNumber
> +    5,                                              //AssetTag
> +    6,                                              //PartNumber
> +    0,                                              //CoreCount
> +    0,                                              //EnabledCoreCount
> +    0,                                              //ThreadCount
> +    0,                                              //ProcessorCharacteristics
> +    ProcessorFamilyARM,                             //ProcessorFamily2
> +    0,                                              //CoreCount2
> +    0,                                              //EnabledCoreCount2
> +    0                                               //ThreadCount2
> +  },
> +
> +  //CPU1
> +  {
> +    {                                               //Header
> +      EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION,          //Type
> +      sizeof (SMBIOS_TABLE_TYPE4),                    //Length
> +      0                                               //Handle
> +    },
> +    1,                                              //Socket
> +    CentralProcessor,                               //ProcessorType
> +    ProcessorFamilyIndicatorFamily2,                //ProcessorFamily
> +    2,                                              //ProcessorManufacture
> +    {                                               //ProcessorId
> +      {                                               //Signature
> +        0
> +      },
> +      {                                               //FeatureFlags
> +        0
> +      }
> +    },
> +    3,                                              //ProcessorVersion
> +    {                                               //Voltage
> +      0
> +    },
> +    0,                                              //ExternalClock
> +    0,                                              //MaxSpeed
> +    0,                                              //CurrentSpeed
> +    0,                                              //Status
> +    ProcessorUpgradeUnknown,                        //ProcessorUpgrade
> +    0xFFFF,                                         //L1CacheHandle
> +    0xFFFF,                                         //L2CacheHandle
> +    0xFFFF,                                         //L3CacheHandle
> +    4,                                              //SerialNumber
> +    5,                                              //AssetTag
> +    6,                                              //PartNumber
> +    0,                                              //CoreCount
> +    0,                                              //EnabledCoreCount
> +    0,                                              //ThreadCount
> +    0,                                              //ProcessorCharacteristics
> +    ProcessorFamilyARMv8,                           //ProcessorFamily2
> +    0,                                              //CoreCount2
> +    0,                                              //EnabledCoreCount2
> +    0                                               //ThreadCount2
> +  }
> +};
> +
> +
> +UINT16
> +GetCpuFrequency (
> +  IN  UINT8 ProcessorNumber
> +)

indent )

> +{
> +  return (UINT16)(PlatformGetCpuFreq (ProcessorNumber)/1000/1000);
> +}
> +
> +UINTN
> +GetCacheSocketStr (
> +  IN  UINT8     CacheLevel,
> +  IN  UINT8     CacheSubLevel,
> +  OUT CHAR16    *CacheSocketStr
> +  )
> +{
> +  UINTN CacheSocketStrLen;
> +
> +  if (CacheLevel == CPU_CACHE_L1 && CacheSubLevel == 0) {
> +    CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Instruction Cache", CacheLevel + 1);
> +  } else if (CacheLevel == CPU_CACHE_L1 && CacheSubLevel == 1) {
> +    CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Data Cache", CacheLevel + 1);
> +  } else {
> +    CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Cache", CacheLevel + 1);
> +  }
> +
> +  return CacheSocketStrLen;
> +}
> +
> +/**
> +  Add Type 7 SMBIOS Record for Cache Information.
> +
> +  @param[in]    ProcessorNumber     Processor number of specified processor.
> +  @param[out]   L1CacheHandle       Pointer to the handle of the L1 Cache SMBIOS record.
> +  @param[out]   L2CacheHandle       Pointer to the handle of the L2 Cache SMBIOS record.
> +  @param[out]   L3CacheHandle       Pointer to the handle of the L3 Cache SMBIOS record.
> +
> +**/
> +EFI_STATUS
> +AddSmbiosCacheTypeTable (
> +  IN UINTN                  ProcessorNumber,
> +  OUT EFI_SMBIOS_HANDLE     *L1CacheHandle,
> +  OUT EFI_SMBIOS_HANDLE     *L2CacheHandle,
> +  OUT EFI_SMBIOS_HANDLE     *L3CacheHandle
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  SMBIOS_TABLE_TYPE7          *Type7Record;
> +  EFI_SMBIOS_HANDLE           SmbiosHandle;
> +  UINTN                       TableSize;
> +  UINT8                       CacheLevel;
> +  UINT8                       CacheSubLevel;
> +  CHAR8                       *OptionalStrStart;
> +  EFI_STRING                  CacheSocketStr;
> +  UINTN                       CacheSocketStrLen;
> +  UINTN                       StringBufferSize;
> +
> +  CLIDR_DATA                  Clidr;
> +  CSSELR_DATA                 Csselr;
> +  CCSIDR_DATA                 Ccsidr;
> +
> +  UINT16                      CacheSize16;
> +  UINT32                      CacheSize32;
> +  UINT64                      CacheSize64;
> +  BOOLEAN                     CcidxSupported;
> +  UINT32                      Associativity;
> +  UINT8                       MaxCacheLevel;

The list of local variables tell me this function is going to be too
long and needs to be split up into helpers.

> +
> +  CONST UINT8                 MAX_ARM_CACHE_LEVEL = 7;

This needs to be a #define somewhere under ArmPkg/Include.

> +
> +  Status = EFI_SUCCESS;
> +
> +  MaxCacheLevel = 0;
> +
> +  // Read the CLIDR register to find out what caches are present.
> +  Clidr.Data = ReadCLIDR ();
> +
> +  // Get the cache type for the L1 cache. If it's 0, there are no caches.
> +  if (CLIDR_GET_CACHE_TYPE (Clidr.Data, 0) == CLIDR_CACHE_TYPE_NONE) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  for (CacheLevel = 1; CacheLevel < MAX_ARM_CACHE_LEVEL; CacheLevel++) {
> +    if (CLIDR_GET_CACHE_TYPE (Clidr.Data, CacheLevel) == CLIDR_CACHE_TYPE_NONE) {
> +      MaxCacheLevel = CacheLevel;
> +      break;
> +    }
> +  }
> +
> +  CcidxSupported = ArmIsCcidxImplemented ();
> +
> +  for (CacheLevel = 0; CacheLevel < MaxCacheLevel; CacheLevel++)
> +  {

{ goes on previous line.

> +    Type7Record = NULL;
> +
> +    CLIDR_CACHE_TYPE CacheType = CLIDR_GET_CACHE_TYPE (Clidr.Data, CacheLevel);
> +
> +    // At each level of cache, we can have a single type (unified, instruction or data),
> +    // or two types - separate data and instruction caches. If we have separate
> +    // instruction and data caches, then on the first iteration (CacheSubLevel = 0)
> +    // process the instruction cache.
> +    for (CacheSubLevel = 0; CacheSubLevel <= 1; CacheSubLevel++) {
> +      // If there's no separate data/instruction cache, skip the second iteration
> +      if (CacheSubLevel > 0 && CacheType != CLIDR_CACHE_TYPE_SEPARATE) {
> +        continue;
> +      }
> +
> +      // Allocate and fetch the cache description+++
> +      StringBufferSize = sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH;
> +      CacheSocketStr = AllocateZeroPool (StringBufferSize);
> +      if (CacheSocketStr == NULL) {
> +        Status = EFI_OUT_OF_RESOURCES;
> +        goto Exit;
> +      }
> +
> +      CacheSocketStrLen = GetCacheSocketStr (CacheLevel, CacheSubLevel, CacheSocketStr);
> +
> +      TableSize = sizeof (SMBIOS_TABLE_TYPE7) + CacheSocketStrLen + 1 + 1;
> +      Type7Record = AllocateZeroPool (TableSize);
> +      if (Type7Record == NULL) {
> +        Status = EFI_OUT_OF_RESOURCES;
> +        goto Exit;
> +      }
> +
> +      Type7Record->Hdr.Type = EFI_SMBIOS_TYPE_CACHE_INFORMATION;
> +      Type7Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE7);
> +      Type7Record->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
> +
> +      Type7Record->SocketDesignation = 1;
> +
> +      Type7Record->SupportedSRAMType.Unknown = 1;
> +      Type7Record->CurrentSRAMType.Unknown = 1;
> +      Type7Record->CacheSpeed = 0;
> +      Type7Record->ErrorCorrectionType = CacheErrorUnknown;
> +
> +      Csselr.Data = 0;
> +      Csselr.Bits.Level = CacheLevel;
> +
> +      if (CacheSubLevel == 0) {
> +        if (CacheType == CLIDR_CACHE_TYPE_INSTRUCTION_ONLY ||
> +            CacheType == CLIDR_CACHE_TYPE_SEPARATE) {
> +          Csselr.Bits.InD = CSSELR_CACHE_TYPE_INSTRUCTION; // Instruction cache
> +          Type7Record->SystemCacheType = CacheTypeInstruction;
> +        } else {
> +          Csselr.Bits.InD = CSSELR_CACHE_TYPE_DATA_OR_UNIFIED;
> +          if (CacheType == CLIDR_CACHE_TYPE_DATA_ONLY) {
> +            Type7Record->SystemCacheType = CacheTypeData;
> +          } else {
> +            Type7Record->SystemCacheType = CacheTypeUnified;
> +          }
> +        }
> +      } else {
> +        Type7Record->SystemCacheType = CacheTypeData;
> +        Csselr.Bits.InD = CSSELR_CACHE_TYPE_DATA_OR_UNIFIED;
> +      }
> +
> +      // Read the CCSIDR register to get the cache architecture
> +      Ccsidr.Data = ReadCCSIDR (Csselr.Data);
> +
> +      if (CcidxSupported) {
> +        CacheSize64 = (UINT64)(1 << (Ccsidr.BitsCcidx.LineSize + 4)) * (Ccsidr.BitsCcidx.Associativity + 1) * (Ccsidr.BitsCcidx.NumSets + 1);
> +        Associativity = Ccsidr.BitsCcidx.Associativity;
> +      } else {
> +        CacheSize64 = (1 << (Ccsidr.BitsNonCcidx.LineSize + 4)) * (Ccsidr.BitsNonCcidx.Associativity + 1) * (Ccsidr.BitsNonCcidx.NumSets + 1);

Very long lines. Wrap.

> +        Associativity = Ccsidr.BitsNonCcidx.Associativity;
> +      }
> +
> +      CacheSize64 /= 1024; // Minimum granularity is 1K
> +
> +      // Encode the cache size into the format SMBIOS wants
> +      if (CacheSize64 < MAX_INT16) {
> +        CacheSize16 = CacheSize64;
> +        CacheSize32 = CacheSize16;
> +      } else if ((CacheSize64 / 64) < MAX_INT16) {
> +        CacheSize16 = (1 << 15) | (CacheSize64 / 64);
> +        CacheSize32 = CacheSize16;
> +      } else {
> +        if ((CacheSize64 / 1024) <= 2047) {
> +          CacheSize32 = CacheSize64;
> +        } else {
> +          CacheSize32 = (1 << 31) | (CacheSize64 / 64);
> +        }
> +
> +        CacheSize16 = -1;
> +      }
> +
> +      Type7Record->Associativity = Associativity + 1;
> +      Type7Record->MaximumCacheSize = CacheSize16;
> +      Type7Record->InstalledSize = CacheSize16;
> +      Type7Record->MaximumCacheSize2 = CacheSize32;
> +      Type7Record->InstalledSize2 = CacheSize32;
> +
> +      switch (Associativity + 1) {
> +        case 2:
> +          Type7Record->Associativity = CacheAssociativity2Way;
> +          break;
> +        case 4:
> +          Type7Record->Associativity = CacheAssociativity4Way;
> +          break;
> +        case 8:
> +          Type7Record->Associativity = CacheAssociativity8Way;
> +          break;
> +        case 16:
> +          Type7Record->Associativity = CacheAssociativity16Way;
> +          break;
> +        case 12:
> +          Type7Record->Associativity = CacheAssociativity12Way;
> +          break;
> +        case 24:
> +          Type7Record->Associativity = CacheAssociativity24Way;
> +          break;
> +        case 32:
> +          Type7Record->Associativity = CacheAssociativity32Way;
> +          break;
> +        case 48:
> +          Type7Record->Associativity = CacheAssociativity48Way;
> +          break;
> +        case 64:
> +          Type7Record->Associativity = CacheAssociativity64Way;
> +          break;
> +        case 20:
> +          Type7Record->Associativity = CacheAssociativity20Way;
> +          break;
> +        default:
> +          Type7Record->Associativity = CacheAssociativityOther;
> +          break;
> +      }
> +
> +      Type7Record->CacheConfiguration = (3 << 8) | (1 << 7) | (3 << 5) | (0 << 3) | CacheLevel;

The line above alone justifies breaking out into a helper function,
and replacing the live-coded values with some descriptively named
macros.

> +
> +      // Allow the platform to fill in other information such as speed, SRAM type etc.
> +      if (!OemGetCacheInformation (CacheLevel, Type7Record)) {
> +        continue;
> +      }
> +
> +      OptionalStrStart = (CHAR8 *) (Type7Record + 1);

No space after cast.

> +      UnicodeStrToAsciiStrS (CacheSocketStr, OptionalStrStart, CacheSocketStrLen + 1);
> +
> +      SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +      // Finally, install the table
> +      Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)Type7Record);
> +      if (EFI_ERROR (Status)) {
> +        goto Exit;
> +      }
> +
> +      // Config L1/L2/L3 Cache Handle
> +      switch (CacheLevel) {
> +        case CPU_CACHE_L1:
> +          *L1CacheHandle = SmbiosHandle;
> +          break;
> +        case CPU_CACHE_L2:
> +          *L2CacheHandle = SmbiosHandle;
> +          break;
> +        case CPU_CACHE_L3:
> +          *L3CacheHandle = SmbiosHandle;
> +          break;
> +        default:
> +            break;
> +      }
> +Exit:

An Exit label *inside* a for loop?
Making some helper functions would get rid of the need.

> +      if (Type7Record != NULL)
> +      {

{ on preceding line.

> +        FreePool (Type7Record);
> +      }
> +      if (CacheSocketStr != NULL)
> +      {

Here too.

> +        FreePool (CacheSocketStr);
> +        CacheSocketStr = NULL;
> +      }
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Add Type 4 SMBIOS Record for Processor Information.
> +
> +  @param[in]    ProcessorNumber     Processor number of specified processor.
> +
> +**/
> +EFI_STATUS
> +AddSmbiosProcessorTypeTable (
> +  IN UINTN                  ProcessorNumber
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  SMBIOS_TABLE_TYPE4          *Type4Record;
> +  EFI_SMBIOS_HANDLE           SmbiosHandle;
> +  EFI_SMBIOS_HANDLE           L1CacheHandle;
> +  EFI_SMBIOS_HANDLE           L2CacheHandle;
> +  EFI_SMBIOS_HANDLE           L3CacheHandle;
> +
> +  CHAR8                       *OptionalStrStart;
> +  UINT8                       *LegacyVoltage;
> +  EFI_STRING_ID               ProcessorManu;
> +  EFI_STRING_ID               ProcessorVersion;
> +  EFI_STRING_ID               SerialNumber;
> +  EFI_STRING_ID               AssetTag;
> +  EFI_STRING_ID               PartNumber;
> +  EFI_STRING                  ProcessorSocketStr;
> +  EFI_STRING                  ProcessorManuStr;
> +  EFI_STRING                  ProcessorVersionStr;
> +  EFI_STRING                  SerialNumberStr;
> +  EFI_STRING                  AssetTagStr;
> +  EFI_STRING                  PartNumberStr;
> +  UINTN                       ProcessorSocketStrLen;
> +  UINTN                       ProcessorManuStrLen;
> +  UINTN                       ProcessorVersionStrLen;
> +  UINTN                       SerialNumberStrLen;
> +  UINTN                       AssetTagStrLen;
> +  UINTN                       PartNumberStrLen;
> +  UINTN                       StringBufferSize;
> +  UINTN                       TotalSize;
> +
> +  PROCESSOR_STATUS_DATA       ProcessorStatus = {{0}};
> +  MISC_PROCESSOR_DATA         MiscProcessorData;
> +
> +  ARM_SMC_ARGS                Args;
> +  BOOLEAN                     Arm64SocIdSupported = FALSE;
> +  int                         Jep106Code;
> +  int                         SocRevision;
> +  int                         SmcCallStatus;

There is no "int".

> +  UINT64                      *ProcessorId;

Right, so I said the preceding function needed to be broken down based
on its local variables. I think this one has twice as many.

> +
> +  Type4Record         = NULL;
> +  ProcessorManuStr    = NULL;
> +  ProcessorVersionStr = NULL;
> +  SerialNumberStr     = NULL;
> +  AssetTagStr         = NULL;
> +  PartNumberStr       = NULL;
> +
> +
> +  MiscProcessorData.Voltage             = 0;
> +  MiscProcessorData.CurrentSpeed        = 0;
> +  MiscProcessorData.CoreCount           = 0;
> +  MiscProcessorData.CoresEnabled        = 0;
> +  MiscProcessorData.ThreadCount         = 0;
> +  L1CacheHandle       = 0xFFFF;
> +  L2CacheHandle       = 0xFFFF;
> +  L3CacheHandle       = 0xFFFF;
> +
> +  ProcessorManu       = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
> +  ProcessorVersion    = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
> +  SerialNumber        = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
> +  AssetTag            = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
> +  PartNumber          = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
> +
> +  BOOLEAN Populated = OemGetProcessorInformation (ProcessorNumber,
> +                                                  &ProcessorStatus,
> +                                                  (PROCESSOR_CHARACTERISTIC_FLAGS*)&mSmbiosProcessorTable[ProcessorNumber].ProcessorCharacteristics,

Too long.

> +                                                  &MiscProcessorData);
> +  if (Populated)
> +  {

{ on preceding line.
(throughout)

> +    Status = AddSmbiosCacheTypeTable (ProcessorNumber, &L1CacheHandle,
> +                                      &L2CacheHandle, &L3CacheHandle);
> +
> +    ProcessorManu       = STRING_TOKEN (STR_PROCESSOR_MANUFACTURE);
> +    ProcessorVersion    = STRING_TOKEN (STR_PROCESSOR_VERSION);
> +    SerialNumber        = STRING_TOKEN (STR_PROCESSOR_SERIAL_NUMBER);
> +    AssetTag            = STRING_TOKEN (STR_PROCESSOR_ASSET_TAG);
> +    PartNumber          = STRING_TOKEN (STR_PROCESSOR_PART_NUMBER);
> +
> +    ProcessorManuStr = (CHAR16 *) PcdGetPtr (PcdProcessorManufacturer);

No space after cast.

> +
> +    if (StrLen (ProcessorManuStr) > 0)
> +    {
> +      HiiSetString (mHiiHandle, ProcessorManu, ProcessorManuStr, NULL);
> +    }

This pattern seems to be repeated many times, looks like a macro would help.

> +
> +    ProcessorVersionStr = (CHAR16 *) PcdGetPtr (PcdProcessorVersion);
> +
> +    if (StrLen (ProcessorVersionStr) > 0)
> +    {
> +      HiiSetString (mHiiHandle, ProcessorVersion, ProcessorVersionStr, NULL);
> +    }
> +
> +    SerialNumberStr = (CHAR16 *) PcdGetPtr (PcdProcessorSerialNumber);
> +
> +    if (StrLen (SerialNumberStr) > 0)
> +    {
> +      HiiSetString (mHiiHandle, SerialNumber, SerialNumberStr, NULL);
> +    }
> +
> +    AssetTagStr = (CHAR16 *) PcdGetPtr (PcdProcessorAssetTag);
> +
> +    if (StrLen (AssetTagStr) > 0)
> +    {
> +      HiiSetString (mHiiHandle, AssetTag, AssetTagStr, NULL);
> +    }
> +
> +    PartNumberStr = (CHAR16 *) PcdGetPtr (PcdProcessorPartNumber);
> +
> +    if (StrLen (PartNumberStr) > 0)
> +    {
> +      HiiSetString (mHiiHandle, PartNumber, PartNumberStr, NULL);
> +    }
> +  }
> +
> +  // Processor Socket Designation
> +  StringBufferSize = sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH;
> +  ProcessorSocketStr = AllocateZeroPool (StringBufferSize);
> +  if (ProcessorSocketStr == NULL)
> +  {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Exit;
> +  }
> +
> +  ProcessorSocketStrLen = UnicodeSPrint (ProcessorSocketStr, StringBufferSize, L"CPU%02d", ProcessorNumber + 1);

Too long.

> +
> +  // Processor Manufacture
> +  ProcessorManuStr = HiiGetPackageString (&gEfiCallerIdGuid, ProcessorManu, NULL);
> +  ProcessorManuStrLen = StrLen (ProcessorManuStr);
> +
> +  // Processor Version
> +  ProcessorVersionStr = HiiGetPackageString (&gEfiCallerIdGuid, ProcessorVersion, NULL);
> +  ProcessorVersionStrLen = StrLen (ProcessorVersionStr);
> +
> +  // Serial Number
> +  SerialNumberStr = HiiGetPackageString (&gEfiCallerIdGuid, SerialNumber, NULL);
> +  SerialNumberStrLen = StrLen (SerialNumberStr);
> +
> +  // Asset Tag
> +  AssetTagStr = HiiGetPackageString (&gEfiCallerIdGuid, AssetTag, NULL);
> +  AssetTagStrLen = StrLen (AssetTagStr);
> +
> +  // Part Number
> +  PartNumberStr = HiiGetPackageString (&gEfiCallerIdGuid, PartNumber, NULL);
> +  PartNumberStrLen = StrLen (PartNumberStr);
> +
> +  TotalSize = sizeof (SMBIOS_TABLE_TYPE4) + ProcessorSocketStrLen + 1 +
> +                                            ProcessorManuStrLen + 1 +
> +                                            ProcessorVersionStrLen + 1 +
> +                                            SerialNumberStrLen + 1 +
> +                                            AssetTagStrLen + 1 +
> +                                            PartNumberStrLen + 1 + 1;
> +  Type4Record = AllocateZeroPool (TotalSize);
> +  if (Type4Record == NULL)
> +  {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Exit;
> +  }
> +
> +  (VOID)CopyMem (Type4Record, &mSmbiosProcessorTable[ProcessorNumber], sizeof (SMBIOS_TABLE_TYPE4));
> +
> +  LegacyVoltage = (UINT8*)&Type4Record->Voltage;
> +
> +  *LegacyVoltage                          = MiscProcessorData.Voltage;
> +  Type4Record->CurrentSpeed               = MiscProcessorData.CurrentSpeed;
> +  Type4Record->MaxSpeed                   = MiscProcessorData.MaxSpeed;
> +  Type4Record->Status                     = ProcessorStatus.Data;
> +  Type4Record->L1CacheHandle              = L1CacheHandle;
> +  Type4Record->L2CacheHandle              = L2CacheHandle;
> +  Type4Record->L3CacheHandle              = L3CacheHandle;
> +  Type4Record->CoreCount                  = MiscProcessorData.CoreCount;
> +  Type4Record->CoreCount2                 = MiscProcessorData.CoreCount;
> +  Type4Record->EnabledCoreCount           = MiscProcessorData.CoresEnabled;
> +  Type4Record->EnabledCoreCount2          = MiscProcessorData.CoresEnabled;
> +  Type4Record->ThreadCount                = MiscProcessorData.ThreadCount;
> +  Type4Record->ThreadCount2               = MiscProcessorData.ThreadCount;
> +
> +  Type4Record->ExternalClock              = (UINT16)(ArmReadCntFrq () / 1000 / 1000);
> +
> +  ProcessorId = (UINT64 *)&Type4Record->ProcessorId;
> +
> +  Args.Arg0 = ARM_SMC_ID_ARCH_VERSION;
> +  ArmCallSmc (&Args);
> +  SmcCallStatus = (int)Args.Arg0;
> +
> +  if (SmcCallStatus < 0 || (SmcCallStatus >> 16) >= 1) {
> +    Args.Arg0 = ARM_SMC_ID_ARCH_FEATURES;
> +    Args.Arg1 = ARM_SMC_ID_ARCH_SOC_ID;
> +    ArmCallSmc (&Args);
> +
> +    if (Args.Arg0 >= 0) {
> +      PROCESSOR_CHARACTERISTIC_FLAGS *ProcessorCharacteristicFlags = (PROCESSOR_CHARACTERISTIC_FLAGS*)&Type4Record->ProcessorCharacteristics;

Too long.

> +      Args.Arg0 = ARM_SMC_ID_ARCH_SOC_ID;
> +      Args.Arg1 = 0;
> +      ArmCallSmc (&Args);
> +      SmcCallStatus = (int)Args.Arg0;
> +
> +      if (SmcCallStatus >= 0) {
> +        Arm64SocIdSupported = TRUE;
> +        ProcessorCharacteristicFlags->ProcessorArm64SocId = 1;
> +        Jep106Code = (int)Args.Arg0;
> +      } else {
> +        ProcessorCharacteristicFlags->ProcessorArm64SocId  = 0;

Stray space before =.

> +      }
> +      Args.Arg0 = ARM_SMC_ID_ARCH_SOC_ID;
> +      Args.Arg1 = 1;
> +      ArmCallSmc (&Args);
> +      SmcCallStatus = (int)Args.Arg0;
> +
> +      if (SmcCallStatus >= 0) {
> +        SocRevision = (int)Args.Arg0;
> +      }
> +    }
> +  }
> +
> +  if (Arm64SocIdSupported) {
> +    *ProcessorId = ((UINT64)Jep106Code << 32) | SocRevision;
> +  } else {
> +    *ProcessorId = ArmReadMidr ();
> +  }
> +
> +  UINTN MainIdRegister = ArmReadMidr ();
> +  if (((MainIdRegister >> 16) & 0xF) < 8) {
> +    Type4Record->ProcessorFamily2 = ProcessorFamilyARM;
> +  } else {
> +    if (sizeof (VOID*) == 4) {
> +      Type4Record->ProcessorFamily2 = ProcessorFamilyARMv7;
> +    } else {
> +      Type4Record->ProcessorFamily2 = ProcessorFamilyARMv8;
> +    }
> +  }
> +
> +  OptionalStrStart = (CHAR8 *) (Type4Record + 1);

No space after cast.

> +  UnicodeStrToAsciiStrS (ProcessorSocketStr, OptionalStrStart, ProcessorSocketStrLen + 1);
> +  UnicodeStrToAsciiStrS (ProcessorManuStr, OptionalStrStart + ProcessorSocketStrLen + 1, ProcessorManuStrLen + 1);
> +  UnicodeStrToAsciiStrS (ProcessorVersionStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1, ProcessorVersionStrLen + 1);
> +  UnicodeStrToAsciiStrS (SerialNumberStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1, SerialNumberStrLen + 1);
> +  UnicodeStrToAsciiStrS (AssetTagStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1 + SerialNumberStrLen + 1, AssetTagStrLen + 1);
> +  UnicodeStrToAsciiStrS (PartNumberStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1 + SerialNumberStrLen + 1 + AssetTagStrLen + 1, PartNumberStrLen + 1);

Unreadable - use a temporary cariable.

> +
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)Type4Record);
> +  if (EFI_ERROR (Status))
> +  {
> +    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type04 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));

Wrap line.

> +  }
> +  FreePool (Type4Record);
> +
> +Exit:
> +  if (ProcessorSocketStr != NULL)
> +  {
> +    FreePool (ProcessorSocketStr);
> +  }
> +  if (ProcessorManuStr != NULL)
> +  {
> +    FreePool (ProcessorManuStr);
> +  }
> +  if (ProcessorVersionStr != NULL)
> +  {
> +    FreePool (ProcessorVersionStr);
> +  }
> +  if (SerialNumberStr != NULL)
> +  {
> +    FreePool (SerialNumberStr);
> +  }
> +  if (AssetTagStr != NULL)
> +  {
> +    FreePool (AssetTagStr);
> +  }
> +  if (PartNumberStr != NULL)
> +  {
> +    FreePool (PartNumberStr);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Standard EFI driver point.  This driver locates the ProcessorConfigurationData Variable,
> +  if it exists, add the related SMBIOS tables by PI SMBIOS protocol.
> +
> +  @param  ImageHandle     Handle for the image of this driver
> +  @param  SystemTable     Pointer to the EFI System Table
> +
> +  @retval  EFI_SUCCESS    The data was successfully stored.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +ProcessorSubClassEntryPoint(
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINT32                          SocketIndex;
> +
> +  //
> +  // Locate dependent protocols
> +  //
> +  Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&mSmbios);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol.  %r\n", Status));
> +    return Status;
> +  }
> +
> +  //
> +  // Add our default strings to the HII database. They will be modified later.
> +  //
> +  mHiiHandle = HiiAddPackages (
> +              &gEfiCallerIdGuid,

Indentation.

> +              NULL,
> +              ProcessorSubClassStrings,
> +              NULL,
> +              NULL
> +              );
> +  if (mHiiHandle == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  //
> +  // Add SMBIOS tables for populated sockets.
> +  //
> +  for (SocketIndex = 0; SocketIndex < OemGetProcessorMaxSockets(); SocketIndex++) {
> +    Status = AddSmbiosProcessorTypeTable (SocketIndex);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "Add Processor Type Table Failed!  %r.\n", Status));
> +      return Status;
> +    }
> +  }
> +
> +  return Status;
> +}
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c
> new file mode 100644
> index 000000000000..eff045383991
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDataTable.c
> @@ -0,0 +1,50 @@
> +/**@file
> +
> +Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  SmbiosMiscDataTable.c
> +
> +Abstract:
> +
> +  This file provides SMBIOS Misc Type.
> +
> +Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +**/
> +
> +#include "SmbiosMisc.h"
> +
> +  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE0,  MiscBiosVendor, MiscBiosVendor)

Why the indentation?

> +  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE1,  MiscSystemManufacturer, MiscSystemManufacturer)
> +  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE3,  MiscChassisManufacturer, MiscChassisManufacturer)
> +  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE2,  MiscBaseBoardManufacturer, MiscBaseBoardManufacturer)
> +  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE13, MiscNumberOfInstallableLanguages, MiscNumberOfInstallableLanguages)
> +  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE32, MiscBootInformation, MiscBootInformation)

Consider wrapping long lines.

> +
> +
> +EFI_MISC_SMBIOS_DATA_TABLE mSmbiosMiscDataTable[] = {
> +  // Type0
> +  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscBiosVendor, MiscBiosVendor),
> +  // Type1
> +  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscSystemManufacturer, MiscSystemManufacturer),
> +  // Type3
> +  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscChassisManufacturer, MiscChassisManufacturer),
> +  // Type2
> +  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscBaseBoardManufacturer, MiscBaseBoardManufacturer),
> +  // Type13
> +  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscNumberOfInstallableLanguages, MiscNumberOfInstallableLanguages),
> +  // Type32
> +  MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION (MiscBootInformation, MiscBootInformation),
> +};

Consider wrapping long lines.

> +
> +
> +//
> +// Number of Data Table entries.
> +//
> +UINTN mSmbiosMiscDataTableEntries =
> +  (sizeof (mSmbiosMiscDataTable)) / sizeof (EFI_MISC_SMBIOS_DATA_TABLE);
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
> new file mode 100644
> index 000000000000..fe81367d1c28
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
> @@ -0,0 +1,167 @@
> +/**@file
> +
> +Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  SmbiosMiscEntryPoint.c
> +
> +Abstract:
> +
> +  This driver parses the mSmbiosMiscDataTable structure and reports
> +  any generated data using SMBIOS protocol.
> +
> +Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +**/
> +
> +#include "SmbiosMisc.h"
> +
> +#define MAX_HANDLE_COUNT  0x10

Why?
Does this belong in a generic header?

> +
> +EFI_HANDLE              mImageHandle;
> +EFI_HII_HANDLE          mHiiHandle;
> +EFI_SMBIOS_PROTOCOL     *mSmbios = NULL;
> +
> +/**
> +  Standard EFI driver point.  This driver parses the mSmbiosMiscDataTable
> +  structure and reports any generated data using SMBIOS protocol.
> +
> +  @param  ImageHandle     Handle for the image of this driver
> +  @param  SystemTable     Pointer to the EFI System Table
> +
> +  @retval  EFI_SUCCESS    The data was successfully stored.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmbiosMiscEntryPoint(
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  UINTN                Index;
> +  EFI_STATUS           EfiStatus;
> +  EFI_SMBIOS_PROTOCOL  *Smbios;
> +
> +  mImageHandle = ImageHandle;
> +
> +  EfiStatus = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
> +  if (EFI_ERROR (EfiStatus)) {
> +    DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol.  %r\n", EfiStatus));
> +    return EfiStatus;
> +  }
> +
> +  mSmbios = Smbios;
> +
> +  mHiiHandle = HiiAddPackages (
> +                  &gEfiCallerIdGuid,
> +                  mImageHandle,
> +                  SmbiosMiscDxeStrings,
> +                  NULL
> +                  );
> +  if (mHiiHandle == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  for (Index = 0; Index < mSmbiosMiscDataTableEntries; ++Index) {
> +    //
> +    // If the entry have a function pointer, just log the data.
> +    //
> +    if (mSmbiosMiscDataTable[Index].Function != NULL) {
> +      EfiStatus = (*mSmbiosMiscDataTable[Index].Function)(
> +          mSmbiosMiscDataTable[Index].RecordData,
> +          Smbios
> +          );
> +
> +      if (EFI_ERROR(EfiStatus)) {
> +        DEBUG ((DEBUG_ERROR, "Misc smbios store error.  Index=%d, ReturnStatus=%r\n", Index, EfiStatus));
> +        return EfiStatus;
> +      }
> +    }
> +  }
> +
> +  return EfiStatus;
> +}
> +
> +
> +/**
> +  Logs SMBIOS record.
> +
> +  @param  Buffer                The data for the fixed portion of the SMBIOS record. The format of the record is
> +                                determined by EFI_SMBIOS_TABLE_HEADER.Type. The size of the formatted area is defined
> +                                by EFI_SMBIOS_TABLE_HEADER.Length and either followed by a double-null (0x0000) or
> +                                a set of null terminated strings and a null.
> +  @param  SmbiosHandle          A unique handle will be assigned to the SMBIOS record.
> +
> +  @retval EFI_SUCCESS           Record was added.
> +  @retval EFI_OUT_OF_RESOURCES  Record was not added due to lack of system resources.
> +
> +**/
> +EFI_STATUS
> +LogSmbiosData (
> +  IN       UINT8                      *Buffer,
> +  IN  OUT  EFI_SMBIOS_HANDLE          *SmbiosHandle
> +  )
> +{
> +  EFI_STATUS         Status;
> +
> +  *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +
> +  Status = mSmbios->Add (
> +                   mSmbios,
> +                   NULL,
> +                   SmbiosHandle,
> +                   (EFI_SMBIOS_TABLE_HEADER *)Buffer
> +                   );
> +
> +  return Status;
> +}
> +
> +
> +VOID
> +GetLinkTypeHandle(
> +  IN  UINT8                 SmbiosType,
> +  OUT UINT16                **HandleArray,
> +  OUT UINTN                 *HandleCount
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  EFI_SMBIOS_HANDLE                SmbiosHandle;
> +  EFI_SMBIOS_TABLE_HEADER          *LinkTypeData = NULL;
> +
> +  if (mSmbios == NULL) {
> +    return;
> +  }
> +
> +  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +
> +  *HandleArray = AllocateZeroPool (sizeof(UINT16) * MAX_HANDLE_COUNT);
> +  if (*HandleArray == NULL) {
> +    DEBUG ((DEBUG_ERROR, "HandleArray allocate memory resource failed.\n"));
> +    return;
> +  }
> +
> +  *HandleCount = 0;
> +
> +  while(1) {
> +    Status = mSmbios->GetNext (
> +                        mSmbios,
> +                        &SmbiosHandle,
> +                        &SmbiosType,
> +                        &LinkTypeData,
> +                        NULL
> +                        );
> +
> +    if (!EFI_ERROR (Status)) {
> +      (*HandleArray)[*HandleCount] = LinkTypeData->Handle;
> +      (*HandleCount)++;
> +    } else {
> +      break;
> +    }
> +  }
> +}
> +
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorData.c
> new file mode 100644
> index 000000000000..d9a1ed418428
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorData.c
> @@ -0,0 +1,99 @@
> +/*++
> +
> +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  MiscBiosVendorData.c
> +
> +Abstract:
> +
> +  This file provides Smbios Type0 Data
> +
> +Based on the files under Nt32Pkg/MiscSubClassPlatformDxe/
> +
> +**/
> +
> +
> +#include "SmbiosMisc.h"
> +
> +
> +//
> +// Static (possibly build generated) Bios Vendor data.
> +//
> +MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE0, MiscBiosVendor) = {
> +  {                                          //Hdr
> +    EFI_SMBIOS_TYPE_BIOS_INFORMATION,          // Type,
> +    0,                                         // Length,
> +    0                                          // Handle
> +  },
> +  1,                                         //Vendor
> +  2,                                         //BiosVersion
> +  0xE000,                                    //BiosSegment
> +  3,                                         //BiosReleaseDate
> +  0,                                         //BiosSize
> +  {                                          //BiosCharacteristics
> +    0,                                         // Reserved                          :2
> +    0,                                         // Unknown                           :1
> +    0,                                         // BiosCharacteristicsNotSupported   :1
> +    0,                                         // IsaIsSupported                    :1
> +    0,                                         // McaIsSupported                    :1
> +    0,                                         // EisaIsSupported                   :1
> +    1,                                         // PciIsSupported                    :1
> +    0,                                         // PcmciaIsSupported                 :1
> +    1,                                         // PlugAndPlayIsSupported            :1
> +    0,                                         // ApmIsSupported                    :1
> +    1,                                         // BiosIsUpgradable                  :1
> +    1,                                         // BiosShadowingAllowed              :1
> +    0,                                         // VlVesaIsSupported                 :1
> +    0,                                         // EscdSupportIsAvailable            :1
> +    1,                                         // BootFromCdIsSupported             :1
> +    1,                                         // SelectableBootIsSupported         :1
> +    0,                                         // RomBiosIsSocketed                 :1
> +    0,                                         // BootFromPcmciaIsSupported         :1
> +    1,                                         // EDDSpecificationIsSupported       :1
> +    0,                                         // JapaneseNecFloppyIsSupported      :1
> +    0,                                         // JapaneseToshibaFloppyIsSupported  :1
> +    0,                                         // Floppy525_360IsSupported          :1
> +    0,                                         // Floppy525_12IsSupported           :1
> +    0,                                         // Floppy35_720IsSupported           :1
> +    0,                                         // Floppy35_288IsSupported           :1
> +    0,                                         // PrintScreenIsSupported            :1
> +    0,                                         // Keyboard8042IsSupported           :1
> +    0,                                         // SerialIsSupported                 :1
> +    0,                                         // PrinterIsSupported                :1
> +    0,                                         // CgaMonoIsSupported                :1
> +    0,                                         // NecPc98                           :1
> +    0                                          // ReservedForVendor                 :32
> +  },
> +
> +  {
> +    0x03,                                        //BIOSCharacteristicsExtensionBytes[0]
> +    //  {                                          //BiosReserved
> +    //    1,                                         // AcpiIsSupported                   :1
> +    //    1,                                         // UsbLegacyIsSupported              :1
> +    //    0,                                         // AgpIsSupported                    :1
> +    //    0,                                         // I20BootIsSupported                :1
> +    //    0,                                         // Ls120BootIsSupported              :1
> +    //    0,                                         // AtapiZipDriveBootIsSupported      :1
> +    //    0,                                         // Boot1394IsSupported               :1
> +    //    0                                          // SmartBatteryIsSupported           :1
> +    //  },
> +    0x0D                                         //BIOSCharacteristicsExtensionBytes[1]
> +    //  {                                          //SystemReserved
> +    //    1,                                         //BiosBootSpecIsSupported            :1
> +    //    0,                                         //FunctionKeyNetworkBootIsSupported  :1
> +    //    1,                                         //TargetContentDistributionEnabled   :1
> +    //    1,                                         //UefiSpecificationSupported         :1
> +    //    0,                                         //VirtualMachineSupported            :1
> +    //    0                                          //ExtensionByte2Reserved             :3
> +    //  },
> +  },
> +  0xFF,                                        //SystemBiosMajorRelease;
> +  0xFF,                                        //SystemBiosMinorRelease;
> +  0xFF,                                     //EmbeddedControllerFirmwareMajorRelease;
> +  0xFF                                      //EmbeddedControllerFirmwareMinorRelease;
> +};
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c
> new file mode 100644
> index 000000000000..2f6b35d80266
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendorFunction.c
> @@ -0,0 +1,232 @@
> +/** @file
> +
> +  Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +  Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +
> +Module Name:
> +
> +  MiscBiosVendorData.c
> +
> +Abstract:
> +
> +  This driver parses the mMiscSubclassDataTable structure and reports
> +  any generated data to the DataHub.
> +
> +Based on the files under Nt32Pkg/MiscSubClassPlatformDxe/
> +
> +--*/
> +
> +//
> +#include "SmbiosMisc.h"
> +#include <Library/HobLib.h>
> +#include <Guid/VersionInfoHobGuid.h>
> +
> +
> +/**
> +  Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k'
> +  as the unit.
> +
> +  @param  Value              Pointer to Base2_Data
> +
> +  @retval
> +
> +**/
> +UINT8
> +Base2ToByteWith64KUnit (
> +  IN  UINTN  Value
> +  )
> +{
> +  UINT8 Size;
> +
> +  Size = Value / SIZE_64KB + (Value % SIZE_64KB + SIZE_64KB - 1) / SIZE_64KB;
> +
> +  return Size;
> +}
> +
> +
> +/**
> +
> +**/
> +VOID *
> +GetBiosReleaseDate (
> +  VOID
> +  )
> +{
> +  CHAR16                  *ReleaseDate = NULL;
> +  VERSION_INFO            *Version;
> +  VOID                    *Hob;
> +
> +  ReleaseDate = AllocateZeroPool ((sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH);
> +  if (ReleaseDate == NULL) {
> +      return NULL;
> +  }
> +
> +  Hob = GetFirstGuidHob (&gVersionInfoHobGuid);
> +  if (Hob == NULL) {
> +    DEBUG ((DEBUG_ERROR, "[%a:%d] Version info HOB not found!\n", __FUNCTION__, __LINE__));
> +    return NULL;
> +  }
> +
> +  Version = GET_GUID_HOB_DATA (Hob);
> +  (VOID)UnicodeSPrintAsciiFormat (ReleaseDate,
> +                        (sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH,
> +                        "%02d/%02d/%4d",
> +                        Version->BuildTime.Month,
> +                        Version->BuildTime.Day,
> +                        Version->BuildTime.Year
> +                        );
> +
> +  return ReleaseDate;
> +}
> +
> +VOID *
> +GetBiosVersion (
> +  VOID
> +  )
> +{
> +  VERSION_INFO            *Version;
> +  VOID                    *Hob;
> +
> +  Hob = GetFirstGuidHob (&gVersionInfoHobGuid);
> +  if (Hob == NULL) {
> +    DEBUG ((DEBUG_ERROR, "[%a:%d] Version info HOB not found!\n", __FUNCTION__, __LINE__));
> +    return NULL;
> +  }
> +
> +  Version = GET_GUID_HOB_DATA (Hob);
> +  return Version->String;
> +}
> +
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscBiosVendor (Type 0).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(MiscBiosVendor)
> +{
> +  CHAR8                 *OptionalStrStart;
> +  UINTN                 VendorStrLen;
> +  UINTN                 VerStrLen;
> +  UINTN                 DateStrLen;
> +  UINTN                 BiosPhysicalSizeHexValue;
> +  CHAR16                *Vendor;
> +  CHAR16                *Version;
> +  CHAR16                *ReleaseDate;
> +  CHAR16                *Char16String;
> +  EFI_STATUS            Status;
> +  EFI_STRING_ID         TokenToUpdate;
> +  EFI_STRING_ID         TokenToGet;
> +  SMBIOS_TABLE_TYPE0    *SmbiosRecord;
> +  EFI_SMBIOS_HANDLE     SmbiosHandle;
> +  SMBIOS_TABLE_TYPE0    *InputData;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  InputData = (SMBIOS_TABLE_TYPE0 *)RecordData;
> +
> +  Vendor = (CHAR16 *) PcdGetPtr (PcdFirmwareVendor);
> +
> +  if (StrLen (Vendor) > 0) {
> +    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
> +    HiiSetString (mHiiHandle, TokenToUpdate, Vendor, NULL);
> +  }
> +
> +  Version = GetBiosVersion();
> +
> +  if (StrLen (Version) > 0) {
> +    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
> +    HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
> +  } else {
> +    Version = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
> +    if (StrLen (Version) > 0) {
> +      TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
> +      HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
> +    }
> +  }
> +
> +  Char16String = GetBiosReleaseDate ();
> +  if (StrLen(Char16String) > 0) {
> +    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
> +    HiiSetString (mHiiHandle, TokenToUpdate, Char16String, NULL);
> +  }
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
> +  Vendor = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  VendorStrLen = StrLen (Vendor);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION);
> +  Version = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  VerStrLen = StrLen (Version);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
> +  ReleaseDate = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  DateStrLen = StrLen (ReleaseDate);
> +
> +  //
> +  // Now update the BiosPhysicalSize
> +  //
> +  BiosPhysicalSizeHexValue = FixedPcdGet32 (PcdFdSize);
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);

Long line.

> +  if (SmbiosRecord == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Exit;
> +  }
> +
> +  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE0));
> +
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE0);
> +  SmbiosRecord->BiosSegment = (UINT16)(FixedPcdGet32 (PcdFdBaseAddress) / SIZE_64KB);
> +  SmbiosRecord->BiosSize = Base2ToByteWith64KUnit (BiosPhysicalSizeHexValue) - 1;
> +
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  UnicodeStrToAsciiStrS (Vendor, OptionalStrStart, VendorStrLen + 1);
> +  UnicodeStrToAsciiStrS (Version, OptionalStrStart + VendorStrLen + 1, VerStrLen + 1);
> +  UnicodeStrToAsciiStrS (ReleaseDate, OptionalStrStart + VendorStrLen + 1 + VerStrLen + 1, DateStrLen + 1);

Long line. (Use temp var.)

> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this record.
> +  //
> +  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
> +  if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type00 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));

Long line.

> +  }
> +
> +  FreePool (SmbiosRecord);
> +
> +Exit:
> +  if (Vendor != NULL) {
> +    FreePool (Vendor);
> +  }
> +
> +  if (Version != NULL) {
> +    FreePool (Version);
> +  }
> +
> +  if (ReleaseDate != NULL) {
> +    FreePool (ReleaseDate);
> +  }
> +
> +  if (Char16String != NULL) {
> +    FreePool (Char16String);
> +  }
> +
> +  return Status;
> +}
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerData.c
> new file mode 100644
> index 000000000000..8752dbd73132
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerData.c
> @@ -0,0 +1,43 @@
> +/*++
> +
> +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  MiscSystemManufacturerData.c
> +
> +Abstract:
> +
> +  This file provides Smbios Type1 Data
> +
> +Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +
> +**/
> +
> +#include "SmbiosMisc.h"
> +
> +
> +//
> +// Static (possibly build generated) System Manufacturer data.
> +//
> +MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE1, MiscSystemManufacturer) = {
> +  {                                               // Hdr
> +    EFI_SMBIOS_TYPE_SYSTEM_INFORMATION,             // Type,
> +    0,                                              // Length,
> +    0                                               // Handle
> +  },
> +  1,                                              // Manufacturer
> +  2,                                              // ProductName
> +  3,                                              // Version
> +  4,                                              // SerialNumber
> +  {                                               // Uuid
> +    0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
> +  },
> +  SystemWakeupTypePowerSwitch,                    // SystemWakeupType
> +  5,                                              // SKUNumber,
> +  6                                               // Family
> +};
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerFunction.c
> new file mode 100644
> index 000000000000..2f96ce90575e
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturerFunction.c
> @@ -0,0 +1,171 @@
> +/*++
> +
> +Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  MiscSystemManufacturerFunction.c
> +
> +Abstract:
> +
> +  This driver parses the mMiscSubclassDataTable structure and reports
> +  any generated data to smbios.
> +
> +Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +
> +**/
> +
> +#include "SmbiosMisc.h"
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscSystemManufacturer (Type 1).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(MiscSystemManufacturer)
> +{
> +  CHAR8                           *OptionalStrStart;
> +  UINTN                           ManuStrLen;
> +  UINTN                           VerStrLen;
> +  UINTN                           PdNameStrLen;
> +  UINTN                           SerialNumStrLen;
> +  UINTN                           SKUNumStrLen;
> +  UINTN                           FamilyStrLen;
> +  EFI_STRING                      Manufacturer;
> +  EFI_STRING                      ProductName;
> +  EFI_STRING                      Version;
> +  EFI_STRING                      SerialNumber;
> +  EFI_STRING                      SKUNumber;
> +  EFI_STRING                      Family;
> +  EFI_STRING_ID                   TokenToGet;
> +  EFI_SMBIOS_HANDLE               SmbiosHandle;
> +  SMBIOS_TABLE_TYPE1              *SmbiosRecord;
> +  SMBIOS_TABLE_TYPE1              *InputData;
> +  EFI_STATUS                      Status;
> +  EFI_STRING_ID                   TokenToUpdate;
> +  CHAR16                          *Product;
> +  CHAR16                          *pVersion;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  InputData = (SMBIOS_TABLE_TYPE1 *)RecordData;
> +
> +  Product = (CHAR16 *) PcdGetPtr (PcdSystemProductName);
> +  if (StrLen (Product) > 0) {
> +    TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
> +    HiiSetString (mHiiHandle, TokenToUpdate, Product, NULL);
> +  }
> +
> +  pVersion = (CHAR16 *) PcdGetPtr (PcdSystemVersion);
> +  if (StrLen (pVersion) > 0) {
> +    TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
> +    HiiSetString (mHiiHandle, TokenToUpdate, pVersion, NULL);
> +  }
> +  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_SYSTEM_SERIAL_NUMBER), SerialNumType01);
> +  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER), SystemManufacturerType01);
> +
> +  TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER);
> +  Manufacturer = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  ManuStrLen   = StrLen (Manufacturer);
> +
> +  TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
> +  ProductName  = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  PdNameStrLen = StrLen (ProductName);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
> +  Version    = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  VerStrLen  = StrLen (Version);
> +
> +  TokenToGet      = STRING_TOKEN (STR_MISC_SYSTEM_SERIAL_NUMBER);
> +  SerialNumber    = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  SerialNumStrLen = StrLen (SerialNumber);
> +
> +  TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_SKU_NUMBER);
> +  SKUNumber    = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  SKUNumStrLen = StrLen (SKUNumber);
> +
> +  TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_FAMILY);
> +  Family       = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  FamilyStrLen = StrLen (Family);
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen      + 1
> +                                                                + PdNameStrLen    + 1
> +                                                                + VerStrLen       + 1
> +                                                                + SerialNumStrLen + 1
> +                                                                + SKUNumStrLen    + 1
> +                                                                + FamilyStrLen    + 1 + 1);

Use temp variable instead.

> +
> +  if (SmbiosRecord == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Exit;
> +  }
> +
> +  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE1));
> +
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE1);
> +
> +  SmbiosRecord->Uuid = InputData->Uuid;
> +
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  UnicodeStrToAsciiStrS (Manufacturer, OptionalStrStart, ManuStrLen + 1);
> +  UnicodeStrToAsciiStrS (ProductName,  OptionalStrStart + ManuStrLen + 1, PdNameStrLen + 1);
> +  UnicodeStrToAsciiStrS (Version,      OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1, VerStrLen + 1);
> +  UnicodeStrToAsciiStrS (SerialNumber, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1, SerialNumStrLen + 1);
> +  UnicodeStrToAsciiStrS (SKUNumber, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1, SKUNumStrLen + 1);
> +  UnicodeStrToAsciiStrS (Family, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SKUNumStrLen + 1, FamilyStrLen + 1);

Temp var.

> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this record.
> +  //
> +  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type01 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
> +  }
> +
> +  FreePool (SmbiosRecord);
> +
> +Exit:
> +  if (Manufacturer != NULL) {
> +    FreePool (Manufacturer);
> +  }
> +
> +  if (ProductName != NULL) {
> +    FreePool (ProductName);
> +  }
> +
> +  if (Version != NULL) {
> +    FreePool (Version);
> +  }
> +
> +  if (SerialNumber != NULL) {
> +    FreePool (SerialNumber);
> +  }
> +
> +  if (SKUNumber != NULL) {
> +    FreePool (SKUNumber);
> +  }
> +
> +  if (Family != NULL) {
> +    FreePool (Family);
> +  }
> +
> +  return 0;
> +}
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerData.c
> new file mode 100644
> index 000000000000..ed55d87310e2
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerData.c
> @@ -0,0 +1,51 @@
> +/*++
> +
> +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  MiscBaseBoardManufacturerData.c
> +
> +Abstract:
> +
> +  This file provide OEM to define Smbios Type2 Data
> +
> +Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +**/
> +
> +#include "SmbiosMisc.h"
> +
> +//
> +// Static (possibly build generated) Chassis Manufacturer data.
> +//
> +MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE2, MiscBaseBoardManufacturer) = {
> +  {                                                       // Hdr
> +    EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION,                // Type,
> +    0,                                                    // Length,
> +    0                                                     // Handle
> +  },
> +  1,                                                      // BaseBoardManufacturer
> +  2,                                                      // BaseBoardProductName
> +  3,                                                      // BaseBoardVersion
> +  4,                                                      // BaseBoardSerialNumber
> +  5,                                                      // BaseBoardAssetTag
> +  {                                                       // FeatureFlag
> +    1,                                                    // Motherboard           :1
> +    0,                                                    // RequiresDaughterCard  :1
> +    0,                                                    // Removable             :1
> +    1,                                                    // Replaceable           :1
> +    0,                                                    // HotSwappable          :1
> +    0                                                     // Reserved              :3
> +  },
> +  6,                                                      // BaseBoardChassisLocation
> +  0,                                                      // ChassisHandle;
> +  BaseBoardTypeMotherBoard,                               // BoardType;
> +  0,                                                      // NumberOfContainedObjectHandles;
> +  {
> +    0
> +  }                                                       // ContainedObjectHandles[1];
> +};
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerFunction.c
> new file mode 100644
> index 000000000000..0528651068c7
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturerFunction.c
> @@ -0,0 +1,184 @@
> +/** @file
> +
> +  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +  Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  MiscBaseBoardManufacturerFunction.c
> +
> +Abstract:
> +
> +  This driver parses the mSmbiosMiscDataTable structure and reports
> +  any generated data using SMBIOS protocol.
> +
> +Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +**/
> +
> +#include "SmbiosMisc.h"
> +
> +
> +/**
> +  This function makes basic board manufacturer to the contents of the
> +  Misc Base Board Manufacturer (Type 2).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(MiscBaseBoardManufacturer)
> +{
> +  CHAR8                             *OptionalStrStart;
> +  UINTN                             ManuStrLen;
> +  UINTN                             ProductNameStrLen;
> +  UINTN                             VerStrLen;
> +  UINTN                             SerialNumStrLen;
> +  UINTN                             AssetTagStrLen;
> +  UINTN                             ChassisLocaStrLen;
> +  UINTN                             HandleCount = 0;
> +  UINT16                            *HandleArray = NULL;
> +  CHAR16                            *BaseBoardManufacturer;
> +  CHAR16                            *BaseBoardProductName;
> +  CHAR16                            *Version;
> +  EFI_STRING                        SerialNumber;
> +  EFI_STRING                        AssetTag;
> +  EFI_STRING                        ChassisLocation;
> +  EFI_STRING_ID                     TokenToGet;
> +  EFI_SMBIOS_HANDLE                 SmbiosHandle;
> +  SMBIOS_TABLE_TYPE2                *SmbiosRecord;
> +  SMBIOS_TABLE_TYPE2                *InputData = NULL;
> +  EFI_STATUS                        Status;
> +
> +  EFI_STRING_ID                     TokenToUpdate;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  InputData = (SMBIOS_TABLE_TYPE2*)RecordData;
> +
> +  BaseBoardManufacturer = (CHAR16 *) PcdGetPtr (PcdBaseBoardManufacturer);
> +  if (StrLen (BaseBoardManufacturer) > 0) {
> +    TokenToUpdate = STRING_TOKEN (STR_MISC_BASE_BOARD_MANUFACTURER);
> +    HiiSetString (mHiiHandle, TokenToUpdate, BaseBoardManufacturer, NULL);
> +  }
> +
> +  BaseBoardProductName = (CHAR16 *) PcdGetPtr (PcdBaseBoardProductName);
> +  if (StrLen (BaseBoardProductName) > 0) {
> +    TokenToUpdate = STRING_TOKEN (STR_MISC_BASE_BOARD_PRODUCT_NAME);
> +    HiiSetString (mHiiHandle, TokenToUpdate, BaseBoardProductName, NULL);
> +  }
> +
> +  Version = (CHAR16 *) PcdGetPtr (PcdBaseBoardVersion);
> +  if (StrLen (Version) > 0) {
> +    TokenToUpdate = STRING_TOKEN (STR_MISC_BASE_BOARD_VERSION);
> +    HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
> +  }
> +
> +  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_BASE_BOARD_ASSET_TAG), AssertTagType02);
> +  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_BASE_BOARD_SERIAL_NUMBER), SrNumType02);
> +  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_BASE_BOARD_MANUFACTURER), BoardManufacturerType02);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_MANUFACTURER);
> +  BaseBoardManufacturer = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  ManuStrLen = StrLen (BaseBoardManufacturer);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_PRODUCT_NAME);
> +  BaseBoardProductName = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  ProductNameStrLen = StrLen (BaseBoardProductName);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_VERSION);
> +  Version = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  VerStrLen = StrLen (Version);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_SERIAL_NUMBER);
> +  SerialNumber = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  SerialNumStrLen = StrLen (SerialNumber);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_ASSET_TAG);
> +  AssetTag = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  AssetTagStrLen = StrLen (AssetTag);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_CHASSIS_LOCATION);
> +  ChassisLocation = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  ChassisLocaStrLen = StrLen (ChassisLocation);
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE2) + ManuStrLen        + 1
> +                                                                + ProductNameStrLen + 1
> +                                                                + VerStrLen         + 1
> +                                                                + SerialNumStrLen   + 1
> +                                                                + AssetTagStrLen    + 1
> +                                                                + ChassisLocaStrLen + 1 + 1);

Use temp var instead.

> +  if (SmbiosRecord == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Exit;
> +  }
> +
> +  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE2));
> +  SmbiosRecord->Hdr.Length        = sizeof (SMBIOS_TABLE_TYPE2);
> +
> +  //
> +  //  Update Contained objects Handle
> +  //
> +  SmbiosRecord->NumberOfContainedObjectHandles = 0;
> +  GetLinkTypeHandle (EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE, &HandleArray, &HandleCount);
> +  if (HandleCount) {
> +    SmbiosRecord->ChassisHandle = HandleArray[0];
> +  }
> +
> +  FreePool(HandleArray);
> +
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  UnicodeStrToAsciiStrS (BaseBoardManufacturer, OptionalStrStart, ManuStrLen + 1);
> +  UnicodeStrToAsciiStrS (BaseBoardProductName, OptionalStrStart + ManuStrLen + 1, ProductNameStrLen + 1);
> +  UnicodeStrToAsciiStrS (Version, OptionalStrStart + ManuStrLen + 1 + ProductNameStrLen + 1, VerStrLen + 1);
> +  UnicodeStrToAsciiStrS (SerialNumber, OptionalStrStart + ManuStrLen + 1 + ProductNameStrLen + 1 + VerStrLen + 1, SerialNumStrLen + 1);
> +  UnicodeStrToAsciiStrS (AssetTag, OptionalStrStart + ManuStrLen + 1 + ProductNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1, AssetTagStrLen + 1);
> +  UnicodeStrToAsciiStrS (ChassisLocation, OptionalStrStart + ManuStrLen + 1 + ProductNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssetTagStrLen + 1, ChassisLocaStrLen + 1);


Temp var.

> +
> +  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type02 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));

Wrap.

> +  }
> +
> +  FreePool (SmbiosRecord);
> +
> +Exit:
> +  if (BaseBoardManufacturer != NULL) {
> +    FreePool (BaseBoardManufacturer);
> +  }
> +
> +  if (BaseBoardProductName != NULL) {
> +    FreePool (BaseBoardProductName);
> +  }
> +
> +  if (Version != NULL) {
> +    FreePool (Version);
> +  }
> +
> +  if (SerialNumber != NULL) {
> +    FreePool (SerialNumber);
> +  }
> +
> +  if (AssetTag != NULL) {
> +    FreePool (AssetTag);
> +  }
> +
> +  if (ChassisLocation != NULL) {
> +    FreePool (ChassisLocation);
> +  }
> +
> +  return 0;
> +}
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerData.c
> new file mode 100644
> index 000000000000..25d1413ed873
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerData.c
> @@ -0,0 +1,58 @@
> +/*++
> +
> +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  MiscChassisManufacturerData.c
> +
> +Abstract:
> +
> +  This file provides Smbios Type3 Data
> +
> +Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +**/
> +
> +#include "SmbiosMisc.h"
> +
> +
> +//
> +// Static (possibly build generated) Chassis Manufacturer data.
> +//
> +MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE3, MiscChassisManufacturer) = {
> +  {                                                       // Hdr
> +    EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE  ,                   // Type,
> +    0,                                                    // Length,
> +    0                                                     // Handle
> +  },
> +  1,                                                      // Manufactrurer
> +  MiscChassisTypeMainServerChassis,                       // Type
> +  2,                                                      // Version
> +  3,                                                      // SerialNumber
> +  4,                                                      // AssetTag
> +  ChassisStateSafe,                                       // BootupState
> +  ChassisStateSafe,                                       // PowerSupplyState
> +  ChassisStateSafe,                                       // ThermalState
> +  ChassisSecurityStatusNone,                              // SecurityState
> +  {
> +    0,                                                    // OemDefined[0]
> +    0,                                                    // OemDefined[1]
> +    0,                                                    // OemDefined[2]
> +    0                                                     // OemDefined[3]
> +  },
> +  2,                                                      // Height
> +  1,                                                      // NumberofPowerCords
> +  0,                                                      // ContainedElementCount
> +  0,                                                      // ContainedElementRecordLength
> +  {                                                       // ContainedElements[0]
> +    {
> +      0,                                                    // ContainedElementType
> +      0,                                                    // ContainedElementMinimum
> +      0                                                     // ContainedElementMaximum
> +    }
> +  }
> +};
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerFunction.c
> new file mode 100644
> index 000000000000..84b4aaaeb89d
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturerFunction.c
> @@ -0,0 +1,182 @@
> +/** @file
> +
> +Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  MiscChassisManufacturerFunction.c
> +
> +Abstract:
> +
> +  This driver parses the mMiscSubclassDataTable structure and reports
> +  any generated data to smbios.
> +
> +Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +**/
> +
> +#include "SmbiosMisc.h"
> +
> +UINT8
> +GetChassisType (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINT8                           ChassisType;
> +
> +  Status = OemGetChassisType (&ChassisType);
> +  if (EFI_ERROR (Status)) {
> +    return 0;
> +  }
> +
> +  return ChassisType;
> +}
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscChassisManufacturer (Type 3).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(MiscChassisManufacturer)
> +{
> +  CHAR8                           *OptionalStrStart;
> +  UINTN                           ManuStrLen;
> +  UINTN                           VerStrLen;
> +  UINTN                           AssertTagStrLen;
> +  UINTN                           SerialNumStrLen;
> +  UINTN                           ChaNumStrLen;
> +  EFI_STRING                      Manufacturer;
> +  EFI_STRING                      Version;
> +  EFI_STRING                      SerialNumber;
> +  EFI_STRING                      AssertTag;
> +  EFI_STRING                      ChassisSkuNumber;
> +  EFI_STRING_ID                   TokenToGet;
> +  EFI_SMBIOS_HANDLE               SmbiosHandle;
> +  SMBIOS_TABLE_TYPE3              *SmbiosRecord;
> +  SMBIOS_TABLE_TYPE3              *InputData;
> +  EFI_STATUS                      Status;
> +
> +  UINT8                           ContainedElementCount;
> +  CONTAINED_ELEMENT               ContainedElements = {0};
> +  UINT8                           ExtendLength = 0;
> +
> +  UINT8                           ChassisType;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  InputData = (SMBIOS_TABLE_TYPE3 *)RecordData;
> +
> +  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_CHASSIS_ASSET_TAG), AssetTagType03);
> +  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_CHASSIS_SERIAL_NUMBER), SrNumType03);
> +  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_CHASSIS_VERSION), VersionType03);
> +  UpdateSmbiosInfo (mHiiHandle, STRING_TOKEN (STR_MISC_CHASSIS_MANUFACTURER), ManufacturerType03);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_MANUFACTURER);
> +  Manufacturer = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  ManuStrLen = StrLen (Manufacturer);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_VERSION);
> +  Version = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  VerStrLen = StrLen (Version);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_SERIAL_NUMBER);
> +  SerialNumber = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  SerialNumStrLen = StrLen (SerialNumber);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_ASSET_TAG);
> +  AssertTag = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  AssertTagStrLen = StrLen (AssertTag);
> +
> +  TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_SKU_NUMBER);
> +  ChassisSkuNumber = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
> +  ChaNumStrLen = StrLen (ChassisSkuNumber);
> +
> +  ContainedElementCount = InputData->ContainedElementCount;
> +
> +  if (ContainedElementCount > 1) {
> +    ExtendLength = (ContainedElementCount - 1) * sizeof (CONTAINED_ELEMENT);
> +  }
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE3) + ExtendLength    + 1
> +                                                                + ManuStrLen      + 1
> +                                                                + VerStrLen       + 1
> +                                                                + SerialNumStrLen + 1
> +                                                                + AssertTagStrLen + 1
> +                                                                + ChaNumStrLen    + 1 + 1);

Use temp var.

> +  if (SmbiosRecord == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Exit;
> +  }
> +
> +  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE3));
> +
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE3) + ExtendLength + 1;
> +
> +  ChassisType = GetChassisType ();
> +  if (ChassisType != 0) {
> +    SmbiosRecord->Type  = ChassisType;
> +  }
> +
> +  //ContainedElements
> +  (VOID)CopyMem (SmbiosRecord + 1, &ContainedElements, ExtendLength);
> +
> +  //ChassisSkuNumber
> +  *((UINT8 *)SmbiosRecord + sizeof (SMBIOS_TABLE_TYPE3) + ExtendLength) = 5;
> +
> +  OptionalStrStart = (CHAR8 *)((UINT8 *)SmbiosRecord + sizeof (SMBIOS_TABLE_TYPE3) + ExtendLength + 1);
> +  UnicodeStrToAsciiStrS (Manufacturer,     OptionalStrStart, ManuStrLen + 1);
> +  UnicodeStrToAsciiStrS (Version, OptionalStrStart + ManuStrLen + 1, VerStrLen + 1);
> +  UnicodeStrToAsciiStrS (SerialNumber, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1, SerialNumStrLen + 1);
> +  UnicodeStrToAsciiStrS (AssertTag, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1, AssertTagStrLen + 1);
> +  UnicodeStrToAsciiStrS (ChassisSkuNumber, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1 + SerialNumStrLen +1 + AssertTagStrLen + 1, ChaNumStrLen + 1);

Temp var.

> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this record.
> +  //
> +  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type03 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));

Wrap.

> +  }
> +
> +  FreePool (SmbiosRecord);
> +
> +Exit:
> +  if (Manufacturer != NULL) {
> +    FreePool (Manufacturer);
> +  }
> +
> +  if (Version != NULL) {
> +    FreePool (Version);
> +  }
> +
> +  if (SerialNumber != NULL) {
> +    FreePool (SerialNumber);
> +  }
> +
> +  if (AssertTag != NULL) {
> +    FreePool (AssertTag);
> +  }
> +
> +  if (ChassisSkuNumber != NULL) {
> +    FreePool (ChassisSkuNumber);
> +  }
> +
> +  return 0;
> +}
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesData.c
> new file mode 100644
> index 000000000000..fa4c574a82c5
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesData.c
> @@ -0,0 +1,39 @@
> +/**@file
> +
> +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  MiscNumberOfInstallableLanguagesData.c
> +
> +Abstract:
> +
> +  This file provides Smbios Type13 Data
> +
> +Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +**/
> +
> +#include "SmbiosMisc.h"
> +
> +//
> +// Static (possibly build generated) Bios Vendor data.
> +//
> +
> +MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE13, MiscNumberOfInstallableLanguages) =
> +{
> +  {                                                     // Hdr
> +    EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION,            // Type,
> +    0,                                                    // Length,
> +    0                                                     // Handle
> +  },
> +  0,                                                    // InstallableLanguages
> +  0,                                                    // Flags
> +  {
> +    0                                                   // Reserved[15]
> +  },
> +  1                                                     // CurrentLanguage
> +};
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesFunction.c
> new file mode 100644
> index 000000000000..dc360aa74cea
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguagesFunction.c
> @@ -0,0 +1,154 @@
> +/** @file
> +
> +Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +**/
> +
> +#include "SmbiosMisc.h"
> +
> +/**
> +  Get next language from language code list (with separator ';').
> +
> +  @param  LangCode       Input: point to first language in the list. On
> +                         Otput: point to next language in the list, or
> +                                NULL if no more language in the list.
> +  @param  Lang           The first language in the list.
> +
> +**/
> +VOID
> +EFIAPI
> +GetNextLanguage (
> +  IN OUT CHAR8      **LangCode,
> +  OUT CHAR8         *Lang
> +  )
> +{
> +  UINTN  Index;
> +  CHAR8  *StringPtr;
> +
> +  if (LangCode == NULL || *LangCode == NULL || Lang == NULL) {
> +    return;
> +  }
> +
> +  Index     = 0;
> +  StringPtr = *LangCode;
> +  while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
> +    Index++;
> +  }
> +
> +  (VOID)CopyMem (Lang, StringPtr, Index);
> +  Lang[Index] = 0;
> +
> +  if (StringPtr[Index] == ';') {
> +    Index++;
> +  }
> +  *LangCode = StringPtr + Index;
> +}
> +
> +/**
> +  This function returns the number of supported languages on HiiHandle.
> +
> +  @param   HiiHandle    The HII package list handle.
> +
> +  @retval  The number of supported languages.
> +
> +**/
> +UINT16
> +EFIAPI
> +GetSupportedLanguageNumber (
> +  IN EFI_HII_HANDLE    HiiHandle
> +  )
> +{
> +  CHAR8   *Lang;
> +  CHAR8   *Languages;
> +  CHAR8   *LanguageString;
> +  UINT16  LangNumber;
> +
> +  Languages = HiiGetSupportedLanguages (HiiHandle);
> +  if (Languages == NULL) {
> +    return 0;
> +  }
> +
> +  LangNumber = 0;
> +  Lang = AllocatePool (AsciiStrSize (Languages));
> +  if (Lang != NULL) {
> +    LanguageString = Languages;
> +    while (*LanguageString != 0) {
> +      GetNextLanguage (&LanguageString, Lang);
> +      LangNumber++;
> +    }
> +    FreePool (Lang);
> +  }
> +  FreePool (Languages);
> +  return LangNumber;
> +}
> +
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscNumberOfInstallableLanguages (Type 13).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +MISC_SMBIOS_TABLE_FUNCTION(MiscNumberOfInstallableLanguages)
> +{
> +  UINTN                                     LangStrLen;
> +  CHAR8                                     CurrentLang[SMBIOS_STRING_MAX_LENGTH + 1];
> +  CHAR8                                     *OptionalStrStart;
> +  EFI_STATUS                                Status;
> +  EFI_SMBIOS_HANDLE                         SmbiosHandle;
> +  SMBIOS_TABLE_TYPE13                       *SmbiosRecord;
> +  SMBIOS_TABLE_TYPE13                       *InputData = NULL;;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  InputData = (SMBIOS_TABLE_TYPE13 *)RecordData;
> +
> +  InputData->InstallableLanguages = GetSupportedLanguageNumber (mHiiHandle);
> +
> +  //
> +  // Try to check if current langcode matches with the langcodes in installed languages
> +  //
> +  ZeroMem (CurrentLang, SMBIOS_STRING_MAX_LENGTH - 1);
> +  (VOID)AsciiStrCpyS (CurrentLang, SMBIOS_STRING_MAX_LENGTH - 1, "en|US|iso8859-1");
> +  LangStrLen = AsciiStrLen (CurrentLang);
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1);
> +  if (SmbiosRecord == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE13));
> +
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE13);
> +
> +  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
> +  (VOID)AsciiStrCpyS (OptionalStrStart, SMBIOS_STRING_MAX_LENGTH - 1, CurrentLang);
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this record.
> +  //
> +  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type13 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));

Wrap.

> +  }
> +
> +  FreePool (SmbiosRecord);
> +  return Status;
> +}
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationData.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationData.c
> new file mode 100644
> index 000000000000..c00225a54005
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationData.c
> @@ -0,0 +1,41 @@
> +/**@file
> +
> +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> +  MiscBootInformationData.c
> +
> +Abstract:
> +
> +  This driver parses the mMiscSubclassDataTable structure and reports
> +  any generated data to the DataHub.
> +
> +Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +**/
> +
> +#include "SmbiosMisc.h"
> +
> +//
> +// Static (possibly build generated) Bios Vendor data.
> +//
> +MISC_SMBIOS_TABLE_DATA(SMBIOS_TABLE_TYPE32, MiscBootInformation) = {
> +  {                                                     // Hdr
> +    EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION,              // Type,
> +    0,                                                    // Length,
> +    0                                                     // Handle
> +  },
> +  {                                                     // Reserved[6]
> +    0,
> +    0,
> +    0,
> +    0,
> +    0,
> +    0
> +  },
> +  BootInformationStatusNoError                          // BootInformationStatus
> +};
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationFunction.c b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationFunction.c
> new file mode 100644
> index 000000000000..25da6de1bfa6
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type32/MiscBootInformationFunction.c
> @@ -0,0 +1,66 @@
> +/** @file
> +  boot information boot time changes.
> +  SMBIOS type 32.
> +
> +Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +**/
> +
> +#include "SmbiosMisc.h"
> +
> +/**
> +  This function makes boot time changes to the contents of the
> +  MiscBootInformation (Type 32).
> +
> +  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
> +
> +**/
> +
> +MISC_SMBIOS_TABLE_FUNCTION(MiscBootInformation)
> +{
> +  EFI_STATUS                         Status;
> +  EFI_SMBIOS_HANDLE                  SmbiosHandle;
> +  SMBIOS_TABLE_TYPE32                *SmbiosRecord;
> +  SMBIOS_TABLE_TYPE32                *InputData;
> +
> +  //
> +  // First check for invalid parameters.
> +  //
> +  if (RecordData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  InputData = (SMBIOS_TABLE_TYPE32 *)RecordData;
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE32) + 1 + 1);
> +  if (SmbiosRecord == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE32));
> +
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE32);
> +
> +  //
> +  // Now we have got the full smbios record, call smbios protocol to add this record.
> +  //
> +  Status = LogSmbiosData ((UINT8*)SmbiosRecord, &SmbiosHandle);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type32 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
> +  }
> +
> +  FreePool (SmbiosRecord);
> +  return Status;
> +}
> diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
> index 199374ff59e3..874bc2866ac3 100644
> --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
> +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
> @@ -424,6 +424,9 @@ ASM_FUNC(ArmCallWFI)
>    wfi
>    ret
>  
> +ASM_FUNC(ArmReadIdMmfr2)
> +  mrs   x0, ID_AA64MMFR2_EL1           // read EL1 MMFR2
> +  ret
>  

These mrs/mrc wrappers would make sense as a separate patch.

>  ASM_FUNC(ArmReadMpidr)
>    mrs   x0, mpidr_el1           // read EL1 MPIDR
> diff --git a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
> index 0e8d21e2264f..0ae75e4cb9f9 100644
> --- a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
> +++ b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
> @@ -84,7 +84,7 @@ ASM_FUNC(ArmDisableAllExceptions)
>    ret
>  
>  
> -// UINT32
> +// UINTN
>  // ReadCCSIDR (
>  //   IN UINT32 CSSELR
>  //   )
> diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
> index 01c91b10fcb7..39fdb0155065 100644
> --- a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
> +++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
> @@ -60,6 +60,10 @@ ASM_FUNC(ArmDisableInterrupts)
>    isb
>    bx      LR
>  
> +ASM_FUNC(ArmReadIdMmfr4):
> +  mrc    p15,0,r0,c0,c2,6     @ Read ID_MMFR4 Register
> +  bx     lr
> +
>  // UINT32
>  // ReadCCSIDR (
>  //   IN UINT32 CSSELR
> diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm
> index 26ffa331b929..d1bbb0a0fc98 100644
> --- a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm
> +++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.asm
> @@ -64,7 +64,11 @@
>    isb
>    bx      LR
>  
> -// UINT32
> + RVCT_ASM_EXPORT ArmReadIdMmfr4
> +  mrc    p15,0,r0,c0,c2,6     ; Read ID_MMFR2 Register
> +  bx
> +
> +// UINTN
>  // ReadCCSIDR (
>  //   IN UINT32 CSSELR
>  //   )
> diff --git a/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni
> new file mode 100644
> index 000000000000..0f55beb95276
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassStrings.uni
> @@ -0,0 +1,23 @@
> +???///// @file

No BOM needed in .uni files - use plain UTF-8. (throughout)

/
    Leif

> +//
> +//  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
> +//  Copyright (c) 2015, Linaro Limited. All rights reserved.
> +//
> +//  SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +/////
> +
> +/=#
> +
> +#langdef en-US "English"
> +
> +//
> +// Processor Information
> +//
> +#string STR_PROCESSOR_SOCKET_DESIGNATION    #language en-US  "Not Specified"
> +#string STR_PROCESSOR_MANUFACTURE           #language en-US  "Not Specified"
> +#string STR_PROCESSOR_VERSION               #language en-US  "Not Specified"
> +#string STR_PROCESSOR_SERIAL_NUMBER         #language en-US  "Not Specified"
> +#string STR_PROCESSOR_ASSET_TAG             #language en-US  "Not Specified"
> +#string STR_PROCESSOR_PART_NUMBER           #language en-US  "Not Specified"
> +#string STR_PROCESSOR_UNKNOWN               #language en-US  "Unknown"
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni
> new file mode 100644
> index 000000000000..7a82e520904e
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscLibString.uni
> @@ -0,0 +1,21 @@
> +???// *++
> +//
> +// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> +// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +// --*/
> +
> +
> +/=#
> +
> +#langdef en-US "English"
> +
> +#include "./Type00/MiscBiosVendor.uni"
> +#include "./Type01/MiscSystemManufacturer.uni"
> +#include "./Type02/MiscBaseBoardManufacturer.uni"
> +#include "./Type03/MiscChassisManufacturer.uni"
> +#include "./Type13/MiscNumberOfInstallableLanguages.uni"
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni
> new file mode 100644
> index 000000000000..cf14e477d260
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type00/MiscBiosVendor.uni
> @@ -0,0 +1,18 @@
> +???// *++
> +//
> +// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> +// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +// --*/
> +
> +/=#
> +
> +#string STR_MISC_BIOS_VENDOR           #language en-US  "Not Specified"
> +#string STR_MISC_BIOS_VERSION          #language en-US  "Not Specified"
> +#string STR_MISC_BIOS_RELEASE_DATE     #language en-US  "Not Specified"
> +#string STR_MISC_BIOS_VENDOR           #language en-US  "Not Specified"
> +#string STR_MISC_BIOS_RELEASE_DATE     #language en-US  "01/01/2020"
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturer.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturer.uni
> new file mode 100644
> index 000000000000..417a5986c79e
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type01/MiscSystemManufacturer.uni
> @@ -0,0 +1,21 @@
> +???// *++
> +//
> +// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> +// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +// --*/
> +
> +/=#
> +
> +#string STR_MISC_SYSTEM_MANUFACTURER   #language en-US  "Not Specified"
> +#string STR_MISC_SYSTEM_PRODUCT_NAME   #language en-US  "Not Specified"
> +#string STR_MISC_SYSTEM_PRODUCT_NAME   #language en-US  "Not Specified"
> +#string STR_MISC_SYSTEM_VERSION        #language en-US  "Not Specified"
> +#string STR_MISC_SYSTEM_VERSION        #language en-US  "Not Specified"
> +#string STR_MISC_SYSTEM_SERIAL_NUMBER  #language en-US  "Not Specified"
> +#string STR_MISC_SYSTEM_SKU_NUMBER     #language en-US  "Not Specified"
> +#string STR_MISC_SYSTEM_FAMILY         #language en-US  "Not Specified"
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturer.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturer.uni
> new file mode 100644
> index 000000000000..96398d837752
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type02/MiscBaseBoardManufacturer.uni
> @@ -0,0 +1,21 @@
> +???// *++
> +//
> +// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> +// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +// --*/
> +
> +/=#
> +
> +#string STR_MISC_BASE_BOARD_MANUFACTURER     #language en-US  "Not Specified"
> +#string STR_MISC_BASE_BOARD_PRODUCT_NAME     #language en-US  "Not Specified"
> +#string STR_MISC_BASE_BOARD_PRODUCT_NAME     #language en-US  "Not Specified"
> +#string STR_MISC_BASE_BOARD_VERSION          #language en-US  "Not Specified"
> +#string STR_MISC_BASE_BOARD_VERSION          #language en-US  "Not Specified"
> +#string STR_MISC_BASE_BOARD_SERIAL_NUMBER    #language en-US  "Not Specified"
> +#string STR_MISC_BASE_BOARD_ASSET_TAG        #language en-US  "Not Specified"
> +#string STR_MISC_BASE_BOARD_CHASSIS_LOCATION #language en-US  "Not Specified"
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturer.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturer.uni
> new file mode 100644
> index 000000000000..a2b9500f94c5
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type03/MiscChassisManufacturer.uni
> @@ -0,0 +1,18 @@
> +???// *++
> +//
> +// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> +// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +// --*/
> +
> +/=#
> +
> +#string STR_MISC_CHASSIS_MANUFACTURER  #language en-US  "Not Specified"
> +#string STR_MISC_CHASSIS_VERSION       #language en-US  "Not Specified"
> +#string STR_MISC_CHASSIS_SERIAL_NUMBER #language en-US  "Not Specified"
> +#string STR_MISC_CHASSIS_ASSET_TAG     #language en-US  "Not Specified"
> +#string STR_MISC_CHASSIS_SKU_NUMBER    #language en-US  "Not Specified"
> diff --git a/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguages.uni b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguages.uni
> new file mode 100644
> index 000000000000..559003369f21
> --- /dev/null
> +++ b/ArmPkg/Universal/Smbios/SmbiosMiscDxe/Type13/MiscNumberOfInstallableLanguages.uni
> @@ -0,0 +1,43 @@
> +???// *++
> +//
> +// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> +// Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
> +// Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
> +// --*/
> +
> +/=#
> +
> +/=#
> +//
> +// Language String (Long Format)
> +//
> +#string STR_MISC_BIOS_LANGUAGES_ENG_LONG        #language en-US  "en|US|iso8859-1"
> +#string STR_MISC_BIOS_LANGUAGES_FRA_LONG        #language en-US  "fr|CA|iso8859-1"
> +#string STR_MISC_BIOS_LANGUAGES_CHN_LONG        #language en-US  "zh|TW|unicode"
> +#string STR_MISC_BIOS_LANGUAGES_JPN_LONG        #language en-US  "ja|JP|unicode"
> +#string STR_MISC_BIOS_LANGUAGES_ITA_LONG        #language en-US  "it|IT|iso8859-1"
> +#string STR_MISC_BIOS_LANGUAGES_SPA_LONG        #language en-US  "es|ES|iso8859-1"
> +#string STR_MISC_BIOS_LANGUAGES_GER_LONG        #language en-US  "de|DE|iso8859-1"
> +#string STR_MISC_BIOS_LANGUAGES_POR_LONG        #language en-US  "pt|PT|iso8859-1"
> +
> +
> +//
> +// Language String (Abbreviated Format)
> +//
> +#string STR_MISC_BIOS_LANGUAGES_ENG_ABBREVIATE  #language en-US  "enUS"
> +#string STR_MISC_BIOS_LANGUAGES_FRA_ABBREVIATE  #language en-US  "frCA"
> +#string STR_MISC_BIOS_LANGUAGES_CHN_ABBREVIATE  #language en-US  "zhTW"
> +#string STR_MISC_BIOS_LANGUAGES_JPN_ABBREVIATE  #language en-US  "jaJP"
> +#string STR_MISC_BIOS_LANGUAGES_ITA_ABBREVIATE  #language en-US  "itIT"
> +#string STR_MISC_BIOS_LANGUAGES_SPA_ABBREVIATE  #language en-US  "esES"
> +#string STR_MISC_BIOS_LANGUAGES_GER_ABBREVIATE  #language en-US  "deDE"
> +#string STR_MISC_BIOS_LANGUAGES_POR_ABBREVIATE  #language en-US  "ptPT"
> +
> +#string STR_MISC_BIOS_LANGUAGES_SIMPLECH_ABBREVIATE  #language en-US  "zhCN"
> +#string STR_MISC_BIOS_LANGUAGES_SIMPLECH_LONG        #language en-US  "zh|CN|unicode"
> +
> +
> -- 
> 2.26.2
> 

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

* Re: [PATCH v3 3/3] ArmPkg: add Universal/Smbios as a generic SMBIOS library
  2020-11-19 12:58   ` Leif Lindholm
@ 2020-12-07  4:59     ` Rebecca Cran
  2020-12-07 17:11       ` Leif Lindholm
  0 siblings, 1 reply; 14+ messages in thread
From: Rebecca Cran @ 2020-12-07  4:59 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: devel, Ard Biesheuvel, Michael D Kinney, Liming Gao, Zhiguang Liu

On 11/19/20 5:58 AM, Leif Lindholm wrote:


I hope I've addressed these and your other feedback in the new patch 
series I'll post soon.

> Please use --stat=1000 --stat-graph-width=20 when generating
> patches, to avoid above ellipses.
I'll try and remember in future.
> What version? FirmwareVersion? Would make sense to be explicit in the
> name.
I've removed the driver following Ard's feedback.

> Where is this function defined?
It's defined in the platform-specific OemMiscLib implementation.
> Changes to this file in general seem to be removing unused(?) existing
> cache-related macros and adding (architectural) special
> purposeregister descriptions as replacements. This feels like two
> separate changes (and hence patches).

Agreed. I'll split it.

> Eew.
> This is quite possibly very useful, but that '&' made me swear out
> loud. Add a comment describing how this is used further down?
I hope I've addressed this sufficiently in my new revision.
>> +
>> +  MISC_SMBIOS_TABLE_EXTERNS (SMBIOS_TABLE_TYPE0,  MiscBiosVendor, MiscBiosVendor)
> Why the indentation?
I have no idea. I've fixed it.
>> +#define MAX_HANDLE_COUNT  0x10
> Why?
> Does this belong in a generic header?
It's an arbitrary value, since the SMBIOS protocol doesn't have a way of 
letting you know how many records of a certain type are available 
without iterating through them. It might be better to just iterate twice.


-- 
Rebecca Cran


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

* Re: [PATCH v3 3/3] ArmPkg: add Universal/Smbios as a generic SMBIOS library
  2020-12-07  4:59     ` Rebecca Cran
@ 2020-12-07 17:11       ` Leif Lindholm
  0 siblings, 0 replies; 14+ messages in thread
From: Leif Lindholm @ 2020-12-07 17:11 UTC (permalink / raw)
  To: Rebecca Cran
  Cc: devel, Ard Biesheuvel, Michael D Kinney, Liming Gao, Zhiguang Liu

On Sun, Dec 06, 2020 at 21:59:48 -0700, Rebecca Cran wrote:
> On 11/19/20 5:58 AM, Leif Lindholm wrote:
> 
> > > +#define MAX_HANDLE_COUNT  0x10
> > Why?
> > Does this belong in a generic header?
>
> It's an arbitrary value, since the SMBIOS protocol doesn't have a way of
> letting you know how many records of a certain type are available without
> iterating through them. It might be better to just iterate twice.

Sadly, yes.
Avoiding hard-coding of sizes is worth some extra code.

/
    Leif

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

end of thread, other threads:[~2020-12-07 17:11 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-11-11  0:17 [PATCH v3 0/3] ArmPkg,MdePkg: Add Universal/Smbios and Drivers/VersionInfoPeim Rebecca Cran
2020-11-11  0:17 ` [PATCH v3 1/3] ArmPkg: Add ARM SMC Architecture functions to ArmStdSmc.h Rebecca Cran
2020-11-12 21:49   ` [edk2-devel] " Sami Mujawar
2020-11-19 12:00   ` Leif Lindholm
2020-11-11  0:17 ` [PATCH v3 2/3] MdePkg: Update IndustryStandard/SmBios.h with processor status data Rebecca Cran
2020-11-11  1:18   ` 回复: " gaoliming
2020-11-13 11:25   ` [edk2-devel] " Sami Mujawar
2020-11-19 12:05   ` Leif Lindholm
2020-11-11  0:17 ` [PATCH v3 3/3] ArmPkg: add Universal/Smbios as a generic SMBIOS library Rebecca Cran
2020-11-16 13:43   ` [edk2-devel] " Sami Mujawar
2020-11-17  3:27     ` Rebecca Cran
2020-11-19 12:58   ` Leif Lindholm
2020-12-07  4:59     ` Rebecca Cran
2020-12-07 17:11       ` Leif Lindholm

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