public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver
@ 2022-03-10 22:41 Oram, Isaac W
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 1/9] WhitleyOpenBoardPkg: Add definitions needed for " Oram, Isaac W
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: Oram, Isaac W @ 2022-03-10 22:41 UTC (permalink / raw)
  To: devel; +Cc: Nate DeSimone, Chasel Chiu

This series converts the AcpiPlatform driver for Whitley ICX to open source.
The driver requires libraries providing:
16-bit CRC service
A library to update the tables based on boot time data.
A board hook library to control publishing individual tables and to modify tables.
A library to build MADT and SRAT tables during boot.
A Universal Board Abstraction library to translate UBA data.

The driver consumes the AcpiTables data file and the AML opcode patching table From
StaticSkuDataDxe driver.

This code does not support the CooperCity hardware at present.
The code depends on additional DynamicSiLibraryProtocol2 and updated WhitleyFspBinPkg content.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>

Isaac Oram (9):
  WhitleyOpenBoardPkg: Add definitions needed for AcpiPlatform driver
  WhitleySiliconPkg: Add definitions used in ACPI subsystem
  WhitleyOpenBoardPkg/BaseCrcLib: Add library for CRC16
  WhitleyOpenBoardPkg: Add UbaPlatLib Library
  WhitleyOpenBoardPkg/PlatformSpecificAcpiTableLib: Add library
  WhitleyOpenBoardPkg/BuildAcpiTablesLib: Add lib for building MADT and
    SRAT
  WhitleyOpenBoardPkg/AcpiTablesLib: Add library for AcpiPlatform driver
  WhitleyOpenBoardPkg/AcpiPlatform: Add driver for publishing ACPI
    tables
  WhitleyOpenBoardPkg/Build: Remove confusing build options

 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.c                                     |  754 +++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.h                                     |  117 ++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.inf                                   |  107 ++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.c                                |  384 +++++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.h                                |   51 +
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.c                                |  133 ++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.h                                |   66 +
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformVTDHooks.c                             | 1762 ++++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciHostBridge/PciHostBridge.inf                              |    1 +
 Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciPlatform/PciPlatform.inf                                  |    1 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Madt.h                                                           |  118 ++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Slit.h                                                           |   75 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Srat.h                                                           |   53 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/amlresrc.h                                                       |  542 ++++++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc                                                  |   18 +-
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/AcpiPlatformLib.h                                             |  107 ++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h                                          |  111 ++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h                                                      |   42 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSpecificAcpiTableLib.h                                |  129 ++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformStatusCodes.h                                         |  364 ++++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaFpkConfigLib.h                                             |   55 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaSmbiosUpdateLib.h                                          |  275 +++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.c                                |  534 ++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.inf                              |  127 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibApic.c                            |  735 ++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibBdat.c                            | 1574 +++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibDsdt.c                            |  673 ++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibFadt.c                            |   75 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibHmat.c                            | 1710 +++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibLocal.h                           |  441 +++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMcfg.c                            |  134 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMigt.c                            |   69 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMsct.c                            |  101 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibNfit.c                            |   45 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPcat.c                            |   42 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPmtt.c                            |  267 +++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSlit.c                            | 1153 +++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSrat.c                            |  952 +++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSsdt.c                            | 1004 +++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c                                               |   71 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf                                             |   23 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/BoardInitLib/BoardInitDxeLib.inf                                      |    1 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.c                            |  470 ++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf                          |   40 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/AcpiPlatformLibSpcrNull.c            |   23 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.c   |   50 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf |   27 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaGpioPlatformConfigLib.c                              |  388 +++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemBoardInfoLib.c                                 |   62 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemConfigUpdateLib.c                              |   60 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaUsbOcUpdateLib.c                                     |   61 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaAcpiUpdateLib.c                                         |   59 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaFpkConfigLib.c                                          |   57 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaIioConfigLib.c                                          |  132 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaOpromUpdateLib.c                                        |  221 +++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaPlatLib.inf                                             |   62 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSlotUpdateLib.c                                         |  114 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSmbiosUpdateLib.c                                       |  663 ++++++++
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec                                                               |   16 +-
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc                                                               |   15 +-
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.fdf                                                               |    3 +
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkgConfig.dsc                                                         |    7 +-
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaCommon.dsc                                                             |    3 +
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaDxeRpBoards.fdf                                                        |    6 +-
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaMain/StaticSkuDataDxe/Readme.md                                        |    1 +
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaRpBoards.dsc                                                           |    6 +-
 Platform/Intel/WhitleyOpenBoardPkg/WilsonCityRvp/AmlOffsets/AmlOffsets.inf                                       |    2 +-
 Silicon/Intel/WhitleySiliconPkg/CpRcPkg.dec                                                                      |    3 +
 Silicon/Intel/WhitleySiliconPkg/Cpu/Include/CpuDataStruct.h                                                      |    7 +
 Silicon/Intel/WhitleySiliconPkg/Cpu/Include/Library/CpuConfigLib.h                                               |   82 +
 Silicon/Intel/WhitleySiliconPkg/Include/BackCompatible.h                                                         |    3 +
 Silicon/Intel/WhitleySiliconPkg/Include/BdatSchema.h                                                             |  301 ++++
 Silicon/Intel/WhitleySiliconPkg/Include/Guid/MemoryMapData.h                                                     |    2 +
 Silicon/Intel/WhitleySiliconPkg/Include/IioRegs.h                                                                |   74 +-
 Silicon/Intel/WhitleySiliconPkg/Include/Library/EnhancedWarningLogLib.h                                          |  494 ++++++
 Silicon/Intel/WhitleySiliconPkg/Include/Library/SpdAccessLib.h                                                   |   32 +
 Silicon/Intel/WhitleySiliconPkg/Include/MemCommon.h                                                              |    7 +
 Silicon/Intel/WhitleySiliconPkg/Include/Platform.h                                                               |    7 +
 Silicon/Intel/WhitleySiliconPkg/Include/Ppi/MemoryPolicyPpi.h                                                    |    2 +-
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/AcpiPlatformProtocol.h                                          |   51 +
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/CpuCsrAccess.h                                                  |  254 +++
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol.h                                      |   43 +-
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol2.h                                     |  255 +++
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/NfitTableUpdateProtocol.h                                       |   27 +
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/SmbiosMemInfo.h                                                 |   87 +
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MemRegs.h                                 |    2 +
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MrcCommonTypes.h                          |   25 +
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/SysHost.h                                 |   34 +-
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Platform/MemDefaults.h                                 |    7 +
 Silicon/Intel/WhitleySiliconPkg/Pch/SouthClusterLbg/Include/PchInfoHob.h                                         |   50 +
 Silicon/Intel/WhitleySiliconPkg/Product/Whitley/SiliconPkg10nmPcds.dsc                                           |    4 +-
 Silicon/Intel/WhitleySiliconPkg/WhitleySiliconPkg.dec                                                            |    1 +
 92 files changed, 19300 insertions(+), 98 deletions(-)
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformVTDHooks.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Madt.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Slit.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Srat.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/amlresrc.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/AcpiPlatformLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSpecificAcpiTableLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformStatusCodes.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaFpkConfigLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaSmbiosUpdateLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibApic.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibBdat.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibDsdt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibFadt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibHmat.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibLocal.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMcfg.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMigt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMsct.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibNfit.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPcat.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPmtt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSlit.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSrat.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSsdt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/AcpiPlatformLibSpcrNull.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaGpioPlatformConfigLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemBoardInfoLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemConfigUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaUsbOcUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaAcpiUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaFpkConfigLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaIioConfigLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaOpromUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaPlatLib.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSlotUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSmbiosUpdateLib.c
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/BdatSchema.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Library/EnhancedWarningLogLib.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Library/SpdAccessLib.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/AcpiPlatformProtocol.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/CpuCsrAccess.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol2.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/NfitTableUpdateProtocol.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/SmbiosMemInfo.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Pch/SouthClusterLbg/Include/PchInfoHob.h

--
2.27.0.windows.1

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

* [edk2-devel][edk2-platforms][PATCH V1 1/9] WhitleyOpenBoardPkg: Add definitions needed for AcpiPlatform driver
  2022-03-10 22:41 [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Oram, Isaac W
@ 2022-03-10 22:41 ` Oram, Isaac W
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 2/9] WhitleySiliconPkg: Add definitions used in ACPI subsystem Oram, Isaac W
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Oram, Isaac W @ 2022-03-10 22:41 UTC (permalink / raw)
  To: devel; +Cc: Nate DeSimone, Chasel Chiu

Adds various definitions needed to move the AcpiPlatform driver from
FvLateOpenBoard binary to open source.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>
---
 Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciHostBridge/PciHostBridge.inf |   1 +
 Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciPlatform/PciPlatform.inf     |   1 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Madt.h                              | 118 +++++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Slit.h                              |  75 +++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Srat.h                              |  53 ++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/amlresrc.h                          | 542 ++++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc                     |   6 +-
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/AcpiPlatformLib.h                | 107 ++++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformStatusCodes.h            | 364 +++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaFpkConfigLib.h                |  55 ++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaSmbiosUpdateLib.h             | 275 ++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BoardInitLib/BoardInitDxeLib.inf         |   1 +
 12 files changed, 1597 insertions(+), 1 deletion(-)

diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciHostBridge/PciHostBridge.inf b/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciHostBridge/PciHostBridge.inf
index faea9726f7..80a4288895 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciHostBridge/PciHostBridge.inf
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciHostBridge/PciHostBridge.inf
@@ -34,6 +34,7 @@
   WhitleySiliconPkg/CpRcPkg.dec
   WhitleySiliconPkg/Cpu/CpuRcPkg.dec
   WhitleyOpenBoardPkg/PlatformPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
 
 [LibraryClasses]
   UefiDriverEntryPoint
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciPlatform/PciPlatform.inf b/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciPlatform/PciPlatform.inf
index 4121ea8982..cf5148b135 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciPlatform/PciPlatform.inf
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciPlatform/PciPlatform.inf
@@ -32,6 +32,7 @@
   WhitleySiliconPkg/CpRcPkg.dec
   WhitleySiliconPkg/Cpu/CpuRcPkg.dec
   WhitleyOpenBoardPkg/PlatformPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
 
 [LibraryClasses]
   UefiDriverEntryPoint
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Madt.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Madt.h
new file mode 100644
index 0000000000..1860e1104d
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Madt.h
@@ -0,0 +1,118 @@
+/** @file
+  This file describes the contents of the ACPI Multiple APIC Description
+  Table (MADT).  Some additional ACPI values are defined in Acpi1_0.h and
+  Acpi2_0.h.
+  To make changes to the MADT, it is necessary to update the count for the
+  APIC structure being updated, and to modify table found in Madt.c.
+
+  @copyright
+  Copyright 1996 - 2014 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MADT_H
+#define _MADT_H
+
+//
+// Statements that include other files
+//
+#include <IndustryStandard/Acpi.h>
+#include "Platform.h"
+
+//
+// MADT Definitions
+//
+#define EFI_ACPI_OEM_MADT_REVISION                      0x00000000
+//
+// Multiple APIC Flags are defined in AcpiX.0.h
+//
+#define EFI_ACPI_6_2_MULTIPLE_APIC_FLAGS  (EFI_ACPI_6_2_PCAT_COMPAT)
+
+//
+// Local APIC address
+//
+#define EFI_ACPI_LOCAL_APIC_ADDRESS 0xFEE00000
+//
+// Define the number of each table type.
+// This is where the table layout is modified.
+//
+#define EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT           MAX_CPU_NUM
+#define EFI_ACPI_LOCAL_APIC_NMI_COUNT                 MAX_CPU_NUM
+#define EFI_ACPI_PROCESSOR_LOCAL_X2APIC_COUNT         MAX_CPU_NUM
+#define EFI_ACPI_LOCAL_X2APIC_NMI_COUNT               MAX_CPU_NUM
+#define EFI_ACPI_IO_APIC_COUNT                        32 + 1  // IIO I/O APIC (PCH) +  I/O APIC (PC00-PC31)
+#define EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT      2
+#define EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT  0
+#define EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT    0
+#define EFI_ACPI_IO_SAPIC_COUNT                       0
+#define EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT          0
+#define EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT     0
+
+//
+// MADT structure
+//
+//
+// Ensure proper structure formats
+//
+#pragma pack(1)
+//
+// ACPI 4.0 Table structure
+//
+typedef struct {
+  EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER   Header;
+
+#if EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT > 0              // Type 0x00
+  EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_STRUCTURE           LocalApic[EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT];
+#endif
+
+#if EFI_ACPI_IO_APIC_COUNT > 0                          // Type 0x01
+  EFI_ACPI_6_2_IO_APIC_STRUCTURE                        IoApic[EFI_ACPI_IO_APIC_COUNT];
+#endif
+
+#if EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT > 0        // Type 0x02
+  EFI_ACPI_6_2_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE      Iso[EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT];
+#endif
+
+#if EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT > 0    // Type 0x03
+  EFI_ACPI_6_2_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE  NmiSource[EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT];
+#endif
+
+#if EFI_ACPI_LOCAL_APIC_NMI_COUNT > 0                    // Type 0x04
+  EFI_ACPI_6_2_LOCAL_APIC_NMI_STRUCTURE                 LocalApicNmi;
+#endif
+
+#if EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT > 0      // Type 0x05
+  EFI_ACPI_6_2_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE    LocalApicOverride[EFI_ACPI_LOCAL_APIC_OVERRIDE_COUNT];
+#endif
+
+#if EFI_ACPI_IO_SAPIC_COUNT > 0                          // Type 0x06
+  EFI_ACPI_6_2_IO_SAPIC_STRUCTURE                       IoSapic[EFI_ACPI_IO_SAPIC_COUNT];
+#endif
+
+#if EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT > 0            // Type 0x07 : This table changes in madt 2.0
+  EFI_ACPI_6_2_PROCESSOR_LOCAL_SAPIC_STRUCTURE          LocalSapic[EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT];
+#endif
+
+#if EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT > 0        // Type 0x08
+  EFI_ACPI_6_2_PLATFORM_INTERRUPT_SOURCES_STRUCTURE     PlatformInterruptSources[
+    EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT];
+#endif
+
+#if EFI_ACPI_PROCESSOR_LOCAL_X2APIC_COUNT  > 0          //Type 0x09
+  EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_STRUCTURE LocalX2Apic[EFI_ACPI_PROCESSOR_LOCAL_X2APIC_COUNT];
+#endif
+
+#if EFI_ACPI_LOCAL_X2APIC_NMI_COUNT > 0                  //Type 0x0A
+  EFI_ACPI_6_2_LOCAL_X2APIC_NMI_STRUCTURE X2ApicNmi;
+#endif
+
+
+} EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE;
+
+
+
+
+#pragma pack()
+
+#endif
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Slit.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Slit.h
new file mode 100644
index 0000000000..bda37bc3cf
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Slit.h
@@ -0,0 +1,75 @@
+/** @file
+  This file describes the contents of the ACPI System Locality Information
+  Table (SLIT).  Some additional ACPI 3.0 values are defined in Acpi3_0.h.
+  All changes to the Slit contents should be done in this file.
+
+  @copyright
+  Copyright 1999 - 2019 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SLIT_H_
+#define _SLIT_H_
+
+#include "MaxSocket.h"
+
+//
+// SLIT Definitions, see TBD specification for details.
+//
+
+#define EFI_ACPI_OEM_SLIT_REVISION  0x00000001
+//
+// SLIT Revision (defined in spec)
+//
+#define EFI_ACPI_SLIT_PMEM_NODES_SOCKET_MAX_CNT 8  // Max number of PMEM nodes per socket
+#define EFI_ACPI_SLIT_NODES_SOCKET_MAX_CNT      4  // Max number of SNC nodes
+#define EFI_ACPI_SLIT_DOMAINS_NODES_MAX_CNT     2  // Max number of Domins per SNC node (1LM domain and 2LM domain)
+
+#define EFI_ACPI_SLIT_NODES_MAX_CNT \
+  (MAX_SOCKET * ((EFI_ACPI_SLIT_NODES_SOCKET_MAX_CNT * EFI_ACPI_SLIT_DOMAINS_NODES_MAX_CNT) \
+  + EFI_ACPI_SLIT_PMEM_NODES_SOCKET_MAX_CNT))
+
+#define EFI_ACPI_SYSTEM_LOCALITIES_ENTRY_COUNT \
+  (EFI_ACPI_SLIT_NODES_MAX_CNT * EFI_ACPI_SLIT_NODES_MAX_CNT)
+
+#define EFI_ACPI_SLIT_PMEM_INFO_CNT \
+  (MAX_SOCKET * EFI_ACPI_SLIT_PMEM_NODES_SOCKET_MAX_CNT)
+
+#define PMEM_INVALID_SOCKET         0xFF
+
+#define PMEM_ZERO_HOP               10
+#define PMEM_ONE_ONE                17
+#define PMEM_ONE_HOP                28
+#define PMEM_TWO_HOP                38
+
+#define ZERO_HOP                    10
+#define ZERO_ONE                    11
+#define ZERO_TWO                    12
+#define ZERO_THREE                  13
+#define ONE_HOP                     20
+#define ONE_ONE                     21
+#define ONE_TWO                     22
+#define TWO_HOP                     30
+#define THREE_HOP                   40
+#define DISTANT_NODE_4S_EP          2
+#define DISTANT_NODE_4S_EP_COD      (DISTANT_NODE_4S_EP * 2)
+
+typedef struct {
+  UINT8 Socket;
+  UINT8 Pmem;
+  UINT8 Valid;
+} EFI_ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE_PMEM_INFO;
+
+typedef struct {
+  UINT8   Entry;
+} ACPI_SYSTEM_LOCALITIES_STRUCTURE;
+
+typedef struct {
+  EFI_ACPI_6_2_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER    Header;
+  ACPI_SYSTEM_LOCALITIES_STRUCTURE                                  NumSlit[0];
+
+} ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE;
+
+
+#endif
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Srat.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Srat.h
new file mode 100644
index 0000000000..3f3a6545c2
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Srat.h
@@ -0,0 +1,53 @@
+/** @file
+  ACPI Static resource definition table implementation, defined at
+  http://microsoft.com/hwdev/design/srat.htm.
+
+  @copyright
+  Copyright 1999 - 2019 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SRAT_H_
+#define _SRAT_H_
+
+//
+// Statements that include other files
+//
+#include <IndustryStandard/Acpi.h>
+
+//
+#define EFI_ACPI_OEM_SRAT_REVISION  0x00000002  //
+
+//
+// TBD :Backward Compatibility per ACPI 3.0. Required by Hyper-V. OS's ok so far as of 5/27/09
+//
+#define EFI_ACPI_SRAT_RESERVED_FOR_BACKWARD_COMPATIBILITY  0x00000001
+//
+// Define the number of each table type.
+// This is where the table layout is modified.
+//
+#define PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE_COUNT   MAX_CPU_NUM
+#define MEMORY_AFFINITY_STRUCTURE_COUNT                       MC_MAX_NODE*MAX_CRS_ENTRIES_PER_NODE
+#define X2APIC_AFFINITY_STRUCTURE_COUNT                       MAX_CPU_NUM
+//
+// Statis Resource Affinity Table header definition.  The table
+// must be defined in a platform specific manner.
+//
+//
+// Ensure proper structure formats
+//
+#pragma pack(1)
+
+typedef struct {
+  EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER          *SratHeader;
+
+  EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE  *Apic;
+  EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE                      *Memory;
+  EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE      *x2Apic;
+
+} STATIC_RESOURCE_AFFINITY_TABLE;
+
+#pragma pack()
+
+#endif
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/amlresrc.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/amlresrc.h
new file mode 100644
index 0000000000..ddbca04903
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/amlresrc.h
@@ -0,0 +1,542 @@
+/** @file
+
+  @copyright
+  Copyright 1999 - 2017 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+/* acpisrc:StructDefs -- for acpisrc conversion */
+
+#ifndef __AMLRESRC_H
+#define __AMLRESRC_H
+
+
+/*
+ * Resource descriptor tags, as defined in the ACPI specification.
+ * Used to symbolically reference fields within a descriptor.
+ */
+#define ACPI_RESTAG_ADDRESS                     "_ADR"
+#define ACPI_RESTAG_ALIGNMENT                   "_ALN"
+#define ACPI_RESTAG_ADDRESSSPACE                "_ASI"
+#define ACPI_RESTAG_ACCESSSIZE                  "_ASZ"
+#define ACPI_RESTAG_TYPESPECIFICATTRIBUTES      "_ATT"
+#define ACPI_RESTAG_BASEADDRESS                 "_BAS"
+#define ACPI_RESTAG_BUSMASTER                   "_BM_"  /* Master(1), Slave(0) */
+#define ACPI_RESTAG_DEBOUNCETIME                "_DBT"
+#define ACPI_RESTAG_DECODE                      "_DEC"
+#define ACPI_RESTAG_DEVICEPOLARITY              "_DPL"
+#define ACPI_RESTAG_DMA                         "_DMA"
+#define ACPI_RESTAG_DMATYPE                     "_TYP"  /* Compatible(0), A(1), B(2), F(3) */
+#define ACPI_RESTAG_DRIVESTRENGTH               "_DRS"
+#define ACPI_RESTAG_ENDIANNESS                  "_END"
+#define ACPI_RESTAG_FLOWCONTROL                 "_FLC"
+#define ACPI_RESTAG_GRANULARITY                 "_GRA"
+#define ACPI_RESTAG_INTERRUPT                   "_INT"
+#define ACPI_RESTAG_INTERRUPTLEVEL              "_LL_"  /* ActiveLo(1), ActiveHi(0) */
+#define ACPI_RESTAG_INTERRUPTSHARE              "_SHR"  /* Shareable(1), NoShare(0) */
+#define ACPI_RESTAG_INTERRUPTTYPE               "_HE_"  /* Edge(1), Level(0) */
+#define ACPI_RESTAG_IORESTRICTION               "_IOR"
+#define ACPI_RESTAG_LENGTH                      "_LEN"
+#define ACPI_RESTAG_LINE                        "_LIN"
+#define ACPI_RESTAG_MEMATTRIBUTES               "_MTP"  /* Memory(0), Reserved(1), ACPI(2), NVS(3) */
+#define ACPI_RESTAG_MEMTYPE                     "_MEM"  /* NonCache(0), Cacheable(1) Cache+combine(2), Cache+prefetch(3) */
+#define ACPI_RESTAG_MAXADDR                     "_MAX"
+#define ACPI_RESTAG_MINADDR                     "_MIN"
+#define ACPI_RESTAG_MAXTYPE                     "_MAF"
+#define ACPI_RESTAG_MINTYPE                     "_MIF"
+#define ACPI_RESTAG_MODE                        "_MOD"
+#define ACPI_RESTAG_PARITY                      "_PAR"
+#define ACPI_RESTAG_PHASE                       "_PHA"
+#define ACPI_RESTAG_PIN                         "_PIN"
+#define ACPI_RESTAG_PINCONFIG                   "_PPI"
+#define ACPI_RESTAG_POLARITY                    "_POL"
+#define ACPI_RESTAG_REGISTERBITOFFSET           "_RBO"
+#define ACPI_RESTAG_REGISTERBITWIDTH            "_RBW"
+#define ACPI_RESTAG_RANGETYPE                   "_RNG"
+#define ACPI_RESTAG_READWRITETYPE               "_RW_"  /* ReadOnly(0), Writeable (1) */
+#define ACPI_RESTAG_LENGTH_RX                   "_RXL"
+#define ACPI_RESTAG_LENGTH_TX                   "_TXL"
+#define ACPI_RESTAG_SLAVEMODE                   "_SLV"
+#define ACPI_RESTAG_SPEED                       "_SPE"
+#define ACPI_RESTAG_STOPBITS                    "_STB"
+#define ACPI_RESTAG_TRANSLATION                 "_TRA"
+#define ACPI_RESTAG_TRANSTYPE                   "_TRS"  /* Sparse(1), Dense(0) */
+#define ACPI_RESTAG_TYPE                        "_TTP"  /* Translation(1), Static (0) */
+#define ACPI_RESTAG_XFERTYPE                    "_SIZ"  /* 8(0), 8And16(1), 16(2) */
+#define ACPI_RESTAG_VENDORDATA                  "_VEN"
+
+
+/* Default sizes for "small" resource descriptors */
+
+#define ASL_RDESC_IRQ_SIZE                      0x02
+#define ASL_RDESC_DMA_SIZE                      0x02
+#define ASL_RDESC_ST_DEPEND_SIZE                0x00
+#define ASL_RDESC_END_DEPEND_SIZE               0x00
+#define ASL_RDESC_IO_SIZE                       0x07
+#define ASL_RDESC_FIXED_IO_SIZE                 0x03
+#define ASL_RDESC_FIXED_DMA_SIZE                0x05
+#define ASL_RDESC_END_TAG_SIZE                  0x01
+
+
+typedef struct asl_resource_node
+{
+    UINT32                          BufferLength;
+    VOID                            *Buffer;
+    struct asl_resource_node        *Next;
+
+} ASL_RESOURCE_NODE;
+
+
+/* Macros used to generate AML resource length fields */
+
+#define ACPI_AML_SIZE_LARGE(r)      (sizeof (r) - sizeof (AML_RESOURCE_LARGE_HEADER))
+#define ACPI_AML_SIZE_SMALL(r)      (sizeof (r) - sizeof (AML_RESOURCE_SMALL_HEADER))
+
+/*
+ * Resource descriptors defined in the ACPI specification.
+ *
+ * Packing/alignment must be BYTE because these descriptors
+ * are used to overlay the raw AML byte stream.
+ */
+#pragma pack(1)
+
+/*
+ * SMALL descriptors
+ */
+#define AML_RESOURCE_SMALL_HEADER_COMMON \
+    UINT8                           DescriptorType;
+
+typedef struct aml_resource_small_header
+{
+    AML_RESOURCE_SMALL_HEADER_COMMON
+
+} AML_RESOURCE_SMALL_HEADER;
+
+
+typedef struct aml_resource_irq
+{
+    AML_RESOURCE_SMALL_HEADER_COMMON
+    UINT16                          IrqMask;
+    UINT8                           Flags;
+
+} AML_RESOURCE_IRQ;
+
+
+typedef struct aml_resource_irq_noflags
+{
+    AML_RESOURCE_SMALL_HEADER_COMMON
+    UINT16                          IrqMask;
+
+} AML_RESOURCE_IRQ_NOFLAGS;
+
+
+typedef struct aml_resource_dma
+{
+    AML_RESOURCE_SMALL_HEADER_COMMON
+    UINT8                           DmaChannelMask;
+    UINT8                           Flags;
+
+} AML_RESOURCE_DMA;
+
+
+typedef struct aml_resource_start_dependent
+{
+    AML_RESOURCE_SMALL_HEADER_COMMON
+    UINT8                           Flags;
+
+} AML_RESOURCE_START_DEPENDENT;
+
+
+typedef struct aml_resource_start_dependent_noprio
+{
+    AML_RESOURCE_SMALL_HEADER_COMMON
+
+} AML_RESOURCE_START_DEPENDENT_NOPRIO;
+
+
+typedef struct aml_resource_end_dependent
+{
+    AML_RESOURCE_SMALL_HEADER_COMMON
+
+} AML_RESOURCE_END_DEPENDENT;
+
+
+typedef struct aml_resource_io
+{
+    AML_RESOURCE_SMALL_HEADER_COMMON
+    UINT8                           Flags;
+    UINT16                          Minimum;
+    UINT16                          Maximum;
+    UINT8                           Alignment;
+    UINT8                           AddressLength;
+
+} AML_RESOURCE_IO;
+
+
+typedef struct aml_resource_fixed_io
+{
+    AML_RESOURCE_SMALL_HEADER_COMMON
+    UINT16                          Address;
+    UINT8                           AddressLength;
+
+} AML_RESOURCE_FIXED_IO;
+
+
+typedef struct aml_resource_vendor_small
+{
+    AML_RESOURCE_SMALL_HEADER_COMMON
+
+} AML_RESOURCE_VENDOR_SMALL;
+
+
+typedef struct aml_resource_end_tag
+{
+    AML_RESOURCE_SMALL_HEADER_COMMON
+    UINT8                           Checksum;
+
+} AML_RESOURCE_END_TAG;
+
+
+typedef struct aml_resource_fixed_dma
+{
+    AML_RESOURCE_SMALL_HEADER_COMMON
+    UINT16                          RequestLines;
+    UINT16                          Channels;
+    UINT8                           Width;
+
+} AML_RESOURCE_FIXED_DMA;
+
+
+/*
+ * LARGE descriptors
+ */
+#define AML_RESOURCE_LARGE_HEADER_COMMON \
+    UINT8                           DescriptorType;\
+    UINT16                          ResourceLength;
+
+typedef struct aml_resource_large_header
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+
+} AML_RESOURCE_LARGE_HEADER;
+
+
+/* General Flags for address space resource descriptors */
+
+#define ACPI_RESOURCE_FLAG_DEC      2
+#define ACPI_RESOURCE_FLAG_MIF      4
+#define ACPI_RESOURCE_FLAG_MAF      8
+
+typedef struct aml_resource_memory24
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    UINT8                           Flags;
+    UINT16                          Minimum;
+    UINT16                          Maximum;
+    UINT16                          Alignment;
+    UINT16                          AddressLength;
+
+} AML_RESOURCE_MEMORY24;
+
+
+typedef struct aml_resource_vendor_large
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+
+} AML_RESOURCE_VENDOR_LARGE;
+
+
+typedef struct aml_resource_memory32
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    UINT8                           Flags;
+    UINT32                          Minimum;
+    UINT32                          Maximum;
+    UINT32                          Alignment;
+    UINT32                          AddressLength;
+
+} AML_RESOURCE_MEMORY32;
+
+
+typedef struct aml_resource_fixed_memory32
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    UINT8                           Flags;
+    UINT32                          Address;
+    UINT32                          AddressLength;
+
+} AML_RESOURCE_FIXED_MEMORY32;
+
+
+#define AML_RESOURCE_ADDRESS_COMMON \
+    UINT8                           ResourceType; \
+    UINT8                           Flags; \
+    UINT8                           SpecificFlags;
+
+
+typedef struct aml_resource_address
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    AML_RESOURCE_ADDRESS_COMMON
+
+} AML_RESOURCE_ADDRESS;
+
+
+typedef struct aml_resource_extended_address64
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    AML_RESOURCE_ADDRESS_COMMON
+    UINT8                           RevisionID;
+    UINT8                           Reserved;
+    UINT64                          Granularity;
+    UINT64                          Minimum;
+    UINT64                          Maximum;
+    UINT64                          TranslationOffset;
+    UINT64                          AddressLength;
+    UINT64                          TypeSpecific;
+
+} AML_RESOURCE_EXTENDED_ADDRESS64;
+
+#define AML_RESOURCE_EXTENDED_ADDRESS_REVISION          1       /* ACPI 3.0 */
+
+
+typedef struct aml_resource_address64
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    AML_RESOURCE_ADDRESS_COMMON
+    UINT64                          Granularity;
+    UINT64                          Minimum;
+    UINT64                          Maximum;
+    UINT64                          TranslationOffset;
+    UINT64                          AddressLength;
+
+} AML_RESOURCE_ADDRESS64;
+
+
+typedef struct aml_resource_address32
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    AML_RESOURCE_ADDRESS_COMMON
+    UINT32                          Granularity;
+    UINT32                          Minimum;
+    UINT32                          Maximum;
+    UINT32                          TranslationOffset;
+    UINT32                          AddressLength;
+
+} AML_RESOURCE_ADDRESS32;
+
+
+typedef struct aml_resource_address16
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    AML_RESOURCE_ADDRESS_COMMON
+    UINT16                          Granularity;
+    UINT16                          Minimum;
+    UINT16                          Maximum;
+    UINT16                          TranslationOffset;
+    UINT16                          AddressLength;
+
+} AML_RESOURCE_ADDRESS16;
+
+
+typedef struct aml_resource_extended_irq
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    UINT8                           Flags;
+    UINT8                           InterruptCount;
+    UINT32                          Interrupts[1];
+    /* ResSourceIndex, ResSource optional fields follow */
+
+} AML_RESOURCE_EXTENDED_IRQ;
+
+
+typedef struct aml_resource_generic_register
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    UINT8                           AddressSpaceId;
+    UINT8                           BitWidth;
+    UINT8                           BitOffset;
+    UINT8                           AccessSize; /* ACPI 3.0, was previously Reserved */
+    UINT64                          Address;
+
+} AML_RESOURCE_GENERIC_REGISTER;
+
+
+/* Common descriptor for GpioInt and GpioIo (ACPI 5.0) */
+
+typedef struct aml_resource_gpio
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    UINT8                           RevisionId;
+    UINT8                           ConnectionType;
+    UINT16                          Flags;
+    UINT16                          IntFlags;
+    UINT8                           PinConfig;
+    UINT16                          DriveStrength;
+    UINT16                          DebounceTimeout;
+    UINT16                          PinTableOffset;
+    UINT8                           ResSourceIndex;
+    UINT16                          ResSourceOffset;
+    UINT16                          VendorOffset;
+    UINT16                          VendorLength;
+    /*
+     * Optional fields follow immediately:
+     * 1) PIN list (Words)
+     * 2) Resource Source String
+     * 3) Vendor Data bytes
+     */
+
+} AML_RESOURCE_GPIO;
+
+#define AML_RESOURCE_GPIO_REVISION              1       /* ACPI 5.0 */
+
+/* Values for ConnectionType above */
+
+#define AML_RESOURCE_GPIO_TYPE_INT              0
+#define AML_RESOURCE_GPIO_TYPE_IO               1
+#define AML_RESOURCE_MAX_GPIOTYPE               1
+
+
+/* Common preamble for all serial descriptors (ACPI 5.0) */
+
+#define AML_RESOURCE_SERIAL_COMMON \
+    UINT8                           RevisionId; \
+    UINT8                           ResSourceIndex; \
+    UINT8                           Type; \
+    UINT8                           Flags; \
+    UINT16                          TypeSpecificFlags; \
+    UINT8                           TypeRevisionId; \
+    UINT16                          TypeDataLength; \
+
+/* Values for the type field above */
+
+#define AML_RESOURCE_I2C_SERIALBUSTYPE          1
+#define AML_RESOURCE_SPI_SERIALBUSTYPE          2
+#define AML_RESOURCE_UART_SERIALBUSTYPE         3
+#define AML_RESOURCE_MAX_SERIALBUSTYPE          3
+#define AML_RESOURCE_VENDOR_SERIALBUSTYPE       192 /* Vendor defined is 0xC0-0xFF (NOT SUPPORTED) */
+
+typedef struct aml_resource_common_serialbus
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    AML_RESOURCE_SERIAL_COMMON
+
+} AML_RESOURCE_COMMON_SERIALBUS;
+
+typedef struct aml_resource_i2c_serialbus
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    AML_RESOURCE_SERIAL_COMMON
+    UINT32                          ConnectionSpeed;
+    UINT16                          SlaveAddress;
+    /*
+     * Optional fields follow immediately:
+     * 1) Vendor Data bytes
+     * 2) Resource Source String
+     */
+
+} AML_RESOURCE_I2C_SERIALBUS;
+
+#define AML_RESOURCE_I2C_REVISION               1       /* ACPI 5.0 */
+#define AML_RESOURCE_I2C_TYPE_REVISION          1       /* ACPI 5.0 */
+#define AML_RESOURCE_I2C_MIN_DATA_LEN           6
+
+typedef struct aml_resource_spi_serialbus
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    AML_RESOURCE_SERIAL_COMMON
+    UINT32                          ConnectionSpeed;
+    UINT8                           DataBitLength;
+    UINT8                           ClockPhase;
+    UINT8                           ClockPolarity;
+    UINT16                          DeviceSelection;
+    /*
+     * Optional fields follow immediately:
+     * 1) Vendor Data bytes
+     * 2) Resource Source String
+     */
+
+} AML_RESOURCE_SPI_SERIALBUS;
+
+#define AML_RESOURCE_SPI_REVISION               1       /* ACPI 5.0 */
+#define AML_RESOURCE_SPI_TYPE_REVISION          1       /* ACPI 5.0 */
+#define AML_RESOURCE_SPI_MIN_DATA_LEN           9
+
+
+typedef struct aml_resource_uart_serialbus
+{
+    AML_RESOURCE_LARGE_HEADER_COMMON
+    AML_RESOURCE_SERIAL_COMMON
+    UINT32                          DefaultBaudRate;
+    UINT16                          RxFifoSize;
+    UINT16                          TxFifoSize;
+    UINT8                           Parity;
+    UINT8                           LinesEnabled;
+    /*
+     * Optional fields follow immediately:
+     * 1) Vendor Data bytes
+     * 2) Resource Source String
+     */
+
+} AML_RESOURCE_UART_SERIALBUS;
+
+#define AML_RESOURCE_UART_REVISION              1       /* ACPI 5.0 */
+#define AML_RESOURCE_UART_TYPE_REVISION         1       /* ACPI 5.0 */
+#define AML_RESOURCE_UART_MIN_DATA_LEN          10
+
+
+/* restore default alignment */
+
+#pragma pack()
+
+/* Union of all resource descriptors, so we can allocate the worst case */
+
+typedef union aml_resource
+{
+    /* Descriptor headers */
+
+    UINT8                                   DescriptorType;
+    AML_RESOURCE_SMALL_HEADER               SmallHeader;
+    AML_RESOURCE_LARGE_HEADER               LargeHeader;
+
+    /* Small resource descriptors */
+
+    AML_RESOURCE_IRQ                        Irq;
+    AML_RESOURCE_DMA                        Dma;
+    AML_RESOURCE_START_DEPENDENT            StartDpf;
+    AML_RESOURCE_END_DEPENDENT              EndDpf;
+    AML_RESOURCE_IO                         Io;
+    AML_RESOURCE_FIXED_IO                   FixedIo;
+    AML_RESOURCE_FIXED_DMA                  FixedDma;
+    AML_RESOURCE_VENDOR_SMALL               VendorSmall;
+    AML_RESOURCE_END_TAG                    EndTag;
+
+    /* Large resource descriptors */
+
+    AML_RESOURCE_MEMORY24                   Memory24;
+    AML_RESOURCE_GENERIC_REGISTER           GenericReg;
+    AML_RESOURCE_VENDOR_LARGE               VendorLarge;
+    AML_RESOURCE_MEMORY32                   Memory32;
+    AML_RESOURCE_FIXED_MEMORY32             FixedMemory32;
+    AML_RESOURCE_ADDRESS16                  Address16;
+    AML_RESOURCE_ADDRESS32                  Address32;
+    AML_RESOURCE_ADDRESS64                  Address64;
+    AML_RESOURCE_EXTENDED_ADDRESS64         ExtAddress64;
+    AML_RESOURCE_EXTENDED_IRQ               ExtendedIrq;
+    AML_RESOURCE_GPIO                       Gpio;
+    AML_RESOURCE_I2C_SERIALBUS              I2cSerialBus;
+    AML_RESOURCE_SPI_SERIALBUS              SpiSerialBus;
+    AML_RESOURCE_UART_SERIALBUS             UartSerialBus;
+    AML_RESOURCE_COMMON_SERIALBUS           CommonSerialBus;
+
+    /* Utility overlays */
+
+    AML_RESOURCE_ADDRESS                    Address;
+    UINT32                                  DwordItem;
+    UINT16                                  WordItem;
+    UINT8                                   ByteItem;
+
+} AML_RESOURCE;
+
+#endif
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc b/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc
index d806521abf..1a85a26e25 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc
@@ -134,9 +134,13 @@ DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS) $(ME
 #
 # Override the VFR compile flags to speed the build time
 #
-
 *_*_*_VFR_FLAGS                     ==  -n
 
+#
+# Disable remarks, enable warnings as errors, disable integer optimization,
+#
+  *_*_*_ASL_FLAGS = -vr -we -oi
+
 #
 # add to the build options for DXE/SMM drivers to remove the log message:
 # !!!!!!!!  InsertImageRecord - Section Alignment(0x20) is not 4K  !!!!!!!!
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/AcpiPlatformLib.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/AcpiPlatformLib.h
new file mode 100644
index 0000000000..8ec25b8c16
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/AcpiPlatformLib.h
@@ -0,0 +1,107 @@
+/** @file
+
+  @copyright
+  Copyright 1996 - 2017 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_PLATFORM_LIB_H_
+#define _ACPI_PLATFORM_LIB_H_
+
+//
+// Statements that include other header files
+//
+#include <PiDxe.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+
+#include <IndustryStandard/Acpi.h>
+
+#include <Protocol/MpService.h>
+
+#include <Protocol/AcpiSystemDescriptionTable.h>
+
+
+EFI_STATUS
+AcpiPlatformHooksIsActiveTable (
+  IN OUT EFI_ACPI_COMMON_HEADER     *Table
+  );
+
+/*++
+
+Routine Description:
+
+  Called for every ACPI table found in the BIOS flash.
+  Returns whether a table is active or not. Inactive tables
+  are not published in the ACPI table list. This hook can be
+  used to implement optional SSDT tables or enabling/disabling
+  specific functionality (e.g. SPCR table) based on a setup
+  switch or platform preference. In case of optional SSDT tables,
+  the platform flash will include all the SSDT tables but will
+  return EFI_SUCCESS only for those tables that need to be
+  published.
+  This hook can also be used to update the table data. The header
+  is updated by the common code. For example, if a platform wants
+  to use an SSDT table to export some platform settings to the
+  ACPI code, it needs to update the data inside that SSDT based
+  on platform preferences in this hook.
+
+Arguments:
+
+  None
+
+Returns:
+
+  Status  - EFI_SUCCESS if the table is active
+  Status  - EFI_UNSUPPORTED if the table is not active
+*/
+
+/**
+
+  This function will update any runtime platform specific information.
+  This currently includes:
+    Setting OEM table values, ID, table ID, creator ID and creator revision.
+    Enabling the proper processor entries in the APIC tables.
+
+  @param Table  -  The table to update
+
+  @retval EFI_SUCCESS  -  The function completed successfully.
+
+**/
+EFI_STATUS
+PlatformUpdateTables (
+  IN OUT EFI_ACPI_COMMON_HEADER     *Table
+  ,IN OUT EFI_ACPI_TABLE_VERSION     *Version
+  );
+
+/**
+  Give the platform a chance to build tables.
+
+  Some tables can be built from scratch more efficiently than being prebuilt
+  and updated. This function builds any such tables for the platform.
+
+  @retval EFI_SUCCESS   Any platform tables were successfully built.
+**/
+EFI_STATUS
+PlatformBuildTables (
+  VOID
+  );
+
+/**
+  Platform hook to initialize Platform Specific ACPI Parameters
+
+  @retval EFI_SUCCESS            Platform specific parameters in mAcpiParameter
+                                 initialized successfully.
+  @retval EFI_INVALID_PARAMETER  mAcpiParameter global was NULL.
+**/
+EFI_STATUS
+PlatformHookAfterAcpiParamInit (
+  VOID
+  );
+
+#endif
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformStatusCodes.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformStatusCodes.h
new file mode 100644
index 0000000000..dbe7fa075e
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformStatusCodes.h
@@ -0,0 +1,364 @@
+/** @file
+  PostCode status code definition.
+
+  @copyright
+  Copyright 2011 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PLATFORM_STATUS_CODES_INTERNAL_H__
+#define __PLATFORM_STATUS_CODES_INTERNAL_H__
+
+#include <Pi/PiStatusCode.h>
+
+//
+//Error Code Operations
+//
+// ME related error definitions
+#define EFI_COMPUTING_UNIT_ME_PROCESSOR            (EFI_COMPUTING_UNIT | 0x00800000)
+#define EFI_CU_ME_SELFTEST_FAIL                    (EFI_OEM_SPECIFIC | 0x00000000)
+
+//Chipset:EFI_COMPUTING_UNIT_CHIPSET
+#define EFI_CU_CHIPSET_EC_NVVARIABLES_CLEARED      (EFI_OEM_SPECIFIC | 0x00000003)
+#define EFI_CU_CHIPSET_EC_NVVARIABLES_CORRUPTED    (EFI_OEM_SPECIFIC | 0x00000004)
+#define EFI_CU_CHIPSET_SOFT_RECOVERY_MODE          (EFI_OEM_SPECIFIC | 0x00000009)
+
+// TPM related error definations
+#define EFI_COMPUTING_UNIT_TPM           (EFI_COMPUTING_UNIT | 0x00810000)
+#define EFI_CU_TPM_NOT_DETECTED          (EFI_OEM_SPECIFIC | 0x00000000)
+#define EFI_CU_TPM_TIMEOUT_FAILURE       (EFI_OEM_SPECIFIC | 0x00000001)
+#define EFI_CU_TPM_FAIL                  (EFI_OEM_SPECIFIC | 0x00000002)
+#define EFI_CU_TPM_FAILED_SELFTEST       (EFI_OEM_SPECIFIC | 0x00000003)
+
+//TXT related error definations
+#define EFI_COMPUTING_UNIT_TXT           (EFI_COMPUTING_UNIT | 0x00820000)
+#define EFI_CU_TXT_ACM_ERROR             (EFI_OEM_SPECIFIC | 0x00000004)
+
+//Subclass of Computing Unit Class:EFI_COMPUTING_UNIT_MEMORY
+#define EFI_CU_MEMORY_EC_POPU_FAIL       (EFI_OEM_SPECIFIC | 0x00000000)
+
+//Subclass of Computing Unit Class:  EFI_COMPUTING_UNIT_HOST_PROCESSOR
+#define EFI_CU_DISABLE_INFO                (EFI_OEM_SPECIFIC | 0x00000017)
+
+//Software Subclass definitions:EFI_SOFTWARE_PEI_MODULE
+#define EFI_SW_PEIM_EC_NO_RECOVERY_CAPSULE (EFI_OEM_SPECIFIC | 0x00000000)
+
+//
+//Progress Code:Start from 0x8500 for OEM use
+//
+
+#define EFI_SW_RS_PC_VARIABLE_INIT                   (EFI_OEM_SPECIFIC | 0x00000501)
+#define EFI_SW_DXE_BS_SETUP_INIT                     (EFI_OEM_SPECIFIC | 0x00000502)
+#define EFI_SW_DXE_BS_ACPI_INIT                      (EFI_OEM_SPECIFIC | 0x00000503)
+#define EFI_SW_DXE_BS_CSM_INIT                       (EFI_OEM_SPECIFIC | 0x00000504)
+#define EFI_SW_SMM_ACPI_ENABLE                       (EFI_OEM_SPECIFIC | 0x00000505)
+#define EFI_SW_RS_PC_VARIABLE_RECLAIM                (EFI_OEM_SPECIFIC | 0x00000506)
+#define EFI_IOB_PCI_RES_ASSIGN                       (EFI_OEM_SPECIFIC | 0x00000507)
+#ifndef EFI_SW_PEI_PC_S3_STARTED
+#define EFI_SW_PEI_PC_S3_STARTED                     (EFI_OEM_SPECIFIC | 0x00000508)
+#endif
+#define EFI_SW_PEI_PC_S3_VIDEO_REPOST                (EFI_OEM_SPECIFIC | 0x00000509)
+#define EFI_SW_RS_PC_POST_END_CLEAR_STATUS           (EFI_OEM_SPECIFIC | 0x0000050a)
+#define EFI_SW_OEM_END_OF_DXE                        (EFI_OEM_SPECIFIC | 0x0000050b)
+
+#define BOOT_CLEAR_STATUS                            (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_POST_END_CLEAR_STATUS)
+#define DXE_NVRAM_INIT                               (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_VARIABLE_INIT)
+#define DXE_SETUP_INIT                               (EFI_SOFTWARE_DXE_BS_DRIVER       | EFI_SW_DXE_BS_SETUP_INIT)
+#define DXE_ACPI_INIT                                (EFI_SOFTWARE_DXE_BS_DRIVER       | EFI_SW_DXE_BS_ACPI_INIT)
+#define DXE_CSM_INIT                                 (EFI_SOFTWARE_DXE_BS_DRIVER       | EFI_SW_DXE_BS_CSM_INIT)
+#define DXE_ACPI_ENABLE                              (EFI_SOFTWARE_SMM_DRIVER          | EFI_SW_SMM_ACPI_ENABLE)
+#define DXE_NVRAM_CLEANUP                            (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_VARIABLE_RECLAIM)
+#define DXE_END_OF_DXE                               (EFI_SOFTWARE_UNSPECIFIED         | EFI_SW_OEM_END_OF_DXE)
+
+#define DXE_RTC_YEAR_IS_ERROR                        (EFI_SOFTWARE_SYSTEM_ERROR | EFI_SW_EC_CMOS_DATE_TIME_ERROR)
+
+
+typedef struct{
+  EFI_STATUS_CODE_VALUE Value;
+  UINT32                Data;
+} STATUS_CODE_TO_DATA_MAP;
+
+//
+// Enable PEI/DXE status code
+//
+#define PEI_STATUS_CODE 1
+#define DXE_STATUS_CODE 1
+
+#define STATUS_CODE_TYPE(Type)                ((Type)&EFI_STATUS_CODE_TYPE_MASK)
+#define STATUS_CODE_CLASS(Value)              ((Value)&EFI_STATUS_CODE_CLASS_MASK)
+
+//Progress/Error codes
+#define PEI_CORE_STARTED                      (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_ENTRY_POINT)
+#define PEI_RESET_NOT_AVAILABLE               (EFI_SOFTWARE_PEI_CORE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE)
+#define PEI_DXEIPL_NOT_FOUND                  (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_EC_DXEIPL_NOT_FOUND)
+#define PEI_DXE_CORE_NOT_FOUND                (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_EC_DXE_CORRUPT)
+#define PEI_S3_RESUME_ERROR                    (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_EC_S3_RESUME_FAILED)
+#define PEI_RECOVERY_FAILED                   (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_EC_RECOVERY_FAILED)
+#define DXE_CORE_STARTED                      (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT)
+
+#define DXE_EXIT_BOOT_SERVICES_END            (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES)
+
+// Reported by CPU PEIM
+#define PEI_CAR_CPU_INIT                      (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_POWER_ON_INIT)
+
+
+// Reported by SB PEIM
+#define EFI_CU_CHIPSET_PLATFORM_TYPE_INIT     0x00000001
+#define EFI_CU_CHIPSET_PLATFORM_PEIM_INIT     0x00000002
+#define PEI_PLATFORM_TYPE_INIT                (EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_CHIPSET_PLATFORM_TYPE_INIT)
+#define PEI_PLATFORM_PEIM_INIT                (EFI_COMPUTING_UNIT_CHIPSET | EFI_CU_CHIPSET_PLATFORM_PEIM_INIT)
+
+//Reported by Memory Detection PEIM
+#define PEI_MEMORY_SPD_READ                   (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_SPD_READ)
+#define PEI_MEMORY_PRESENCE_DETECT            (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_PRESENCE_DETECT)
+#define PEI_MEMORY_TIMING                     (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_TIMING)
+#define PEI_MEMORY_CONFIGURING                (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_CONFIGURING)
+#define PEI_MEMORY_OPTIMIZING                 (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_OPTIMIZING)
+#define PEI_MEMORY_INIT                       (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_INIT)
+#define PEI_MEMORY_TEST                       (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_PC_TEST)
+#define PEI_MEMORY_INVALID_TYPE               (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_TYPE)
+#define PEI_MEMORY_INVALID_SPEED              (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_SPEED)
+#define PEI_MEMORY_SPD_FAIL                   (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_SPD_FAIL)
+#define PEI_MEMORY_INVALID_SIZE               (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_SIZE)
+#define PEI_MEMORY_MISMATCH                   (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_MISMATCH)
+#define PEI_MEMORY_S3_RESUME_FAILED           (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_S3_RESUME_FAIL)
+#define PEI_MEMORY_NOT_DETECTED               (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_NONE_DETECTED)
+#define PEI_MEMORY_NONE_USEFUL                (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_NONE_USEFUL)
+#define PEI_MEMORY_ERROR                      (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_EC_NON_SPECIFIC)
+#define PEI_MEMORY_INSTALLED                  (EFI_SOFTWARE_PEI_SERVICE  | EFI_SW_PS_PC_INSTALL_PEI_MEMORY)
+#define PEI_MEMORY_NOT_INSTALLED              (EFI_SOFTWARE_PEI_SERVICE  | EFI_SW_PEI_CORE_EC_MEMORY_NOT_INSTALLED)
+#define PEI_MEMORY_INSTALLED_TWICE            (EFI_SOFTWARE_PEI_SERVICE  | EFI_SW_PS_EC_MEMORY_INSTALLED_TWICE)
+
+//Reported by CPU PEIM
+#define PEI_CPU_INIT                          (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_PC_INIT_BEGIN)
+#define PEI_CPU_CACHE_INIT                    (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_CACHE_INIT)
+#define PEI_CPU_BSP_SELECT                    (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_BSP_SELECT)
+#define PEI_CPU_AP_INIT                       (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_AP_INIT)
+#define PEI_CPU_SMM_INIT                      (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT)
+#define PEI_CPU_INVALID_TYPE                  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INVALID_TYPE)
+#define PEI_CPU_INVALID_SPEED                 (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INVALID_SPEED)
+#define PEI_CPU_MISMATCH                      (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_MISMATCH)
+#define PEI_CPU_SELF_TEST_FAILED              (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)
+#define PEI_CPU_CACHE_ERROR                   (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_CACHE)
+#define PEI_CPU_MICROCODE_UPDATE_FAILED       (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_MICROCODE_UPDATE)
+#define PEI_CPU_NO_MICROCODE                  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_NO_MICROCODE_UPDATE)
+//If non of the errors above apply use this one
+#define PEI_CPU_INTERNAL_ERROR                (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INTERNAL)
+//Generic CPU error. It should only be used if non of the errors above apply
+#define PEI_CPU_ERROR                         (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_EC_NON_SPECIFIC)
+
+// Reported by NB PEIM
+#define PEI_MEM_NB_INIT                       (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_PEI_MEM_NB_INIT)
+// Reported by SB PEIM
+#define PEI_MEM_SB_INIT                       (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_PEI_MEM_SB_INIT)
+
+//Reported by PEIM which detected forced or auto recovery condition
+#define PEI_RECOVERY_AUTO                     (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_AUTO)
+#define PEI_RECOVERY_USER                     (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_USER)
+
+//Reported by DXE IPL
+#define PEI_RECOVERY_PPI_NOT_FOUND            (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND)
+#define PEI_S3_RESUME_PPI_NOT_FOUND           (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND)
+#define PEI_S3_RESUME_FAILED                  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_FAILED)
+
+//Reported by Recovery PEIM
+#define PEI_RECOVERY_STARTED                  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_BEGIN)
+#define PEI_RECOVERY_CAPSULE_FOUND            (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_LOAD)
+#define PEI_RECOVERY_NO_CAPSULE               (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE)
+#define PEI_RECOVERY_CAPSULE_LOADED           (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_START)
+#define PEI_RECOVERY_INVALID_CAPSULE          (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_INVALID_CAPSULE_DESCRIPTOR)
+
+//Reported by S3 Resume PEIM
+#define PEI_S3_BOOT_SCRIPT                    (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_S3_BOOT_SCRIPT)
+#define PEI_S3_OS_WAKE                        (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE)
+#define PEI_S3_BOOT_SCRIPT_ERROR              (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_BOOT_SCRIPT_ERROR)
+#define PEI_S3_OS_WAKE_ERROR                  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR)
+#define PEI_S3_STARTED                        (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_S3_STARTED)
+#define PEI_S3_VIDEO_REPOST                   (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_S3_VIDEO_REPOST)
+
+
+#define PEI_PEIM_STARTED                      (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN)
+#define PEI_PEIM_ENDED                        (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END)
+
+//Reported by DXE IPL
+#define PEI_DXE_IPL_STARTED                   (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT)
+
+//Reported by PEIM which installs Reset PPI
+#define PEI_RESET_SYSTEM                      (EFI_SOFTWARE_PEI_SERVICE | EFI_SW_PS_PC_RESET_SYSTEM)
+
+//Reported by the PEIM or DXE driver which detected the error
+#define GENERIC_MEMORY_CORRECTABLE_ERROR      (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_CORRECTABLE)
+#define GENERIC_MEMORY_UNCORRECTABLE_ERROR    (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_UNCORRECTABLE)
+
+//Reported by Flash Update DXE driver
+#define DXE_FLASH_UPDATE_FAILED               (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_UPDATE_FAIL)
+
+//Reported by the PEIM or DXE driver which detected the error
+#define GENERIC_CPU_THERMAL_ERROR             (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_THERMAL)
+#define GENERIC_CPU_LOW_VOLTAGE               (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_LOW_VOLTAGE)
+#define GENERIC_CPU_HIGH_VOLTAGE              (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_HIGH_VOLTAGE)
+#define GENERIC_CPU_CORRECTABLE_ERROR         (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_CORRECTABLE)
+#define GENERIC_CPU_UNCORRECTABLE_ERROR       (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_UNCORRECTABLE)
+#define GENERIC_BAD_DATE_TIME_ERROR           (EFI_SOFTWARE_UNSPECIFIED | EFI_SW_EC_BAD_DATE_TIME)
+#define GENERIC_MEMORY_SIZE_DECREASE          (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_MISMATCH)
+
+//Reported by DXE Core
+#define DXE_DRIVER_STARTED                    (EFI_SOFTWARE_EFI_DXE_SERVICE | EFI_SW_PC_INIT_BEGIN)
+#define DXE_DRIVER_ENED                       (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END)
+#define DXE_ARCH_PROTOCOLS_AVAILABLE          (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ARCH_READY)
+#define DXE_DRIVER_CONNECTED                  (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_START_DRIVER)
+#define DXE_ARCH_PROTOCOL_NOT_AVAILABLE       (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_EC_NO_ARCH)
+
+//Reported by DXE CPU driver
+#define DXE_CPU_SELF_TEST_FAILED              (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)
+
+//Reported by PCI Host Bridge driver
+#define DXE_NB_HB_INIT                        (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_HB_INIT )
+
+// Reported by NB Driver
+#define DXE_NB_INIT                           (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_NB_INIT )
+#define DXE_NB_SMM_INIT                       (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_NB_SMM_INIT )
+#define DXE_NB_ERROR                          (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_EC_DXE_NB_ERROR )
+
+// Reported by SB Driver(s)
+#define DXE_SBRUN_INIT                        (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_SB_RT_INIT )
+#define DXE_SB_INIT                           (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_SB_INIT )
+#define DXE_SB_SMM_INIT                       (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_SB_SMM_INIT )
+#define DXE_SB_DEVICES_INIT                   (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_SB_DEVICES_INIT )
+#define DXE_SB_BAD_BATTERY                    (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_EC_BAD_BATTERY)
+#define DXE_SB_ERROR                          (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_EC_DXE_SB_ERROR )
+
+#define EFI_SW_DXE_BS_PC_ACPI_INIT            0x00000005
+#ifndef EFI_SW_DXE_BS_PC_CSM_INIT
+#define EFI_SW_DXE_BS_PC_CSM_INIT             0x00000006
+#endif
+
+//Reported by DXE Core
+#define DXE_BDS_STARTED                       (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT)
+
+//Reported by BDS
+#define DXE_BDS_CONNECT_DRIVERS               (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_BEGIN_CONNECTING_DRIVERS)
+
+//Reported by Boot Manager
+#define DXE_READY_TO_BOOT                     (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT)
+
+//Reported by DXE Core
+#define DXE_EXIT_BOOT_SERVICES                (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES)
+#define DXE_EXIT_BOOT_SERVICES_EVENT          (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_EXIT_BOOT_SERVICES_EVENT)
+
+//Reported by driver that installs Runtime AP
+#define RT_SET_VIRTUAL_ADDRESS_MAP_BEGIN      (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_SET_VIRTUAL_ADDRESS_MAP)
+#define RT_SET_VIRTUAL_ADDRESS_MAP_END        (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_VIRTUAL_ADDRESS_CHANGE_EVENT)
+
+//Reported by CSM
+#define DXE_LEGACY_OPROM_INIT                 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_LEGACY_OPROM_INIT)
+#define DXE_LEGACY_BOOT                       (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT)
+#define DXE_LEGACY_OPROM_NO_SPACE             (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE)
+
+//Reported by SETUP
+#define DXE_SETUP_START                       (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
+#define DXE_SETUP_INPUT_WAIT                  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)
+#define DXE_INVALID_PASSWORD                  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_INVALID_PASSWORD)
+#define DXE_INVALID_IDE_PASSWORD              (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_INVALID_IDE_PASSWORD)
+#define DXE_BOOT_OPTION_LOAD_ERROR            (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR)
+#define DXE_BOOT_OPTION_FAILED                (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED)
+
+//Reported by a Driver that installs Reset AP
+#define DXE_RESET_SYSTEM                      (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_RESET_SYSTEM)
+#define DXE_RESET_NOT_AVAILABLE               (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE)
+
+// Reported by PCI bus driver
+#define DXE_PCI_BUS_BEGIN                     (EFI_IO_BUS_PCI | EFI_IOB_PC_INIT)
+#define DXE_PCI_BUS_ENUM                      (EFI_IO_BUS_PCI | EFI_IOB_PCI_BUS_ENUM)
+#define DXE_PCI_BUS_HPC_INIT                  (EFI_IO_BUS_PCI | EFI_IOB_PCI_HPC_INIT)
+#define DXE_PCI_BUS_REQUEST_RESOURCES         (EFI_IO_BUS_PCI | EFI_IOB_PCI_RES_ALLOC)
+#define DXE_PCI_BUS_ASSIGN_RESOURCES          (EFI_IO_BUS_PCI | EFI_IOB_PC_ENABLE)
+#define DXE_PCI_BUS_HOTPLUG                   (EFI_IO_BUS_PCI | EFI_IOB_PC_HOTPLUG)
+#define DXE_PCI_BUS_OUT_OF_RESOURCES          (EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT)
+
+// Reported by USB bus driver
+#define DXE_USB_BEGIN                         (EFI_IO_BUS_USB | EFI_IOB_PC_INIT)
+#define DXE_USB_RESET                         (EFI_IO_BUS_USB | EFI_IOB_PC_RESET)
+#define DXE_USB_DETECT                        (EFI_IO_BUS_USB | EFI_IOB_PC_DETECT)
+#define DXE_USB_ENABLE                        (EFI_IO_BUS_USB | EFI_IOB_PC_ENABLE)
+#define DXE_USB_HOTPLUG                       (EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG)
+
+//Reported by IDE bus driver
+#define DXE_IDE_BEGIN                         (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_INIT)
+#define DXE_IDE_RESET                         (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET)
+#define DXE_IDE_DETECT                        (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_DETECT)
+#define DXE_IDE_ENABLE                        (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_ENABLE)
+#define DXE_IDE_SMART_ERROR                   (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)
+#define DXE_IDE_CONTROLLER_ERROR              (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR)
+#define DXE_IDE_DEVICE_FAILURE                (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_INTERFACE_ERROR)
+
+// Reported by SCSI bus driver
+#define DXE_SCSI_BEGIN                        (EFI_IO_BUS_SCSI | EFI_IOB_PC_INIT)
+#define DXE_SCSI_RESET                        (EFI_IO_BUS_SCSI | EFI_IOB_PC_RESET)
+#define DXE_SCSI_DETECT                       (EFI_IO_BUS_SCSI | EFI_IOB_PC_DETECT)
+#define DXE_SCSI_ENABLE                       (EFI_IO_BUS_SCSI | EFI_IOB_PC_ENABLE)
+
+// Reported by Super I/O driver
+#define DXE_SIO_INIT                          (EFI_IO_BUS_LPC | EFI_IOB_PC_INIT)
+
+// Reported by Keyboard driver
+#define DXE_KEYBOARD_INIT                     (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_INIT)
+#define DXE_KEYBOARD_RESET                    (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET)
+#define DXE_KEYBOARD_DISABLE                  (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE)
+#define DXE_KEYBOARD_DETECT                   (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT)
+#define DXE_KEYBOARD_ENABLE                   (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE)
+#define DXE_KEYBOARD_CLEAR_BUFFER             (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER)
+#define DXE_KEYBOARD_SELF_TEST                (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST)
+
+// Reported by Mouse driver
+#define DXE_MOUSE_INIT                        (EFI_PERIPHERAL_MOUSE | EFI_P_PC_INIT)
+#define DXE_MOUSE_RESET                       (EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET)
+#define DXE_MOUSE_DISABLE                     (EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE)
+#define DXE_MOUSE_DETECT                      (EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT)
+#define DXE_MOUSE_ENABLE                      (EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE)
+
+// Reported by Mass Storage drivers
+#define DXE_FIXED_MEDIA_INIT                  (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_INIT)
+#define DXE_FIXED_MEDIA_RESET                 (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_RESET)
+#define DXE_FIXED_MEDIA_DISABLE               (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_DISABLE)
+#define DXE_FIXED_MEDIA_DETECT                (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_PRESENCE_DETECT)
+#define DXE_FIXED_MEDIA_ENABLE                (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_ENABLE)
+#define DXE_REMOVABLE_MEDIA_INIT              (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_INIT)
+#define DXE_REMOVABLE_MEDIA_RESET             (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_RESET)
+#define DXE_REMOVABLE_MEDIA_DISABLE           (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE)
+#define DXE_REMOVABLE_MEDIA_DETECT            (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_PRESENCE_DETECT)
+#define DXE_REMOVABLE_MEDIA_ENABLE            (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE)
+#define DXE_REMOVABLE_MEDIA_DETECTED          (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DETECTED)
+#define DXE_REMOVABLE_MEDIA_DISABLED          (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_DISABLED)
+//
+// Reset/Sleep conditions specific to CRK that map to a port80 code.
+//
+#define CRK_DXE_RESET                          8  // Action qualifier. (bits 2:0) of error code == PCH_RESET_TYPE when sleep == 1.
+//
+// Progress code reflects a legitimate HW forced transition to S5 via GPIO activated PWRBTN.
+#define PWRBTN_SHUTDOWN                       (EFI_SOFTWARE_SMM_DRIVER | EFI_SUBCLASS_SPECIFIC | 7)
+
+// If sleep bit and progress type: ProgressCode(2:0) == 7 and represent legitimate SW request for S5 transition.
+// If sleep bit and error type:    ProgressCode(2:0) == state of the field represented by the sleep request prior to mapping to S5.
+#define SLEEP_SHUTDOWN                        (EFI_SOFTWARE_SMM_DRIVER | EFI_OEM_SPECIFIC | 7)
+
+// If sleep bit and error type:    ProgressCode(2:0) == PCH_RESET_TYPE request forced to transition to S5.
+#define DXE_RESET_ERROR                       (EFI_SOFTWARE_DXE_RT_DRIVER  | EFI_OEM_SPECIFIC | CRK_DXE_RESET)
+
+// Reported by BDS
+#define DXE_CON_OUT_CONNECT                   (EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_INIT)
+#define DXE_CON_IN_CONNECT                    (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_INIT)
+#define DXE_NO_CON_OUT                        (EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_NOT_DETECTED)
+#define DXE_NO_CON_IN                         (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED)
+
+#define DXE_CMOS_CLR_REQUEST                  (EFI_SOFTWARE_AL | EFI_SW_EC_CFG_CLR_REQUEST)
+#define DXE_WATCHDOG_TIMER_EXPIRED            (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_TIMER_EXPIRED)
+
+#define EFI_IOB_PCI_EXP_VGA_ILLEAGL           (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+
+#define EFI_CU_QPI_ERROR                      (EFI_OEM_SPECIFIC | 0x00000005)
+#define EFI_CU_QPI_LINK_DOWN                  (EFI_COMPUTING_UNIT | 0x000A0000)
+
+
+#endif
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaFpkConfigLib.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaFpkConfigLib.h
new file mode 100644
index 0000000000..bdd42b2d69
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaFpkConfigLib.h
@@ -0,0 +1,55 @@
+/** @file
+  UBA FPK configuration library header
+
+  @copyright
+  Copyright 2016 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _UBA_FPK_CONFIG_LIB_H
+#define _UBA_FPK_CONFIG_LIB_H
+
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/GpioLib.h>
+
+#define PLATFORM_FPK_CONFIG_SIGNATURE  SIGNATURE_32 ('P', 'F', 'P', 'K')
+#define PLATFORM_FPK_CONFIG_VERSION    01
+
+// {38F0930C-E7FB-49CC-B88E-D9909EB65D77}
+#define PLATFORM_FPK_CONFIG_DATA_GUID \
+{ 0x38f0930c, 0xe7fb, 0x49cc, { 0xb8, 0x8e, 0xd9, 0x90, 0x9e, 0xb6, 0x5d, 0x77 } }
+
+typedef enum {
+  PortMappedToFunc0,
+  PortMappedToFunc1,
+  PortMappedToFunc2,
+  PortMappedToFunc3,
+  PortNotMapped
+} PLATFORM_FPK_PORT_MAP;
+
+typedef struct _PLATFORM_FPK_CONFIG_STRUCT {
+  UINT32                            Signature;
+  UINT32                            Version;
+  PLATFORM_FPK_PORT_MAP             *PortToFuncMapPtr;
+  UINTN                             PortToFuncMapSize;
+  GPIO_PAD                          PciDisNGpioPad;
+  GPIO_PAD                          LanDisNGpioPad;
+} PLATFORM_FPK_CONFIG_STRUCT;
+
+/**
+  Retrieves FPK config struct from UBA database
+
+  @retval EFI_SUCCESS           Config struct is retrieved.
+  @retval EFI_NOT_FOUND         UBA protocol, platform or data not found.
+  @retval EFI_INVALID_PARAMETER If PlatformFpkConfigStruct is NULL.
+**/
+EFI_STATUS
+FpkConfigGetConfigStruct (
+  OUT PLATFORM_FPK_CONFIG_STRUCT *PlatformFpkConfigStruct
+  );
+
+STATIC EFI_GUID gPlatformFpkConfigDataGuid = PLATFORM_FPK_CONFIG_DATA_GUID;
+
+#endif // !_UBA_FPK_CONFIG_LIB_H
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaSmbiosUpdateLib.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaSmbiosUpdateLib.h
new file mode 100644
index 0000000000..9ea87b62df
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaSmbiosUpdateLib.h
@@ -0,0 +1,275 @@
+/** @file
+  UBA smbios Update Library Header File.
+
+  @copyright
+  Copyright 2012 - 2015 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _UBA_SMBIOS_UPDATE_LIB_
+#define _UBA_SMBIOS_UPDATE_LIB_
+
+#include <Base.h>
+#include <Uefi.h>
+#include <IndustryStandard/SmBios.h>
+
+
+typedef enum
+{
+  SmbiosDelayUpdate,
+  SmbiosNormalUpdate,
+} SmbiosUpdateType;
+
+
+#define PLATFORM_SMBIOS_UPDATE_SIGNATURE  SIGNATURE_32 ('P', 'S', 'M', 'B')
+#define PLATFORM_SMBIOS_UPDATE_VERSION    01
+
+// {AAC6CAFD-42C6-440a-B958-9FD4C84B50EA}
+STATIC EFI_GUID  gPlatformSmbiosConfigDataGuid =
+{ 0xaac6cafd, 0x42c6, 0x440a, { 0xb9, 0x58, 0x9f, 0xd4, 0xc8, 0x4b, 0x50, 0xea } };
+
+
+/**
+  Callback function for SMBIOS dynamic update.
+
+  @param Smbios                   The SMBIOS data buffer pointer.
+  @param BufferSize               The SMBIOS data buffer size allocated for you.
+  @param Instance                 Instance number for this type.
+
+  @retval EFI_INVALID_PARAMETER   Check your register data if the call return this error.
+  @retval EFI_NOT_FOUND           The data process have error occur.
+  @retval EFI_SUCCESS             Data have been updated successfully.
+
+**/
+typedef
+EFI_STATUS
+(*SMBIOS_UPDATE_CALLBACK) (
+  VOID
+);
+
+typedef struct {
+  UINT32                  Signature;
+  UINT32                  Version;
+
+  UINT32                  PlatformType;
+  SmbiosUpdateType        UpdateType;       // DelayUpdate or NormalUpdate
+  SMBIOS_UPDATE_CALLBACK  CallUpdate;
+} SMBIOS_UPDATE_DATA;
+
+/**
+  Provide the RegData and register a callback for dynamic update SMBIOS data.
+
+  @param RegData                  Callback register data.
+
+  @retval EFI_NOT_FOUND           Data log protocol not found.
+  @retval EFI_OUT_OF_RESOURCES    Data was not logged due to lack of system resources.
+  @retval EFI_SUCCESS             Data have been updated successfully.
+
+**/
+EFI_STATUS
+PlatformRegisterSmbiosUpdate (
+  IN  SMBIOS_UPDATE_DATA              *RegData
+);
+
+/**
+  Update a String for a filled SMBIOS data structure, the structure must be filled
+  before update string.
+  This function update a string indicated by StringNumber to the tail of SMBIOS
+  structure.
+
+  @param Smbios                   SMBIOS structure data buffer pointer.
+  @param BufferSize               SMBIOS structure data buffer size.
+  @param StringNumber             The string index number of SMBIOS structure.
+  @param String                   String want to update.
+
+  @retval EFI_OUT_OF_RESOURCES    No enough memory for this action.
+  @retval EFI_SUCCESS             String updated successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosUpdateString (
+  IN  OUT SMBIOS_STRUCTURE_POINTER    Smbios,
+  IN      UINTN                       BufferSize,
+  IN      UINTN                       StringNumber,
+  IN      CHAR16                      *String
+);
+
+/**
+  Get SMBIOS data structure length, include the string in tail.
+
+  @param Smbios                   SMBIOS structure data buffer pointer.
+  @param TypeSize                 SMBIOS structure size.
+
+  @retval EFI_INVALID_PARAMETER   Input paramter invalid.
+  @retval EFI_SUCCESS             Caculate data structure size successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosGetTypeLength (
+  IN  OUT SMBIOS_STRUCTURE_POINTER    Smbios,
+  IN  OUT UINTN                       *TypeSize
+);
+
+/**
+  Add a new SMBIOS structure into SMBIOS database.
+
+  @param Smbios                   SMBIOS structure data buffer pointer.
+
+  @retval EFI_NOT_FOUND           SMBIOS protocol not installed.
+  @retval EFI_SUCCESS             Add data structure successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosAddNew (
+  IN      SMBIOS_STRUCTURE_POINTER    SmbiosPtr
+);
+
+/**
+  Get the number of instance of SMBIOS type structure in SMBIOS database.
+  return 0 means no instance for this type now.
+
+  @param Type                     SMBIOS type.
+
+  @retval Count                   Number of instance.
+
+**/
+UINTN
+PlatformSmbiosGetInstanceCount (
+  IN      UINT8                       Type
+);
+
+/**
+  Get SMBIOS type data structure in SMBIOS database.
+
+  This function give you a pointer of SMBIOS structure directly in the database, you can update
+  the value in formated structure area and it's take affect immediately, but never directly or
+  call PlatformSmbiosUpdateString to edit the string in this buffer,
+  use PlatformSmbiosGetEditCopy->PlatformSmbiosUpdateType instead.
+
+  One of the SmbiosPtr or Handle must be valid value.
+
+  @param Type                     SMBIOS type.
+  @param Instance                 The instance of this type.
+  @param SmbiosPtr                Optional parameter, on input, pass a pointer of SMBIOS_STRUCTURE_POINTER
+                                  to this function.
+                                  On output, return the SMBIOS data pointer in SmbiosPtr.
+  @param Handle                   Optional parameter, on input, pass a pointer of Handle.
+                                  On output, return the SMBIOS data handle value
+
+  @retval EFI_INVALID_PARAMETER   Both the SmbiosPtr and Handle is NULL.
+  @retval EFI_NOT_FOUND           SMBIOS protocol not installed.
+  @retval EFI_SUCCESS             Get structure data successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosGetInstance (
+  IN      UINT8                       Type,
+  IN      UINTN                       Instance,
+  IN  OUT SMBIOS_STRUCTURE_POINTER    *SmbiosPtr,
+  IN  OUT UINT16                      *Handle
+);
+
+/**
+  Get a copy of SMBIOS type structure data in SMBIOS database.
+  Must allocate memory large enough first, then call this function to get the copy.
+
+  @param Type                     SMBIOS type.
+  @param Instance                 The instance of this type.
+  @param SmbiosPtr                A valid buffer pointer which SMBIOS data will copy to this buffer.
+
+  @retval EFI_NOT_FOUND           SMBIOS protocol not installed.
+  @retval EFI_SUCCESS             Get structure data successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosGetEditCopy (
+  IN      UINT8                       Type,
+  IN      UINTN                       Instance,
+  IN  OUT SMBIOS_STRUCTURE_POINTER    SmbiosPtr
+);
+
+/**
+  Update a string which in SMBIOS database.
+  The data structure which string belong to must installed before.
+
+  @param Type                     SMBIOS type.
+  @param Instance                 The instance of this type.
+  @param StringNumber             The string number.
+  @param String                   The string want to update.
+
+  @retval EFI_NOT_FOUND           SMBIOS protocol not installed.
+  @retval EFI_SUCCESS             Update data successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosUpdateInstalledString (
+  IN      UINT8                       Type,
+  IN      UINTN                       Instance,
+  IN      UINTN                       StringNumber,
+  IN      CHAR16                      *String
+);
+
+/**
+  Remove a SMBIOS instance in SMBIOS database.
+
+  @param Type                     SMBIOS type.
+  @param Instance                 The instance of this type.
+
+  @retval EFI_NOT_FOUND           SMBIOS protocol not installed.
+  @retval EFI_SUCCESS             Remove data successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosRemoveType (
+  IN      UINT8                       Type,
+  IN      UINTN                       Instance
+);
+
+/**
+  Remove all the instance of specific SMBIOS type in SMBIOS database.
+
+  @param Type                     SMBIOS type.
+
+  @retval EFI_NOT_FOUND           SMBIOS protocol not installed.
+  @retval EFI_SUCCESS             Remove data successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosRemoveAll (
+  IN      UINT8                       Type
+);
+
+/**
+  Update SMBIOS data structure in database with new structure data.
+
+  @param Type                     SMBIOS type.
+  @param Instance                 The instance of this type.
+  @param SmbiosPtr                A valid buffer pointer which new SMBIOS data stored.
+
+  @retval EFI_NOT_FOUND           SMBIOS protocol not installed.
+  @retval EFI_SUCCESS             Update data successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosUpdateType (
+  IN      UINT8                       Type,
+  IN      UINTN                       Instance,
+  IN      SMBIOS_STRUCTURE_POINTER    SmbiosPtr
+);
+
+/**
+  Function provide to DXE driver, which initial the dynamic update.
+
+  @param NULL
+
+  @retval EFI_NOT_FOUND           Required protocol not found.
+  @retval EFI_SUCCESS             Init successfully.
+
+**/
+EFI_STATUS
+PlatformInitSmbiosUpdate (
+  VOID
+);
+
+#endif //_UBA_SMBIOS_UPDATE_LIB_
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/BoardInitLib/BoardInitDxeLib.inf b/Platform/Intel/WhitleyOpenBoardPkg/Library/BoardInitLib/BoardInitDxeLib.inf
index 219512566c..57ec872e33 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/Library/BoardInitLib/BoardInitDxeLib.inf
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BoardInitLib/BoardInitDxeLib.inf
@@ -27,6 +27,7 @@
   WhitleySiliconPkg/SiliconPkg.dec
   WhitleySiliconPkg/CpRcPkg.dec
   WhitleyOpenBoardPkg/PlatformPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
 
 [LibraryClasses]
   IoLib
-- 
2.27.0.windows.1


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

* [edk2-devel][edk2-platforms][PATCH V1 2/9] WhitleySiliconPkg: Add definitions used in ACPI subsystem
  2022-03-10 22:41 [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Oram, Isaac W
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 1/9] WhitleyOpenBoardPkg: Add definitions needed for " Oram, Isaac W
@ 2022-03-10 22:41 ` Oram, Isaac W
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 3/9] WhitleyOpenBoardPkg/BaseCrcLib: Add library for CRC16 Oram, Isaac W
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Oram, Isaac W @ 2022-03-10 22:41 UTC (permalink / raw)
  To: devel; +Cc: Nate DeSimone, Chasel Chiu

Needed to convert FvLateOpenBoard ACPI binary drivers to open source.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>
---
 Silicon/Intel/WhitleySiliconPkg/CpRcPkg.dec                                             |   3 +
 Silicon/Intel/WhitleySiliconPkg/Cpu/Include/CpuDataStruct.h                             |   7 +
 Silicon/Intel/WhitleySiliconPkg/Cpu/Include/Library/CpuConfigLib.h                      |  82 ++++
 Silicon/Intel/WhitleySiliconPkg/Include/BackCompatible.h                                |   3 +
 Silicon/Intel/WhitleySiliconPkg/Include/BdatSchema.h                                    | 301 ++++++++++++
 Silicon/Intel/WhitleySiliconPkg/Include/Guid/MemoryMapData.h                            |   2 +
 Silicon/Intel/WhitleySiliconPkg/Include/IioRegs.h                                       |  74 ++-
 Silicon/Intel/WhitleySiliconPkg/Include/Library/EnhancedWarningLogLib.h                 | 494 ++++++++++++++++++++
 Silicon/Intel/WhitleySiliconPkg/Include/Library/SpdAccessLib.h                          |  32 ++
 Silicon/Intel/WhitleySiliconPkg/Include/MemCommon.h                                     |   7 +
 Silicon/Intel/WhitleySiliconPkg/Include/Platform.h                                      |   7 +
 Silicon/Intel/WhitleySiliconPkg/Include/Ppi/MemoryPolicyPpi.h                           |   2 +-
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/AcpiPlatformProtocol.h                 |  51 ++
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/CpuCsrAccess.h                         | 254 ++++++++++
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol.h             |  43 +-
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol2.h            | 255 ++++++++++
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/NfitTableUpdateProtocol.h              |  27 ++
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/SmbiosMemInfo.h                        |  87 ++++
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MemRegs.h        |   2 +
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MrcCommonTypes.h |  25 +
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/SysHost.h        |  34 +-
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Platform/MemDefaults.h        |   7 +
 Silicon/Intel/WhitleySiliconPkg/Pch/SouthClusterLbg/Include/PchInfoHob.h                |  50 ++
 Silicon/Intel/WhitleySiliconPkg/WhitleySiliconPkg.dec                                   |   1 +
 24 files changed, 1783 insertions(+), 67 deletions(-)

diff --git a/Silicon/Intel/WhitleySiliconPkg/CpRcPkg.dec b/Silicon/Intel/WhitleySiliconPkg/CpRcPkg.dec
index 902abd30f8..2ccdbffa35 100644
--- a/Silicon/Intel/WhitleySiliconPkg/CpRcPkg.dec
+++ b/Silicon/Intel/WhitleySiliconPkg/CpRcPkg.dec
@@ -82,6 +82,9 @@
   gRcSimBiosIdFileGuid            = { 0xf0c51ad5, 0x44f0, 0x4622, { 0x95, 0x15, 0xe2, 0x7, 0x71, 0xf0, 0xe0, 0xf2 }}
   gSystemTopologyGuid             = { 0x743e5992, 0xf2a0, 0x4c9f, { 0xa5, 0xf5, 0x3b, 0x24, 0xad, 0xe8, 0x7f, 0x4d }}
 
+[Protocols]
+  gEfiCpuCsrAccessGuid            = { 0x0067835f, 0x9a50, 0x433a, { 0x8c, 0xbb, 0x85, 0x20, 0x78, 0x19, 0x78, 0x14 }}
+
 [PPIs]
   ## Include/Ppi/MemorySetupPolicyPpi.h
   gMemoryPolicyPpiGuid             = { 0x731b6dbc, 0x18ac, 0x4cc3, { 0x9e, 0xe2, 0x9e, 0x5f, 0x33, 0x39, 0x68, 0x81 }}
diff --git a/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/CpuDataStruct.h b/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/CpuDataStruct.h
index aaabf032f9..e1416a0d1c 100644
--- a/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/CpuDataStruct.h
+++ b/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/CpuDataStruct.h
@@ -24,4 +24,11 @@
 //
 #define CONFIG_TDP_TOTAL_LEVEL  5
 
+typedef struct {
+  UINT32  RegEax;
+  UINT32  RegEbx;
+  UINT32  RegEcx;
+  UINT32  RegEdx;
+} EFI_CPUID_REGISTER;
+
 #endif
diff --git a/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/Library/CpuConfigLib.h b/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/Library/CpuConfigLib.h
index 298fe08624..805f2ac6c8 100644
--- a/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/Library/CpuConfigLib.h
+++ b/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/Library/CpuConfigLib.h
@@ -19,6 +19,88 @@
 #define C0_ENABLE                           0x00
 #define C6_ENABLE                           0x03
 
+//
+// Structure for collected CPUID data.
+//
+typedef struct {
+  EFI_CPUID_REGISTER         *CpuIdLeaf;
+  UINTN                      NumberOfBasicCpuidLeafs;
+  UINTN                      NumberOfExtendedCpuidLeafs;
+  UINTN                      NumberOfCacheAndTlbCpuidLeafs;
+  UINTN                      NumberOfDeterministicCacheParametersCpuidLeafs;
+  UINTN                      NumberOfExtendedTopologyEnumerationLeafs;
+} CPU_CPUID_DATA;
+
+typedef struct {
+  UINTN    Ratio;
+  UINTN    Vid;
+  UINTN    Power;
+  UINTN    TransitionLatency;
+  UINTN    BusMasterLatency;
+} FVID_ENTRY;
+
+typedef struct {
+  VOID     *MicrocodeData;
+  UINTN    MicrocodeSize;
+  UINT32   ProcessorId;
+} MICROCODE_INFO;
+
+//
+// Miscellaneous processor data
+//
+typedef struct {
+  //
+  // Local Apic Data
+  //
+  UINT32                     InitialApicID;  ///< Initial APIC ID
+  UINT32                     ApicID;         ///< Current APIC ID
+  EFI_PHYSICAL_ADDRESS       ApicBase;
+  UINT32                     ApicVersion;
+  //
+  // Frequency data
+  //
+  UINTN                      IntendedFsbFrequency;
+  UINTN                      ActualFsbFrequency;
+  UINTN                      MaxCoreToBusRatio;
+  UINTN                      MinCoreToBusRatio;
+  UINTN                      MaxTurboRatio;
+  UINTN                      PackageTdp;
+  UINTN                      NumberOfPStates;
+  FVID_ENTRY                 *FvidTable;
+  UINTN                      GreaterNumberOfPStates;  // Greater Than 16 p-state support
+  FVID_ENTRY                 *GreaterFvidTable;       // Greater Than 16 p-state support
+  //
+  // Other data
+  //
+  UINT32                     MicrocodeRevision;
+  UINT64                     EnabledThreadCountMsr;
+  MICROCODE_INFO             MicrocodeInfo;
+  UINT64                     MiscEnablesMsr;
+} CPU_MISC_DATA;
+
+//
+// Structure for all collected processor data
+//
+typedef struct {
+  CPU_CPUID_DATA             CpuidData;
+  EFI_CPU_PHYSICAL_LOCATION  ProcessorLocation;
+  CPU_MISC_DATA              CpuMiscData;
+  UINT8                      PackageIdBitOffset;
+  BOOLEAN                    PackageBsp;
+} CPU_COLLECTED_DATA;
+
+//
+// Definition of Processor Configuration Context Buffer
+//
+typedef struct {
+  UINTN                    NumberOfProcessors;
+  UINTN                    BspNumber;
+  CPU_COLLECTED_DATA       *CollectedDataBuffer;
+  CPU_REGISTER_TABLE       *PreSmmInitRegisterTable;
+  CPU_REGISTER_TABLE       *RegisterTable;
+  BOOLEAN                  RegisterTableSaved;
+} CPU_CONFIG_CONTEXT_BUFFER;
+
 //
 // Structure conveying socket ID configuration information.
 //
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/BackCompatible.h b/Silicon/Intel/WhitleySiliconPkg/Include/BackCompatible.h
index 0e9fbde11f..88d7e02dcf 100644
--- a/Silicon/Intel/WhitleySiliconPkg/Include/BackCompatible.h
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/BackCompatible.h
@@ -12,6 +12,9 @@
 
 #define R_ACPI_LV2                          0x14
 
+#define R_IOPORT_CMOS_STANDARD_INDEX            0x70
+#define R_IOPORT_CMOS_STANDARD_DATA             0x71
+
 #define R_IOPORT_CMOS_UPPER_INDEX               0x72
 #define R_IOPORT_CMOS_UPPER_DATA                0x73
 
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/BdatSchema.h b/Silicon/Intel/WhitleySiliconPkg/Include/BdatSchema.h
new file mode 100644
index 0000000000..0b80015c65
--- /dev/null
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/BdatSchema.h
@@ -0,0 +1,301 @@
+/** @file
+
+  @copyright
+  Copyright 2006 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _bdat_h
+#define _bdat_h
+
+//
+// Memory location that don't care was set to 0xFF
+//
+#define DO_NOT_CARE 0xFF
+
+#pragma pack(1)
+
+typedef struct bdatSchemaHeader {
+  EFI_GUID                      SchemaId;
+  UINT32                        DataSize;
+  UINT16                        Crc16;
+} BDAT_SCHEMA_HEADER_STRUCTURE;
+
+//
+// SPD data schema related definition
+//
+
+//
+// Memory SPD Data Header
+//
+typedef struct {
+  EFI_GUID  MemSpdGuid;   // GUID that uniquely identifies the memory SPD data revision
+  UINT32    Size;         // Total size in bytes including the header and all SPD data
+  UINT32    Crc;          // 32-bit CRC generated over the whole size minus this crc field
+                          // Note: UEFI 32-bit CRC implementation (CalculateCrc32)
+                          // Consumers can ignore CRC check if not needed.
+  UINT32    Reserved;     // Reserved for future use, must be initialized to 0
+} MEM_SPD_RAW_DATA_HEADER;
+
+//
+// Memory SPD Raw Data
+//
+typedef struct {
+  MEM_SPD_RAW_DATA_HEADER  Header;
+
+  //
+  // This is a dynamic region, where SPD data entries are filled out.
+  //
+} MEM_SPD_DATA_STRUCTURE;
+
+typedef struct {
+  BDAT_SCHEMA_HEADER_STRUCTURE  SchemaHeader;
+  MEM_SPD_DATA_STRUCTURE        SpdData;
+} BDAT_MEM_SPD_STRUCTURE;
+
+//
+// List of all entry types supported by this revision of memory SPD data structure
+//
+typedef enum {
+  MemSpdDataType0  = 0,
+
+  MemSpdDataTypeMax,
+  MemSpdDataTypeDelim = MAX_INT32
+} MEM_SPD_DATA_TYPE;
+
+//
+// Generic entry header for all memory SPD raw data entries
+//
+typedef struct {
+  MEM_SPD_DATA_TYPE      Type;
+  UINT16                 Size;     // Entries will be packed by byte in contiguous space. Size of the entry includes the header.
+} MEM_SPD_DATA_ENTRY_HEADER;
+
+//
+// Structure to specify SPD dimm memory location
+//
+typedef struct {
+  UINT8     Socket;
+  UINT8     Channel;
+  UINT8     Dimm;
+} MEM_SPD_DATA_ENTRY_MEMORY_LOCATION;
+
+//
+// Type 0: SPD RDIMM/LRDIMM DDR4
+// The NumberOfBytes are 512 for DDR4.
+//
+typedef struct {
+  MEM_SPD_DATA_ENTRY_HEADER           Header;
+  MEM_SPD_DATA_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  UINT16                              NumberOfBytes;
+  //
+  // This is a dynamic region, where SPD data are filled out.
+  // The total number of bytes of the SPD data must match NumberOfBytes
+  //
+} MEM_SPD_ENTRY_TYPE0;
+
+//
+// Memory training data schema related definition
+//
+
+//
+// Memory training Data Header
+//
+typedef struct {
+  EFI_GUID  MemDataGuid;  // GUID that uniquely identifies the memory training data revision
+  UINT32    Size;         // Total size in bytes including the header and all memory training data
+  UINT32    Crc;          // 32-bit CRC generated over the whole size minus this crc field
+                          // Note: UEFI 32-bit CRC implementation (CalculateCrc32)
+                          // Consumers can ignore CRC check if not needed.
+  UINT32    Reserved;     // Reserved for future use, must be initialized to 0
+} MEM_TRAINING_DATA_HEADER;
+
+//
+// Memory SPD Raw Data
+//
+typedef struct {
+  MEM_TRAINING_DATA_HEADER  Header;
+
+  //
+  // This is a dynamic region, where memory training data entries are filled out.
+  //
+} MEM_TRAINING_DATA_STRUCTURE;
+
+typedef struct {
+  BDAT_SCHEMA_HEADER_STRUCTURE  SchemaHeader;
+  MEM_TRAINING_DATA_STRUCTURE   Data;
+} BDAT_MEM_TRAINING_STRUCTURE;
+
+//
+// List of all entry types supported by this revision of memory training data structure
+//
+typedef enum {
+  MemTrainingDataCapability  = 0,
+  MemTrainingDataIoGroup     = 1,
+  MemTrainingDataDram        = 2,
+  MemTrainingDataRcd         = 3,
+  MemTrainingDataIoSignal    = 4,
+  MemTrainingDataIoLatency   = 5,
+
+  MemTrainingDataTypeMax,
+  MemTrainingDataTypeDelim = MAX_INT32
+} MEM_TRAINING_DATA_TYPE;
+
+//
+// Generic entry header for all memory training data entries
+//
+typedef struct {
+  MEM_TRAINING_DATA_TYPE      Type;
+  UINT16                      Size;     // Entries will be packed by byte in contiguous space. Size of the entry includes the header.
+} MEM_TRAINING_DATA_ENTRY_HEADER;
+
+//
+// Structure to specify memory training data location
+//
+typedef struct {
+  UINT8     Socket;
+  UINT8     Channel;
+  UINT8     SubChannel;
+  UINT8     Dimm;      // 0xFF = n/a
+  UINT8     Rank;      // 0xFF = n/a
+} MEM_TRAINING_DATA_ENTRY_MEMORY_LOCATION;
+
+//
+// List of memory training data scope
+//
+typedef enum {
+  PerBitMemTrainData         = 0,
+  PerStrobeMemTrainData      = 1,
+  PerRankMemTrainData        = 2,
+  PerSubChannelMemTrainData  = 3,
+  PerChannelMemTrainData     = 4,
+
+  MemTrainDataScopeMax,
+  MemTrainDataScopDelim = MAX_INT32
+} MEM_TRAINING_DATA_SCOPE;
+
+//
+// Type 0: Define the capability. This info can be helpful for
+// the code to display the training data.
+//
+
+typedef struct {
+  MEM_TRAINING_DATA_ENTRY_HEADER           Header;
+  UINT8                                    EccEnable;
+  UINT8                                    MaxSocket;
+  UINT8                                    MaxChannel;
+  UINT8                                    MaxSubChannel;           // It is 1 if there is no sub-channel
+  UINT8                                    MaxDimm;
+  UINT8                                    MaxRank;
+  UINT8                                    MaxStrobePerSubChannel;  // It is the MaxStrobe of the chanenl if there is no sub-channel
+  UINT8                                    MaxBitsPerSubChannel;    // It is the MaxBits of the chanenl if there is no sub-channel
+} MEM_TRAINING_DATA_ENTRY_TYPE0;
+
+//
+// Type 1: General training data that commonly accessed by GetSet API via Group
+//
+
+typedef struct {
+  MEM_TRAINING_DATA_ENTRY_HEADER           Header;
+  MEM_TRAINING_DATA_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  MRC_LT                                   Level;
+  MRC_GT                                   Group;
+  MEM_TRAINING_DATA_SCOPE                  Scope;            // If Scope is PerSubChannelMemTrainData or PerChannelMemTrainData, the training
+                                                             // is applicable to whole SubChannel or Channel regardless the Dimm or Rank.
+                                                             // The MemoryLoaction.Dimm and MemoryLoaction.Rank should be ignored.
+  UINT8                                    NumberOfElements;
+  UINT8                                    SizeOfElement;    // Number of bytes of each training data element.
+                                                             // 1: UINT8
+                                                             // 2: UINT16
+                                                             // 4: UINT32
+  //
+  // This is a dynamic region, where training data are filled out.
+  // The total number of bytes of the training data must be equal to
+  // NumberOfElements * SizeOfElement
+  //
+} MEM_TRAINING_DATA_ENTRY_TYPE1;
+
+//
+// Type 2: DRAM mode register data
+//
+
+typedef struct {
+  MEM_TRAINING_DATA_ENTRY_HEADER           Header;
+  MEM_TRAINING_DATA_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  UINT8                                    NumberOfModeRegisters;
+  UINT8                                    NumberOfDrams;
+
+  //
+  // This is a dynamic region, where DRAM mode register data are filled out.
+  // Each mode register data is one byte. The total number of bytes of the data must be equal to
+  // NumberOfModeRegisters * NumberOfDrams. The data is indexed as [ModeRegister][Dram]
+  //
+} MEM_TRAINING_DATA_ENTRY_TYPE2;
+
+//
+// Type 3:  RCD data
+//
+
+typedef struct {
+  MEM_TRAINING_DATA_ENTRY_HEADER           Header;
+  MEM_TRAINING_DATA_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  UINT8                                    NumberOfRegisters;
+
+  //
+  // This is a dynamic region, where RCD RW register data are filled out.
+  // Each RW register data is one byte. The total number of bytes of the data must be equal to
+  // NumberOfRegisters.
+  //
+} MEM_TRAINING_DATA_ENTRY_TYPE3;
+
+//
+// Type 4: IO Signal training data
+//
+typedef struct {
+  MRC_GT                                   Signal;
+  INT16                                    Value;
+} SIGNAL_DATA;
+
+typedef struct {
+  MEM_TRAINING_DATA_ENTRY_HEADER           Header;
+  MEM_TRAINING_DATA_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  MRC_LT                                   Level;
+  MEM_TRAINING_DATA_SCOPE                  Scope;            // If Scope is PerSubChannelMemTrainData or PerChannelMemTrainData, the training
+                                                             // is applicable to whole SubChannel or Channel regardless the Dimm or Rank.
+                                                             // The MemoryLoaction.Dimm and MemoryLoaction.Rank should be ignored.
+  UINT8                                    NumberOfSignals;  // Number of SIGNAL_DATA struct
+  //
+  // This is a dynamic region, where signal training data are filled out.
+  // Each signal training data element is defined by a SIGNAL_DATA struct.
+  // The total number of bytes of the training data must be equal to
+  // NumberOfSignals * sizeof (SIGNAL_DATA)
+  //
+} MEM_TRAINING_DATA_ENTRY_TYPE4;
+
+//
+// Type 5: IO latency, Round trip and IO Comp training data
+//
+
+typedef struct {
+  MEM_TRAINING_DATA_ENTRY_HEADER           Header;
+  MEM_TRAINING_DATA_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  MEM_TRAINING_DATA_SCOPE                  Scope;            // If Scope is PerSubChannelMemTrainData or PerChannelMemTrainData, the training
+                                                             // is applicable to whole SubChannel or Channel regardless the Dimm or Rank.
+                                                             // The MemoryLoaction.Dimm and MemoryLoaction.Rank should be ignored.
+  UINT8                                    IoLatency;
+  UINT8                                    RoundTrip;
+  UINT8                                    IoComp;
+} MEM_TRAINING_DATA_ENTRY_TYPE5;
+
+//
+// Memory training data HOB header
+// This header contains the actual size of the training data in the HOB. The HOB data size is
+// always mutiples of 8.
+//
+typedef struct {
+  UINT32    Size;
+} MEM_TRAINING_DATA_HOB_HEADER;
+
+#pragma pack()
+#endif // _bdat_h
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Guid/MemoryMapData.h b/Silicon/Intel/WhitleySiliconPkg/Include/Guid/MemoryMapData.h
index 1512b90881..73f303594a 100644
--- a/Silicon/Intel/WhitleySiliconPkg/Include/Guid/MemoryMapData.h
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/Guid/MemoryMapData.h
@@ -13,6 +13,8 @@
 #include "SysHost.h"
 #include "PartialMirrorGuid.h"
 
+#define MEM_IMCCH_TO_SKTCH(Imc, Ch) ((Imc) * MAX_MC_CH + (Ch))
+
 #define RESERVED_2    2
 #define RESERVED_4    4
 
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/IioRegs.h b/Silicon/Intel/WhitleySiliconPkg/Include/IioRegs.h
index 98f759be81..37a1e627da 100644
--- a/Silicon/Intel/WhitleySiliconPkg/Include/IioRegs.h
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/IioRegs.h
@@ -124,32 +124,54 @@
 //-----------------------------------------------------------------------------------
 // Port Index definition for ICX-SP
 //------------------------------------------------------------------------------------
+#define PCIE_PORT_0_DEV_0     0x03
+#define PCIE_PORT_0_FUNC_0    0x00
 
-// IOU0
-#define PORT_1A_INDEX_1           1
-#define PORT_1B_INDEX_1           2
-#define PORT_1C_INDEX_1           3
-#define PORT_1D_INDEX_1           4
-// IOU1
-#define PORT_2A_INDEX_2           5
-#define PORT_2B_INDEX_2           6
-#define PORT_2C_INDEX_2           7
-#define PORT_2D_INDEX_2           8
-// IOU2
-#define PORT_3A_INDEX_3           9
-#define PORT_3B_INDEX_3           10
-#define PORT_3C_INDEX_3           11
-#define PORT_3D_INDEX_3           12
-// IOU3
-#define PORT_4A_INDEX_4           13
-#define PORT_4B_INDEX_4           14
-#define PORT_4C_INDEX_4           15
-#define PORT_4D_INDEX_4           16
-// IOU4
-#define PORT_5A_INDEX_5           17
-#define PORT_5B_INDEX_5           18
-#define PORT_5C_INDEX_5           19
-#define PORT_5D_INDEX_5           20
+#define PCIE_PORT_1A_DEV_1    0x02
+#define PCIE_PORT_1A_FUNC_1   0x00
+#define PCIE_PORT_1B_DEV_1    0x03
+#define PCIE_PORT_1C_DEV_1    0x04
+#define PCIE_PORT_1D_DEV_1    0x05
+#define PCIE_PORT_1A_FUNC_1   0x00
+#define PCIE_PORT_1B_FUNC_1   0x00
+#define PCIE_PORT_1C_FUNC_1   0x00
+#define PCIE_PORT_1D_FUNC_1   0x00
+
+#define PCIE_PORT_2A_DEV_2    0x02
+#define PCIE_PORT_2B_DEV_2    0x03
+#define PCIE_PORT_2C_DEV_2    0x04
+#define PCIE_PORT_2D_DEV_2    0x05
+#define PCIE_PORT_2A_FUNC_2   0x00
+#define PCIE_PORT_2B_FUNC_2   0x00
+#define PCIE_PORT_2C_FUNC_2   0x00
+#define PCIE_PORT_2D_FUNC_2   0x00
+
+#define PCIE_PORT_3A_DEV_3    0x02
+#define PCIE_PORT_3B_DEV_3    0x03
+#define PCIE_PORT_3C_DEV_3    0x04
+#define PCIE_PORT_3D_DEV_3    0x05
+#define PCIE_PORT_3A_FUNC_3   0x00
+#define PCIE_PORT_3B_FUNC_3   0x00
+#define PCIE_PORT_3C_FUNC_3   0x00
+#define PCIE_PORT_3D_FUNC_3   0x00
+
+#define PCIE_PORT_4A_DEV_4    0x02
+#define PCIE_PORT_4B_DEV_4    0x03
+#define PCIE_PORT_4C_DEV_4    0x04
+#define PCIE_PORT_4D_DEV_4    0x05
+#define PCIE_PORT_4A_FUNC_4   0x00
+#define PCIE_PORT_4B_FUNC_4   0x00
+#define PCIE_PORT_4C_FUNC_4   0x00
+#define PCIE_PORT_4D_FUNC_4   0x00
+
+#define PCIE_PORT_5A_DEV_5    0x02
+#define PCIE_PORT_5B_DEV_5    0x03
+#define PCIE_PORT_5C_DEV_5    0x04
+#define PCIE_PORT_5D_DEV_5    0x05
+#define PCIE_PORT_5A_FUNC_5   0x00
+#define PCIE_PORT_5B_FUNC_5   0x00
+#define PCIE_PORT_5C_FUNC_5   0x00
+#define PCIE_PORT_5D_FUNC_5   0x00
 
 //
 // Port Config Mode
@@ -158,6 +180,8 @@
 #define VMD_OWNERSHIP                 3
 #define PCIEAIC_OCL_OWNERSHIP         4
 
+#define DMI_BUS_NUM                   0
+
 #define NUMBER_TRACE_HUB_PER_SOCKET                           1
 
 //
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Library/EnhancedWarningLogLib.h b/Silicon/Intel/WhitleySiliconPkg/Include/Library/EnhancedWarningLogLib.h
new file mode 100644
index 0000000000..211dc48c86
--- /dev/null
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/Library/EnhancedWarningLogLib.h
@@ -0,0 +1,494 @@
+/** @file
+  Interface header file for the Enhanced warning log library class.
+
+  @copyright
+  Copyright 2018 - 2021 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ENHANCED_WARNING_LOG_LIB_
+#define _ENHANCED_WARNING_LOG_LIB_
+
+#include <Uefi.h>
+#include <MrcCommonTypes.h>
+
+#pragma pack(1)
+
+///
+/// Enhanced Warning Log Identification GUID
+/// This GUID is used for HOB, UEFI variables, or UEFI Configuration Table as needed by platform implementations
+/// {D8E05800-005E-4462-AA3D-9C6B4704920B}
+///
+#define EWL_ID_GUID { 0xd8e05800, 0x5e, 0x4462, { 0xaa, 0x3d, 0x9c, 0x6b, 0x47, 0x4, 0x92, 0xb } };
+
+///
+/// Enhanced Warning Log Revision GUID
+/// Rev 1:  {75713370-3805-46B0-9FED-60F282486CFC}
+///
+#define EWL_REVISION1_GUID { 0x75713370, 0x3805, 0x46b0, { 0x9f, 0xed, 0x60, 0xf2, 0x82, 0x48, 0x6c, 0xfc } };
+
+///
+/// Enhanced Warning Log Header
+///
+typedef struct {
+  EFI_GUID  EwlGuid;      /// GUID that uniquely identifies the EWL revision
+  UINT32    Size;         /// Total size in bytes including the header and buffer
+  UINT32    FreeOffset;   /// Offset of the beginning of the free space from byte 0
+                          /// of the buffer immediately following this structure
+                          /// Can be used to determine if buffer has sufficient space for next entry
+  UINT32    Crc;          /// 32-bit CRC generated over the whole size minus this crc field
+                          /// Note: UEFI 32-bit CRC implementation (CalculateCrc32) (References [7])
+                          /// Consumers can ignore CRC check if not needed.
+  UINT32    Reserved;     /// Reserved for future use, must be initialized to 0
+} EWL_HEADER;
+
+///
+/// List of all entry types supported by this revision of EWL
+///
+typedef enum {
+  EwlType0  = 0,
+  EwlType1  = 1,
+  EwlType2  = 2,
+  EwlType3  = 3,
+  EwlType4  = 4,
+  EwlType5  = 5,
+  EwlType6  = 6,
+  EwlType7  = 7,
+  EwlType8  = 8,
+  EwlType9  = 9,
+  EwlType10 = 10,
+  EwlType11 = 11,
+  EwlType12 = 12,
+  EwlType13 = 13,
+  EwlType14 = 14,
+  EwlType15 = 15,
+  EwlType16 = 16,
+  EwlType17 = 17,
+  EwlType18 = 18,
+  EwlType19 = 19,
+  EwlType20 = 20,
+  EwlType21 = 21,
+  EwlType22 = 22,
+  EwlType23 = 23,
+  EwlType24 = 24,
+  EwlType25 = 25,
+  EwlType26 = 26,
+  EwlType27 = 27,
+  EwlType28 = 28,
+  EwlType29 = 29,
+  EwlTypeMax,
+  EwlTypeOem = 0x8000,
+  EwlTypeDelim = MAX_INT32
+  } EWL_TYPE;
+
+///
+/// EWL severities
+///
+typedef enum {
+  EwlSeverityInfo,
+  EwlSeverityWarning,
+  EwlSeverityFatal,
+  EwlSeverityMax,
+  EwlSeverityDelim = MAX_INT32
+  } EWL_SEVERITY;
+
+///
+/// EWL Size\Type Structure for error checking
+///
+typedef struct {
+  EWL_TYPE Type;
+  UINT16   Size;
+} EWL_SIZE_CHECK;
+
+///
+/// Generic entry header for parsing the log
+///
+typedef struct {
+  EWL_TYPE      Type;
+  UINT16        Size;     /// Entries will be packed by byte in contiguous space
+  EWL_SEVERITY  Severity; /// Warning, error, informational, this may be extended in the future
+} EWL_ENTRY_HEADER;
+
+///
+/// Legacy content provides context of the warning
+///
+typedef struct {
+  UINT8     MajorCheckpoint;  // EWL Spec - Appendix B
+  UINT8     MinorCheckpoint;
+  UINT8     MajorWarningCode; // EWL Spec - Appendix A
+  UINT8     MinorWarningCode;
+} EWL_ENTRY_CONTEXT;
+
+///
+/// Legacy content to specify memory location
+///
+typedef struct {
+  UINT8     Socket;     /// 0xFF = n/a
+  UINT8     Channel;    /// 0xFF = n/a
+  UINT8     Dimm;       /// 0xFF = n/a
+  UINT8     Rank;       /// 0xFF = n/a
+} EWL_ENTRY_MEMORY_LOCATION;
+
+///
+/// Type 1 = Legacy memory warning log content plus checkpoint
+///
+typedef struct {
+  EWL_ENTRY_HEADER           Header;
+  EWL_ENTRY_CONTEXT          Context;
+  EWL_ENTRY_MEMORY_LOCATION  MemoryLocation;
+} EWL_ENTRY_TYPE1;
+
+///
+/// Type 2 = Enhanced type for data IO errors per device, per bit.
+///   Primarily associated with MRC training failures. Checkpoint information provides additional
+///   details to identify associated training step.
+///
+typedef struct {
+  EWL_ENTRY_HEADER           Header;
+  EWL_ENTRY_CONTEXT          Context;
+  EWL_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  UINT8                      Strobe;     /// 0xFF = n/a; include mapping of Dqs to Dq bits
+  UINT8                      Bit;        /// 0xFF = n/a; Dq bit# within strobe group
+  MRC_LT                     Level;      /// MrcGtDelim = n/a; Check BIOS SSA spec (References [1])
+  MRC_GT                     Group;      /// MrcGtDelim = n/a; Check BIOS SSA spec (References [1])
+  UINT8                      EyeSize;    /// 0xFF = n/a
+} EWL_ENTRY_TYPE2;
+
+///
+/// Type 3 = Enhanced type for command, control IO errors
+///   Primarily associated with MRC training failures. Checkpoint information provides additional
+///   details to identify associated training step.
+///
+typedef struct {
+  EWL_ENTRY_HEADER           Header;
+  EWL_ENTRY_CONTEXT          Context;
+  EWL_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  MRC_LT                     Level;       /// MrcGtDelim = n/a; Check BIOS SSA spec (References [1])
+  MRC_GT                     Group;       /// MrcGtDelim = n/a; Check BIOS SSA spec (References [1])
+  GSM_CSN                    Signal;      /// GsmCsnDelim = n/a
+  UINT8                      EyeSize;     /// 0xFF = n/a
+} EWL_ENTRY_TYPE3;
+
+///
+/// Requisite definitions for Type 4
+///
+/// Advanced Memtest Types
+///
+typedef enum {
+  AdvMtMax = 20,
+  AdvMtDelim = MAX_INT32
+  } ADV_MT_TYPE;
+
+///
+/// Advanced Memtest Error log structure based on processor specific CSR definitions
+///
+typedef struct {
+  UINT32 Dat0S;
+  UINT32 Dat1S;
+  UINT32 Dat2S;
+  UINT32 Dat3S;
+  UINT32 EccS;
+  UINT32 Chunk;
+  UINT32 Column;
+  UINT32 ColumnExt;
+  UINT32 Row;
+  UINT32 RowExt;
+  UINT32 Bank;
+  UINT32 Rank;
+  UINT32 Subrank;
+} EWL_ADV_MT_STATUS;
+
+///
+/// Type 4 = Enhanced type for DRAM Advanced Memtest errors
+///
+typedef struct {
+  EWL_ENTRY_HEADER           Header;
+  EWL_ENTRY_CONTEXT          Context;
+  EWL_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  ADV_MT_TYPE                MemtestType;
+  EWL_ADV_MT_STATUS          AdvMemtestErrorInfo;
+  UINT32                     Count;
+} EWL_ENTRY_TYPE4;
+
+///
+/// Type 5 = Legacy Memtest accumulated DQ errors
+///
+typedef struct {
+  EWL_ENTRY_HEADER           Header;
+  EWL_ENTRY_CONTEXT          Context;
+  EWL_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  UINT8                      SubRank;
+  UINT8                      BankAddress;
+  UINT8                      DqBytes[9];  /// Byte 0 = DQ[7:0], byte 1 = DQ[15:8], etc.
+} EWL_ENTRY_TYPE5;
+
+///
+/// Type 6 = Legacy UPI/KTIRC warning log content plus checkpoint
+///
+typedef struct {
+  EWL_ENTRY_HEADER        Header;
+  EWL_ENTRY_CONTEXT       Context;
+  UINT8                   SocketMask; /// Bitmask of CPU Sockets affected; 0xFF = SystemWide
+  UINT8                   SocketType; /// 0 = CPU Socket, 1 = FPGA, 0xFF = System Wide Warning
+  UINT8                   Port;       /// 0xFF = n/a; bitmask of affected port(s)
+} EWL_ENTRY_TYPE6;
+
+///
+/// Type 7 = CPU BIST failures
+///
+typedef struct{
+  EWL_ENTRY_HEADER        Header;
+  EWL_ENTRY_CONTEXT       Context;
+  UINT8                   Socket;  /// Socket number, 0 based
+  UINT32                  Core;    /// Core number, 0 based
+} EWL_ENTRY_TYPE7;
+
+///
+/// IIO Link Error log structure primary based on PCIE Specification 3.0 (References [8])
+///
+typedef struct {
+  UINT8                   Socket;          /// Socket number, 0 based
+  UINT8                   Stack;           /// 0-4, 0 = Cstack, 1-3 = Pstack, 4 MCP-stack (Only SKX-F)
+  UINT8                   Port;            /// 0-3
+  UINT8                   LtssmMainState;  /// Link state
+  UINT8                   LtssmSubState;   /// Check Appendix C to review states definitions
+  UINT32                  DidVid;          /// [31:16] DeviceID, [15:0] VendorID of the device
+                                           ///   attached to the Root Port
+} EWL_IIO_LINK_DESCRIPTION;
+
+///
+/// Type 8 = IIO Link Degraded width
+///
+typedef struct {
+  EWL_ENTRY_HEADER         Header;
+  EWL_ENTRY_CONTEXT        Context;
+  EWL_IIO_LINK_DESCRIPTION LinkDescription;
+  UINT8                    ExpectedLinkWidth;  /// Check register "Link Capabilities Register" over
+  UINT8                    ActualLinkWidth;    /// PCIE Specification 3.0 (References [8])
+} EWL_ENTRY_TYPE8;
+
+///
+/// Type 9 = IIO Link Degraded speed
+///
+typedef struct {
+  EWL_ENTRY_HEADER         Header;
+  EWL_ENTRY_CONTEXT        Context;
+  EWL_IIO_LINK_DESCRIPTION LinkDescription;
+  UINT8                    ExpectedLinkSpeed;  /// Check register "Link Capabilities Register" over
+  UINT8                    ActualLinkSpeed;    /// PCIE Specification 3.0 (References [8])
+} EWL_ENTRY_TYPE9;
+
+///
+/// Type 10 = Dq Swizzle Discovery errors
+///   Error if 0 or greater than 1 bit set in SwizzledDqLanes per strobe
+///
+typedef struct {
+  EWL_ENTRY_HEADER           Header;
+  EWL_ENTRY_CONTEXT          Context;
+  EWL_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  UINT8                      SwizzlePattern;  /// DQ pattern sent from device
+  UINT8                      SwizzledDqLanes; /// DQ pattern received at Host
+  UINT8                      LanesPerStrobe;  /// 4 or 8
+  UINT8                      Strobe;          /// DQS number to identify device
+} EWL_ENTRY_TYPE10;
+
+///
+/// Type 13 = NVMDIMM Training Failure
+///   Reported when a training issue is encountered
+///   Includes additional details on the NVMDIMM SPD and FW revisions
+///
+typedef struct {
+  EWL_ENTRY_HEADER           Header;
+  EWL_ENTRY_CONTEXT          Context;
+  EWL_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  UINT16                     RevisionNvmdimmFw;
+  UINT8                      RevisionNvmdimmSpd;
+} EWL_ENTRY_TYPE13;
+
+///
+/// Type 17 = ME communication failures
+///   Failure to communicate with Manageability Engine
+///
+typedef struct {
+  EWL_ENTRY_HEADER       Header;
+  EWL_ENTRY_CONTEXT      Context;
+  UINT32                 Revision;       /// ME API Revision
+  UINT32                 Mefs1;          /// ME Firmware Status 1 (HECI-1 HFS)
+  UINT32                 Mefs2;          /// ME Firmware Status 2 (HECI-1 GS_SHDW)
+  UINT8                  HeciDevice;     /// HECI device (1, 2, or 3)
+  UINT8                  MeAddress;      /// HECI address of ME entity
+  UINT8                  SendStatus;     /// Status of send operation
+  UINT8                  ReceiveStatus;  /// Status of receive operation
+  UINT64                 Request;        /// First 8 bytes of request message
+  UINT32                 Response;       /// First 4 bytes of response message
+} EWL_ENTRY_TYPE17;
+
+///
+/// To get more information about Machine-Check Architecture please check Chapter 15 from Vol. 3B
+///  of the Intel(R) 64 and IA-32 Architectures Software Developer's Manual (References [6]) for a
+///  general review.
+///
+/// Type 20 = CPU Machine Check Errors
+///
+typedef struct {
+  EWL_ENTRY_HEADER        Header;
+  EWL_ENTRY_CONTEXT       Context;
+  UINT32                  CpuId;         /// Refer to CPUID(EAX = 1) instruction to get Type, Family,
+                                         ///  Model, and Stepping ID from (References [6])
+  UINT8                   Socket;        /// Socket number, 0 based
+  UINT32                  Core;          /// Core number, 0 based
+  UINT32                  McBankNum;     /// Please refer to mcBankTable
+  UINT32                  McBankStatus;  /// Check register IA32_MCi_STATUS MSRs (References [6]&[5])
+  UINT32                  McBankAddr;    /// Check register IA32_MCi_ADDR MSRs (References [6]&[5])
+  UINT32                  McBankMisc;    /// Check register IA32_MCi_MISC MSRs (References [6]&[5])
+} EWL_ENTRY_TYPE20;
+
+///
+/// Requisite definitions for Type 21
+///
+/// Reasons for Topology degradation
+///
+typedef enum {
+  Undefined           = 0,
+  LinkFail            = 1,
+  InvalidTopology     = 2,
+  FeatureVsTopology   = 3,
+  DegradeReasonMax,
+  DegradeReasonDelim  = MAX_INT32
+  } TOPOLOGY_DEGRADE_REASON;
+
+///
+/// Type 21: Warning for tracking changes to KTI/UPI topology
+///
+/// Topology will be represented with a UINT64 bit array
+/// 0 indicates absent or inactive link
+/// 1 indicates active KTI/UPI link
+///
+/// Link Bit array member variables follow this format
+/// Each nibble corresponds to a socket:
+/// Each socket has MAX_FW_KTI_PORTS bits
+/// [(8*MAX_FW_KTI_PORTS - 1):7*MAX_FW_KTI_PORTS] - link bit mask for socket 7
+/// [(7*MAX_FW_KTI_PORTS - 1):6*MAX_FW_KTI_PORTS] - link bit mask for socket 6
+/// ....
+/// [(2*MAX_FW_KTI_PORTS - 1):  MAX_FW_KTI_PORTS] - link bit mask for socket 1
+/// [(MAX_FW_KTI_PORTS - 1)  :                 0] - link bit mask for socket 0
+///
+///   Bit 0 indicates an active link on port socket 0 port 0
+///   Bit 1 indicates an active link on port socket 0 port 1
+///   and so on.
+
+typedef struct {
+  EWL_ENTRY_HEADER        Header;
+  TOPOLOGY_DEGRADE_REASON Reason;
+  UINT64                  DegradedFrom;     /// Link Bit Array
+  UINT64                  NewTopology;      /// Link Bit Array
+} EWL_ENTRY_TYPE21;
+
+///
+/// To get more information about Machine-Check Architecture please check Chapter 15 from Vol. 3B
+///  of the Intel 64 and IA-32 Architectures Software Developer's Manual (References [6]) for a
+///  general review.
+///
+/// Type 22 = CPU Machine Check Errors. 2nd Version.
+///
+typedef struct {
+  EWL_ENTRY_HEADER        Header;
+  EWL_ENTRY_CONTEXT       Context;
+  UINT32                  CpuId;         /// Refer to CPUID(EAX=1) instruction to get Type, Family,
+                                         ///  Model, and Stepping ID from (References [6])
+  UINT8                   Socket;        /// Socket number, 0 based
+  UINT32                  Core;          /// Core number, 0 based
+  UINT32                  McBankNum;     /// Please refer to mcBankTable
+  UINT64                  McBankStatus;  /// Check register IA32_MCi_STATUS MSRs (References [6]&[5])
+  UINT64                  McBankAddr;    /// Check register IA32_MCi_ADDR MSRs (References [6]&[5])
+  UINT64                  McBankMisc;    /// Check register IA32_MCi_MISC MSRs (References [6]&[5])
+} EWL_ENTRY_TYPE22;
+
+//
+// Memory Boot Health check Warning log.
+//
+typedef struct {
+  EWL_ENTRY_HEADER           Header;
+  EWL_ENTRY_CONTEXT          Context;
+  EWL_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  MRC_GT                     Group;      /// MrcGtDelim = n/a;
+  INT16                      Offset;     /// Signal offset size that caused the error
+} EWL_ENTRY_TYPE25;
+
+//
+// Memory Power Management Errors
+//
+typedef struct {
+  EWL_ENTRY_HEADER           Header;
+  EWL_ENTRY_CONTEXT          Context;
+  EWL_ENTRY_MEMORY_LOCATION  MemoryLocation;
+} EWL_ENTRY_TYPE26;
+
+///
+/// Type 27 = NVMDIMM Media Log
+///   Reported NVMDIMM Media log
+///
+typedef struct {
+  EWL_ENTRY_HEADER           Header;
+  EWL_ENTRY_CONTEXT          Context;
+  EWL_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  UINT64                     TimeStamp;
+  UINT64                     DPA;
+  UINT64                     PDA;
+  UINT8                      Range;
+  UINT8                      ErrorType;
+  UINT8                      ErrorFlag;
+  UINT8                      TransacationType;
+  UINT16                     SequenceNumber;
+  UINT16                     Rsvd;
+} EWL_ENTRY_TYPE27;
+
+///
+/// Type 28 = NVMDIMM Thermal Log
+///   Reported NVMDIMM Thermal log
+///
+typedef struct {
+  EWL_ENTRY_HEADER           Header;
+  EWL_ENTRY_CONTEXT          Context;
+  EWL_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  UINT64                     TimeStamp;
+  UINT32                     HostReportedTempData;
+  UINT16                     SequenceNumber;
+  UINT16                     Rsvd;
+} EWL_ENTRY_TYPE28;
+
+//
+// RMT minimum margin check warning log.
+//
+typedef struct {
+  EWL_ENTRY_HEADER           Header;
+  EWL_ENTRY_CONTEXT          Context;
+  EWL_ENTRY_MEMORY_LOCATION  MemoryLocation;
+  MRC_GT                     Group;
+  INT16                      NegativeMargin;
+  INT16                      PositiveMargin;
+  INT16                      MinimumMargin;
+} EWL_ENTRY_TYPE29;
+
+#pragma pack()
+
+///
+/// Enhanced Warning Log Spec defined data log structure
+///
+typedef struct {
+  EWL_HEADER Header;          /// The size will vary by implementation and should not be assumed
+  UINT8      Buffer[4 * 1024];  /// The spec requirement is that the buffer follow the header
+} EWL_PUBLIC_DATA;
+
+///
+/// EWL private data structure.  This is going to be implementation dependent
+///   When we separate OEM hooks via a PPI, we can remove this
+///
+typedef struct {
+  UINT32            bufSizeOverflow;  // Number of bytes that could not be added to buffer
+  UINT32            numEntries;       // Number of entries currently logged
+  EWL_PUBLIC_DATA   status;           // Spec defined EWL
+} EWL_PRIVATE_DATA;
+
+#endif // #ifndef _ENHANCED_WARNING_LOG_LIB_
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Library/SpdAccessLib.h b/Silicon/Intel/WhitleySiliconPkg/Include/Library/SpdAccessLib.h
new file mode 100644
index 0000000000..4b15795665
--- /dev/null
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/Library/SpdAccessLib.h
@@ -0,0 +1,32 @@
+/** @file
+  The SPD Access Library API provides the necessary functions to initiate SPD
+  read/write transactions.
+
+  This API is designed to function as an interface between an agent that needs
+  to read/write to a DIMM SPD and a lower level library (such as an SMBus library)
+  which handles the actual transactions.  The read/write functions accept DIMM
+  location information as well as the SPD byte offset and should then handle
+  the steps necessary to initiate (for example) a SMBus transaction to do the
+  reading/writing.  Functions are also provided to initialize any data/setup
+  steps needed before attempting a read/write transaction and to communicate to
+  the library that DIMM detection is complete providing a way for the library
+  to know that it can check for a DIMM's presence bofore initiating a transaction.
+
+  @copyright
+  Copyright 2018 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SPD_ACCESS_LIB_H_
+#define _SPD_ACCESS_LIB_H_
+
+//
+// DDR Technology supported
+//
+typedef enum {
+  Ddr4Type = 0,         // DDR4 Technology support
+  DdrMaxType            // Enum limit to check valid value
+} DDR_TECHNOLOGY_TYPE;
+
+#endif // #ifndef _SPD_ACCESS_LIB_H_
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/MemCommon.h b/Silicon/Intel/WhitleySiliconPkg/Include/MemCommon.h
index 6958b1431b..af9f0b0734 100644
--- a/Silicon/Intel/WhitleySiliconPkg/Include/MemCommon.h
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/MemCommon.h
@@ -38,4 +38,11 @@ typedef enum {
   TYPE_MAX_MMIO_BAR
 } MMIO_BARS;
 
+//
+// Memory parameters and SPD JEDEC definitions
+//
+#define MAX_SPD_BYTE_DDR4 512 // Number of bytes in Serial EEPROM on DDR4
+
+#define MAX_SPD_BYTE_DDR MAX_SPD_BYTE_DDR4
+
 #endif //#ifndef __MEM_COMMON_H__
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Platform.h b/Silicon/Intel/WhitleySiliconPkg/Include/Platform.h
index b8ed188f16..e3cc80acde 100644
--- a/Silicon/Intel/WhitleySiliconPkg/Include/Platform.h
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/Platform.h
@@ -224,6 +224,8 @@
 
 #define PCH_TCO_BASE_ADDRESS            PcdGet16 (PcdTcoBaseAddress)
 
+#define PM_BASE_ADDRESS                 PCH_ACPI_BASE_ADDRESS
+
 #define SIO_GPIO_BASE_ADDRESS           0x0800
 
 //
@@ -240,6 +242,8 @@
 #define CMOS_PLATFORM_ID_LO             0x18            // Second bank CMOS location of Platform ID
 #define CMOS_PLATFORM_ID_HI             0x19            //
 
+#define HPET_BLOCK_ADDRESS                            0x0FED00000
+
 #define PCI_BUS_NUMBER_PCH_HPET                       0x0
 #define PCI_DEVICE_NUMBER_PCH_HPET                    0x1F
 
@@ -250,6 +254,9 @@
 
 #define PCI_FUNCTION_NUMBER_PCH_IOAPIC                0x0
 
+#define SW_SMI_OS_REQUEST      0x83  // OS transition request.
+#define MEM_ADDR_SHFT_VAL         26    // For 64 MB granularity
+
 //
 // AHCI port offset values
 //
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Ppi/MemoryPolicyPpi.h b/Silicon/Intel/WhitleySiliconPkg/Include/Ppi/MemoryPolicyPpi.h
index 6c5ca06bc1..38b90713f7 100644
--- a/Silicon/Intel/WhitleySiliconPkg/Include/Ppi/MemoryPolicyPpi.h
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/Ppi/MemoryPolicyPpi.h
@@ -999,7 +999,7 @@ struct memSetup {
   /// @brief
   /// Pirnt length of SPD data.<BR>
   /// @details
-  ///   0 - AUTO(512 for DDR4, 1024 for DDR5).<BR>
+  ///   0 - AUTO(512 for DDR4).<BR>
   ///   256.<BR>
   ///   512.<BR>
   ///
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/AcpiPlatformProtocol.h b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/AcpiPlatformProtocol.h
new file mode 100644
index 0000000000..d7f1adca4d
--- /dev/null
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/AcpiPlatformProtocol.h
@@ -0,0 +1,51 @@
+/** @file
+  EFI ACPI Platform Protocol
+
+  @copyright
+  Copyright 2018 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_PLATFORM_PROTOCOL_H
+#define _ACPI_PLATFORM_PROTOCOL_H
+
+#include <IndustryStandard/Acpi62.h>
+
+///
+/// ACPI Platform protocol provided for DXE phase
+///
+typedef struct _ACPI_PLATFORM_PROTOCOL  ACPI_PLATFORM_PROTOCOL;
+
+typedef EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE ACPI_MEMORY_AFFINITY_DATA;
+#define ACPI_MEMORY_NONVOLATILE   EFI_ACPI_6_2_MEMORY_NONVOLATILE
+
+/**
+  Function retrieves selected data of ACPI SRAT Memory Affinity Structures
+  (please note that data will not be available until SRAT table installation)
+
+  @param[out] *MemAffData         ACPI Memory Affinity Data
+  @param[out] *MemAffDataLength   ACPI Memory Affinity Data Length
+
+  @retval EFI_SUCCESS             ACPI Memory Affinity Data retrieved successfully
+  @retval EFI_NOT_FOUND           ACPI Memory Affinity Data not found (SRAT ACPI table was not published)
+  @retval EFI_INVALID_PARAMETER   One or more of input arguments is NULL
+**/
+typedef
+EFI_STATUS
+(EFIAPI *GET_ACPI_MEMORY_AFFINITY_DATA) (
+  OUT ACPI_MEMORY_AFFINITY_DATA **MemAffData,
+  OUT UINTN                     *MemAffDataLength
+  );
+
+
+/**
+  ACPI Platform protocol provided for DXE phase
+**/
+struct _ACPI_PLATFORM_PROTOCOL {
+  GET_ACPI_MEMORY_AFFINITY_DATA GetAcpiMemoryAffinityData;
+};
+
+extern EFI_GUID gAcpiPlatformProtocolGuid;
+
+#endif // _ACPI_PLATFORM_PROTOCOL_H
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/CpuCsrAccess.h b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/CpuCsrAccess.h
new file mode 100644
index 0000000000..4ace32de62
--- /dev/null
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/CpuCsrAccess.h
@@ -0,0 +1,254 @@
+/** @file
+  Header file for IOX access APIs.
+
+  @copyright
+  Copyright 2007 - 2019 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_CSR_ACCESS_H_
+#define _CPU_CSR_ACCESS_H_
+
+extern EFI_GUID         gEfiCpuCsrAccessGuid;
+
+/**
+
+  Computes address of CPU Uncore & IIO PCI configuration space using the MMIO mechanism
+
+  @param[in] SocId      - CPU Socket Node number
+  @param[in] BoxInst    - Box Instance, 0 based
+  @param[in] Offset     - Register offset; values come from the auto generated header file
+  @param[in, out] Size  - Ptr to register size in bytes (may be updated if pseudo-offset)
+
+  @retval Address
+
+**/
+
+typedef
+UINT64
+(EFIAPI *GET_CPU_CSR_ADDRESS) (
+  IN UINT8    SocId,
+  IN UINT8    BoxInst,
+  IN UINT32   Offset,
+  IN OUT UINT8 *Size
+  );
+
+/**
+
+  Reads CPU Uncore & IIO PCI configuration space using the MMIO mechanism
+
+  @param[in] SocId    - CPU Socket Node number
+  @param[in] BoxInst  - Box Instance, 0 based
+  @param[in] Offset   - Register offset; values come from the auto generated header file
+
+  @retval Register value
+
+**/
+
+typedef
+UINT32
+(EFIAPI *READ_CPU_CSR) (
+  IN UINT8    SocId,
+  IN UINT8    BoxInst,
+  IN UINT32   Offset
+  );
+
+/**
+
+  Writes CPU Uncore & IIO PCI configuration space using the MMIO mechanism
+
+  @param[in] SocId     - CPU Socket Node number
+  @param[in] BoxInst   - Box Instance, 0 based
+  @param[in] Offset    - Register offset; values come from the auto generated header file
+  @param[in] Data      - Register data to be written
+
+  @retval None
+
+**/
+
+typedef
+VOID
+(EFIAPI *WRITE_CPU_CSR) (
+  IN UINT8    SocId,
+  IN UINT8    BoxInst,
+  IN UINT32   Offset,
+  IN UINT32   Data
+  );
+
+/**
+
+  Reads CPU Memory Controller configuration space using the MMIO mechanism
+
+  @param[in] SocId        - Socket ID
+  @param[in] McId         - Memory controller ID
+  @param[in] Offset       - Register offset; values come from the auto generated header file
+
+  @retval Register value
+
+**/
+
+typedef
+UINT32
+(EFIAPI *READ_MC_CPU_CSR) (
+  IN UINT8    SocId,
+  IN UINT8    McId,
+  IN UINT32   Offset
+  );
+
+/**
+
+  Writes CPU Memory Controller configuration space using the MMIO mechanism
+
+  @param[in] SocId        - Socket ID
+  @param[in] McId         - Memory controller ID
+  @param[in] RegOffset    - Register offset; values come from the auto generated header file
+  @param[in] Data         - Register data to be written
+
+  @retval None
+
+**/
+
+typedef
+VOID
+(EFIAPI *WRITE_MC_CPU_CSR) (
+  IN UINT8    SocId,
+  IN UINT8    McId,
+  IN UINT32   RegOffset,
+  IN UINT32   Data
+  );
+
+/**
+
+  Get CPU Memory Controller configuration space address used by MMIO mechanism
+
+  @param[in] SocId        - Socket ID
+  @param[in] McId         - Memory controller ID
+  @param[in] Offset       - Register offset; values come from the auto generated header file
+
+  @retval MC Register MMCFG address
+
+**/
+
+typedef
+UINTN
+(EFIAPI *GET_MC_CPU_ADDR) (
+  IN UINT8    SocId,
+  IN UINT8    McId,
+  IN UINT32   RegOffset
+  );
+
+/**
+
+  Reads PCI configuration space using the MMIO mechanism
+
+  @param[in] Socket - Socket
+  @param[in] Reg    - "Reg" uses the format in the Bus_Dev_Func_CFG.H files
+
+  @retval Value in requested reg
+
+**/
+
+typedef
+UINT32
+(EFIAPI *READ_PCI_CSR) (
+  IN UINT8    Socket,
+  IN UINT32   Reg
+  );
+
+/**
+
+  Writes specified data to PCI configuration space using the MMIO mechanism
+
+  @param[in] Socket - Socket
+  @param[in] Reg    - "Reg" uses the format in the Bus_Dev_Func_CFG.H files
+  @param[in] Data   - Value to write
+
+  @retval VOID
+
+**/
+
+typedef
+VOID
+(EFIAPI *WRITE_PCI_CSR) (
+  IN UINT8    Socket,
+  IN UINT32   Reg,
+  IN UINT32   Data
+  );
+
+/**
+
+  Get PCI configuration space address used MMIO mechanism
+
+  @param[in] Socket - Socket
+  @param[in] Reg    - "Reg" uses the format in the Bus_Dev_Func_CFG.H files
+
+  @retval Address of requested reg
+
+**/
+
+typedef
+UINT32
+(EFIAPI *GET_PCI_CSR_ADDR) (
+  IN UINT8    Socket,
+  IN UINT32   Reg
+  );
+
+/**
+
+   Writes the given command to BIOS to PCU Mailbox Interface CSR register
+
+  @param[in] Socket   - CPU Socket number
+  @param[in] Command  - Pcu mailbox command to write
+  @param[in] Data     - Pcu mailbox data
+
+  @retval error code from the Pcu mailbox (0 = NO ERROR)
+
+**/
+
+typedef
+UINT64
+(EFIAPI *BIOS_2_VCODE_MAILBOX_WRITE) (
+  IN UINT8  Socket,
+  IN UINT32 Command,
+  IN UINT32 Data
+  );
+
+/**
+
+  Writes the checkpoint code to the checkpoint CSR and breaks if match with debug breakpoint
+  @param[in] Socket    - Socket to write
+  @param[in] majorCode - Major Checkpoint code to write
+  @param[in] minorCode - Minor Checkpoint code to write
+  @param[in] data      - Data specific to the minor checkpoint is written to
+                         low word of the checkpoint CSR
+
+  @retval VOID
+
+**/
+
+typedef
+VOID
+(EFIAPI *BREAK_AT_CHECK_POINT) (
+  IN UINT8    Socket,
+  IN UINT8    MajorCode,
+  IN UINT8    MinorCode,
+  IN UINT16   Data
+  );
+
+typedef struct _EFI_CPU_CSR_ACCESS_PROTOCOL {
+  GET_CPU_CSR_ADDRESS         GetCpuCsrAddress;
+  READ_CPU_CSR                ReadCpuCsr;
+  WRITE_CPU_CSR               WriteCpuCsr;
+  BIOS_2_VCODE_MAILBOX_WRITE  Bios2VcodeMailBoxWrite;
+  READ_MC_CPU_CSR             ReadMcCpuCsr;
+  WRITE_MC_CPU_CSR            WriteMcCpuCsr;
+  GET_MC_CPU_ADDR             GetMcCpuCsrAddress;
+  READ_PCI_CSR                ReadPciCsr;
+  WRITE_PCI_CSR               WritePciCsr;
+  GET_PCI_CSR_ADDR            GetPciCsrAddress;
+  BREAK_AT_CHECK_POINT        BreakAtCheckpoint;
+} EFI_CPU_CSR_ACCESS_PROTOCOL;
+
+#endif // _CPU_CSR_ACCESS_H_
+
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol.h b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol.h
index df8317937f..b9531dbf75 100644
--- a/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol.h
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol.h
@@ -1,5 +1,5 @@
 /** @file
-  Dynamic link silicon library service access Protocol
+  Dynamic link silicon library service access Protocol for earlier boot functions
 
   This protocol abstracts silicon static library accesses via a protocol
 
@@ -19,6 +19,9 @@
 #include <Library/CpuEarlyDataLib.h>
 #include <UsraAccessType.h>
 #include <IioUniversalData.h>
+#include <Protocol/IioUds.h>
+#include <Protocol/CpuCsrAccess.h>
+#include <GpioConfig.h>
 
 #define DYNAMIC_SI_LIBARY_PROTOCOL_GUID \
   { 0xb235fbed, 0x3b25, 0x4cb3, { 0x98, 0x9c, 0x8c, 0xe7, 0xec, 0x49, 0x8b, 0x7e } }
@@ -30,13 +33,6 @@
 // Functions
 //
 
-typedef
-EFI_STATUS
-(EFIAPI *DXE_SET_GPIO_OUTPUT_VALUE) (
-  IN  UINT32                              GPioPad,
-  IN  UINT32                              Value
-  );
-
 typedef
 BOOLEAN
 (EFIAPI *DXE_IsCpuAndRevision) (
@@ -79,6 +75,27 @@ VOID
   IN  UINT32         DidVid
   );
 
+typedef
+EFI_STATUS
+(EFIAPI *DXE_GpioGetInputValue) (
+  IN GPIO_PAD                  GpioPad,
+  OUT UINT32                   *InputVal
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DXE_SET_GPIO_OUTPUT_VALUE) (
+  IN  UINT32                              GPioPad,
+  IN  UINT32                              Value
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DXE_GpioSetPadConfig) (
+  IN GPIO_PAD                  GpioPad,
+  IN GPIO_CONFIG               *GpioData
+  );
+
 typedef
 CHAR8*
 (EFIAPI *DXE_PchGetSeriesStr) (
@@ -210,6 +227,13 @@ UINT32
   VOID
   );
 
+typedef
+VOID
+(EFIAPI *DXE_WriteScratchpad5) (
+  UINT8   Socket,
+  UINT32  Value
+  );
+
 //
 // UBA specific silicon abstraction protocol
 //
@@ -223,7 +247,9 @@ typedef struct {
   DXE_MmPciBase                           MmPciBase;
   DXE_GetSysCpuCsrAccessVar               GetSysCpuCsrAccessVar;
   DXE_IioPciHookBeforeEnumeration         IioPciHookBeforeEnumeration;
+  DXE_GpioGetInputValue                   GpioGetInputValue;
   DXE_SET_GPIO_OUTPUT_VALUE               GpioSetOutputValue;
+  DXE_GpioSetPadConfig                    GpioSetPadConfig;
   DXE_PchGetSeriesStr                     PchGetSeriesStr;
   DXE_PchGetSteppingStr                   PchGetSteppingStr;
   DXE_PchGetSkuStr                        PchGetSkuStr;
@@ -245,6 +271,7 @@ typedef struct {
   DXE_ProgramImr2Regs                     ProgramImr2Regs;
   DXE_CheckAndPopulateIedTraceMemory      CheckAndPopulateIedTraceMemory;
   DXE_ReadScratchpad7                     ReadScratchpad7;
+  DXE_WriteScratchpad5                    WriteScratchpad5;
 } DYNAMIC_SI_LIBARY_PROTOCOL;
 
 extern EFI_GUID gDynamicSiLibraryProtocolGuid;
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol2.h b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol2.h
new file mode 100644
index 0000000000..5f984aa391
--- /dev/null
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol2.h
@@ -0,0 +1,255 @@
+/** @file
+  Dynamic link silicon library service access Protocol for later boot functions
+
+  This protocol abstracts silicon static library accesses via a protocol
+
+  @copyright
+  Copyright 2021 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DYNAMIC_SI_LIBARY_PROTOCOL2_H_
+#define _DYNAMIC_SI_LIBARY_PROTOCOL2_H_
+
+#include <Protocol/IioUds.h>
+#include <Protocol/CpuCsrAccess.h>
+#include <IndustryStandard/Acpi.h>
+#include <Library/CpuConfigLib.h>
+#include <IndustryStandard/Acpi.h>
+
+#define DYNAMIC_SI_LIBARY_PROTOCOL2_GUID { 0x98bdd399, 0x9349, 0x4131, { 0x87, 0x60, 0x90, 0xaf, 0x68, 0x01, 0x21, 0xee } }
+
+#define DYNAMIC_SI_LIBARY_PROTOCOL2_SIGNATURE  SIGNATURE_32('D', 'S', 'L', '2')
+#define DYNAMIC_SI_LIBARY_PROTOCOL2_VERSION    0x01
+
+//
+// Functions
+//
+
+typedef
+UINT32
+(EFIAPI *DXE_GetVtdBar) (
+  IN UINT8     SocId,
+  IN UINT8     StackId
+  );
+
+typedef
+UINT8
+(EFIAPI *DXE_GetMaxPortPerSocket) (
+  IN UINT8     SocId
+  );
+
+typedef
+UINT8
+(EFIAPI *DXE_GetStackPerPort) (
+  IN UINT8     SocId,
+  IN UINT8     PortIndex
+  );
+
+typedef
+UINT8
+(EFIAPI *DXE_GetSocketPortBusNum) (
+  IN UINT8     SocId,
+  IN UINT8     PortIndex
+  );
+
+typedef
+BOOLEAN
+(EFIAPI *DXE_IioNtbIsEnabled) (
+  IN  UINT8    IioIndex,
+  IN  UINT8    IioPort,
+  OUT UINT8   *DevNoPtr,
+  OUT UINT8   *FuncNoPtr
+  );
+
+typedef
+BOOLEAN
+(EFIAPI *DXE_IioVmdPortIsEnabled) (
+  IN  UINT8    IioIndex,
+  IN  UINT8    IioPort
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DXE_IioVmdGetPciLocation) (
+  IN  UINT8    IioIndex,
+  IN  UINT8    IioStack,
+  OUT UINT8   *PciDevPtr,
+  OUT UINT8   *PciFuncPtr
+  );
+
+typedef
+UINT8
+(EFIAPI *DXE_GetCurrentPXPMap) (
+  IN UINT8     SocId,
+  IN UINT8     PortIndex
+  );
+
+typedef
+BOOLEAN
+(EFIAPI *DXE_IsSlowBoot) (
+  VOID
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DXE_UpdatePcatTable) (
+   IN OUT   EFI_ACPI_COMMON_HEADER  *Table
+   );
+
+#pragma pack(1)
+typedef struct {
+  UINT32  ApicId;
+  UINT32  ThreadIdValue;
+  UINT32  CollocatedChaId;
+  UINT32  SNCProximityDomain;
+} CPU_LOGICAL_THREAD_ID_TABLE;
+#pragma pack()
+
+typedef
+UINT8
+(EFIAPI *DXE_GetNumOfClusterPerSystem) (
+  VOID
+  );
+
+typedef
+UINT8
+(EFIAPI *DXE_GetMaxPhysicalAddrBits) (
+  VOID
+  );
+
+typedef
+BOOLEAN
+(EFIAPI *DXE_IsMemTypeVolatile) (
+  MEM_TYPE MemType
+  );
+
+typedef
+BOOLEAN
+(EFIAPI *DXE_IsMemType2lm) (
+  MEM_TYPE MemType
+  );
+
+typedef
+BOOLEAN
+(EFIAPI *DXE_IsMemTypeReserved) (
+  MEM_TYPE MemType
+  );
+
+typedef
+BOOLEAN
+(EFIAPI *DXE_IsMemTypeAppDirect) (
+  MEM_TYPE MemType
+  );
+
+typedef
+BOOLEAN
+(EFIAPI *DXE_IsMemTypeFpga) (
+  MEM_TYPE MemType
+  );
+
+typedef
+UINT8
+(EFIAPI *DXE_GetKtiPortCnt) (
+  VOID
+  );
+
+typedef
+UINT8
+(EFIAPI *DXE_GetMaxImc) (
+  VOID
+  );
+
+typedef
+UINT8
+(EFIAPI *DXE_GetNumChannelPerMc) (
+  VOID
+  );
+
+typedef
+UINT8
+(EFIAPI *DXE_GetAcpiDieCount) (
+  IN UINT8   SocketId
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DXE_SpdReadByte) (
+  IN UINT8      Socket,
+  IN UINT8      Chan,
+  IN UINT8      Dimm,
+  IN UINT16     ByteOffset,
+  OUT UINT8     *Data
+  );
+
+typedef
+UINT8
+(EFIAPI *DXE_DetectHwpFeature) (
+   VOID
+  );
+
+typedef
+BOOLEAN
+(EFIAPI *DXE_SocketPresent) (
+  IN UINT32     SocId
+  );
+
+typedef
+BOOLEAN
+(EFIAPI *DXE_IfStackPresent) (
+  IN UINT8     SocId,
+  IN UINT8     StackId
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DXE_PchHpetBaseGet) (
+  OUT UINT32                            *HpetBase
+  );
+
+typedef
+UINT32
+(EFIAPI *DXE_PcuGetDesiredCoreSmtDis) (
+  UINT8 Socket
+  );
+
+//
+// UBA specific silicon abstraction protocol
+//
+typedef struct {
+  UINT32                                  Signature;
+  UINT32                                  Version;
+
+  DXE_GetVtdBar                           GetVtdBar;
+  DXE_GetMaxPortPerSocket                 GetMaxPortPerSocket;
+  DXE_GetStackPerPort                     GetStackPerPort;
+  DXE_GetSocketPortBusNum                 GetSocketPortBusNum;
+  DXE_IioNtbIsEnabled                     IioNtbIsEnabled;
+  DXE_IioVmdPortIsEnabled                 IioVmdPortIsEnabled;
+  DXE_IioVmdGetPciLocation                IioVmdGetPciLocation;
+  DXE_GetCurrentPXPMap                    GetCurrentPXPMap;
+  DXE_IsSlowBoot                          IsSlowBoot;
+  DXE_UpdatePcatTable                     UpdatePcatTable;
+  DXE_GetNumOfClusterPerSystem            GetNumOfClusterPerSystem;
+  DXE_GetMaxPhysicalAddrBits              GetMaxPhysicalAddrBits;
+  DXE_IsMemTypeVolatile                   IsMemTypeVolatile;
+  DXE_IsMemType2lm                        IsMemType2lm;
+  DXE_IsMemTypeReserved                   IsMemTypeReserved;
+  DXE_IsMemTypeAppDirect                  IsMemTypeAppDirect;
+  DXE_IsMemTypeFpga                       IsMemTypeFpga;
+  DXE_GetKtiPortCnt                       GetKtiPortCnt;
+  DXE_GetMaxImc                           GetMaxImc;
+  DXE_GetNumChannelPerMc                  GetNumChannelPerMc;
+  DXE_GetAcpiDieCount                     GetAcpiDieCount;
+  DXE_SpdReadByte                         SpdReadByte;
+  DXE_DetectHwpFeature                    DetectHwpFeature;
+  DXE_SocketPresent                       SocketPresent;
+  DXE_IfStackPresent                      IfStackPresent;
+  DXE_PchHpetBaseGet                      PchHpetBaseGet;
+  DXE_PcuGetDesiredCoreSmtDis             PcuGetDesiredCoreSmtDis;
+} DYNAMIC_SI_LIBARY_PROTOCOL2;
+
+extern EFI_GUID gDynamicSiLibraryProtocol2Guid;
+
+#endif // _DYNAMIC_SI_LIBARY_PROTOCOL2_H_
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/NfitTableUpdateProtocol.h b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/NfitTableUpdateProtocol.h
new file mode 100644
index 0000000000..bd85f646c9
--- /dev/null
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/NfitTableUpdateProtocol.h
@@ -0,0 +1,27 @@
+/** @file
+
+  @copyright
+  Copyright 2018 - 2019 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _NFIT_TABLE_UPDATE_PROTOCOL_H_
+#define _NFIT_TABLE_UPDATE_PROTOCOL_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiNfitTableUpdateProtocolGuid;
+
+typedef
+EFI_STATUS
+(EFIAPI *NFIT_TABLE_UPDATE) (
+  UINT64 *NfitTablePointer
+  );
+
+typedef struct _EFI_NFIT_TABLE_UPDATE_PROTOCOL {
+  NFIT_TABLE_UPDATE   UpdateAcpiTable;
+} EFI_NFIT_TABLE_UPDATE_PROTOCOL;
+
+#endif // _NFIT_TABLE_UPDATE_PROTOCOL_H_
diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/SmbiosMemInfo.h b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/SmbiosMemInfo.h
new file mode 100644
index 0000000000..7b398cf1dc
--- /dev/null
+++ b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/SmbiosMemInfo.h
@@ -0,0 +1,87 @@
+/** @file
+  This file publishes protocol that provides additional information
+  for memory related SMBIOS entries.
+  NOTE: Currently only Type17 entries are used, no need for others identified.
+  Only Type17 entries that represent existing DIMMs are listed.
+
+  @copyright
+  Copyright 2017 - 2018 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PROTOCOL_SMBIOSMEMINFO_H_
+#define _PROTOCOL_SMBIOSMEMINFO_H_
+
+#define SMBIOS_MEMINFO_PROT_VERSION 1
+
+//
+// Invalid SMBIOS handle to use if Type17 entry does not exist.
+//
+#define SMBIOS_INVALID_HANDLE       0xFFFF
+
+typedef struct _SMBIOS_MEM_INFO_PROTOCOL_ SMBIOS_MEM_INFO_PROTOCOL;
+
+/**
+ * Localization information for SMBIOS Type17 entries that represent DIMMs.
+ */
+typedef struct _SMBIOS_DIMM_INFO_ {
+  INT8              Socket;       ///< Socket index (0 based)
+  INT8              Imc;          ///< Intergrated memory controller in the above socket
+  INT8              Channel;      ///< Channel in the above IMC
+  INT8              Dimm;         ///< DIMM slot index in the above channel
+  EFI_SMBIOS_HANDLE Type17Handle; ///< Type17 handle in SMBIOS table
+  BOOLEAN           IsNvDimm;     ///< True if it is Non Volatile DIMM
+} SMBIOS_DIMM_INFO;
+
+
+/**
+  This function finds SMBIOS Type17 entry for given SMBIOS handle.
+
+  On input Info->Handle must be set.
+  On output, unless error was returned, the rest of the structure is filled.
+
+  @param[in]     This  - Pointer to the protocol
+  @param[in,out] Info  - Pointer to DIMM info structure
+
+  @return Standard status codes are returned.
+**/
+typedef EFI_STATUS (EFIAPI *SMBIOS_GET_DIMM_BY_HANDLE) (
+  IN     SMBIOS_MEM_INFO_PROTOCOL *This,
+  IN OUT SMBIOS_DIMM_INFO         *Info
+  );
+
+/**
+  This function finds SMBIOS Type17 entry for given DIMM location.
+
+  On input Info->Socket, Info->Imc, Info->Channel, Info->Dimm must be set.
+  On output, unless error was returned, the rest of the structure is filled.
+
+  @param[in]     This  - Pointer to the protocol
+  @param[in,out] Info  - Pointer to DIMM info structure.
+
+  @return Standard status codes are returned.
+**/
+typedef EFI_STATUS (EFIAPI *SMBIOS_GET_DIMM_BY_LOCATION) (
+  IN     SMBIOS_MEM_INFO_PROTOCOL *This,
+  IN OUT SMBIOS_DIMM_INFO         *Info
+  );
+
+/**
+ * This protocol provides information about memory related SMBIOS entries.
+ *
+ * NOTE: Currently only Type17 entries are used, no need for others.
+ *       Only Type17 entries that represent existing DIMMs are listed.
+ */
+typedef struct _SMBIOS_MEM_INFO_PROTOCOL_ {
+  UINT16                      SmbiosMemInfoProtVersion;
+  UINT8                       Reserved[2];
+  UINT32                      SmbiosDimmNum; ///< Number of DIMM (Type17) handles in SMBIOS
+
+  SMBIOS_GET_DIMM_BY_HANDLE   SmbiosGetDimmByHandle;
+  SMBIOS_GET_DIMM_BY_LOCATION SmbiosGetDimmByLocation;
+} SMBIOS_MEM_INFO_PROTOCOL;
+
+extern EFI_GUID gSmbiosMemInfoProtocolGuid;
+
+#endif // _PROTOCOL_SMBIOSMEMINFO_H_
diff --git a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MemRegs.h b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MemRegs.h
index 3c8abe4dbb..7b2baa3284 100644
--- a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MemRegs.h
+++ b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MemRegs.h
@@ -10,6 +10,8 @@
 #ifndef _memregs_h
 #define _memregs_h
 
+#define SPD_TYPE_DDR4         0x0C  // DDR4 SDRAM
+
 //
 // NVM DIMM Reg Structs
 //
diff --git a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MrcCommonTypes.h b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MrcCommonTypes.h
index eba0a14354..a85e10609a 100644
--- a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MrcCommonTypes.h
+++ b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MrcCommonTypes.h
@@ -21,8 +21,33 @@ typedef struct {
   UINT32        NumDqLanesPerCh;  // Number of active DQ lanes in a data channel (bus width)
 } MRC_MSM;
 
+typedef enum {
+  DdrLevel = 0,                         ///< Refers to frontside of DIMM
+  LrbufLevel = 1,                         ///< Refers to data level at backside of LRDIMM or NVMDIMM buffer
+  RegALevel = 2,                         ///< Refers to cmd level at backside of register, side A
+  RegBLevel = 3,                         ///< Refers to cmd level at backside of register, side B
+  HbmLevel = 4,                         ///< Refers to HBM
+  MrcLtMax,
+  MrcLtDelim = MAX_INT32
+  } MRC_LT;
+
+///
+/// Memory training margin group selectors.
+///
+typedef enum {
+  MrcGtMax = 224,
+  MrcGtDelim = MAX_INT32
+  } MRC_GT;
+
 typedef enum {
   MrcTtDelim = MAX_INT32
 } MRC_TT;
 
+///
+/// External signal names
+///
+typedef enum {
+  gsmCsnDelim = MAX_INT32
+} GSM_CSN;
+
 #endif // _MrcCommonTypes_h_
diff --git a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/SysHost.h b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/SysHost.h
index d419edea4a..50aa342994 100644
--- a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/SysHost.h
+++ b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/SysHost.h
@@ -27,39 +27,7 @@ typedef struct sysHost SYSHOST, *PSYSHOST;
 #include "PlatformHost.h"
 #include "MemHost.h"
 #include <Ppi/MemoryPolicyPpi.h>
-
-///
-/// Enhanced Warning Log Header
-///
-typedef struct {
-  EFI_GUID  EwlGuid;      /// GUID that uniquely identifies the EWL revision
-  UINT32    Size;         /// Total size in bytes including the header and buffer
-  UINT32    FreeOffset;   /// Offset of the beginning of the free space from byte 0
-                          /// of the buffer immediately following this structure
-                          /// Can be used to determine if buffer has sufficient space for next entry
-  UINT32    Crc;          /// 32-bit CRC generated over the whole size minus this crc field
-                          /// Note: UEFI 32-bit CRC implementation (CalculateCrc32) (References [7])
-                          /// Consumers can ignore CRC check if not needed.
-  UINT32    Reserved;     /// Reserved for future use, must be initialized to 0
-} EWL_HEADER;
-
-///
-/// Enhanced Warning Log Spec defined data log structure
-///
-typedef struct {
-  EWL_HEADER Header;          /// The size will vary by implementation and should not be assumed
-  UINT8      Buffer[4 * 1024];  /// The spec requirement is that the buffer follow the header
-} EWL_PUBLIC_DATA;
-
-///
-/// EWL private data structure.  This is going to be implementation dependent
-///   When we separate OEM hooks via a PPI, we can remove this
-///
-typedef struct {
-  UINT32            bufSizeOverflow;  // Number of bytes that could not be added to buffer
-  UINT32            numEntries;       // Number of entries currently logged
-  EWL_PUBLIC_DATA   status;           // Spec defined EWL
-} EWL_PRIVATE_DATA;
+#include <Library/EnhancedWarningLogLib.h>
 
 #pragma pack(1)
 
diff --git a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Platform/MemDefaults.h b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Platform/MemDefaults.h
index 68c2f447c9..97f1f45290 100644
--- a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Platform/MemDefaults.h
+++ b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Platform/MemDefaults.h
@@ -17,6 +17,13 @@
 #define SMB_CLK_700K       2
 #define SMB_CLK_1M         3
 
+//
+// Volatile Memory Mode
+//
+#define VOL_MEM_MODE_1LM            0
+#define VOL_MEM_MODE_2LM            1
+#define VOL_MEM_MODE_MIX_1LM2LM     2
+
 #define MAX_PARTIAL_MIRROR      4  //Maximum number of partial mirror regions that can be created
 
 //
diff --git a/Silicon/Intel/WhitleySiliconPkg/Pch/SouthClusterLbg/Include/PchInfoHob.h b/Silicon/Intel/WhitleySiliconPkg/Pch/SouthClusterLbg/Include/PchInfoHob.h
new file mode 100644
index 0000000000..0972181531
--- /dev/null
+++ b/Silicon/Intel/WhitleySiliconPkg/Pch/SouthClusterLbg/Include/PchInfoHob.h
@@ -0,0 +1,50 @@
+/** @file
+  This file contains definitions of PCH Info HOB.
+
+@copyright
+  Copyright 2018 Intel Corporation.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_INFO_HOB_H_
+#define _PCH_INFO_HOB_H_
+
+#include <Library/PchPcieRpLib.h>
+
+extern EFI_GUID gPchInfoHobGuid;
+
+#define PCH_INFO_HOB_REVISION  2
+
+#pragma pack (push,1)
+/**
+  This structure is used to provide the information of PCH controller.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add CridSupport, CridOrgRid, and CridNewRid.
+**/
+typedef struct {
+  /**
+    This member specifies the revision of the PCH Info HOB. This field is used
+    to indicate backwards compatible changes to the protocol. Platform code that
+    consumes this protocol must read the correct revision value to correctly interpret
+    the content of the protocol fields.
+  **/
+  UINT8        Revision;
+
+  /**
+    Publish Hpet BDF and IoApic BDF information for VTD.
+  **/
+  UINT32       HpetBusNum    :  8;
+  UINT32       HpetDevNum    :  5;
+  UINT32       HpetFuncNum   :  3;
+  UINT32       IoApicBusNum  :  8;
+  UINT32       IoApicDevNum  :  5;
+  UINT32       IoApicFuncNum :  3;
+} PCH_INFO_HOB;
+
+#pragma pack (pop)
+
+#endif // _PCH_INFO_HOB_H_
diff --git a/Silicon/Intel/WhitleySiliconPkg/WhitleySiliconPkg.dec b/Silicon/Intel/WhitleySiliconPkg/WhitleySiliconPkg.dec
index ae951e0b14..d50b1d8da3 100644
--- a/Silicon/Intel/WhitleySiliconPkg/WhitleySiliconPkg.dec
+++ b/Silicon/Intel/WhitleySiliconPkg/WhitleySiliconPkg.dec
@@ -37,6 +37,7 @@ PACKAGE_GUID = 6f1ec317-5d04-456a-8908-6290453d57ac
 
 [Protocols]
   gDynamicSiLibraryProtocolGuid                 = { 0xb235fbed, 0x3b25, 0x4cb3, { 0x98, 0x9c, 0x8c, 0xe7, 0xec, 0x49, 0x8b, 0x7e }}
+  gDynamicSiLibraryProtocol2Guid                = { 0x98bdd399, 0x9349, 0x4131, { 0x87, 0x60, 0x90, 0xaf, 0x68, 0x01, 0x21, 0xee }}
   gDynamicSiLibrarySmmProtocolGuid              = { 0x82faf3a3, 0x6226, 0x48be, {0xb0, 0x4e, 0xc2, 0xfb, 0x0f, 0x72, 0xcf, 0x2f }}
 
 [PcdsDynamicEx]
-- 
2.27.0.windows.1


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

* [edk2-devel][edk2-platforms][PATCH V1 3/9] WhitleyOpenBoardPkg/BaseCrcLib: Add library for CRC16
  2022-03-10 22:41 [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Oram, Isaac W
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 1/9] WhitleyOpenBoardPkg: Add definitions needed for " Oram, Isaac W
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 2/9] WhitleySiliconPkg: Add definitions used in ACPI subsystem Oram, Isaac W
@ 2022-03-10 22:41 ` Oram, Isaac W
  2022-03-10 23:18   ` Pedro Falcato
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 4/9] WhitleyOpenBoardPkg: Add UbaPlatLib Library Oram, Isaac W
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Oram, Isaac W @ 2022-03-10 22:41 UTC (permalink / raw)
  To: devel; +Cc: Nate DeSimone, Chasel Chiu

Core only supports CRC32, this library adds CRC16 support.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>
---
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h          | 42 ++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c   | 71 ++++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf | 23 +++++++
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc                   |  1 +
 4 files changed, 137 insertions(+)

diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h
new file mode 100644
index 0000000000..7ca3b7cabb
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h
@@ -0,0 +1,42 @@
+/** @file
+  Interface header file for the CRC library class.
+
+  @copyright
+  Copyright 2016 - 2018 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CRC_LIB_H_
+#define _CRC_LIB_H_
+
+#include <Uefi.h>
+
+/**
+  Calculate a 16-bit CRC.
+
+  The algorithm used is MSB-first form of the ITU-T Recommendation V.41, which
+  uses an initial value of 0x0000 and a polynomial of 0x1021. It is the same
+  algorithm used by XMODEM.
+
+  The output CRC location is not updated until the calculation is finished, so
+  it is possible to pass a structure as the data, and the CRC field of the same
+  structure as the output location for the calculated CRC. The CRC field should
+  be set to zero before calling this function. Once the CRC field is updated by
+  this function, running it again over the structure produces a CRC of zero.
+
+  @param[in]  Data              A pointer to the target data.
+  @param[in]  DataSize          The target data size.
+  @param[out] CrcOut            A pointer to the return location of the CRC.
+
+  @retval EFI_SUCCESS           The CRC was calculated successfully.
+  @retval EFI_INVALID_PARAMETER A null pointer was provided.
+**/
+EFI_STATUS
+CalculateCrc16 (
+  IN  VOID    *Data,
+  IN  UINTN   DataSize,
+  OUT UINT16  *CrcOut
+  );
+
+#endif  // _CRC_LIB_H_
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c
new file mode 100644
index 0000000000..3e8fa402ad
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c
@@ -0,0 +1,71 @@
+/** @file
+  Base implementation of the CRC library class.
+
+  @copyright
+  Copyright 2016 - 2018 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/CrcLib.h>
+
+/**
+  Calculate a 16-bit CRC.
+
+  The algorithm used is MSB-first form of the ITU-T Recommendation V.41, which
+  uses an initial value of 0x0000 and a polynomial of 0x1021. It is the same
+  algorithm used by XMODEM.
+
+  The output CRC location is not updated until the calculation is finished, so
+  it is possible to pass a structure as the data, and the CRC field of the same
+  structure as the output location for the calculated CRC. The CRC field should
+  be set to zero before calling this function. Once the CRC field is updated by
+  this function, running it again over the structure produces a CRC of zero.
+
+  @param[in]  Data              A pointer to the target data.
+  @param[in]  DataSize          The target data size.
+  @param[out] CrcOut            A pointer to the return location of the CRC.
+
+  @retval EFI_SUCCESS           The CRC was calculated successfully.
+  @retval EFI_INVALID_PARAMETER A null pointer was provided.
+**/
+EFI_STATUS
+CalculateCrc16 (
+  IN  VOID    *Data,
+  IN  UINTN   DataSize,
+  OUT UINT16  *CrcOut
+  )
+{
+  UINT32  Crc;
+  UINTN   Index;
+  UINT8   *Byte;
+
+  if (Data == NULL || CrcOut == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Crc = 0x0000;
+  for (Byte = (UINT8 *) Data; Byte < (UINT8 *) Data + DataSize; Byte++) {
+    //
+    // XOR the next data byte into the CRC.
+    //
+    Crc ^= (UINT16) *Byte << 8;
+    //
+    // Shift out eight bits, feeding back based on the polynomial whenever a
+    // 1 is shifted out of bit 15.
+    //
+    for (Index = 0; Index < 8; Index++) {
+      Crc <<= 1;
+      if (Crc & BIT16) {
+        Crc ^= 0x1021;
+      }
+    }
+  }
+
+  //
+  // Mask and return the 16-bit CRC.
+  //
+  *CrcOut = (UINT16) (Crc & 0xFFFF);
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
new file mode 100644
index 0000000000..6b404e1259
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
@@ -0,0 +1,23 @@
+## @file
+# Base implementation of the CRC library class.
+#
+# @copyright
+# Copyright 2016 Intel Corporation. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                   = 0x00010019
+  BASE_NAME                     = BaseCrcLib
+  FILE_GUID                     = F3BE9A28-78A2-4B02-AB26-D27EE85D9256
+  MODULE_TYPE                   = BASE
+  VERSION_STRING                = 1.0
+  LIBRARY_CLASS                 = CrcLib
+
+[Sources]
+  BaseCrcLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
index e78a104004..9cdb5bc2f6 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
+++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
@@ -618,6 +618,7 @@
   PciSegmentInfoLib|$(PLATFORM_PKG)/Pci/Library/PciSegmentInfoLibSimple/PciSegmentInfoLibSimple.inf
   PlatformOpromPolicyLib|$(RP_PKG)/Library/PlatformOpromPolicyLibNull/PlatformOpromPolicyLibNull.inf
   VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
+  CrcLib|WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
 
 [LibraryClasses.Common.SEC, LibraryClasses.Common.PEI_CORE, LibraryClasses.Common.PEIM]
   FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
-- 
2.27.0.windows.1


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

* [edk2-devel][edk2-platforms][PATCH V1 4/9] WhitleyOpenBoardPkg: Add UbaPlatLib Library
  2022-03-10 22:41 [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Oram, Isaac W
                   ` (2 preceding siblings ...)
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 3/9] WhitleyOpenBoardPkg/BaseCrcLib: Add library for CRC16 Oram, Isaac W
@ 2022-03-10 22:41 ` Oram, Isaac W
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 5/9] WhitleyOpenBoardPkg/PlatformSpecificAcpiTableLib: Add library Oram, Isaac W
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Oram, Isaac W @ 2022-03-10 22:41 UTC (permalink / raw)
  To: devel; +Cc: Nate DeSimone, Chasel Chiu

UbaPlatLib is required by AcpiTablesLib used by AcpiPlatform driver.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>
---
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaGpioPlatformConfigLib.c | 388 ++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemBoardInfoLib.c    |  62 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemConfigUpdateLib.c |  60 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaUsbOcUpdateLib.c        |  61 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaAcpiUpdateLib.c            |  59 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaFpkConfigLib.c             |  57 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaIioConfigLib.c             | 132 ++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaOpromUpdateLib.c           | 221 +++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaPlatLib.inf                |  62 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSlotUpdateLib.c            | 114 ++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSmbiosUpdateLib.c          | 663 ++++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaCommon.dsc                                |   3 +
 12 files changed, 1882 insertions(+)

diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaGpioPlatformConfigLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaGpioPlatformConfigLib.c
new file mode 100644
index 0000000000..d03f0f9957
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaGpioPlatformConfigLib.c
@@ -0,0 +1,388 @@
+/** @file
+
+  @copyright
+  Copyright 2012 - 2017 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/UbaCfgDb.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Protocol/SmmBase2.h>
+#include <Protocol/DynamicSiLibraryProtocol.h>
+
+//
+// UBA and GPIO headers
+//
+
+#include <Library/UbaGpioPlatformConfig.h>
+#include <Library/GpioLib.h>
+
+STATIC PLATFORM_GPIO_CONFIG_TABLE             mGpioParams;
+DYNAMIC_SI_LIBARY_PROTOCOL                    *mDynamicSiLibraryProtocol = NULL;
+
+/**
+  The library constructor call. Gets required protocols and stores for later usage
+  This also applies for SMM mode usage
+
+  @param[in]  None
+
+  @retval EFI_SUCCESS             The function completed successfully
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeDxeUbaPlatLib (
+  IN  EFI_HANDLE        ImageHandle,
+  IN  EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS                            Status;
+  UBA_CONFIG_DATABASE_PROTOCOL          *UbaConfigProtocol = NULL;
+  UINTN                                 TableSize;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &mDynamicSiLibraryProtocol);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return EFI_NOT_FOUND;
+  }
+
+    Status = gBS->LocateProtocol (
+                    &gUbaConfigDatabaseProtocolGuid,
+                    NULL,
+                    &UbaConfigProtocol
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+  TableSize = sizeof (PLATFORM_GPIO_CONFIG_TABLE);
+  Status = UbaConfigProtocol->GetData (
+                                UbaConfigProtocol,
+                                &gPlatformGpioPlatformConfigDataGuid,
+                                &mGpioParams,
+                                &TableSize
+                                );
+
+  return Status;
+
+}
+
+/**
+  Reads GPIO pin to get DFX jumper status
+
+  @param[out] DfxJumper - The pointer to the DFX jumper input
+
+  @retval Status - Success if GPIO's are read properly
+
+**/
+EFI_STATUS
+GpioGetDfxPadVal (
+  OUT UINT32 *DfxJumper
+  )
+{
+  EFI_STATUS           Status;
+
+  if (mGpioParams.ReservedM == UNUSED_GPIO) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = mDynamicSiLibraryProtocol->GpioGetInputValue (mGpioParams.ReservedM, DfxJumper);
+  return Status;
+}
+
+/**
+  Reads GPIO pin to get recovery jumper status
+
+  @param[out] RcvJumper - The pointer to the Recovery jumper input
+
+  @retval Status - Success if GPIO's are read properly
+
+**/
+EFI_STATUS
+GpioGetRcvPadVal (
+  OUT UINT32 *RcvJumper
+  )
+{
+  EFI_STATUS           Status;
+
+  if (mGpioParams.RcvJumper == UNUSED_GPIO) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = mDynamicSiLibraryProtocol->GpioGetInputValue (mGpioParams.RcvJumper, RcvJumper);
+  return Status;
+}
+
+/**
+  Reads GPIO pin to get FM ADR trigger pin
+
+  @param[out] FmAdrTrigger - The pointer to the ADR trigger input
+
+  @retval Status - Success if GPIO's are read properly
+
+**/
+EFI_STATUS
+GpioGetFmAdrTriggerPadVal (
+  OUT UINT32 *FmAdrTrigger
+  )
+{
+  EFI_STATUS           Status;
+
+  if (mGpioParams.FmAdrTrigger == UNUSED_GPIO) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = mDynamicSiLibraryProtocol->GpioGetInputValue (mGpioParams.FmAdrTrigger, FmAdrTrigger);
+  return Status;
+}
+
+/**
+  Sets GPIO pin to enable ADR on the board
+
+  @param Set[in] - If TRUE means the pas should go 'high', otherwise 'low'
+
+  @retval Status - Success if GPIO set properly
+
+**/
+EFI_STATUS
+GpioSetAdrEnablePadOutVal (
+  IN BOOLEAN Set
+  )
+{
+  EFI_STATUS           Status;
+
+  if (mGpioParams.AdrEnable == UNUSED_GPIO) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (Set) {
+    Status = mDynamicSiLibraryProtocol->GpioSetOutputValue (mGpioParams.AdrEnable, GpioOutHigh);
+  } else {
+    Status = mDynamicSiLibraryProtocol->GpioSetOutputValue (mGpioParams.AdrEnable, GpioOutLow);
+  }
+  return Status;
+}
+
+/**
+  Reads GPIO pin to Force to S1 config mode pad
+
+  @param[out] ForceS1ConfigPad - Input value of the Force S1 Config pad
+
+  @retval Status - Success if GPIO's are read properly
+
+**/
+EFI_STATUS
+GpioGetForcetoS1ConfigModePadVal (
+  OUT UINT32 *ForceS1ConfigPad
+  )
+{
+  EFI_STATUS           Status;
+
+  if (mGpioParams.ForceTo1SConfigModePad == UNUSED_GPIO) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = mDynamicSiLibraryProtocol->GpioGetInputValue (mGpioParams.ForceTo1SConfigModePad, ForceS1ConfigPad);
+  return Status;
+}
+
+/**
+  Reads GPIO pin related to QAT
+
+  @param[out] QATPad - Input value of the QAT pad
+
+  @retval Status - Success if GPIO's are read properly
+
+**/
+EFI_STATUS
+GpioGetQATPadVal (
+  OUT UINT32 *QATPad
+  )
+{
+  EFI_STATUS           Status;
+
+  if (mGpioParams.QATGpio == UNUSED_GPIO) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = mDynamicSiLibraryProtocol->GpioGetInputValue (mGpioParams.QATGpio, QATPad);
+  return Status;
+}
+
+/**
+  Get GPIO pin for SCI detection for WHEA RAS functionality
+
+  @param[out] WheaSciPad - Input value of the Whea SCI pad
+
+  @retval Status - Success if GPIO's pad read properly
+
+**/
+EFI_STATUS
+GpioGetWheaSciPad (
+  OUT UINT32 *WheaSciPad
+  )
+{
+  if (mGpioParams.WheaSciPad == UNUSED_GPIO) {
+    return EFI_UNSUPPORTED;
+  }
+
+  *WheaSciPad = (UINT32) mGpioParams.WheaSciPad;
+  return EFI_SUCCESS;
+}
+
+/**
+  Get GPIO pin for FPGA error detection RAS functionality
+
+  @param[out] FpgaErrorPad -The input value of the FPGA error 1 pad
+
+  @retval Status - Success if GPIO's pad read properly
+
+**/
+EFI_STATUS
+GpioGetFpgaErrorPad1 (
+  OUT UINT32 *FpgaErrorPad
+  )
+{
+  if (mGpioParams.FpgaErrorSingnalPad1 == UNUSED_GPIO) {
+    return EFI_UNSUPPORTED;
+  }
+
+  *FpgaErrorPad = (UINT32) mGpioParams.FpgaErrorSingnalPad1;
+  return EFI_SUCCESS;
+}
+
+/**
+  Get GPIO pin for FPGA error detection RAS functionality
+
+  @param[out] FpgaErrorPad -The input value of the FPGA error 2 pad
+
+  @retval Status - Success if GPIO's pad read properly
+
+**/
+EFI_STATUS
+GpioGetFpgaErrorPad2 (
+  OUT UINT32 *FpgaErrorPad
+  )
+{
+
+  if (mGpioParams.FpgaErrorSingnalPad2 == UNUSED_GPIO) {
+    return EFI_UNSUPPORTED;
+  }
+
+  *FpgaErrorPad = (UINT32) mGpioParams.FpgaErrorSingnalPad2;
+  return EFI_SUCCESS;
+}
+
+/**
+  Get GPIO pin for CPU HP SMI detection for RAS functionality
+
+  @retval Status - Success if GPIO's pad read properly
+
+**/
+EFI_STATUS
+GpioGetCpuHpSmiPad (
+  OUT UINT32 *CpuHpSmiPad
+  )
+{
+
+  if (mGpioParams.CpuHpSmiPad == UNUSED_GPIO) {
+    return EFI_UNSUPPORTED;
+  }
+
+  *CpuHpSmiPad = (UINT32) mGpioParams.CpuHpSmiPad;
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads GPIO pin that is first bit of the Board ID indication word
+
+  @param[out] BoardID0Gpio - Input value of the first Board ID pad
+
+  @retval Status - Success if GPIO's are read properly
+
+**/
+EFI_STATUS
+GpioGetBoardId0PadVal (
+  OUT UINT32 *BoardID0Gpio
+  )
+{
+  EFI_STATUS           Status;
+
+  if (mGpioParams.BoardID0Gpio == UNUSED_GPIO) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = mDynamicSiLibraryProtocol->GpioGetInputValue (mGpioParams.BoardID0Gpio, BoardID0Gpio);
+  return Status;
+}
+
+/**
+  Sets GPIO's used for Boot Mode
+
+  @param None
+
+  @retval Status - Success if GPIO's are configured
+
+**/
+EFI_STATUS
+GpioConfigForMFGMode (
+  VOID
+  )
+{
+  EFI_STATUS                  Status;
+
+  if (mGpioParams.GpioMfgPad.GpioPad == UNUSED_GPIO) {
+    return EFI_UNSUPPORTED;
+  }
+
+  DEBUG ((DEBUG_INFO, "Start ConfigureGpio() for BootMode Detection.\n"));
+
+  Status = mDynamicSiLibraryProtocol->GpioSetPadConfig (mGpioParams.GpioMfgPad.GpioPad,
+    &mGpioParams.GpioMfgPad.GpioConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "End ConfigureGpio() for BootMode Detection.\n"));
+  return Status;
+}
+
+/**
+  Checks whether the MDF jumper has been set
+
+  @param None
+
+  @retval ManufacturingMode - TRUE when MFG jumper is on, FALSE otherwise
+
+**/
+BOOLEAN
+IsManufacturingMode (
+  VOID
+  )
+{
+  BOOLEAN ManufacturingMode = TRUE;
+
+  EFI_STATUS Status;
+  UINT32 GpiValue;
+
+  if (mGpioParams.GpioMfgPad.GpioPad == UNUSED_GPIO) {
+    return FALSE;
+  }
+
+  Status = GpioConfigForMFGMode ();
+  ASSERT_EFI_ERROR (Status);
+
+  Status = mDynamicSiLibraryProtocol->GpioGetInputValue (mGpioParams.GpioMfgPad.GpioPad, &GpiValue);
+  ASSERT_EFI_ERROR (Status);
+
+  if (!GpiValue) {
+    ManufacturingMode = FALSE;
+  }
+  return ManufacturingMode;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemBoardInfoLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemBoardInfoLib.c
new file mode 100644
index 0000000000..f585b1ac9e
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemBoardInfoLib.c
@@ -0,0 +1,62 @@
+/** @file
+
+  @copyright
+  Copyright 2017 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+#include <Library/UbaSystemBoardInfoLib.h>
+#include <Protocol/UbaCfgDb.h>
+
+
+EFI_STATUS
+GetSystemBoardInfo (
+  IN OUT   DXE_SYSTEM_BOARD_INFO       **SystemboardInfoTableBuffer
+  )
+{
+  EFI_STATUS                        Status;
+  UBA_CONFIG_DATABASE_PROTOCOL      *UbaConfigProtocol = NULL;
+  UINTN                             DataLength = 0;
+  SYSTEM_BOARD_INFO_DATA            SystemBoardInfoData;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR," [GetSystemBoardInfo] Locate UbaConfigProtocol fail!\n"));
+    return Status;
+  }
+
+  DataLength = sizeof(SystemBoardInfoData);
+  Status = UbaConfigProtocol->GetData (
+                                   UbaConfigProtocol,
+                                   &gSystemBoardInfoConfigDataGuid,
+                                   &SystemBoardInfoData,
+                                   &DataLength
+                                   );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR," [GetSystemBoardInfo] Get Data fail!\n"));
+    return Status;
+  }
+
+  ASSERT (SystemBoardInfoData.Signature == SYSTEM_SYSTEM_BOARD_INFO_SIGNATURE);
+  ASSERT (SystemBoardInfoData.Version   == SYSTEM_SYSTEM_BOARD_INFO_VERSION);
+
+  *SystemboardInfoTableBuffer = SystemBoardInfoData.CallUpdate ();
+
+  return Status;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemConfigUpdateLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemConfigUpdateLib.c
new file mode 100644
index 0000000000..525e44358f
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemConfigUpdateLib.c
@@ -0,0 +1,60 @@
+/** @file
+
+  @copyright
+  Copyright 2017 - 2018 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+#include <Library/UbaSystemConfigUpdateLib.h>
+#include <Protocol/UbaCfgDb.h>
+
+EFI_STATUS
+UpdateIioDefaultConfig (
+  IN  SYSTEM_CONFIGURATION       *Default
+  )
+{
+  EFI_STATUS                        Status;
+  UBA_CONFIG_DATABASE_PROTOCOL      *UbaConfigProtocol = NULL;
+  UINTN                             DataLength = 0;
+  SYSTEM_CONFIG_UPDATE_DATA         SystemConfigUpdateTable;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR," [UpdateIioDefaultConfig] Locate UbaConfigProtocol fail!\n"));
+    return Status;
+  }
+
+  DataLength = sizeof(SystemConfigUpdateTable);
+  Status = UbaConfigProtocol->GetData (
+                                   UbaConfigProtocol,
+                                   &gSystemConfigUpdateDataGuid,
+                                   &SystemConfigUpdateTable,
+                                   &DataLength
+                                   );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR," [UpdateIioDefaultConfig] Get Data fail!\n"));
+    return Status;
+  }
+
+  ASSERT (SystemConfigUpdateTable.Signature == SYSTEM_CONFIG_UPDATE_SIGNATURE);
+  ASSERT (SystemConfigUpdateTable.Version   == SYSTEM_CONFIG_UPDATE_VERSION);
+
+  SystemConfigUpdateTable.CallUpdateIioConfig (Default);
+
+  return Status;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaUsbOcUpdateLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaUsbOcUpdateLib.c
new file mode 100644
index 0000000000..bdbd012913
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaUsbOcUpdateLib.c
@@ -0,0 +1,61 @@
+/** @file
+
+  @copyright
+  Copyright 2012 - 2019 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/UbaCfgDb.h>
+#include <Library/UbaUsbOcUpdateLib.h>
+
+EFI_STATUS
+PlatformGetUsbOcMappings (
+  IN OUT   USB_OVERCURRENT_PIN   **Usb20OverCurrentMappings,
+  IN OUT   USB_OVERCURRENT_PIN   **Usb30OverCurrentMappings,
+  IN OUT   USB2_PHY_PARAMETERS   **Usb20AfeParams
+  )
+{
+  EFI_STATUS                            Status;
+  UBA_CONFIG_DATABASE_PROTOCOL          *UbaConfigProtocol = NULL;
+  PLATFORM_USBOC_UPDATE_TABLE           UsbOcUpdateTable;
+  UINTN                                 TableSize;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  TableSize = sizeof(UsbOcUpdateTable);
+  Status = UbaConfigProtocol->GetData (
+                                UbaConfigProtocol,
+                                &gDxePlatformUbaOcConfigDataGuid,
+                                &UsbOcUpdateTable,
+                                &TableSize
+                                );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (UsbOcUpdateTable.Signature == PLATFORM_USBOC_UPDATE_SIGNATURE);
+  ASSERT (UsbOcUpdateTable.Version == PLATFORM_USBOC_UPDATE_VERSION);
+
+  UsbOcUpdateTable.CallUsbOcUpdate ( Usb20OverCurrentMappings,
+                                     Usb30OverCurrentMappings,
+                                     Usb20AfeParams
+                                   );
+
+  return Status;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaAcpiUpdateLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaAcpiUpdateLib.c
new file mode 100644
index 0000000000..595d1a62fd
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaAcpiUpdateLib.c
@@ -0,0 +1,59 @@
+/** @file
+
+  @copyright
+  Copyright 2013 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+#include <Library/UbaAcpiUpdateLib.h>
+
+#include <Protocol/UbaCfgDb.h>
+
+EFI_STATUS
+PlatformGetAcpiFixTableDataPointer (
+  IN  VOID                               **TablePtr
+  )
+{
+  EFI_STATUS                              Status;
+
+  UBA_CONFIG_DATABASE_PROTOCOL            *UbaConfigProtocol = NULL;
+  UINTN                                   DataLength = 0;
+  ACPI_FIX_UPDATE_TABLE                   AcpiFixUpdateTable;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DataLength  = sizeof (AcpiFixUpdateTable);
+  Status = UbaConfigProtocol->GetData (
+                                    UbaConfigProtocol,
+                                    &gPlatformAcpiFixTableGuid,
+                                    &AcpiFixUpdateTable,
+                                    &DataLength
+                                    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (AcpiFixUpdateTable.Signature == PLATFORM_ACPI_FIX_UPDATE_SIGNATURE);
+  ASSERT (AcpiFixUpdateTable.Version == PLATFORM_ACPI_FIX_UPDATE_VERSION);
+
+  *TablePtr = AcpiFixUpdateTable.TablePtr;
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaFpkConfigLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaFpkConfigLib.c
new file mode 100644
index 0000000000..9d1c867cab
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaFpkConfigLib.c
@@ -0,0 +1,57 @@
+/** @file
+  UBA FPK configuration library
+
+  @copyright
+  Copyright 2016 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/UbaCfgDb.h>
+#include <Library/UbaFpkConfigLib.h>
+
+/**
+  Retrieves FPK config struct from UBA database
+
+  @retval EFI_SUCCESS           Config struct is retrieved.
+  @retval EFI_NOT_FOUND         UBA protocol, platform or data not found.
+  @retval EFI_INVALID_PARAMETER If PlatformFpkConfigStruct is NULL.
+**/
+EFI_STATUS
+FpkConfigGetConfigStruct (
+  OUT PLATFORM_FPK_CONFIG_STRUCT *PlatformFpkConfigStruct
+  )
+{
+  EFI_STATUS                        Status;
+  UBA_CONFIG_DATABASE_PROTOCOL      *UbaConfigProtocol = NULL;
+  UINTN                             DataLength = 0;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DataLength = sizeof (*PlatformFpkConfigStruct);
+  Status = UbaConfigProtocol->GetData (
+                                    UbaConfigProtocol,
+                                    &gPlatformFpkConfigDataGuid,
+                                    PlatformFpkConfigStruct,
+                                    &DataLength
+                                    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (PlatformFpkConfigStruct->Signature == PLATFORM_FPK_CONFIG_SIGNATURE);
+  ASSERT (PlatformFpkConfigStruct->Version   == PLATFORM_FPK_CONFIG_VERSION);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaIioConfigLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaIioConfigLib.c
new file mode 100644
index 0000000000..0e18b4543b
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaIioConfigLib.c
@@ -0,0 +1,132 @@
+/** @file
+  DxeUbaIioConfigLib implementation.
+
+  @copyright
+  Copyright 2012 - 2018 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/UbaCfgDb.h>
+#include <Library/UbaIioConfigLib.h>
+
+EFI_STATUS
+PlatformIioConfigInit (
+  IN OUT IIO_BIFURCATION_DATA_ENTRY       **BifurcationTable,
+  IN OUT UINT8                            *BifurcationEntries,
+  IN OUT IIO_SLOT_CONFIG_DATA_ENTRY       **SlotTable,
+  IN OUT UINT8                            *SlotEntries
+  )
+{
+  EFI_STATUS                        Status;
+  UBA_CONFIG_DATABASE_PROTOCOL      *UbaConfigProtocol = NULL;
+  UINTN                             DataLength = 0;
+  PLATFORM_IIO_CONFIG_UPDATE_TABLE  IioUpdateTable;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DataLength  = sizeof (IioUpdateTable);
+  Status = UbaConfigProtocol->GetData (
+                                    UbaConfigProtocol,
+                                    &gPlatformIioConfigDataDxeGuid,
+                                    &IioUpdateTable,
+                                    &DataLength
+                                    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (IioUpdateTable.Signature == PLATFORM_IIO_CONFIG_UPDATE_SIGNATURE);
+  ASSERT (IioUpdateTable.Version == PLATFORM_IIO_CONFIG_UPDATE_VERSION);
+
+  *BifurcationTable = IioUpdateTable.IioBifurcationTablePtr;
+  *BifurcationEntries = (UINT8) (IioUpdateTable.IioBifurcationTableSize / sizeof(IIO_BIFURCATION_DATA_ENTRY));
+
+  *SlotTable = IioUpdateTable.IioSlotTablePtr;
+  *SlotEntries = (UINT8)(IioUpdateTable.IioSlotTableSize / sizeof(IIO_SLOT_CONFIG_DATA_ENTRY));
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PlatformIioConfigInit2 (
+  IN     UINT8                            SkuPersonalityType,
+  IN OUT IIO_BIFURCATION_DATA_ENTRY       **BifurcationTable,
+  IN OUT UINT8                            *BifurcationEntries,
+  IN OUT IIO_SLOT_CONFIG_DATA_ENTRY       **SlotTable,
+  IN OUT UINT8                            *SlotEntries
+  )
+{
+  EFI_STATUS                        Status;
+  UBA_CONFIG_DATABASE_PROTOCOL      *UbaConfigProtocol = NULL;
+  UINTN                             DataLength = 0;
+  PLATFORM_IIO_CONFIG_UPDATE_TABLE  IioUpdateTable;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DataLength  = sizeof (IioUpdateTable);
+  if (SkuPersonalityType == 1) {
+    Status = UbaConfigProtocol->GetData (
+                                      UbaConfigProtocol,
+                                      &gPlatformIioConfigDataDxeGuid_1,
+                                      &IioUpdateTable,
+                                      &DataLength
+                                      );
+  } else if (SkuPersonalityType == 2) {
+    Status = UbaConfigProtocol->GetData (
+                                      UbaConfigProtocol,
+                                      &gPlatformIioConfigDataDxeGuid_2,
+                                      &IioUpdateTable,
+                                      &DataLength
+                                      );
+  } else if (SkuPersonalityType == 3) {
+    Status = UbaConfigProtocol->GetData (
+                                      UbaConfigProtocol,
+                                      &gPlatformIioConfigDataDxeGuid_3,
+                                      &IioUpdateTable,
+                                      &DataLength
+                                      );
+  } else {
+    Status = UbaConfigProtocol->GetData (
+                                      UbaConfigProtocol,
+                                      &gPlatformIioConfigDataDxeGuid,
+                                      &IioUpdateTable,
+                                      &DataLength
+                                      );
+  }
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (IioUpdateTable.Signature == PLATFORM_IIO_CONFIG_UPDATE_SIGNATURE);
+  ASSERT (IioUpdateTable.Version == PLATFORM_IIO_CONFIG_UPDATE_VERSION);
+
+  *BifurcationTable = IioUpdateTable.IioBifurcationTablePtr;
+  *BifurcationEntries = (UINT8) (IioUpdateTable.IioBifurcationTableSize / sizeof(IIO_BIFURCATION_DATA_ENTRY));
+
+  *SlotTable = IioUpdateTable.IioSlotTablePtr;
+  *SlotEntries = (UINT8)(IioUpdateTable.IioSlotTableSize / sizeof(IIO_SLOT_CONFIG_DATA_ENTRY));
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaOpromUpdateLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaOpromUpdateLib.c
new file mode 100644
index 0000000000..922b7daaca
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaOpromUpdateLib.c
@@ -0,0 +1,221 @@
+/** @file
+
+  @copyright
+  Copyright 2013 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+#include <Library/UbaOpromUpdateLib.h>
+
+#include <Protocol/UbaCfgDb.h>
+
+
+BOOLEAN
+PlatformCheckPcieRootPort (
+  IN  UINTN                 Bus,
+  IN  UINT32                PcieSlotOpromBitMap
+  )
+{
+  EFI_STATUS                              Status;
+
+  UBA_CONFIG_DATABASE_PROTOCOL            *UbaConfigProtocol = NULL;
+  UINTN                                   DataLength = 0;
+  PLATFORM_OPTION_ROM_UPDATE_DATA         OptionRomUpdateTable;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return TRUE;
+  }
+
+  DataLength  = sizeof (OptionRomUpdateTable);
+  Status = UbaConfigProtocol->GetData (
+                                    UbaConfigProtocol,
+                                    &gPlatformOptionRomUpdateConfigDataGuid,
+                                    &OptionRomUpdateTable,
+                                    &DataLength
+                                    );
+  if (EFI_ERROR (Status)) {
+    return TRUE;
+  }
+
+  ASSERT (OptionRomUpdateTable.Signature == PLATFORM_OPTION_ROM_UPDATE_SIGNATURE);
+  ASSERT (OptionRomUpdateTable.Version == PLATFORM_OPTION_ROM_UPDATE_VERSION);
+
+  return OptionRomUpdateTable.CallCheckRootPort (Bus, PcieSlotOpromBitMap);
+}
+
+EFI_STATUS
+PlatformGetOptionRomTable (
+  IN  PC_PCI_OPTION_ROM_TABLE         **OptionRomTable
+  )
+{
+  EFI_STATUS                              Status;
+
+  UBA_CONFIG_DATABASE_PROTOCOL            *UbaConfigProtocol = NULL;
+  UINTN                                   DataLength = 0;
+  PLATFORM_OPTION_ROM_UPDATE_DATA         OptionRomUpdateTable;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DataLength  = sizeof (OptionRomUpdateTable);
+  Status = UbaConfigProtocol->GetData (
+                                    UbaConfigProtocol,
+                                    &gPlatformOptionRomUpdateConfigDataGuid,
+                                    &OptionRomUpdateTable,
+                                    &DataLength
+                                    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (OptionRomUpdateTable.Signature == PLATFORM_OPTION_ROM_UPDATE_SIGNATURE);
+  ASSERT (OptionRomUpdateTable.Version == PLATFORM_OPTION_ROM_UPDATE_VERSION);
+
+  if (OptionRomUpdateTable.GetOptionRomTable == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  return OptionRomUpdateTable.GetOptionRomTable (OptionRomTable);
+}
+
+EFI_STATUS
+PlatformGetNicSetupConfigTable (
+  IN  NIC_SETUP_CONFIGURATION_STUCT     **NicSetupConfigTable,
+  IN  UINTN                             *NumOfConfig
+  )
+{
+  EFI_STATUS                              Status;
+
+  UBA_CONFIG_DATABASE_PROTOCOL            *UbaConfigProtocol = NULL;
+  UINTN                                   DataLength = 0;
+  PLATFORM_OPTION_ROM_UPDATE_DATA         OptionRomUpdateTable;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DataLength  = sizeof (OptionRomUpdateTable);
+  Status = UbaConfigProtocol->GetData (
+                                    UbaConfigProtocol,
+                                    &gPlatformOptionRomUpdateConfigDataGuid,
+                                    &OptionRomUpdateTable,
+                                    &DataLength
+                                    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (OptionRomUpdateTable.Signature == PLATFORM_OPTION_ROM_UPDATE_SIGNATURE);
+  ASSERT (OptionRomUpdateTable.Version == PLATFORM_OPTION_ROM_UPDATE_VERSION);
+
+  if (OptionRomUpdateTable.GetNicSetupConfigTable == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  return OptionRomUpdateTable.GetNicSetupConfigTable (NicSetupConfigTable, NumOfConfig);
+}
+
+EFI_STATUS
+PlatformGetNicCapabilityTable (
+  IN  NIC_OPTIONROM_CAPBILITY_STRUCT    **NicCapabilityTable,
+  IN  UINTN                             *NumOfNicCapTable
+  )
+{
+  EFI_STATUS                              Status;
+
+  UBA_CONFIG_DATABASE_PROTOCOL            *UbaConfigProtocol = NULL;
+  UINTN                                   DataLength = 0;
+  PLATFORM_OPTION_ROM_UPDATE_DATA         OptionRomUpdateTable;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DataLength  = sizeof (OptionRomUpdateTable);
+  Status = UbaConfigProtocol->GetData (
+                                    UbaConfigProtocol,
+                                    &gPlatformOptionRomUpdateConfigDataGuid,
+                                    &OptionRomUpdateTable,
+                                    &DataLength
+                                    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (OptionRomUpdateTable.Signature == PLATFORM_OPTION_ROM_UPDATE_SIGNATURE);
+  ASSERT (OptionRomUpdateTable.Version == PLATFORM_OPTION_ROM_UPDATE_VERSION);
+
+  if (OptionRomUpdateTable.GetNicCapabilityTable == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  return OptionRomUpdateTable.GetNicCapabilityTable (NicCapabilityTable, NumOfNicCapTable);
+}
+
+EFI_STATUS
+PlatformSetupPcieSlotNumber (
+  OUT  UINT8                   *PcieSlotItemCtrl
+  )
+{
+  EFI_STATUS                              Status;
+
+  UBA_CONFIG_DATABASE_PROTOCOL            *UbaConfigProtocol = NULL;
+  UINTN                                   DataLength = 0;
+  PLATFORM_OPTION_ROM_UPDATE_DATA         OptionRomUpdateTable;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DataLength  = sizeof (OptionRomUpdateTable);
+  Status = UbaConfigProtocol->GetData (
+                                    UbaConfigProtocol,
+                                    &gPlatformOptionRomUpdateConfigDataGuid,
+                                    &OptionRomUpdateTable,
+                                    &DataLength
+                                    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (OptionRomUpdateTable.Signature == PLATFORM_OPTION_ROM_UPDATE_SIGNATURE);
+  ASSERT (OptionRomUpdateTable.Version == PLATFORM_OPTION_ROM_UPDATE_VERSION);
+
+  return OptionRomUpdateTable.SetupSlotNumber (PcieSlotItemCtrl);
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaPlatLib.inf b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaPlatLib.inf
new file mode 100644
index 0000000000..aa5f43a8b5
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaPlatLib.inf
@@ -0,0 +1,62 @@
+## @file
+#
+# @copyright
+# Copyright 2014 - 2017 Intel Corporation. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = UbaPlatLib
+  FILE_GUID                      = 771FA963-A317-47aa-9D0B-186917B7D829
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = UbaPlatLib | DXE_DRIVER DXE_SMM_DRIVER DXE_RUNTIME_DRIVER
+  CONSTRUCTOR                    = InitializeDxeUbaPlatLib
+
+[sources]
+  UbaAcpiUpdateLib.c
+  UbaOpromUpdateLib.c
+  UbaSmbiosUpdateLib.c
+  UbaIioConfigLib.c
+  UbaSlotUpdateLib.c
+  DxeUbaUsbOcUpdateLib.c
+  DxeUbaGpioPlatformConfigLib.c
+  DxeUbaSystemBoardInfoLib.c
+  DxeUbaSystemConfigUpdateLib.c
+  UbaFpkConfigLib.c
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  UefiLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  WhitleySiliconPkg/CpRcPkg.dec
+  WhitleySiliconPkg/SiliconPkg.dec
+  WhitleySiliconPkg/WhitleySiliconPkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[Protocols]
+  gUbaConfigDatabaseProtocolGuid
+  gEfiSmbiosProtocolGuid
+  gEfiPciIoProtocolGuid
+  gDynamicSiLibraryProtocolGuid                  ## CONSUMES
+
+[Guids]
+  gEfiEndOfDxeEventGroupGuid
+  gSystemBoardInfoConfigDataGuid
+
+[FixedPcd]
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuCoreCount
+
+[Depex]
+  gDynamicSiLibraryProtocolGuid
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSlotUpdateLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSlotUpdateLib.c
new file mode 100644
index 0000000000..1d39cb7d6f
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSlotUpdateLib.c
@@ -0,0 +1,114 @@
+/** @file
+  UbaSlotUpdateLib implementation.
+
+  @copyright
+  Copyright 2012 - 2016 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UbaSlotUpdateLib.h>
+#include <Protocol/UbaCfgDb.h>
+
+EFI_STATUS
+PlatformGetSlotTableData (
+  IN OUT IIO_BROADWAY_ADDRESS_DATA_ENTRY  **BroadwayTable,
+  IN OUT UINT8                            *IOU2Setting,
+  IN OUT UINT8                            *FlagValue
+  )
+{
+  EFI_STATUS                        Status;
+  UBA_CONFIG_DATABASE_PROTOCOL      *UbaConfigProtocol = NULL;
+  UINTN                             DataLength = 0;
+  PLATFORM_SLOT_UPDATE_TABLE        IioSlotUpdateTable;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DataLength = sizeof(IioSlotUpdateTable);
+  Status = UbaConfigProtocol->GetData (
+                                   UbaConfigProtocol,
+                                   &gPlatformSlotDataDxeGuid,
+                                   &IioSlotUpdateTable,
+                                   &DataLength
+                                   );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (IioSlotUpdateTable.Signature == PLATFORM_SLOT_UPDATE_SIGNATURE);
+  ASSERT (IioSlotUpdateTable.Version   == PLATFORM_SLOT_UPDATE_VERSION);
+
+  *BroadwayTable  = IioSlotUpdateTable.BroadwayTablePtr;
+  *IOU2Setting    = IioSlotUpdateTable.GetIOU2Setting (*IOU2Setting);
+  *FlagValue      = IioSlotUpdateTable.FlagValue;
+  return Status;
+}
+
+EFI_STATUS
+PlatformGetSlotTableData2 (
+  IN OUT IIO_BROADWAY_ADDRESS_DATA_ENTRY  **BroadwayTable,
+  IN OUT UINT8                            *IOU0Setting,
+  IN OUT UINT8                            *FlagValue,
+  IN OUT UINT8                            *IOU2Setting,
+  IN     UINT8                            SkuPersonalityType
+  )
+{
+  EFI_STATUS                        Status;
+  UBA_CONFIG_DATABASE_PROTOCOL      *UbaConfigProtocol = NULL;
+  UINTN                             DataLength = 0;
+  PLATFORM_SLOT_UPDATE_TABLE2       IioSlotUpdateTable;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DataLength = sizeof(IioSlotUpdateTable);
+  if ((SkuPersonalityType == 1) || (SkuPersonalityType == 3)) {
+    Status = UbaConfigProtocol->GetData (
+                                     UbaConfigProtocol,
+                                     &gPlatformSlotDataDxeGuid2_1,
+                                     &IioSlotUpdateTable,
+                                     &DataLength
+                                     );
+  } else {
+    Status = UbaConfigProtocol->GetData (
+                                     UbaConfigProtocol,
+                                     &gPlatformSlotDataDxeGuid2,
+                                     &IioSlotUpdateTable,
+                                     &DataLength
+                                     );
+  }
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (IioSlotUpdateTable.Signature == PLATFORM_SLOT_UPDATE_SIGNATURE);
+  ASSERT (IioSlotUpdateTable.Version   == PLATFORM_SLOT_UPDATE_VERSION);
+
+  *BroadwayTable = IioSlotUpdateTable.BroadwayTablePtr;
+  *IOU0Setting   = IioSlotUpdateTable.GetIOU0Setting (*IOU0Setting);
+  *FlagValue     = IioSlotUpdateTable.FlagValue;
+  *IOU2Setting   = IioSlotUpdateTable.GetIOU2Setting (SkuPersonalityType, *IOU2Setting);
+
+  return Status;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSmbiosUpdateLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSmbiosUpdateLib.c
new file mode 100644
index 0000000000..5d4ed55969
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSmbiosUpdateLib.c
@@ -0,0 +1,663 @@
+/** @file
+  UbaSmbiosUpdateLib implementation.
+
+  @copyright
+  Copyright 2012 - 2017 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <IndustryStandard/SmBios.h>
+
+#include <Protocol/Smbios.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UbaSmbiosUpdateLib.h>
+
+#include <Protocol/UbaCfgDb.h>
+#include <Guid/EventGroup.h>
+
+#define SMBIOS_TYPE_MAX_LENGTH    0x300
+
+/**
+  Provide the RegData and register a callback for dynamic update SMBIOS data.
+
+  @param RegData                  Callback register data.
+
+  @retval EFI_NOT_FOUND           Data log protocol not found.
+  @retval EFI_OUT_OF_RESOURCES    Data was not logged due to lack of system resources.
+  @retval EFI_SUCCESS             Data have been updated successfully.
+
+**/
+EFI_STATUS
+PlatformRegisterSmbiosUpdate (
+  IN  SMBIOS_UPDATE_DATA              *RegData
+  )
+{
+  EFI_STATUS                              Status;
+  STATIC  UBA_CONFIG_DATABASE_PROTOCOL    *UbaConfigProtocol = NULL;
+
+  if (UbaConfigProtocol == NULL) {
+
+    Status = gBS->LocateProtocol (
+                    &gUbaConfigDatabaseProtocolGuid,
+                    NULL,
+                    &UbaConfigProtocol
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  RegData->Signature  = PLATFORM_SMBIOS_UPDATE_SIGNATURE;
+  RegData->Version    = PLATFORM_SMBIOS_UPDATE_VERSION;
+
+  Status = UbaConfigProtocol->AddData (
+                                     UbaConfigProtocol,
+                                     &gPlatformSmbiosConfigDataGuid,
+                                     RegData,
+                                     sizeof(SMBIOS_UPDATE_DATA)
+                                     );
+  return Status;
+}
+
+/**
+  Update a String for a filled SMBIOS data structure, the structure must be filled
+  before update string.
+  This function update a string indicated by StringNumber to the tail of SMBIOS
+  structure.
+
+  @param Smbios                   SMBIOS structure data buffer pointer.
+  @param BufferSize               SMBIOS structure data buffer size.
+  @param StringNumber             The string index number of SMBIOS structure.
+  @param String                   String want to update.
+
+  @retval EFI_OUT_OF_RESOURCES    No enough memory for this action.
+  @retval EFI_SUCCESS             String updated successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosUpdateString (
+  IN  OUT SMBIOS_STRUCTURE_POINTER    Smbios,
+  IN      UINTN                       BufferSize,
+  IN      UINTN                       StringNumber,
+  IN      CHAR16                      *String
+  )
+{
+  EFI_STATUS                          Status;
+  CHAR8                               *AsciiString = NULL;
+
+  UINTN                               InputStrLen;
+  UINTN                               TargetStrLen;
+  UINTN                               StrIndex;
+  UINTN                               TargetStrOffset;
+  CHAR8                               *StrStart;
+
+  SMBIOS_STRUCTURE_POINTER            NewSmbiosPtr;
+
+  UINTN                               OrigSize = 0;
+  UINTN                               NewSize = 0;
+  UINTN                               StringSize = 0;
+
+  StringSize = StrSize (String);
+  AsciiString = AllocateZeroPool (StringSize);
+  ASSERT (AsciiString != NULL);
+  if (AsciiString == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  UnicodeStrToAsciiStrS (String, AsciiString, StringSize);
+  InputStrLen = AsciiStrLen (AsciiString);
+
+  Status = PlatformSmbiosGetTypeLength (Smbios, &OrigSize);
+
+  //
+  // Point to unformed string section
+  //
+  StrStart = (CHAR8 *) Smbios.Hdr + Smbios.Hdr->Length;
+  for (StrIndex = 1, TargetStrOffset = 0; StrIndex < StringNumber; StrStart++, TargetStrOffset++) {
+    //
+    // A string ends in 00h
+    //
+    if (*StrStart == 0) {
+      StrIndex++;
+    }
+  }
+
+  //
+  // Now we get the string target
+  //
+  TargetStrLen = AsciiStrLen(StrStart);
+  if (InputStrLen == TargetStrLen) {
+    Status = AsciiStrCpyS(StrStart, TargetStrLen + 1, AsciiString);
+    ASSERT_EFI_ERROR (Status);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Original string buffer size is not exactly match input string length.
+  // Re-allocate buffer is needed.
+  //
+  NewSmbiosPtr.Hdr = AllocateZeroPool (SMBIOS_TYPE_MAX_LENGTH);
+  if (NewSmbiosPtr.Hdr == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Copy SMBIOS structure and optional strings.
+  //
+  CopyMem (NewSmbiosPtr.Hdr, Smbios.Hdr, Smbios.Hdr->Length + TargetStrOffset);
+  CopyMem ((CHAR8*)NewSmbiosPtr.Hdr + Smbios.Hdr->Length + TargetStrOffset, AsciiString, InputStrLen + 1);
+  CopyMem ((CHAR8*)NewSmbiosPtr.Hdr + Smbios.Hdr->Length + TargetStrOffset + InputStrLen + 1,
+           (CHAR8*)Smbios.Hdr + Smbios.Hdr->Length + TargetStrOffset + TargetStrLen + 1,
+           OrigSize - Smbios.Hdr->Length - TargetStrOffset - TargetStrLen - 1);
+
+  Status = PlatformSmbiosGetTypeLength (NewSmbiosPtr, &NewSize);
+  CopyMem (Smbios.Hdr, NewSmbiosPtr.Hdr, NewSize);
+
+  FreePool (NewSmbiosPtr.Hdr);
+  FreePool (AsciiString);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Get SMBIOS data structure length, include the string in tail.
+
+  @param Smbios                   SMBIOS structure data buffer pointer.
+  @param TypeSize                 SMBIOS structure size.
+
+  @retval EFI_INVALID_PARAMETER   Input paramter invalid.
+  @retval EFI_SUCCESS             Caculate data structure size successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosGetTypeLength (
+  IN  OUT SMBIOS_STRUCTURE_POINTER    Smbios,
+  IN  OUT UINTN                       *TypeSize
+  )
+{
+  UINTN                               FullSize;
+  UINTN                               StrLen;
+  UINTN                               MaxLen;
+  INT8*                               CharInStr;
+
+  if (TypeSize == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  FullSize  = Smbios.Hdr->Length;
+  CharInStr = (INT8*)Smbios.Hdr + Smbios.Hdr->Length;
+  *TypeSize = FullSize;
+  StrLen    = 0;
+
+  //
+  // look for the two consecutive zeros, check the string limit by the way.
+  //
+  while (*CharInStr != 0 || *(CharInStr+1) != 0) {
+    if (*CharInStr == 0) {
+      *TypeSize += 1;
+      CharInStr++;
+    }
+
+    MaxLen = SMBIOS_STRING_MAX_LENGTH;
+    for (StrLen = 0 ; StrLen < MaxLen; StrLen++) {
+      if (*(CharInStr+StrLen) == 0) {
+        break;
+      }
+    }
+
+    if (StrLen == MaxLen) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    //
+    // forward the pointer
+    //
+    CharInStr += StrLen;
+    *TypeSize += StrLen;
+  }
+
+  //
+  // count ending two zeros.
+  //
+  *TypeSize += 2;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Add a new SMBIOS structure into SMBIOS database.
+
+  @param Smbios                   SMBIOS structure data buffer pointer.
+
+  @retval EFI_NOT_FOUND           SMBIOS protocol not installed.
+  @retval EFI_SUCCESS             Add data structure successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosAddNew (
+  IN      SMBIOS_STRUCTURE_POINTER    SmbiosPtr
+  )
+{
+  EFI_STATUS                          Status;
+
+  STATIC  EFI_SMBIOS_PROTOCOL         *Smbios = NULL;
+  EFI_SMBIOS_HANDLE                   SmbiosHandle;
+
+  if (Smbios == NULL) {
+    Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  SmbiosHandle  = SMBIOS_HANDLE_PI_RESERVED;
+  Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*)SmbiosPtr.Hdr);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Get the number of instance of SMBIOS type structure in SMBIOS database.
+  return 0 means no instance for this type now.
+
+  @param Type                     SMBIOS type.
+
+  @retval Count                   Number of instance.
+
+**/
+UINTN
+PlatformSmbiosGetInstanceCount (
+  IN      UINT8                       Type
+  )
+{
+  EFI_STATUS                          Status;
+
+  STATIC  EFI_SMBIOS_PROTOCOL         *Smbios = NULL;
+  EFI_SMBIOS_TABLE_HEADER             *SmbiosRecord;
+  EFI_SMBIOS_HANDLE                   SmbiosHandle;
+  EFI_SMBIOS_TYPE                     SmbiosType;
+
+  UINTN                               Count = 0;
+
+  if (Smbios == NULL) {
+    Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  SmbiosHandle  = SMBIOS_HANDLE_PI_RESERVED;
+  SmbiosType    = Type;
+
+  do {
+    Status = Smbios->GetNext (Smbios, &SmbiosHandle, &SmbiosType, &SmbiosRecord, NULL);
+    if (!EFI_ERROR (Status) && (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED)) {
+      Count ++;
+    }
+  } while (!EFI_ERROR (Status) && (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED));
+
+  return Count;
+}
+
+/**
+  Get SMBIOS type data structure in SMBIOS database.
+
+  This function give you a pointer of SMBIOS structure directly in the database, you can update
+  the value in formated structure area and it's take affect immediately, but never directly or
+  call PlatformSmbiosUpdateString to edit the string in this buffer,
+  use PlatformSmbiosGetEditCopy->PlatformSmbiosUpdateType instead.
+
+  One of the SmbiosPtr or Handle must be valid value.
+
+  @param Type                     SMBIOS type.
+  @param Instance                 The instance of this type.
+  @param SmbiosPtr                Optional parameter, on input, pass a pointer of SMBIOS_STRUCTURE_POINTER
+                                  to this function.
+                                  On output, return the SMBIOS data pointer in SmbiosPtr.
+  @param Handle                   Optional parameter, on input, pass a pointer of Handle.
+                                  On output, return the SMBIOS data handle value
+
+  @retval EFI_INVALID_PARAMETER   Both the SmbiosPtr and Handle is NULL.
+  @retval EFI_NOT_FOUND           SMBIOS protocol not installed.
+  @retval EFI_SUCCESS             Get structure data successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosGetInstance (
+  IN      UINT8                       Type,
+  IN      UINTN                       Instance,
+  IN  OUT SMBIOS_STRUCTURE_POINTER    *SmbiosPtr,
+  IN  OUT UINT16                      *Handle
+  )
+{
+  EFI_STATUS                          Status;
+
+  STATIC  EFI_SMBIOS_PROTOCOL         *Smbios = NULL;
+  EFI_SMBIOS_TABLE_HEADER             *SmbiosRecord;
+  EFI_SMBIOS_HANDLE                   SmbiosHandle;
+  EFI_SMBIOS_TYPE                     SmbiosType;
+
+  UINTN                               Count = 0;
+
+  if ((SmbiosPtr == NULL) && (Handle == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Smbios == NULL) {
+    Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  SmbiosHandle  = SMBIOS_HANDLE_PI_RESERVED;
+  SmbiosType    = Type;
+
+  do {
+    Status = Smbios->GetNext (Smbios, &SmbiosHandle, &SmbiosType, &SmbiosRecord, NULL);
+    if (!EFI_ERROR (Status) && (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED)) {
+
+      if (++Count == Instance) {
+
+        if (SmbiosPtr != NULL) {
+          (*SmbiosPtr).Hdr = (SMBIOS_STRUCTURE*)SmbiosRecord;
+        }
+
+        if (Handle != NULL) {
+          *Handle = SmbiosHandle;
+        }
+
+        return EFI_SUCCESS;
+      }
+    }
+  } while (!EFI_ERROR (Status) && (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED));
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Get a copy of SMBIOS type structure data in SMBIOS database.
+  Must allocate memory large enough first, then call this function to get the copy.
+
+  @param Type                     SMBIOS type.
+  @param Instance                 The instance of this type.
+  @param SmbiosPtr                A valid buffer pointer which SMBIOS data will copy to this buffer.
+
+  @retval EFI_NOT_FOUND           SMBIOS protocol not installed.
+  @retval EFI_SUCCESS             Get structure data successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosGetEditCopy (
+  IN      UINT8                       Type,
+  IN      UINTN                       Instance,
+  IN  OUT SMBIOS_STRUCTURE_POINTER    SmbiosPtr
+  )
+{
+  EFI_STATUS                          Status;
+  SMBIOS_STRUCTURE_POINTER            NewSmbiosPtr;
+  UINTN                               Size;
+
+  Status = PlatformSmbiosGetInstance (Type, Instance, &NewSmbiosPtr, NULL);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = PlatformSmbiosGetTypeLength (NewSmbiosPtr, &Size);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  CopyMem (SmbiosPtr.Hdr, NewSmbiosPtr.Hdr, Size);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Update a string which in SMBIOS database.
+  The data structure which string belong to must installed before.
+
+  @param Type                     SMBIOS type.
+  @param Instance                 The instance of this type.
+  @param StringNumber             The string number.
+  @param String                   The string want to update.
+
+  @retval EFI_NOT_FOUND           SMBIOS protocol not installed.
+  @retval EFI_SUCCESS             Update data successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosUpdateInstalledString (
+  IN      UINT8                       Type,
+  IN      UINTN                       Instance,
+  IN      UINTN                       StringNumber,
+  IN      CHAR16                      *String
+  )
+{
+  EFI_STATUS                          Status;
+  STATIC  EFI_SMBIOS_PROTOCOL         *Smbios = NULL;
+  EFI_SMBIOS_HANDLE                   SmbiosHandle;
+
+  CHAR8                               *AsciiStr = NULL;
+  UINTN                               StringSize = 0;
+
+  if (Smbios == NULL) {
+    Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  StringSize = StrSize (String);
+  AsciiStr = AllocateZeroPool (StringSize);
+  UnicodeStrToAsciiStrS (String, AsciiStr, StringSize);
+
+  Status = PlatformSmbiosGetInstance (Type, Instance, NULL, &SmbiosHandle);
+  if (!EFI_ERROR (Status)) {
+    Status = Smbios->UpdateString (Smbios, &SmbiosHandle, &StringNumber, AsciiStr);
+  }
+
+  FreePool (AsciiStr);
+
+  return Status;
+}
+
+/**
+  Remove a SMBIOS instance in SMBIOS database.
+
+  @param Type                     SMBIOS type.
+  @param Instance                 The instance of this type.
+
+  @retval EFI_NOT_FOUND           SMBIOS protocol not installed.
+  @retval EFI_SUCCESS             Remove data successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosRemoveType (
+  IN      UINT8                       Type,
+  IN      UINTN                       Instance
+  )
+{
+  EFI_STATUS                          Status;
+
+  STATIC  EFI_SMBIOS_PROTOCOL         *Smbios = NULL;
+  EFI_SMBIOS_HANDLE                   SmbiosHandle;
+
+  if (Smbios == NULL) {
+    Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  Status = PlatformSmbiosGetInstance (Type, Instance, NULL, &SmbiosHandle);
+  if (!EFI_ERROR (Status)) {
+    Status = Smbios->Remove (Smbios, SmbiosHandle);
+  }
+
+  return Status;
+}
+
+/**
+  Remove all the instance of specific SMBIOS type in SMBIOS database.
+
+  @param Type                     SMBIOS type.
+
+  @retval EFI_NOT_FOUND           SMBIOS protocol not installed.
+  @retval EFI_SUCCESS             Remove data successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosRemoveAll (
+  IN      UINT8                       Type
+  )
+{
+  EFI_STATUS                          Status;
+  UINTN                               Count;
+  UINTN                               Index;
+
+  Count = PlatformSmbiosGetInstanceCount (Type);
+
+  for (Index = 0; Index < Count; Index++) {
+    Status = PlatformSmbiosRemoveType (Type, 1);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Update SMBIOS data structure in database with new structure data.
+
+  @param Type                     SMBIOS type.
+  @param Instance                 The instance of this type.
+  @param SmbiosPtr                A valid buffer pointer which new SMBIOS data stored.
+
+  @retval EFI_NOT_FOUND           SMBIOS protocol not installed.
+  @retval EFI_SUCCESS             Update data successfully.
+
+**/
+EFI_STATUS
+PlatformSmbiosUpdateType (
+  IN      UINT8                       Type,
+  IN      UINTN                       Instance,
+  IN      SMBIOS_STRUCTURE_POINTER    SmbiosPtr
+  )
+{
+  EFI_STATUS                          Status;
+  STATIC  EFI_SMBIOS_PROTOCOL         *Smbios = NULL;
+  EFI_SMBIOS_HANDLE                   SmbiosHandle;
+
+  if (Smbios == NULL) {
+    Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  Status = PlatformSmbiosGetInstance (Type, Instance, NULL, &SmbiosHandle);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = PlatformSmbiosRemoveType (Type, Instance);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = PlatformSmbiosAddNew (SmbiosPtr);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return Status;
+}
+
+/**
+  Implement the dynamic SMBIOS data update.
+
+  @param UpdateType               Immediately update or delay update at BDS.
+
+  @retval EFI_SUCCESS             Update successfully.
+
+**/
+EFI_STATUS
+DispatchSmbiosDynamicUpdate (
+  IN      SmbiosUpdateType            UpdateType
+  )
+{
+  EFI_STATUS                              Status;
+
+  UBA_CONFIG_DATABASE_PROTOCOL            *UbaConfigProtocol = NULL;
+  UINTN                                   DataLength = 0;
+  SMBIOS_UPDATE_DATA                      RegData;
+
+  Status = gBS->LocateProtocol (
+                  &gUbaConfigDatabaseProtocolGuid,
+                  NULL,
+                  &UbaConfigProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DataLength  = sizeof (SMBIOS_UPDATE_DATA);
+  Status = UbaConfigProtocol->GetData (
+                                    UbaConfigProtocol,
+                                    &gPlatformSmbiosConfigDataGuid,
+                                    &RegData,
+                                    &DataLength
+                                    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (RegData.Signature == PLATFORM_SMBIOS_UPDATE_SIGNATURE);
+  ASSERT (RegData.Version == PLATFORM_SMBIOS_UPDATE_VERSION);
+
+  //
+  // Check for updatetype match.
+  //
+  if ((RegData.UpdateType == UpdateType) && (RegData.CallUpdate != NULL)) {
+    //
+    // Invoke the callback and update every instance of this type
+    //
+    Status = RegData.CallUpdate ();
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Function provide to DXE driver, which initial the dynamic update.
+
+  @param NULL
+
+  @retval EFI_NOT_FOUND           Required protocol not found.
+  @retval EFI_SUCCESS             Init successfully.
+
+**/
+EFI_STATUS
+PlatformInitSmbiosUpdate (
+  VOID
+  )
+{
+  EFI_STATUS                        Status;
+
+  DEBUG ((DEBUG_INFO, "UBA SMBIOS Update Library: PlatformInitSmbiosUpdate!\n"));
+  Status = DispatchSmbiosDynamicUpdate (SmbiosDelayUpdate);
+
+  return Status;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaCommon.dsc b/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaCommon.dsc
index a3e961aa76..28f75477c4 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaCommon.dsc
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaCommon.dsc
@@ -11,6 +11,9 @@
   UbaPlatLib|$(RP_PKG)/Library/PeiUbaPlatLib/PeiUbaPlatLib.inf
   UbaGpioInitLib|$(RP_PKG)/Library/UbaGpioInitLib/UbaGpioInitLib.inf
 
+[LibraryClasses.X64]
+  UbaPlatLib|$(RP_PKG)/Library/UbaPlatLib/UbaPlatLib.inf
+
 [Components.IA32]
   $(RP_PKG)/Uba/CfgDb/Pei/CfgDbPei.inf
   $(RP_PKG)/Uba/UbaUpdatePcds/Pei/UpdatePcdsPei.inf
-- 
2.27.0.windows.1


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

* [edk2-devel][edk2-platforms][PATCH V1 5/9] WhitleyOpenBoardPkg/PlatformSpecificAcpiTableLib: Add library
  2022-03-10 22:41 [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Oram, Isaac W
                   ` (3 preceding siblings ...)
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 4/9] WhitleyOpenBoardPkg: Add UbaPlatLib Library Oram, Isaac W
@ 2022-03-10 22:41 ` Oram, Isaac W
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 6/9] WhitleyOpenBoardPkg/BuildAcpiTablesLib: Add lib for building MADT and SRAT Oram, Isaac W
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Oram, Isaac W @ 2022-03-10 22:41 UTC (permalink / raw)
  To: devel; +Cc: Nate DeSimone, Chasel Chiu

Enables boards to modify the AcpiPlatform driver behaviors.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>
---
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSpecificAcpiTableLib.h                                | 129 ++++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/AcpiPlatformLibSpcrNull.c            |  23 ++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.c   |  50 ++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf |  27 ++++
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc                                                               |   1 +
 5 files changed, 230 insertions(+)

diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSpecificAcpiTableLib.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSpecificAcpiTableLib.h
new file mode 100644
index 0000000000..a260703274
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSpecificAcpiTableLib.h
@@ -0,0 +1,129 @@
+/** @file
+  This library provides a set of platform only ACPI tables and functions.
+
+  @copyright
+  Copyright 2012 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_SPECIFIC_ACPI_TABLE_LIB_H_
+#define _PLATFORM_SPECIFIC_ACPI_TABLE_LIB_H_
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/AcpiPlatformLib.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/SerialIo.h>
+#include <Protocol/SuperIo.h>
+#include <Guid/GlobalVariable.h>
+#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
+
+/**
+  This function will check ACPI Table is active or not active.
+  This allows boards to prevent publication of unused tables.
+
+  @param Table  -  The table to check
+
+  @retval EFI_SUCCESS  -  The Table is active.
+
+**/
+EFI_STATUS
+PlatformAcpiReportHooksTableIsActive (
+  IN OUT EFI_ACPI_COMMON_HEADER     *Table
+  );
+
+/**
+  This function will patch to update platform ACPI Table information.
+
+  @param [in, out]      Table       The table to be udated.
+
+  @retval EFI_SUCCESS  -  The function completed successfully.
+
+**/
+EFI_STATUS
+PatchPlatformSpecificAcpiTableHooks (
+  IN OUT EFI_ACPI_COMMON_HEADER     *Table
+  );
+
+/**
+  This function will patch to update SPCR Table information.
+
+  @param [in, out]      Table       The table to be udated.
+
+  @retval EFI_SUCCESS  -  The function completed successfully.
+
+**/
+EFI_STATUS
+PatchSpcrAcpiTable (
+  IN OUT  EFI_ACPI_COMMON_HEADER  *Table
+  );
+
+/**
+  Update the HMAT table.
+
+  @param [in, out]      Table       The table to be udated.
+
+  @retval EFI SUCCESS   Procedure returned successfully.
+**/
+EFI_STATUS
+PatchHmatAcpiTable (
+  IN OUT  EFI_ACPI_COMMON_HEADER  *Table
+  );
+
+/**
+  Update the PMTT ACPI table
+
+  @param [in, out]      Table       The table to be udated.
+
+  @retval EFI_SUCCESS -  Returns Success
+
+**/
+EFI_STATUS
+PatchPlatformMemoryTopologyTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER  *Table
+  );
+
+/**
+  Update the MSCT ACPI table
+
+  @param [in, out]      Table       The table to be udated.
+
+  @retval EFI_SUCCESS -  Returns Success
+
+**/
+EFI_STATUS
+PatchMsctAcpiTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER   *Table
+  );
+
+/**
+
+  Update the MIGT ACPI table
+
+  @param [in, out]      Table       The table to be udated.
+
+  @retval EFI_SUCCESS -  Returns Success
+
+**/
+EFI_STATUS
+PatchMigtAcpiTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER   *Table
+  );
+
+/**
+  Update the BDAT ACPI table: Multiple instances of the BDAT DATA HOB are placed into one contiguos memory range
+
+  @param [in, out]      Table       The table to be udated.
+
+  @retval EFI_SUCCESS -  Returns Success
+
+**/
+EFI_STATUS
+PatchBdatAcpiTable (
+  IN OUT  EFI_ACPI_COMMON_HEADER  *Table
+  );
+
+#endif
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/AcpiPlatformLibSpcrNull.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/AcpiPlatformLibSpcrNull.c
new file mode 100644
index 0000000000..0f4ffcf86f
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/AcpiPlatformLibSpcrNull.c
@@ -0,0 +1,23 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2016 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include <Library/PlatformSpecificAcpiTableLib.h>
+
+EFI_STATUS
+PatchSpcrAcpiTable (
+  IN OUT  EFI_ACPI_COMMON_HEADER  *Table
+  )
+{
+  EFI_STATUS    Status = EFI_SUCCESS;
+
+  return Status;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.c
new file mode 100644
index 0000000000..74bce3141d
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.c
@@ -0,0 +1,50 @@
+/** @file
+   Hooks for Platform populate different function and Platform only ACPI Table.
+
+  @copyright
+  Copyright 2013 - 2019 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+#include <Library/PlatformSpecificAcpiTableLib.h>
+
+/**
+  This function will check ACPI Table is active or not active.
+
+  @param [in, out]      Table       The table to be udated.
+
+  @retval EFI_SUCCESS  -  The Table is active.
+
+**/
+EFI_STATUS
+PlatformAcpiReportHooksTableIsActive (
+  IN OUT EFI_ACPI_COMMON_HEADER     *Table
+  )
+{
+  EFI_ACPI_DESCRIPTION_HEADER     *TableHeader;
+
+  TableHeader   = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
+  if (TableHeader->Signature == EFI_ACPI_6_2_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE) {
+    return EFI_NOT_FOUND;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function will patch to update platform level Acpi Table information.
+
+  @param [in, out]      Table       The table to be udated.
+
+  @retval EFI_SUCCESS  -  The function completed successfully.
+
+**/
+EFI_STATUS
+PatchPlatformSpecificAcpiTableHooks (
+  IN OUT EFI_ACPI_COMMON_HEADER     *Table
+  )
+{
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf b/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf
new file mode 100644
index 0000000000..48359b6bf5
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf
@@ -0,0 +1,27 @@
+## @file
+# Hooks to deactive or active platform ACPI Tables and patch platform only ACPI Table.
+#
+# @copyright
+# Copyright 2012 - 2018 Intel Corporation. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformSpecificAcpiTableLibNull
+  FILE_GUID                      = 6EF9D22E-89E7-45c7-8A3F-8D0207A084E4
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformSpecificAcpiTableLibNull
+
+[sources]
+  PlatformSpecificAcpiTableLibNull.c
+  AcpiPlatformLibSpcrNull.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
+  WhitleySiliconPkg/SiliconPkg.dec
+  WhitleySiliconPkg/CpRcPkg.dec
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
index 9cdb5bc2f6..2ac4a81e81 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
+++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
@@ -619,6 +619,7 @@
   PlatformOpromPolicyLib|$(RP_PKG)/Library/PlatformOpromPolicyLibNull/PlatformOpromPolicyLibNull.inf
   VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
   CrcLib|WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
+  PlatformSpecificAcpiTableLib|WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf
 
 [LibraryClasses.Common.SEC, LibraryClasses.Common.PEI_CORE, LibraryClasses.Common.PEIM]
   FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
-- 
2.27.0.windows.1


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

* [edk2-devel][edk2-platforms][PATCH V1 6/9] WhitleyOpenBoardPkg/BuildAcpiTablesLib: Add lib for building MADT and SRAT
  2022-03-10 22:41 [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Oram, Isaac W
                   ` (4 preceding siblings ...)
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 5/9] WhitleyOpenBoardPkg/PlatformSpecificAcpiTableLib: Add library Oram, Isaac W
@ 2022-03-10 22:41 ` Oram, Isaac W
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 7/9] WhitleyOpenBoardPkg/AcpiTablesLib: Add library for AcpiPlatform driver Oram, Isaac W
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Oram, Isaac W @ 2022-03-10 22:41 UTC (permalink / raw)
  To: devel; +Cc: Nate DeSimone, Chasel Chiu

Library for building tables during the boot.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>
---
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h                 | 111 +++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.c   | 470 ++++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf |  40 ++
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc                                      |   1 +
 4 files changed, 622 insertions(+)

diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h
new file mode 100644
index 0000000000..99aa1c02f7
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h
@@ -0,0 +1,111 @@
+/** @file
+  Library for building ACPI Tables.
+
+  @copyright
+  Copyright 2016 - 2019 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _BUILD_ACPI_TABLES_LIB_H_
+#define _BUILD_ACPI_TABLES_LIB_H_
+
+#include <IndustryStandard/Acpi.h>
+
+/** Structure of a MADT and SRAT sub-structure header.
+
+  This structure contains the type and length fields, which are common to every
+  sub-structure of the MADT and SRAT tables. A pointer to any structure can be cast as this.
+**/
+typedef struct {
+  UINT8 Type;
+  UINT8 Length;
+} STRUCTURE_HEADER;
+
+/**
+  Initialize the MADT header.
+
+  This function fills in the MADT's standard table header with correct values,
+  except for the length and checksum fields, which are filled in when building
+  the whole table.
+
+  @param[in,out]  MadtHeader    Pointer to the MADT header structure.
+
+  @retval EFI_SUCCESS           Successfully initialized the MADT header.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+**/
+EFI_STATUS
+InitializeMadtHeader (
+  IN OUT EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtHeader
+  );
+
+/**
+  Initialize the SRAT header.
+
+  This function fills in the SRAT's standard table header with correct values,
+  except for the length and checksum fields, which are filled in when building
+  the whole table.
+
+  @param[in,out]  SratHeader    Pointer to the SRAT header structure.
+
+  @retval EFI_SUCCESS           Successfully initialized the SRAT header.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+**/
+EFI_STATUS
+InitializeSratHeader (
+  IN OUT EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *SratHeader
+  );
+
+/**
+  Copy an ACPI sub-structure; MADT and SRAT supported
+
+  This function validates the structure type and size of a sub-structure
+  and returns a newly allocated copy of it.
+
+  @param[in]  Header            Pointer to the header of the table.
+  @param[in]  Structure         Pointer to the structure to copy.
+  @param[in]  NewStructure      Newly allocated copy of the structure.
+
+  @retval EFI_SUCCESS           Successfully copied the structure.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+  @retval EFI_INVALID_PARAMETER Structure type was unknown.
+  @retval EFI_INVALID_PARAMETER Structure length was wrong for its type.
+  @retval EFI_UNSUPPORTED       Header passed in is not supported.
+**/
+EFI_STATUS
+CopyStructure (
+  IN  EFI_ACPI_DESCRIPTION_HEADER *Header,
+  IN  STRUCTURE_HEADER *Structure,
+  OUT STRUCTURE_HEADER **NewStructure
+  );
+
+/**
+  Build ACPI Table. MADT and SRAT tables supported.
+
+  This function builds the ACPI table from the header plus the list of sub-structures
+  passed in. The table returned by this function is ready to be installed using
+  the ACPI table protocol's InstallAcpiTable function, which copies it into
+  ACPI memory. After that, the caller should free the memory returned by this
+  function.
+
+  @param[in]  AcpiHeader             Pointer to the header structure.
+  @param[in]  TableSpecificHdrLength Size of the table specific header, not the ACPI standard header size.
+  @param[in]  Structures             Pointer to an array of sub-structure pointers.
+  @param[in]  StructureCount         Number of structure pointers in the array.
+  @param[out] NewTable               Newly allocated and initialized pointer to the ACPI Table.
+
+  @retval EFI_SUCCESS           Successfully built the ACPI table.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+  @retval EFI_INVALID_PARAMETER Header parameter had the wrong signature.
+  @retval EFI_OUT_OF_RESOURCES  Space for the ACPI Table could not be allocated.
+**/
+EFI_STATUS
+BuildAcpiTable (
+  IN  EFI_ACPI_DESCRIPTION_HEADER  *AcpiHeader,
+  IN  UINTN                        TableSpecificHdrLength,
+  IN  STRUCTURE_HEADER             **Structures,
+  IN  UINTN                        StructureCount,
+  OUT UINT8                        **NewTable
+  );
+
+#endif // _BUILD_ACPI_TABLES_LIB_H_
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.c
new file mode 100644
index 0000000000..778136311e
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.c
@@ -0,0 +1,470 @@
+/** @file
+  Library for building ACPI Tables.
+
+  @copyright
+  Copyright 2016 - 2019 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+#include <Acpi/Madt.h>
+#include <Acpi/Srat.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <UncoreCommonIncludes.h>
+#include <Library/BuildAcpiTablesLib.h> // library class being implemented
+
+STRUCTURE_HEADER mMadtStructureTable[] = {
+  {EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC,          sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_STRUCTURE)},
+  {EFI_ACPI_6_2_IO_APIC,                       sizeof (EFI_ACPI_6_2_IO_APIC_STRUCTURE)},
+  {EFI_ACPI_6_2_INTERRUPT_SOURCE_OVERRIDE,     sizeof (EFI_ACPI_6_2_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE)},
+  {EFI_ACPI_6_2_NON_MASKABLE_INTERRUPT_SOURCE, sizeof (EFI_ACPI_6_2_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE)},
+  {EFI_ACPI_6_2_LOCAL_APIC_NMI,                sizeof (EFI_ACPI_6_2_LOCAL_APIC_NMI_STRUCTURE)},
+  {EFI_ACPI_6_2_LOCAL_APIC_ADDRESS_OVERRIDE,   sizeof (EFI_ACPI_6_2_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE)},
+  {EFI_ACPI_6_2_IO_SAPIC,                      sizeof (EFI_ACPI_6_2_IO_SAPIC_STRUCTURE)},
+  {EFI_ACPI_6_2_LOCAL_SAPIC,                   sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_SAPIC_STRUCTURE)},
+  {EFI_ACPI_6_2_PLATFORM_INTERRUPT_SOURCES,    sizeof (EFI_ACPI_6_2_PLATFORM_INTERRUPT_SOURCES_STRUCTURE)},
+  {EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC,        sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_STRUCTURE)},
+  {EFI_ACPI_6_2_LOCAL_X2APIC_NMI,              sizeof (EFI_ACPI_6_2_LOCAL_X2APIC_NMI_STRUCTURE)}
+};
+
+STRUCTURE_HEADER mSratStructureTable[] = {
+  {EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY, sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE)},
+  {EFI_ACPI_6_2_MEMORY_AFFINITY,                     sizeof (EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE)},
+  {EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY,     sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE)}
+};
+
+/**
+  Get the size of the ACPI table.
+
+  This function calculates the size needed for the ACPI Table based on the number and
+  size of the sub-structures that will compose it.
+
+  @param[in]  TableSpecificHdrLength  Size of the table specific header, not the ACPI standard header size.
+  @param[in]  Structures              Pointer to an array of sub-structure pointers.
+  @param[in]  StructureCount          Number of structure pointers in the array.
+
+  @return     Total size needed for the ACPI table.
+**/
+UINT32
+GetTableSize (
+  IN  UINTN                 TableSpecificHdrLength,
+  IN  STRUCTURE_HEADER      **Structures,
+  IN  UINTN                 StructureCount
+  )
+{
+  UINT32  TableLength;
+  UINT32  Index;
+
+  //
+  // Compute size of the ACPI table; header plus all structures needed.
+  //
+  TableLength = (UINT32) TableSpecificHdrLength;
+
+  for (Index = 0; Index < StructureCount; Index++) {
+    ASSERT (Structures[Index] != NULL);
+    if (Structures[Index] == NULL) {
+      return 0;
+    }
+
+    TableLength += Structures[Index]->Length;
+  }
+
+  return TableLength;
+}
+
+/**
+  Allocate the ACPI Table.
+
+  This function allocates space for the ACPI table based on the number and size of
+  the sub-structures that will compose it.
+
+  @param[in]  TableSpecificHdrLength  Size of the table specific header, not the ACPI standard header size.
+  @param[in]  Structures  Pointer to an array of sub-structure pointers.
+  @param[in]  StructureCount  Number of structure pointers in the array.
+  @param[out] Table            Newly allocated ACPI Table pointer.
+
+  @retval EFI_SUCCESS           Successfully allocated the Table.
+  @retval EFI_OUT_OF_RESOURCES  Space for the Table could not be allocated.
+**/
+EFI_STATUS
+AllocateTable (
+  IN  UINTN                        TableSpecificHdrLength,
+  IN  STRUCTURE_HEADER             **Structures,
+  IN  UINTN                        StructureCount,
+  OUT EFI_ACPI_DESCRIPTION_HEADER  **Table
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      Size;
+  EFI_ACPI_DESCRIPTION_HEADER *InternalTable;
+
+  //
+  // Get the size of the ACPI table and allocate memory.
+  //
+  Size = GetTableSize (TableSpecificHdrLength, Structures, StructureCount);
+  InternalTable = (EFI_ACPI_DESCRIPTION_HEADER *) AllocatePool (Size);
+
+  if (InternalTable == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    DEBUG ((
+      DEBUG_ERROR,
+      "Failed to allocate %d bytes for ACPI Table\n",
+      Size
+      ));
+  } else {
+    Status = EFI_SUCCESS;
+    *Table = InternalTable;
+  }
+
+  return Status;
+}
+
+/**
+  Initialize the header.
+
+  This function fills in the standard table header with correct values,
+  except for the length and checksum fields, which are filled in later.
+
+  @param[in,out]  Header        Pointer to the header structure.
+
+  @retval EFI_SUCCESS           Successfully initialized the header.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+**/
+EFI_STATUS
+InitializeHeader (
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER *Header,
+  IN      UINT32                      Signature,
+  IN      UINT8                       Revision,
+  IN      UINT32                      OemRevision
+  )
+{
+  UINT64 AcpiTableOemId;
+
+  if (Header == NULL) {
+    DEBUG ((DEBUG_ERROR, "Header pointer is NULL\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Header->Signature  = Signature;
+  Header->Length     = 0; // filled in by Build function
+  Header->Revision   = Revision;
+  Header->Checksum   = 0; // filled in by InstallAcpiTable
+
+  CopyMem (
+    (VOID *) &Header->OemId,
+    PcdGetPtr (PcdAcpiDefaultOemId),
+    sizeof (Header->OemId)
+    );
+
+  AcpiTableOemId = PcdGet64 (PcdAcpiDefaultOemTableId);
+  CopyMem (
+    (VOID *) &Header->OemTableId,
+    (VOID *) &AcpiTableOemId,
+    sizeof (Header->OemTableId)
+    );
+
+  Header->OemRevision     = OemRevision;
+  Header->CreatorId       = EFI_ACPI_CREATOR_ID;
+  Header->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Initialize the MADT header.
+
+  This function fills in the MADT's standard table header with correct values,
+  except for the length and checksum fields, which are filled in later.
+
+  @param[in,out]  MadtHeader    Pointer to the MADT header structure.
+
+  @retval EFI_SUCCESS           Successfully initialized the MADT header.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+**/
+EFI_STATUS
+InitializeMadtHeader (
+  IN OUT EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtHeader
+  )
+{
+  EFI_STATUS Status;
+
+  if (MadtHeader == NULL) {
+    DEBUG ((DEBUG_ERROR, "MADT header pointer is NULL\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = InitializeHeader (
+    &MadtHeader->Header,
+    EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
+    EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
+    EFI_ACPI_OEM_MADT_REVISION
+    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  MadtHeader->LocalApicAddress       = EFI_ACPI_LOCAL_APIC_ADDRESS;
+  MadtHeader->Flags                  = EFI_ACPI_6_2_MULTIPLE_APIC_FLAGS;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Initialize the SRAT header.
+
+  This function fills in the SRAT's standard table header with correct values,
+  except for the length and checksum fields, which are filled in when building
+  the whole table.
+
+  @param[in,out]  SratHeader    Pointer to the SRAT header structure.
+
+  @retval EFI_SUCCESS           Successfully initialized the SRAT header.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+**/
+EFI_STATUS
+InitializeSratHeader (
+  IN OUT EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *SratHeader
+  )
+{
+  EFI_STATUS Status;
+
+  if (SratHeader == NULL) {
+    DEBUG ((DEBUG_ERROR, "SRAT header pointer is NULL\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = InitializeHeader (
+    &SratHeader->Header,
+    EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE,
+    EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION,
+    EFI_ACPI_OEM_SRAT_REVISION
+    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SratHeader->Reserved1 = EFI_ACPI_SRAT_RESERVED_FOR_BACKWARD_COMPATIBILITY;
+  SratHeader->Reserved2 = EFI_ACPI_RESERVED_QWORD;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Copy an ACPI sub-structure; MADT and SRAT supported
+
+  This function validates the structure type and size of a sub-structure
+  and returns a newly allocated copy of it.
+
+  @param[in]  Header            Pointer to the header of the table.
+  @param[in]  Structure         Pointer to the structure to copy.
+  @param[in]  NewStructure      Newly allocated copy of the structure.
+
+  @retval EFI_SUCCESS           Successfully copied the structure.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+  @retval EFI_INVALID_PARAMETER Structure type was unknown.
+  @retval EFI_INVALID_PARAMETER Structure length was wrong for its type.
+  @retval EFI_UNSUPPORTED       Header passed in is not supported.
+**/
+EFI_STATUS
+CopyStructure (
+  IN  EFI_ACPI_DESCRIPTION_HEADER *Header,
+  IN  STRUCTURE_HEADER *Structure,
+  OUT STRUCTURE_HEADER **NewStructure
+  )
+{
+  STRUCTURE_HEADER      *NewStructureInternal;
+  STRUCTURE_HEADER      *StructureTable;
+  UINTN                 TableNumEntries;
+  BOOLEAN               EntryFound;
+  UINT8                 Index;
+
+  //
+  // Initialize the number of table entries and the table based on the table header passed in.
+  //
+  if (Header->Signature == EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
+    TableNumEntries = sizeof (mMadtStructureTable) / sizeof (STRUCTURE_HEADER);
+    StructureTable = mMadtStructureTable;
+  } else if (Header->Signature == EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE) {
+    TableNumEntries = sizeof (mSratStructureTable) / sizeof (STRUCTURE_HEADER);
+    StructureTable = mSratStructureTable;
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check the incoming structure against the table of supported structures.
+  //
+  EntryFound = FALSE;
+  for (Index = 0; Index < TableNumEntries; Index++) {
+    if (Structure->Type == StructureTable[Index].Type) {
+      if (Structure->Length == StructureTable[Index].Length) {
+        EntryFound = TRUE;
+      } else {
+        DEBUG ((
+          DEBUG_ERROR,
+          "Invalid length for structure type %d: expected %d, actually %d\n",
+          Structure->Type,
+          StructureTable[Index].Length,
+          Structure->Length
+          ));
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+  }
+
+  //
+  // If no entry in the table matches the structure type and length passed in
+  // then return invalid parameter.
+  //
+  if (!EntryFound) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "Unknown structure type: %d\n",
+      Structure->Type
+      ));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  NewStructureInternal = (STRUCTURE_HEADER *) AllocatePool (Structure->Length);
+  if (NewStructureInternal == NULL) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "Failed to allocate %d bytes for type %d structure\n",
+      Structure->Length,
+      Structure->Type
+      ));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  CopyMem (
+    (VOID *) NewStructureInternal,
+    (VOID *) Structure,
+    Structure->Length
+    );
+
+  *NewStructure = NewStructureInternal;
+  return EFI_SUCCESS;
+}
+
+/**
+  Build ACPI Table. MADT and SRAT tables supported.
+
+  This function builds the ACPI table from the header plus the list of sub-structures
+  passed in. The table returned by this function is ready to be installed using
+  the ACPI table protocol's InstallAcpiTable function, which copies it into
+  ACPI memory. After that, the caller should free the memory returned by this
+  function.
+
+  @param[in]  AcpiHeader             Pointer to the header structure.
+  @param[in]  TableSpecificHdrLength Size of the table specific header, not the ACPI standard header size.
+  @param[in]  Structures             Pointer to an array of sub-structure pointers.
+  @param[in]  StructureCount         Number of structure pointers in the array.
+  @param[out] NewTable               Newly allocated and initialized pointer to the ACPI Table.
+
+  @retval EFI_SUCCESS           Successfully built the ACPI table.
+  @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+  @retval EFI_INVALID_PARAMETER Header parameter had the wrong signature.
+  @retval EFI_OUT_OF_RESOURCES  Space for the ACPI Table could not be allocated.
+**/
+EFI_STATUS
+BuildAcpiTable (
+  IN  EFI_ACPI_DESCRIPTION_HEADER  *AcpiHeader,
+  IN  UINTN                        TableSpecificHdrLength,
+  IN  STRUCTURE_HEADER             **Structures,
+  IN  UINTN                        StructureCount,
+  OUT UINT8                        **NewTable
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_ACPI_DESCRIPTION_HEADER *InternalTable;
+  UINTN                       Index;
+  UINT8                       *CurrPtr;
+  UINT8                       *EndOfTablePtr;
+
+  if (AcpiHeader == NULL) {
+    DEBUG ((DEBUG_ERROR, "AcpiHeader pointer is NULL\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (AcpiHeader->Signature != EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE &&
+      AcpiHeader->Signature != EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "MADT or SRAT header signature is expected, actually 0x%08x\n",
+      AcpiHeader->Signature
+      ));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Structures == NULL) {
+    DEBUG ((DEBUG_ERROR, "Structure array pointer is NULL\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  for (Index = 0; Index < StructureCount; Index++) {
+    if (Structures[Index] == NULL) {
+      DEBUG ((DEBUG_ERROR, "Structure pointer %d is NULL\n", Index));
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // Allocate the memory needed for the table.
+  //
+  Status = AllocateTable (
+    TableSpecificHdrLength,
+    Structures,
+    StructureCount,
+    &InternalTable
+    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Copy Header and patch in structure length, checksum is programmed later
+  // after all structures are populated.
+  //
+  CopyMem (
+    (VOID *) InternalTable,
+    (VOID *) AcpiHeader,
+    TableSpecificHdrLength
+    );
+
+  InternalTable->Length = GetTableSize (TableSpecificHdrLength, Structures, StructureCount);
+
+  //
+  // Copy all the sub structures to the table.
+  //
+  CurrPtr = ((UINT8 *) InternalTable) + TableSpecificHdrLength;
+  EndOfTablePtr = ((UINT8 *) InternalTable) + InternalTable->Length;
+
+  for (Index = 0; Index < StructureCount; Index++) {
+    ASSERT (Structures[Index] != NULL);
+    if (Structures[Index] == NULL) {
+      break;
+    }
+
+    CopyMem (
+      (VOID *) CurrPtr,
+      (VOID *) Structures[Index],
+      Structures[Index]->Length
+      );
+
+    CurrPtr += Structures[Index]->Length;
+    ASSERT (CurrPtr <= EndOfTablePtr);
+    if (CurrPtr > EndOfTablePtr) {
+      break;
+    }
+  }
+
+  //
+  // Update the return pointer.
+  //
+  *NewTable = (UINT8 *) InternalTable;
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf b/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf
new file mode 100644
index 0000000000..c2bb068fcf
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf
@@ -0,0 +1,40 @@
+## @file
+# Library for building ACPI Tables.
+#
+# @copyright
+# Copyright 2016 - 2017 Intel Corporation. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010019
+  BASE_NAME                      = DxeBuildAcpiTablesLib
+  FILE_GUID                      = E4F78A63-7B78-43CD-A5C4-6CCB785B8854
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BuildAcpiTablesLib|DXE_DRIVER
+
+[Sources]
+  DxeBuildAcpiTablesLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  WhitleySiliconPkg/CpRcPkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
+  WhitleySiliconPkg/SiliconPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  MemoryAllocationLib
+  PcdLib
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+
+[FixedPcd]
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuCoreCount
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
index 2ac4a81e81..39b93d9289 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
+++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
@@ -620,6 +620,7 @@
   VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
   CrcLib|WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
   PlatformSpecificAcpiTableLib|WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf
+  BuildAcpiTablesLib|WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf
 
 [LibraryClasses.Common.SEC, LibraryClasses.Common.PEI_CORE, LibraryClasses.Common.PEIM]
   FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
-- 
2.27.0.windows.1


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

* [edk2-devel][edk2-platforms][PATCH V1 7/9] WhitleyOpenBoardPkg/AcpiTablesLib: Add library for AcpiPlatform driver
  2022-03-10 22:41 [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Oram, Isaac W
                   ` (5 preceding siblings ...)
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 6/9] WhitleyOpenBoardPkg/BuildAcpiTablesLib: Add lib for building MADT and SRAT Oram, Isaac W
@ 2022-03-10 22:41 ` Oram, Isaac W
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 8/9] WhitleyOpenBoardPkg/AcpiPlatform: Add driver for publishing ACPI tables Oram, Isaac W
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Oram, Isaac W @ 2022-03-10 22:41 UTC (permalink / raw)
  To: devel; +Cc: Nate DeSimone, Chasel Chiu

AcpiTablesLib allows for board specific updates to ACPI tables.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>
---
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.c      |  534 ++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.inf    |  127 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibApic.c  |  735 +++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibBdat.c  | 1574 ++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibDsdt.c  |  673 ++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibFadt.c  |   75 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibHmat.c  | 1710 ++++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibLocal.h |  441 +++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMcfg.c  |  134 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMigt.c  |   69 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMsct.c  |  101 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibNfit.c  |   45 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPcat.c  |   42 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPmtt.c  |  267 +++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSlit.c  | 1153 +++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSrat.c  |  952 +++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSsdt.c  | 1004 ++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec                                     |    5 +
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc                                     |    1 +
 19 files changed, 9642 insertions(+)

diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.c
new file mode 100644
index 0000000000..f321c73a51
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.c
@@ -0,0 +1,534 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatformLibLocal.h"
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Library/UbaPlatLib.h>
+#include <Library/PlatformSpecificAcpiTableLib.h>
+#include <Protocol/DynamicSiLibraryProtocol.h>
+#include <Protocol/DynamicSiLibraryProtocol2.h>
+
+extern BIOS_ACPI_PARAM      *mAcpiParameter;
+
+EFI_PLATFORM_INFO           *mPlatformInfo;
+EFI_CPU_CSR_ACCESS_PROTOCOL *mCpuCsrAccess;
+EFI_ACPI_TABLE_PROTOCOL     *mAcpiTable;
+extern EFI_IIO_UDS_PROTOCOL *mIioUds;
+CPU_CSR_ACCESS_VAR          *mCpuCsrAccessVarPtr;
+
+
+UINT32                      mNumOfBitShift;
+BOOLEAN                     mX2ApicEnabled;
+
+SYSTEM_MEMORY_MAP_HOB      *mSystemMemoryMap;
+
+SOCKET_MEMORY_CONFIGURATION   mSocketMemoryConfiguration;
+SOCKET_MP_LINK_CONFIGURATION  mSocketMpLinkConfiguration;
+SOCKET_IIO_CONFIGURATION      mSocketIioConfiguration;
+SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanagementConfiguration;
+SOCKET_COMMONRC_CONFIGURATION mSocketCommonRcConfiguration;
+SOCKET_PROCESSORCORE_CONFIGURATION   mSocketProcessorCoreConfiguration;
+
+CPU_CONFIG_CONTEXT_BUFFER *mCpuConfigLibConfigContextBuffer = NULL;
+
+EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE *mSpcrTable = NULL;
+
+/**
+  The constructor function of AcpiPlatormL Library.
+
+  The constructor function caches the value of PCD entry
+
+  @param  ImageHandle   The firmware allocated handle for the EFI image.
+  @param  SystemTable   A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiPlatformLibConstructor (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_HOB_GUID_TYPE             *GuidHob;
+
+  DYNAMIC_SI_LIBARY_PROTOCOL  *DynamicSiLibraryProtocol = NULL;
+
+  mCpuConfigLibConfigContextBuffer = (CPU_CONFIG_CONTEXT_BUFFER *) (UINTN) PcdGet64 (PcdCpuConfigContextBuffer);
+  if (mCpuConfigLibConfigContextBuffer == NULL) {
+    ASSERT_EFI_ERROR (RETURN_NOT_FOUND);
+    return RETURN_NOT_FOUND;
+  }
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &DynamicSiLibraryProtocol);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  GuidHob    = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+  if (GuidHob == NULL) {
+    ASSERT (GuidHob != NULL);
+    return EFI_NOT_FOUND;
+  }
+  mPlatformInfo = GET_GUID_HOB_DATA (GuidHob);
+
+  //
+  // Locate the IIO Protocol Interface
+  //
+  Status = gBS->LocateProtocol (&gEfiIioUdsProtocolGuid,NULL,&mIioUds);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  Status = gBS->LocateProtocol (&gEfiCpuCsrAccessGuid, NULL, &mCpuCsrAccess);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  mCpuCsrAccessVarPtr = DynamicSiLibraryProtocol->GetSysCpuCsrAccessVar ();
+  mSystemMemoryMap = DynamicSiLibraryProtocol->GetSystemMemoryMapData ();
+  ASSERT (mSystemMemoryMap != NULL);
+
+  mMpService = NULL;
+
+  Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, &mMpService);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  //
+  // Determine the number of processors
+  //
+  mMpService->GetNumberOfProcessors (
+    mMpService,
+    &mNumberOfCPUs,
+    &mNumberOfEnabledCPUs
+    );
+  ASSERT (mNumberOfCPUs <= MAX_CPU_NUM && mNumberOfEnabledCPUs >= 1);
+  if (mNumberOfCPUs > MAX_CPU_NUM) {
+    mNumberOfCPUs = MAX_CPU_NUM;
+  }
+
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, &mAcpiTable);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Platform hook to initialize Platform Specific ACPI Parameters
+
+  @retval EFI_SUCCESS            Platform specific parameters in mAcpiParameter
+                                 initialized successfully.
+  @retval EFI_INVALID_PARAMETER  mAcpiParameter global was NULL.
+**/
+EFI_STATUS
+PlatformHookAfterAcpiParamInit (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+
+  Status = EFI_SUCCESS;
+
+  if (mAcpiParameter == NULL) {
+    ASSERT (mAcpiParameter != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DEBUG ((DEBUG_INFO, "ACPI Parameter Block Address: 0x%X\n", mAcpiParameter));
+
+
+  //
+  // Call for Local APIC ID Reorder
+  //
+  Status = SortCpuLocalApicInTable ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[ACPI] ERROR: SortCpuLocalApicInTable failed: %r\n", Status));
+    return Status;
+  }
+
+  return Status;
+}
+
+
+EFI_STATUS
+AcpiPlatformHooksIsActiveTable (
+  IN OUT EFI_ACPI_COMMON_HEADER     *Table
+  )
+{
+  EFI_NFIT_TABLE_UPDATE_PROTOCOL  *NfitTableUpdateProtocol;
+  EFI_ACPI_DESCRIPTION_HEADER     *TableHeader;
+  EFI_STATUS                      Status;
+  SETUP_DATA                      SetupData;
+  SYSTEM_CONFIGURATION            SystemConfiguration;
+  UINT8                           *OemSkuAcpiName;
+
+  Status = GetEntireConfig (&SetupData);
+  ASSERT_EFI_ERROR (Status);
+  CopyMem (&SystemConfiguration, &(SetupData.SystemConfig), sizeof(SYSTEM_CONFIGURATION));
+
+  if (mSystemMemoryMap == NULL) {
+
+    ASSERT (FALSE);
+    return EFI_NOT_FOUND;
+  }
+  TableHeader   = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
+  if (TableHeader->Signature == ACPI_PMTT_TABLE_SIGNATURE) {
+    if (!mSystemMemoryMap->DcpmmPresent) {
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  if (TableHeader->Signature == EFI_BDAT_TABLE_SIGNATURE) {
+    if (mSocketMemoryConfiguration.bdatEn == 0) {
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  if (TableHeader->Signature == NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE_SIGNATURE) {
+    if (mSystemMemoryMap->DcpmmPresent == 0) {
+        return EFI_NOT_FOUND;
+    }
+  }
+
+  if (TableHeader->Signature == NVDIMM_FW_INTERFACE_TABLE_SIGNATURE) {
+    Status = gBS->LocateProtocol (&gEfiNfitTableUpdateProtocolGuid, NULL, &NfitTableUpdateProtocol);
+    if (EFI_ERROR (Status)){
+      // If NfitTableUpdateProtocol is not found we assume no NVDIMM is present - it means don't publish NFIT
+      DEBUG ((DEBUG_ERROR, "NfitTableUpdateProtocol is not installed.\n"));
+      return EFI_NOT_FOUND;
+    }
+  }
+  if (TableHeader->Signature  ==  EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE) {
+    //
+    // Initialize the SPCR table pointer.
+    // SPCR table is not ready yet, update it before booting.
+    //
+    mSpcrTable = (EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE *) Table;
+    return EFI_NOT_READY;
+  }
+
+  if ((TableHeader->Signature == EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE) ||
+      (TableHeader->Signature == EFI_ACPI_6_2_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE) ||
+      (TableHeader->Signature == EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE) ||
+      TableHeader->Signature == EFI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE) {
+    //
+    // Only publish SRAT/SLIT/MSCT/HMAT if NUMA is enabled in setup.
+    //
+    if (!mSocketCommonRcConfiguration.NumaEn) {
+
+      DEBUG ((DEBUG_INFO, "[ACPI] NUMA disabled, do not publish '%c%c%c%c' table\n",
+              ((CHAR8*)&TableHeader->Signature)[0], ((CHAR8*)&TableHeader->Signature)[1],
+              ((CHAR8*)&TableHeader->Signature)[2], ((CHAR8*)&TableHeader->Signature)[3]));
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  if (TableHeader->Signature == EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE) {
+      return EFI_NOT_FOUND;
+  }
+
+  if (TableHeader->Signature == EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
+    OemSkuAcpiName = PcdGetPtr (PcdOemSkuAcpiName);
+    if (OemSkuAcpiName == NULL) {
+      return EFI_UNSUPPORTED;
+    }
+    if ( (0 == CompareMem (&(TableHeader->OemTableId), OemSkuAcpiName, 8)) ) {
+      Status = PlatformGetAcpiFixTableDataPointer (&mAmlOffsetTablePointer);
+      if (!EFI_ERROR(Status)) {
+        DEBUG((DEBUG_INFO, "[ACPI] Platform DSDT Fixup table found\n"));
+        DEBUG((DEBUG_INFO, "[ACPI] Platform SRP: Using %a DSDT\n", OemSkuAcpiName));
+        return EFI_SUCCESS;
+      } else {
+        DEBUG((DEBUG_ERROR, "[ACPI] Platform DSDT Fixup table not found.\n"));
+        return EFI_UNSUPPORTED;
+      }
+    } else {
+      DEBUG ((DEBUG_INFO, "[ACPI] Platform DSDT OemSkuAcpiName '%c%c%c%c%c%c%c%c':\n",
+              ((CHAR8*)OemSkuAcpiName)[0], ((CHAR8*)OemSkuAcpiName)[1],
+              ((CHAR8*)OemSkuAcpiName)[2], ((CHAR8*)OemSkuAcpiName)[3],
+              ((CHAR8*)OemSkuAcpiName)[4], ((CHAR8*)OemSkuAcpiName)[5],
+              ((CHAR8*)OemSkuAcpiName)[6], ((CHAR8*)OemSkuAcpiName)[7]));
+
+      DEBUG ((DEBUG_INFO, " no match for OemTableId '%c%c%c%c%c%c%c%c' from FwVol.\n",
+              ((CHAR8*)&TableHeader->OemTableId)[0], ((CHAR8*)&TableHeader->OemTableId)[1],
+              ((CHAR8*)&TableHeader->OemTableId)[2], ((CHAR8*)&TableHeader->OemTableId)[3],
+              ((CHAR8*)&TableHeader->OemTableId)[4], ((CHAR8*)&TableHeader->OemTableId)[5],
+              ((CHAR8*)&TableHeader->OemTableId)[6], ((CHAR8*)&TableHeader->OemTableId)[7]));
+
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Hooks for checking additional platform ACPI Table is active or not.
+  // If ACPI Table is not in list, it should be reported and returned EFI_SUCCESS.
+  //
+  return PlatformAcpiReportHooksTableIsActive (Table);
+}
+
+
+/**
+  This function will update any runtime platform specific information.
+  This currently includes:
+    Setting OEM table values, ID, table ID, creator ID and creator revision.
+    Enabling the proper processor entries in the APIC tables.
+
+  @param Table  -  The table to update
+
+  @retval EFI_SUCCESS  -  The function completed successfully.
+**/
+EFI_STATUS
+PlatformUpdateTables (
+  IN OUT EFI_ACPI_COMMON_HEADER     *Table,
+  IN OUT EFI_ACPI_TABLE_VERSION     *Version
+  )
+{
+  EFI_ACPI_DESCRIPTION_HEADER               *TableHeader;
+  EFI_STATUS                                Status;
+  ACPI_APIC_STRUCTURE_PTR                   *ProcessorLocalApicEntry;
+  UINT64                                    TempOemTableId;
+  UINT32                                    Data32;
+
+  DYNAMIC_SI_LIBARY_PROTOCOL2  *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  TableHeader             = NULL;
+
+  ProcessorLocalApicEntry = NULL;
+  Status = EFI_SUCCESS;
+
+  //
+  // By default, a table belongs in all ACPI table versions published.
+  // Some tables will override this because they have different versions of the table.
+  //
+  *Version = EFI_ACPI_TABLE_VERSION_2_0;
+
+  if (Table->Signature != EFI_ACPI_6_2_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE &&
+      Table->Signature != EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE &&
+      Table->Signature != SIGNATURE_32('N', 'F', 'I', 'T') &&
+      Table->Signature != SIGNATURE_32('P', 'C', 'A', 'T') &&
+      Table->Signature != SIGNATURE_32('O', 'E', 'M', '1') &&
+      Table->Signature != SIGNATURE_32('O', 'E', 'M', '2') &&
+      Table->Signature != SIGNATURE_32('O', 'E', 'M', '3') &&
+      Table->Signature != SIGNATURE_32('O', 'E', 'M', '4'))
+  {
+    TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
+    //
+    // Update the OEMID and OEM Table ID.
+    //
+    TempOemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
+
+    CopyMem (TableHeader->OemId, PcdGetPtr(PcdAcpiDefaultOemId), sizeof(TableHeader->OemId));
+    CopyMem (&TableHeader->OemTableId, &TempOemTableId, sizeof(TableHeader->OemTableId));
+
+    //
+    // Update the creator ID
+    //
+    TableHeader->CreatorId = EFI_ACPI_CREATOR_ID;
+
+    //
+    // Update the creator revision
+    //
+    TableHeader->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
+  }
+  //
+  // Complete this function
+  //
+
+  //ASSERT (mMaxNumberOfCPUs <= MAX_CPU_NUM && mNumberOfEnabledCPUs >= 1);
+
+  //
+  // Assign a invalid intial value for update
+  //
+  //
+  // Update the processors in the APIC table
+  //
+  DEBUG ((DEBUG_INFO, "[ACPI] Patching '%c%c%c%c' table...\n",
+          ((CHAR8*)&Table->Signature)[0], ((CHAR8*)&Table->Signature)[1],
+          ((CHAR8*)&Table->Signature)[2], ((CHAR8*)&Table->Signature)[3]));
+  switch (Table->Signature) {
+
+  //
+  // Do not allow a prebuilt MADT, since it is built dynamically.
+  //
+  case EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
+    DEBUG ((DEBUG_ERROR, "[ACPI] ERROR: Prebuilt MADT found\n"));
+    Status = EFI_INVALID_PARAMETER;
+    ASSERT_EFI_ERROR (Status);
+    break;
+
+  case EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
+    Status = PatchFadtTable (Table);
+    break;
+
+  case EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
+    //
+    // Patch the memory resource
+    //
+    Status = PatchDsdtTable (Table);
+    break;
+
+  case EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
+    Status = PatchSsdtTable (Table,Version);
+    break;
+
+  case EFI_ACPI_6_2_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
+    //
+    // Adjust HPET Table to correct the Base Address
+    // Get the address bits in RCRB that configure HPET MMIO space
+    //  and create an offset to the pre-defined HEPT base address
+    //
+    DynamicSiLibraryProtocol2->PchHpetBaseGet (&Data32);
+    //
+    // Add the offset to the base address and copy into HPET DSDT table
+    //
+    ((EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) Table)->BaseAddressLower32Bit.Address = Data32;
+    break;
+
+  case EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
+    Status = PatchMcfgAcpiTable (Table);
+    break;
+
+  case EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE:
+    Status = PatchSpcrAcpiTable (Table);
+    break;
+
+  case ACPI_PMTT_TABLE_SIGNATURE:
+    if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
+      Status = PatchPlatformMemoryTopologyTable (Table);
+    }
+    break;
+
+  case EFI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE:
+    if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
+      Status = PatchHmatAcpiTable (Table);
+    }
+    break;
+
+  case EFI_ACPI_6_2_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE:
+    if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
+      Status = PatchMsctAcpiTable (Table);
+    }
+    break;
+
+  case EFI_MIGT_ACPI_TABLE_SIGNATURE:
+    if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) {
+      if (PcdGetBool (ReservedB)) {
+        Status = PatchMigtAcpiTable (Table);
+      }
+    }
+    break;
+
+  case EFI_BDAT_TABLE_SIGNATURE:
+    if (!PcdGetBool (PcdPlatformNotSupportAcpiBdatTable)) {
+      Status = PatchBdatAcpiTable (Table);
+    }
+    break;
+
+  case NVDIMM_FW_INTERFACE_TABLE_SIGNATURE:
+    Status = UpdateNfitTable (Table);
+    break;
+
+  case NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE_SIGNATURE:
+    Status = UpdatePcatTable (Table);
+    break;
+
+  //Patch Dynamic OEM SSDT table
+  case OEM1_SSDT_TABLE_SIGNATURE:
+    Status = PatchOem1SsdtTable (Table);  //CPU EIST
+    break;
+
+  case OEM2_SSDT_TABLE_SIGNATURE:
+    Status = PatchOem2SsdtTable (Table);  //CPU HWP
+    break;
+
+  case OEM3_SSDT_TABLE_SIGNATURE:
+    Status = PatchOem3SsdtTable (Table);  //CPU TST
+    break;
+
+  case OEM4_SSDT_TABLE_SIGNATURE:
+    Status = PatchOem4SsdtTable (Table);  //CPU CST
+    break;
+  case ACPI_WSMT_SIGNATURE:
+    (((ACPI_WINDOWS_SMM_SECURITY_MITIGATIONS_TABLE *)Table)->ProtectionFlags.Flags) = (UINT32 ) (WSMT_PROTECTION_FLAG & PcdGet32(PcdWsmtProtectionFlags));
+  DEBUG ((DEBUG_INFO, "[WSMT] ProtectionFlags = 0x%x\n", (((ACPI_WINDOWS_SMM_SECURITY_MITIGATIONS_TABLE *)Table)->ProtectionFlags.Flags)));
+      break;
+
+  default:
+    //
+    // Hooks for Platform only table. If the ACPI Table is Platform only, add this table in below hook. then continue to update other Table.
+    //
+    Status = PatchPlatformSpecificAcpiTableHooks (Table);
+    break;
+  }
+  //
+  //
+  // Update the hardware signature in the FACS structure
+  //
+  //
+  //
+  return Status;
+}
+
+/**
+  Give the platform a chance to build tables.
+
+  Some tables can be built from scratch more efficiently than being prebuilt
+  and updated. This function builds any such tables for the platform.
+
+  @retval EFI_SUCCESS   Any platform tables were successfully built.
+**/
+EFI_STATUS
+PlatformBuildTables (
+  VOID
+  )
+{
+  EFI_STATUS ReturnStatus = EFI_SUCCESS;
+  EFI_STATUS Status;
+
+  Status = InstallMadtFromScratch ();
+  if (EFI_ERROR (Status)) {
+    ReturnStatus = Status;
+  }
+
+  if (mSocketCommonRcConfiguration.NumaEn) {
+    Status = InstallSlitTable ();
+    if (EFI_ERROR (Status)) {
+      ReturnStatus = Status;
+    }
+
+    Status = InstallSratTable ();
+    if (EFI_ERROR (Status)) {
+      ReturnStatus = Status;
+    }
+  }
+  //
+  // Return the first error code that occured, or success.
+  //
+  return ReturnStatus;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.inf b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.inf
new file mode 100644
index 0000000000..c571871930
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.inf
@@ -0,0 +1,127 @@
+## @file
+# Library functions for ACPI Table Update library.
+#
+# @copyright
+# Copyright 2015 - 2020 Intel Corporation. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = AcpiPlatformTableLib
+  FILE_GUID                      = 09114814-BF6D-4B2D-BD61-C1F0668DE06E
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = AcpiPlatformTableLib
+  CONSTRUCTOR                    = AcpiPlatformLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = X64
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+  AcpiPlatformLibApic.c
+  AcpiPlatformLibBdat.c
+  AcpiPlatformLibDsdt.c
+  AcpiPlatformLibFadt.c
+  AcpiPlatformLibMcfg.c
+  AcpiPlatformLibMsct.c
+  AcpiPlatformLib.c
+  AcpiPlatformLibLocal.h
+  AcpiPlatformLibNfit.c
+  AcpiPlatformLibPcat.c
+  AcpiPlatformLibSlit.c
+  AcpiPlatformLibSrat.c
+  AcpiPlatformLibSsdt.c
+  AcpiPlatformLibMigt.c
+  AcpiPlatformLibPmtt.c
+  AcpiPlatformLibHmat.c
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+#                              this module.
+#
+################################################################################
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
+  WhitleySiliconPkg/SiliconPkg.dec
+  WhitleySiliconPkg/CpRcPkg.dec
+  WhitleySiliconPkg/Cpu/CpuRcPkg.dec
+  WhitleySiliconPkg/WhitleySiliconPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  PcdLib
+  MemoryAllocationLib
+  BuildAcpiTablesLib
+  CrcLib
+  UbaPlatLib
+  PlatformSpecificAcpiTableLib
+  CompressDxeLib
+  UefiDecompressLib
+
+[Protocols]
+  gDxePchPlatformPolicyProtocolGuid
+  gEfiNfitTableUpdateProtocolGuid
+  gSmbiosMemInfoProtocolGuid
+  gAcpiPlatformProtocolGuid
+  gEfiSmbiosProtocolGuid
+  gEfiCpuCsrAccessGuid
+  gDynamicSiLibraryProtocolGuid                 ## CONSUMES
+  gDynamicSiLibraryProtocol2Guid                ## CONSUMES
+
+[Guids]
+  gEfiPlatformInfoGuid
+  gFpgaSocketVariableGuid
+  gEwlBdatSchemaGuid
+  gSpdBdatSchemaGuid
+  gSpdVersion1Guid
+  gSpdVariableGuid
+  gMemTrainingDataBdatSchemaGuid
+  gMemTrainingDataVersion1Guid
+  gMemTrainingDataHobGuid
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+  gPlatformTokenSpaceGuid.ReservedB
+  gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress
+  gOemSkuTokenSpaceGuid.PcdOemSkuAcpiName
+  gPlatformTokenSpaceGuid.PcdPlatformNotSupportAcpiTable
+  gPlatformTokenSpaceGuid.PcdPlatformNotSupportAcpiBdatTable
+  gPlatformModuleTokenSpaceGuid.PcdWsmtProtectionFlags
+  gPlatformTokenSpaceGuid.PcdHalfWidth
+  gCpuPkgTokenSpaceGuid.PcdCpuConfigContextBuffer       ## CONSUMES
+
+[FixedPcd]
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuCoreCount
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuThreadCount
+  gEfiCpRcPkgTokenSpaceGuid.SaveSpdToBdat
+  gEfiCpRcPkgTokenSpaceGuid.SaveMrcTrainingDataToBdat
+
+[Depex]
+  gDynamicSiLibraryProtocolGuid AND
+  gDynamicSiLibraryProtocol2Guid
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibApic.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibApic.c
new file mode 100644
index 0000000000..0718e81682
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibApic.c
@@ -0,0 +1,735 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatformLibLocal.h"
+
+extern EFI_PLATFORM_INFO            *mPlatformInfo;
+extern BIOS_ACPI_PARAM              *mAcpiParameter;
+extern EFI_ACPI_TABLE_PROTOCOL      *mAcpiTable;
+EFI_IIO_UDS_PROTOCOL                *mIioUds = NULL;
+
+extern UINT32                       mNumOfBitShift;
+
+extern BOOLEAN                      mX2ApicEnabled;
+BOOLEAN                             mCpuOrderSorted = FALSE;
+
+extern CPU_CSR_ACCESS_VAR           *mCpuCsrAccessVarPtr;
+EFI_MP_SERVICES_PROTOCOL            *mMpService;
+CPU_ID_ORDER_MAP                    mCpuApicIdOrderTable[MAX_CPU_NUM];
+UINTN                               mNumberOfCPUs = 0;
+UINTN                               mNumberOfEnabledCPUs = 0;
+
+UINT32                              mEnabledProcessor[MAX_SOCKET];
+
+extern UINT32 mCpuPCPSInfo[MAX_SOCKET];
+extern CPU_LOGICAL_THREAD_ID_TABLE  mCpuThreadIdMsrTable[MAX_CPU_NUM];
+
+
+UINT32 mApicIdMap[MAX_SOCKET][MAX_CORE * MAX_THREAD];
+
+UINT32 mThreadCount[MAX_SOCKET] = {0};
+
+typedef struct {
+  UINT64 EnableMask;
+  UINT8  Id;
+  UINT32 GsiBase;
+} IO_APIC_DESCRIPTOR;
+
+STATIC CONST IO_APIC_DESCRIPTOR IoApicDescList[] = {
+  {PCH_IOAPIC,  PCH_IOAPIC_ID,  PCH_INTERRUPT_BASE},
+  {PC00_IOAPIC, PC00_IOAPIC_ID, PC00_INTERRUPT_BASE},
+  {PC01_IOAPIC, PC01_IOAPIC_ID, PC01_INTERRUPT_BASE},
+  {PC02_IOAPIC, PC02_IOAPIC_ID, PC02_INTERRUPT_BASE},
+  {PC03_IOAPIC, PC03_IOAPIC_ID, PC03_INTERRUPT_BASE},
+  {PC04_IOAPIC, PC04_IOAPIC_ID, PC04_INTERRUPT_BASE},
+  {PC05_IOAPIC, PC05_IOAPIC_ID, PC05_INTERRUPT_BASE},
+  {PC06_IOAPIC, PC06_IOAPIC_ID, PC06_INTERRUPT_BASE},
+  {PC07_IOAPIC, PC07_IOAPIC_ID, PC07_INTERRUPT_BASE},
+  {PC08_IOAPIC, PC08_IOAPIC_ID, PC08_INTERRUPT_BASE},
+  {PC09_IOAPIC, PC09_IOAPIC_ID, PC09_INTERRUPT_BASE},
+  {PC10_IOAPIC, PC10_IOAPIC_ID, PC10_INTERRUPT_BASE},
+  {PC11_IOAPIC, PC11_IOAPIC_ID, PC11_INTERRUPT_BASE},
+  {PC12_IOAPIC, PC12_IOAPIC_ID, PC12_INTERRUPT_BASE},
+  {PC13_IOAPIC, PC13_IOAPIC_ID, PC13_INTERRUPT_BASE},
+  {PC14_IOAPIC, PC14_IOAPIC_ID, PC14_INTERRUPT_BASE},
+  {PC15_IOAPIC, PC15_IOAPIC_ID, PC15_INTERRUPT_BASE},
+  {PC16_IOAPIC, PC16_IOAPIC_ID, PC16_INTERRUPT_BASE},
+  {PC17_IOAPIC, PC17_IOAPIC_ID, PC17_INTERRUPT_BASE},
+  {PC18_IOAPIC, PC18_IOAPIC_ID, PC18_INTERRUPT_BASE},
+  {PC19_IOAPIC, PC19_IOAPIC_ID, PC19_INTERRUPT_BASE},
+  {PC20_IOAPIC, PC20_IOAPIC_ID, PC20_INTERRUPT_BASE},
+  {PC21_IOAPIC, PC21_IOAPIC_ID, PC21_INTERRUPT_BASE},
+  {PC22_IOAPIC, PC22_IOAPIC_ID, PC22_INTERRUPT_BASE},
+  {PC23_IOAPIC, PC23_IOAPIC_ID, PC23_INTERRUPT_BASE},
+  {PC24_IOAPIC, PC24_IOAPIC_ID, PC24_INTERRUPT_BASE},
+  {PC25_IOAPIC, PC25_IOAPIC_ID, PC25_INTERRUPT_BASE},
+  {PC26_IOAPIC, PC26_IOAPIC_ID, PC26_INTERRUPT_BASE},
+  {PC27_IOAPIC, PC27_IOAPIC_ID, PC27_INTERRUPT_BASE},
+  {PC28_IOAPIC, PC28_IOAPIC_ID, PC28_INTERRUPT_BASE},
+  {PC29_IOAPIC, PC29_IOAPIC_ID, PC29_INTERRUPT_BASE},
+  {PC30_IOAPIC, PC30_IOAPIC_ID, PC30_INTERRUPT_BASE},
+  {PC31_IOAPIC, PC31_IOAPIC_ID, PC31_INTERRUPT_BASE},
+  {PC32_IOAPIC, PC32_IOAPIC_ID, PC32_INTERRUPT_BASE},
+  {PC33_IOAPIC, PC33_IOAPIC_ID, PC33_INTERRUPT_BASE},
+  {PC34_IOAPIC, PC34_IOAPIC_ID, PC34_INTERRUPT_BASE},
+  {PC35_IOAPIC, PC35_IOAPIC_ID, PC35_INTERRUPT_BASE},
+  {PC36_IOAPIC, PC36_IOAPIC_ID, PC36_INTERRUPT_BASE},
+  {PC37_IOAPIC, PC37_IOAPIC_ID, PC37_INTERRUPT_BASE},
+  {PC38_IOAPIC, PC38_IOAPIC_ID, PC38_INTERRUPT_BASE},
+  {PC39_IOAPIC, PC39_IOAPIC_ID, PC39_INTERRUPT_BASE},
+  {PC40_IOAPIC, PC40_IOAPIC_ID, PC40_INTERRUPT_BASE},
+  {PC41_IOAPIC, PC41_IOAPIC_ID, PC41_INTERRUPT_BASE},
+  {PC42_IOAPIC, PC42_IOAPIC_ID, PC42_INTERRUPT_BASE},
+  {PC43_IOAPIC, PC43_IOAPIC_ID, PC43_INTERRUPT_BASE},
+  {PC44_IOAPIC, PC44_IOAPIC_ID, PC44_INTERRUPT_BASE},
+  {PC45_IOAPIC, PC45_IOAPIC_ID, PC45_INTERRUPT_BASE},
+  {PC46_IOAPIC, PC46_IOAPIC_ID, PC46_INTERRUPT_BASE},
+  {PC47_IOAPIC, PC47_IOAPIC_ID, PC47_INTERRUPT_BASE}
+};
+
+/**
+  Find OrderTable index which is matching input ApicId
+
+  @param ApicId - input ApicId
+
+  @retval Index       - OrderTable index
+  @retval (UINT32) -1 - Not found
+**/
+UINT32
+ApicId2OrderTableIndex (
+  UINT32 ApicId
+  )
+{
+  UINT32 Index;
+
+  for (Index = 0; Index < MAX_CPU_NUM; Index++) {
+    if ((mCpuApicIdOrderTable[Index].Flags == 1) && (mCpuApicIdOrderTable[Index].ApicId == ApicId)) {
+      return Index;
+    }
+  }
+
+  return (UINT32) -1;
+}
+
+/**
+  Display reordered Apic table for detected CPUs.
+
+  @param None
+
+  @retval None
+**/
+VOID
+DebugDisplayReOrderTable (
+  VOID
+  )
+{
+  UINT32 Index;
+  UINT32 TotalEnabledThreads = 0;
+
+  DEBUG ((DEBUG_INFO, "Index  AcpiProcId  ApicId  Flags  Skt\n"));
+  for (Index = 0; Index < MAX_CPU_NUM; Index++) {
+    if (mCpuApicIdOrderTable[Index].ApicId == (UINT32) -1) {
+      break;
+    }
+    TotalEnabledThreads++;
+    DEBUG ((DEBUG_INFO, " %02d       0x%02X      0x%02X      %d      %d\n",
+                           Index, mCpuApicIdOrderTable[Index].AcpiProcessorId,
+                           mCpuApicIdOrderTable[Index].ApicId,
+                           mCpuApicIdOrderTable[Index].Flags,
+                           mCpuApicIdOrderTable[Index].SocketNum));
+  }
+  DEBUG ((DEBUG_INFO, "\n:ACPI: Total Enabled Threads = %d\n\n", TotalEnabledThreads));
+}
+
+/**
+  Consolidate APIC ID order for all populated socket in mApicIdMap table
+
+  @param None
+
+  @retval None
+**/
+VOID
+UpdateApicIdMap (
+  VOID
+  )
+{
+  UINT32 SocketId;
+  UINT32 ThreadIndex;
+  UINT32 CurrProcessor;
+
+  //
+  // init global mApicIdMap variable
+  //
+  SetMem32 ((VOID *)mApicIdMap, sizeof(mApicIdMap), 0xFFFFFFFF);
+
+  for (SocketId = 0; SocketId < MAX_SOCKET; SocketId++) {
+    if ((mCpuCsrAccessVarPtr->socketPresentBitMap & (1 << SocketId)) == 0) {
+      continue;
+    }
+
+    ThreadIndex = 0;
+    for (CurrProcessor = 0; CurrProcessor < MAX_CPU_NUM; CurrProcessor++) {
+      if (mCpuApicIdOrderTable[CurrProcessor].ApicId == (UINT32) -1) {
+        break;
+      }
+
+      if ((mCpuApicIdOrderTable[CurrProcessor].SocketNum == SocketId) && (ThreadIndex < (MAX_CORE * MAX_THREAD))) {
+        mApicIdMap[SocketId][ThreadIndex] = (UINT32) mCpuApicIdOrderTable[CurrProcessor].ApicId & (UINT32) ~(SocketId<< mNumOfBitShift);
+        ThreadIndex++;
+      }
+    }
+
+    if (ThreadIndex != mThreadCount[SocketId]) {
+      DEBUG((DEBUG_ERROR, ":: Skt: %d - Enabled ThreadCount is incorrect!!!\n"));
+      break;
+    }
+  }
+
+  return;
+}
+
+/**
+  Find the processor index of the thread running and obtain MSR 53 and ApicId data
+  to populate mCpuThreadIdMsrTable array.
+
+  @param None
+
+  @retval None
+**/
+VOID
+GetThreadIdMsrValue (
+  VOID
+  )
+{
+  UINTN     ProcessorNumber;
+  UINT64    LogicalIdMsrValue;
+
+  mMpService->WhoAmI (mMpService, &ProcessorNumber);
+  LogicalIdMsrValue = AsmReadMsr64 (0x00000053);
+  mCpuThreadIdMsrTable[ProcessorNumber].ThreadIdValue = (UINT32) LogicalIdMsrValue;
+  mCpuThreadIdMsrTable[ProcessorNumber].CollocatedChaId = (UINT32) RShiftU64(LogicalIdMsrValue, 32);
+  mCpuThreadIdMsrTable[ProcessorNumber].ApicId = mCpuConfigLibConfigContextBuffer->CollectedDataBuffer[ProcessorNumber].CpuMiscData.ApicID;
+}
+
+/**
+  Sort CPU Local APIC Information.
+
+  This function gets the CPU local APIC information from the MP service
+  protocol into the local table structure, and sorts it based on APIC ID.
+
+  @retval EFI_SUCCESS   Local APIC information was successfully sorted.
+**/
+EFI_STATUS
+SortCpuLocalApicInTable (
+  VOID
+  )
+{
+  EFI_STATUS                                Status;
+  EFI_PROCESSOR_INFORMATION                 ProcessorInfoBuffer;
+  UINTN                                     BufferSize;
+  UINT32                                    Index;
+  UINT32                                    Socket;
+  UINT32                                    CurrProcessor;
+  CPU_ID_ORDER_MAP                          *CpuIdMapPtr;
+  UINT32                                    CoreThreadMask;
+  UINT32                                    CoreThreadCount;
+  UINT32                                    BspApicId;
+  UINT32                                    LowestApicId;
+  UINT32                                    CurrentIndex;
+  UINT32                                    TargetIndex;
+  CPU_ID_ORDER_MAP                          TempEntry;
+  BOOLEAN                                   SecondThreadExistent;
+
+  BufferSize = 0;
+  Index      = 0;
+  Status     = EFI_SUCCESS;
+
+  CoreThreadMask = (UINT32) ((1 << mNumOfBitShift) - 1);
+  CoreThreadCount = 0;
+
+  if (!mCpuOrderSorted) {
+    //
+    // Init ProcessorBitMask table and EnabledProcessor table
+    //
+    for (Index = 0; Index < MAX_SOCKET; Index++) {
+      mAcpiParameter->ProcessorBitMask[Index] = 0;
+      mAcpiParameter->ProcessorBitMaskHi[Index] = 0;
+      mEnabledProcessor[Index] = 0;
+      mCpuPCPSInfo[Index] = 0;
+    }
+
+    Index  = 0;
+    SecondThreadExistent = FALSE;
+    for (CurrProcessor = 0; CurrProcessor < mNumberOfCPUs; CurrProcessor++) {
+      Status = mMpService->GetProcessorInfo (
+        mMpService,
+        CurrProcessor,
+        &ProcessorInfoBuffer
+        );
+      ASSERT_EFI_ERROR (Status);
+      if (EFI_ERROR (Status)) {
+        continue;
+      }
+
+
+      if (ProcessorInfoBuffer.ProcessorId & 1) {  // secondary thread
+        CpuIdMapPtr = &mCpuApicIdOrderTable[(Index - 1) + MAX_CPU_NUM / 2];
+        SecondThreadExistent= TRUE;
+      } else {                                    // primary thread
+        CpuIdMapPtr = &mCpuApicIdOrderTable[Index];
+        Index++;
+      }
+
+      CpuIdMapPtr->ApicId  = (UINT32) ProcessorInfoBuffer.ProcessorId;
+      CpuIdMapPtr->Flags   = ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0);
+      CpuIdMapPtr->SocketNum = (UINT32) ProcessorInfoBuffer.Location.Package;
+      CpuIdMapPtr->AcpiProcessorId = (CpuIdMapPtr->SocketNum << mNumOfBitShift) + mThreadCount[CpuIdMapPtr->SocketNum];
+
+      mThreadCount[CpuIdMapPtr->SocketNum]++;
+
+      if (CpuIdMapPtr->Flags == 1) {
+        //
+        // Update EnabledProcessor table
+        //
+        mEnabledProcessor[CpuIdMapPtr->SocketNum]++;
+        mCpuPCPSInfo[CpuIdMapPtr->SocketNum]++; // count enabled processor in current socket
+
+        //
+        // Update processorbitMask
+        //
+        if (ProcessorInfoBuffer.Location.Core < 64) {
+          mAcpiParameter->ProcessorBitMask[CpuIdMapPtr->SocketNum] |=
+            LShiftU64 (1, ProcessorInfoBuffer.Location.Core);
+        } else {
+          mAcpiParameter->ProcessorBitMaskHi[CpuIdMapPtr->SocketNum] |=
+            LShiftU64 (1, ProcessorInfoBuffer.Location.Core - 64);
+        }
+
+        if (ProcessorInfoBuffer.Location.Thread >= CoreThreadCount) {
+          CoreThreadCount = ProcessorInfoBuffer.Location.Thread + 1;
+        }
+      }
+    } //end for CurrentProcessor
+
+    DEBUG ((
+      DEBUG_INFO,
+      "::ACPI::  APIC ID Order Table Init.   CoreThreadMask = 0x%x,   mNumOfBitShift = %d,   CoreThreadCount = %d\n",
+      CoreThreadMask,
+      mNumOfBitShift,
+      CoreThreadCount
+      ));
+
+    DEBUG ((DEBUG_INFO, "::ACPI::  Socket  ProcessorBitMaskHi ProcessorBitMask   ProcessorApicIdBase\n"));
+    for (Index = 0; Index < MAX_SOCKET; Index++) {
+      DEBUG ((
+        DEBUG_INFO,
+        "::ACPI::    %d     0x%016lx %016lx          0x%x\n",
+        Index,
+        mAcpiParameter->ProcessorBitMaskHi[Index],
+        mAcpiParameter->ProcessorBitMask[Index],
+        mAcpiParameter->ProcessorApicIdBase[Index]
+        ));
+    }
+    AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 1, NULL, NULL, NULL, &BspApicId);
+
+    if (mCpuApicIdOrderTable[0].ApicId != BspApicId) {
+      //
+      // check to see if 1st entry is BSP, if not swap it
+      //
+      CurrentIndex = ApicId2OrderTableIndex (BspApicId);
+
+      if (CurrentIndex >= MAX_CPU_NUM) {
+        DEBUG ((DEBUG_ERROR, "BSP index is out of range\n"));
+        ASSERT (CurrentIndex < MAX_CPU_NUM);
+      } else {
+        LowestApicId = mCpuApicIdOrderTable[0].ApicId;
+        TargetIndex = 0;
+        CopyMem (&TempEntry, &mCpuApicIdOrderTable[CurrentIndex], sizeof(TempEntry));
+        CopyMem (&mCpuApicIdOrderTable[CurrentIndex], &mCpuApicIdOrderTable[TargetIndex], sizeof(TempEntry));
+        CopyMem (&mCpuApicIdOrderTable[TargetIndex], &TempEntry, sizeof(TempEntry));
+
+        if (SecondThreadExistent) {
+          //
+          // Also swap BSP's companion thread (the second thread in same core of BSP)
+          //
+          CurrentIndex = ApicId2OrderTableIndex (BspApicId + 1);
+          TargetIndex = ApicId2OrderTableIndex (LowestApicId + 1);
+          if ((CurrentIndex < MAX_CPU_NUM) && (TargetIndex < MAX_CPU_NUM)) {
+            CopyMem (&TempEntry, &mCpuApicIdOrderTable[CurrentIndex], sizeof(TempEntry));
+            CopyMem (&mCpuApicIdOrderTable[CurrentIndex], &mCpuApicIdOrderTable[TargetIndex], sizeof(TempEntry));
+            CopyMem (&mCpuApicIdOrderTable[TargetIndex], &TempEntry, sizeof(TempEntry));
+          }
+        }
+      }
+    }
+
+    //
+    // Make sure no holes between enabled threads
+    //
+    for (CurrProcessor = 0; CurrProcessor < MAX_CPU_NUM; CurrProcessor++) {
+
+      if (mCpuApicIdOrderTable[CurrProcessor].Flags == 0) {
+        //
+        // make sure disabled entry has ProcId set to FFs
+        //
+        mCpuApicIdOrderTable[CurrProcessor].ApicId = (UINT32) -1;
+        mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId = (UINT32) -1;
+
+        for (Index = CurrProcessor + 1; Index < MAX_CPU_NUM; Index++) {
+          if (mCpuApicIdOrderTable[Index].Flags == 1) {
+            //
+            // move enabled entry up
+            //
+            mCpuApicIdOrderTable[CurrProcessor].Flags = 1;
+            mCpuApicIdOrderTable[CurrProcessor].ApicId = mCpuApicIdOrderTable[Index].ApicId;
+            mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId = mCpuApicIdOrderTable[Index].AcpiProcessorId;
+            mCpuApicIdOrderTable[CurrProcessor].SocketNum = mCpuApicIdOrderTable[Index].SocketNum;
+            //
+            // disable moved entry
+            //
+            mCpuApicIdOrderTable[Index].Flags = 0;
+            mCpuApicIdOrderTable[Index].ApicId = (UINT32) -1;
+            mCpuApicIdOrderTable[Index].AcpiProcessorId = (UINT32) -1;
+            break;
+          }
+        }
+      }
+    }
+
+    //
+    // keep for debug purpose
+    //
+    DEBUG ((DEBUG_INFO, "APIC ID Order Table ReOrdered\n"));
+    DebugDisplayReOrderTable ();
+
+    //
+    // Re-sort AcpiProcessorId for all sockets
+    //
+    for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+      Index  = 0;
+
+      for (CurrProcessor = 0; CurrProcessor < MAX_CPU_NUM; CurrProcessor++) {
+        if (mCpuApicIdOrderTable[CurrProcessor].Flags && (mCpuApicIdOrderTable[CurrProcessor].SocketNum == Socket)) {
+          //
+          // re-assign AcpiProcessorId to match MADT (socket, thread)
+          //
+          mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId = (Socket << mNumOfBitShift) + Index;
+          Index++;
+        }
+      }
+    }
+
+    //
+    // keep for debug purpose
+    //
+    DEBUG ((DEBUG_INFO, "APIC ID Ord Tbl ReOrd aft Re-sort AcpiProcessorId\n"));
+    DebugDisplayReOrderTable ();
+
+    //
+    // Update mApicIdMap according the final mCpuApicIdOrderTable
+    //
+    UpdateApicIdMap ();
+
+    for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+    for (Index=0; Index < (MAX_THREAD * MAX_CORE); Index++) {
+        if (mApicIdMap[Socket][Index] != (UINT32) -1) {
+          DEBUG ((DEBUG_INFO, "mApicIdMap[%d][%d] = 0x%x\n", Socket, Index, mApicIdMap[Socket][Index]));
+        }
+      }
+    }
+
+    //
+    // Initialize with safe defaults
+    //
+    for(CurrProcessor = 0; CurrProcessor < MAX_CPU_NUM; CurrProcessor++) {
+      mCpuThreadIdMsrTable[CurrProcessor].ApicId = (UINT32)-1;
+      mCpuThreadIdMsrTable[CurrProcessor].ThreadIdValue = 0xFF;
+      mCpuThreadIdMsrTable[CurrProcessor].CollocatedChaId = 0xFF;
+      mCpuThreadIdMsrTable[CurrProcessor].SNCProximityDomain = 0;
+    }
+    //
+    // Collect MSR 53 value and ApicId for each thread
+    //
+    mMpService->StartupAllAPs (mMpService, (EFI_AP_PROCEDURE)GetThreadIdMsrValue, FALSE, NULL, 0, NULL, NULL);
+    GetThreadIdMsrValue ();
+
+    mCpuOrderSorted = TRUE;
+  }
+
+  return Status;
+}
+
+/**
+  Build from scratch and install the MADT.
+
+  @retval EFI_SUCCESS           The MADT was installed successfully.
+  @retval EFI_OUT_OF_RESOURCES  Could not allocate required structures.
+**/
+EFI_STATUS
+InstallMadtFromScratch (
+  VOID
+  )
+{
+  EFI_STATUS                                          Status;
+  UINTN                                               Index;
+  EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *NewMadtTable;
+  UINTN                                               TableHandle;
+  EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER MadtTableHeader;
+  EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_STRUCTURE         ProcLocalApicStruct;
+  EFI_ACPI_6_2_IO_APIC_STRUCTURE                      IoApicStruct;
+  EFI_ACPI_6_2_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE    IntSrcOverrideStruct;
+  EFI_ACPI_6_2_LOCAL_APIC_NMI_STRUCTURE               LocalApciNmiStruct;
+  EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_STRUCTURE       ProcLocalX2ApicStruct;
+  EFI_ACPI_6_2_LOCAL_X2APIC_NMI_STRUCTURE             LocalX2ApicNmiStruct;
+  STRUCTURE_HEADER                                    **MadtStructs;
+  UINTN                                               MaxMadtStructCount;
+  UINTN                                               MadtStructsIndex;
+
+  NewMadtTable = NULL;
+
+  MaxMadtStructCount = (UINT32) (
+    MAX_CPU_NUM +         // processor local APIC structures
+    MAX_CPU_NUM +         // processor local x2APIC structures
+    MAX_IO_APICS_10NM +   // IOAPIC structures
+    2 +                   // interrupt source override structures
+    1 +                   // local APIC NMI structures
+    1                     // local x2APIC NMI structures
+  );                      // other structures are not used
+
+  MadtStructs = (STRUCTURE_HEADER **) AllocateZeroPool (MaxMadtStructCount * sizeof (STRUCTURE_HEADER *));
+  if (MadtStructs == NULL) {
+    DEBUG ((DEBUG_ERROR, "[ACPI](MADT) Could not allocate MADT structure pointer array\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Initialize the next index into the structure pointer array. It is
+  // incremented every time a structure of any type is copied to the array.
+  //
+  MadtStructsIndex = 0;
+
+  //
+  // Initialize MADT Header Structure
+  //
+  Status = InitializeMadtHeader (&MadtTableHeader);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[ACPI](MADT) InitializeMadtHeader failed: %r\n", Status));
+    goto Done;
+  }
+
+  DEBUG ((DEBUG_INFO, "[ACPI](MADT) Number of CPUs detected = %d \n", mNumberOfCPUs));
+
+  //
+  // Build Processor Local APIC Structures and Processor Local X2APIC Structures
+  //
+  ProcLocalApicStruct.Type = EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC;
+  ProcLocalApicStruct.Length = sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_STRUCTURE);
+
+  ProcLocalX2ApicStruct.Type = EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC;
+  ProcLocalX2ApicStruct.Length = sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_STRUCTURE);
+  ProcLocalX2ApicStruct.Reserved[0] = 0;
+  ProcLocalX2ApicStruct.Reserved[1] = 0;
+
+  for (Index = 0; Index < mNumberOfCPUs; Index++) {
+    //
+    // If x2APIC mode is not enabled, and if it is possible to express the
+    // APIC ID as a UINT8, use a processor local APIC structure. Otherwise,
+    // use a processor local x2APIC structure.
+    //
+    if (!mX2ApicEnabled && mCpuApicIdOrderTable[Index].ApicId < MAX_UINT8) {
+      ProcLocalApicStruct.Flags           = (UINT8) mCpuApicIdOrderTable[Index].Flags;
+      ProcLocalApicStruct.ApicId          = (UINT8) mCpuApicIdOrderTable[Index].ApicId;
+      ProcLocalApicStruct.AcpiProcessorUid = (UINT8) mCpuApicIdOrderTable[Index].AcpiProcessorId;
+
+      ASSERT (MadtStructsIndex < MaxMadtStructCount);
+      Status = CopyStructure (
+        &MadtTableHeader.Header,
+        (STRUCTURE_HEADER *) &ProcLocalApicStruct,
+        &MadtStructs[MadtStructsIndex++]
+        );
+    } else {
+      ProcLocalX2ApicStruct.Flags            = (UINT8) mCpuApicIdOrderTable[Index].Flags;
+      ProcLocalX2ApicStruct.X2ApicId         = mCpuApicIdOrderTable[Index].ApicId;
+      ProcLocalX2ApicStruct.AcpiProcessorUid = mCpuApicIdOrderTable[Index].AcpiProcessorId;
+
+      ASSERT (MadtStructsIndex < MaxMadtStructCount);
+      Status = CopyStructure (
+        &MadtTableHeader.Header,
+        (STRUCTURE_HEADER *) &ProcLocalX2ApicStruct,
+        &MadtStructs[MadtStructsIndex++]
+        );
+    }
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "[ACPI](MADT) CopyMadtStructure (local APIC/x2APIC) failed: %r\n", Status));
+      goto Done;
+    }
+  }
+
+  //
+  // Build IOAPIC Structures
+  //
+  if (mIioUds == NULL) {
+    Status = gBS->LocateProtocol (&gEfiIioUdsProtocolGuid,NULL,&mIioUds);
+    ASSERT_EFI_ERROR (Status);
+    if (EFI_ERROR (Status)) {
+      goto Done;
+    }
+  }
+
+  IoApicStruct.Type = EFI_ACPI_6_2_IO_APIC;
+  IoApicStruct.Length = sizeof (EFI_ACPI_6_2_IO_APIC_STRUCTURE);
+  IoApicStruct.Reserved = 0;
+  IoApicStruct.IoApicId = PCH_IOAPIC_ID;
+  IoApicStruct.IoApicAddress =  mIioUds->IioUdsPtr->PlatformData.IIO_resource[0].StackRes[0].IoApicBase;
+  IoApicStruct.GlobalSystemInterruptBase = PCH_INTERRUPT_BASE;
+  ASSERT (MadtStructsIndex < MaxMadtStructCount);
+  Status = CopyStructure (
+    &MadtTableHeader.Header,
+    (STRUCTURE_HEADER *) &IoApicStruct,
+    &MadtStructs[MadtStructsIndex++]
+    );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[ACPI](MADT) CopyMadtStructure (IOAPIC) failed: %r\n", Status));
+    goto Done;
+  }
+  DEBUG ((DEBUG_INFO, "[ACPI](MADT) Add IOAPIC id %d, addr 0x%x, Interrupt base %d for PCH\n", IoApicStruct.IoApicId, IoApicStruct.IoApicAddress, IoApicStruct.GlobalSystemInterruptBase));
+
+  //
+  // Build Interrupt Source Override Structures
+  //
+  IntSrcOverrideStruct.Type = EFI_ACPI_6_2_INTERRUPT_SOURCE_OVERRIDE;
+  IntSrcOverrideStruct.Length = sizeof (EFI_ACPI_6_2_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE);
+
+  //
+  // IRQ0=>IRQ2 Interrupt Source Override Structure
+  //
+  IntSrcOverrideStruct.Bus = 0x0;                   // Bus - ISA
+  IntSrcOverrideStruct.Source = 0x0;                // Source - IRQ0
+  IntSrcOverrideStruct.GlobalSystemInterrupt = 0x2; // Global System Interrupt - IRQ2
+  IntSrcOverrideStruct.Flags = 0x0;                 // Flags - Conforms to specifications of the bus
+
+  ASSERT (MadtStructsIndex < MaxMadtStructCount);
+  Status = CopyStructure (
+    &MadtTableHeader.Header,
+    (STRUCTURE_HEADER *) &IntSrcOverrideStruct,
+    &MadtStructs[MadtStructsIndex++]
+    );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[ACPI](MADT) CopyMadtStructure (IRQ2 source override) failed: %r\n", Status));
+    goto Done;
+  }
+
+  //
+  // IRQ9 (SCI Active High) Interrupt Source Override Structure
+  //
+  IntSrcOverrideStruct.Bus = 0x0;                   // Bus - ISA
+  IntSrcOverrideStruct.Source = 0x9;                // Source - IRQ9
+  IntSrcOverrideStruct.GlobalSystemInterrupt = 0x9; // Global System Interrupt - IRQ9
+  IntSrcOverrideStruct.Flags = 0xD;                 // Flags - Level-tiggered, Active High
+
+  ASSERT (MadtStructsIndex < MaxMadtStructCount);
+  Status = CopyStructure (
+    &MadtTableHeader.Header,
+    (STRUCTURE_HEADER *) &IntSrcOverrideStruct,
+    &MadtStructs[MadtStructsIndex++]
+    );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[ACPI](MADT) CopyMadtStructure (IRQ9 source override) failed: %r\n", Status));
+    goto Done;
+  }
+
+  //
+  // Build Local APIC NMI Structures
+  //
+  LocalApciNmiStruct.Type   = EFI_ACPI_6_2_LOCAL_APIC_NMI;
+  LocalApciNmiStruct.Length = sizeof (EFI_ACPI_6_2_LOCAL_APIC_NMI_STRUCTURE);
+  LocalApciNmiStruct.AcpiProcessorUid = 0xFF;      // Applies to all processors
+  LocalApciNmiStruct.Flags  = POLARITY_ACTIVE_HIGH | TRIGGERMODE_EDGE; // Flags - Edge-tiggered, Active High
+  LocalApciNmiStruct.LocalApicLint   = 0x1;
+
+  ASSERT (MadtStructsIndex < MaxMadtStructCount);
+  Status = CopyStructure (
+    &MadtTableHeader.Header,
+    (STRUCTURE_HEADER *) &LocalApciNmiStruct,
+    &MadtStructs[MadtStructsIndex++]
+    );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[ACPI](MADT) CopyMadtStructure (APIC NMI) failed: %r\n", Status));
+    goto Done;
+  }
+
+  //
+  // Build Local x2APIC NMI Structure
+  //
+  LocalX2ApicNmiStruct.Type   = EFI_ACPI_6_2_LOCAL_X2APIC_NMI;
+  LocalX2ApicNmiStruct.Length = sizeof (EFI_ACPI_6_2_LOCAL_X2APIC_NMI_STRUCTURE);
+  LocalX2ApicNmiStruct.Flags  = POLARITY_ACTIVE_HIGH | TRIGGERMODE_EDGE; // Flags - Edge-tiggered, Active High
+  LocalX2ApicNmiStruct.AcpiProcessorUid = 0xFFFFFFFF;  // Applies to all processors
+  LocalX2ApicNmiStruct.LocalX2ApicLint  = 0x01;
+  LocalX2ApicNmiStruct.Reserved[0] = 0x00;
+  LocalX2ApicNmiStruct.Reserved[1] = 0x00;
+  LocalX2ApicNmiStruct.Reserved[2] = 0x00;
+
+  ASSERT (MadtStructsIndex < MaxMadtStructCount);
+  Status = CopyStructure (
+    &MadtTableHeader.Header,
+    (STRUCTURE_HEADER *) &LocalX2ApicNmiStruct,
+    &MadtStructs[MadtStructsIndex++]
+    );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[ACPI](MADT) CopyMadtStructure (x2APIC NMI) failed: %r\n", Status));
+    goto Done;
+  }
+
+  //
+  // Build Madt Structure from the Madt Header and collection of pointers in MadtStructs[]
+  //
+  Status = BuildAcpiTable (
+    (EFI_ACPI_DESCRIPTION_HEADER *) &MadtTableHeader,
+    sizeof (EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER),
+    MadtStructs,
+    MadtStructsIndex,
+    (UINT8 **)&NewMadtTable
+    );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[ACPI](MADT) BuildAcpiTable failed: %r\n", Status));
+    goto Done;
+  }
+
+  //
+  // Publish Madt Structure to ACPI
+  //
+  Status = mAcpiTable->InstallAcpiTable (
+    mAcpiTable,
+    NewMadtTable,
+    NewMadtTable->Header.Length,
+    &TableHandle
+    );
+
+Done:
+  //
+  // Free memory
+  //
+  for (MadtStructsIndex = 0; MadtStructsIndex < MaxMadtStructCount; MadtStructsIndex++) {
+    if (MadtStructs[MadtStructsIndex] != NULL) {
+      FreePool (MadtStructs[MadtStructsIndex]);
+    }
+  }
+
+  FreePool (MadtStructs);
+
+  if (NewMadtTable != NULL) {
+    FreePool (NewMadtTable);
+  }
+
+  return Status;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibBdat.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibBdat.c
new file mode 100644
index 0000000000..09464b4a11
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibBdat.c
@@ -0,0 +1,1574 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatformLibLocal.h"
+#include <Library/CrcLib.h>
+#include <BdatSchema.h>
+#include <Guid/MemoryMapData.h>
+#include <Library/CompressedVariableLib.h>
+#include <Protocol/DynamicSiLibraryProtocol2.h>
+#include <Protocol/DynamicSiLibraryProtocol2.h>
+
+extern struct SystemMemoryMapHob   *mSystemMemoryMap;
+extern EFI_IIO_UDS_PROTOCOL        *mIioUds;
+
+#include <Acpi/Bdat.h>
+
+#ifndef MAX_HOB_ENTRY_SIZE
+#define MAX_HOB_ENTRY_SIZE  60*1024
+#endif
+
+/**
+  Save BSSA results to BDAT
+
+  @param[in,out]   BdatHeaderStructPtr - Pointer to BDAT Structure
+  @param[in]       OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
+  @param[in]       SchemaStartAddress  - Starting address where the BSSA result schema will be added
+  @param[in, out]  SchemaIndex         - Current schema index inside the BDAT. Need it to update the schema offsets array.
+  @param[in]       SchemaSize          - The size of the BSSA results schema.
+  @param[out]      SchemaSpaceUsed     - The numebr bytes were filled in all schema
+  @param[out]      LastSchemaSpaceUsed - The numebr bytes were filled in the last schema
+
+  @retval EFI_SUCCESS  - BSSA BDAT scehma created successfully
+  @retval !EFI_SUCCESS - BSSA BDAT scehma creation failed
+**/
+EFI_STATUS
+SaveBssaResultsToBdat (
+  IN OUT BDAT_STRUCTURE          *BdatHeaderStructPtr,
+  IN     UINT32                  OffsetFromLastSchema,
+  IN     EFI_PHYSICAL_ADDRESS    *SchemaStartAddress,
+  IN OUT UINT8                   *SchemaIndex,
+  IN     UINT32                  SchemaSize,
+  OUT    UINT32                  *SchemaSpaceUsed,
+  OUT    UINT32                  *LastSchemaSpaceUsed
+  );
+
+/**
+  Save EWL results to BDAT
+
+  @param[in,out]   BdatHeaderStructPtr - Pointer to BDAT Structure
+  @param[in]       OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
+  @param[in]       SchemaStartAddress  - Starting address where the EWL schema will be added
+  @param[in, out]  SchemaIndex         - Current schema index inside the BDAT. Need it to update the schema offsets array.
+  @param[out]      SchemaSpaceUsed     - The numebr bytes were filled
+
+  @retval EFI_SUCCESS  - EWL BDAT scehma created successfully
+  @retval !EFI_SUCCESS - EWL BDAT scehma creation failed
+**/
+EFI_STATUS
+SaveEwlToBdat (
+  IN OUT BDAT_STRUCTURE          *BdatHeaderStructPtr,
+  IN     UINT32                  OffsetFromLastSchema,
+  IN     EFI_PHYSICAL_ADDRESS    *SchemaStartAddress,
+  IN OUT UINT8                   *SchemaIndex,
+  OUT    UINT32                  *SchemaSpaceUsed
+  );
+
+/**
+  Save SPD date structure to BDAT
+
+  @param[in,out]   BdatHeaderStructPtr - Pointer to BDAT Structure
+  @param[in]       OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
+  @param[in]       SchemaStartAddress  - Starting address where the SPD data schema will be added
+  @param[in, out]  SchemaIndex         - Current schema index inside the BDAT. Need it to update the schema offsets array.
+  @param[out]      SchemaSpaceUsed     - The numebr bytes were filled
+
+  @retval EFI_SUCCESS  - SPD BDAT scehma created successfully
+  @retval !EFI_SUCCESS - SPD BDAT scehma creation failed
+**/
+EFI_STATUS
+SaveSpdToBdat (
+  IN OUT BDAT_STRUCTURE          *BdatHeaderStructPtr,
+  IN     UINT32                  OffsetFromLastSchema,
+  IN     EFI_PHYSICAL_ADDRESS    *SchemaStartAddress,
+  IN OUT UINT8                   *SchemaIndex,
+  OUT    UINT32                  *SchemaSpaceUsed
+  );
+
+/**
+  Save memory training date structure to BDAT
+
+  @param[in,out]   BdatHeaderStructPtr - Pointer to BDAT Structure
+  @param[in]       OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
+  @param[in]       SchemaStartAddress  - Starting address where the memory training data schema will be added
+  @param[in, out]  SchemaIndex         - Current schema index inside the BDAT. Need it to update the schema offsets array.
+  @param[out]      SchemaSpaceUsed     - The numebr bytes were filled
+
+  @retval EFI_SUCCESS  - Memory training data BDAT scehma created successfully
+  @retval !EFI_SUCCESS - Memory training data BDAT scehma creation failed
+**/
+EFI_STATUS
+SaveTrainingDataToBdat (
+  IN OUT BDAT_STRUCTURE          *BdatHeaderStructPtr,
+  IN     UINT32                  OffsetFromLastSchema,
+  IN     EFI_PHYSICAL_ADDRESS    *SchemaStartAddress,
+  IN OUT UINT8                   *SchemaIndex,
+  OUT    UINT32                  *SchemaSpaceUsed
+  );
+
+/**
+  Get the size of SPD data structure not include the SPD BDAT schema header.
+
+  @retval UINT32 - Size of SPD data structure in bytes
+**/
+UINT32
+GetSpdDataSize (
+  VOID
+  );
+
+/**
+  Read the SPD data for one dimm and fill up SPD entry inside SPD BDAT schema space.
+
+  @param[out] Address           - Start Address of the buffer where the SPD entry to be filled
+  @param[in]  Socket            - Socket number
+  @param[in]  Channel           - Channel number inside the Socket
+  @param[in]  Dimm              - Dimm slot number
+  @param[in]  MaxSpdByteOffset  - The max SPD byte offset. DDR4 is 512
+
+  @retval EFI_SUCCESS  - SPD Structure filled successfully
+  @retval !EFI_SUCCESS - SPD structure creation failed
+**/
+EFI_STATUS
+FillSpdPerDimmEntry (
+  OUT EFI_PHYSICAL_ADDRESS    Address,
+  IN UINT8                    Socket,
+  IN UINT8                    Channel,
+  IN UINT8                    Dimm,
+  IN UINT16                   MaxSpdByteOffset
+  );
+
+/**
+  Fill the SPD data structure inside the BDAT schema space.
+
+  @param[out] StartAddress           - Start Address of the buffer where SPD data structure to be filled
+  @param[in]  SpdDataSize            - Size of SPD data structure includes the header
+
+  @retval EFI_SUCCESS  - SPD Structure filled successfully
+  @retval !EFI_SUCCESS - SPD structure creation failed
+**/
+EFI_STATUS
+FillSpdSchema (
+  OUT EFI_PHYSICAL_ADDRESS    StartAddress,
+  IN UINT32                   SpdDataSize
+  );
+
+/**
+  Displays SPD content for debugging.
+
+  @param[in] Address  - The starting address of the SPD entry
+
+  @retval N/A
+**/
+VOID
+DisplaySpdContents (
+  IN EFI_PHYSICAL_ADDRESS  Address
+  );
+
+/**
+  Get Number of Schemas From BSSA HOB
+
+  @retval UINT16 - Number of BSSA Schemas
+**/
+UINT16
+GetNumberOfSchemasFromBssaHob (
+  VOID
+  )
+{
+  UINT32                          GuidIdx = 0;
+  UINT16                          NumberOfBssaSchemas = 0;
+  EFI_STATUS                      Status = EFI_SUCCESS;
+  DYNAMIC_SI_LIBARY_PROTOCOL      *DynamicSiLibraryProtocol = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &DynamicSiLibraryProtocol);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return 0;
+  }
+
+  if (mSystemMemoryMap == NULL) {
+    mSystemMemoryMap = DynamicSiLibraryProtocol->GetSystemMemoryMapData ();
+  }
+
+  ASSERT (mSystemMemoryMap != NULL);
+  if (mSystemMemoryMap == NULL) {
+    return 0;
+  }
+
+  for (GuidIdx = 0; GuidIdx < mSystemMemoryMap->Reserved9; GuidIdx++) {
+    //
+    // No. of HOBS per GUID added up for all GUIDs created from calls to saveToBdat ()
+    //
+    NumberOfBssaSchemas += mSystemMemoryMap->Reserved7[GuidIdx];
+    DEBUG ((DEBUG_VERBOSE, "GuidIdx = %d, total num hobs: %d\n", GuidIdx,  mSystemMemoryMap->Reserved7[GuidIdx]));
+  }
+  return NumberOfBssaSchemas;
+}
+
+/**
+  Create BDAT Header with necessary information.
+  Allocate memory with BdatSize and if failure return status.
+  If Success return the pointer address for copying the schema information
+
+  @param[out] BdatHeaderStructPtr - Pointer to BDAT Structure
+  @param[in]  BdatSize            - Size of BDAT Structure
+  @param[in]  NumberOfSchema      - Total nunber of of schema
+
+  @retval EFI_SUCCESS  - BDAT Structure created successfully
+  @retval !EFI_SUCCESS - BDAT structure creation failed
+**/
+EFI_STATUS
+CreateBdatHeader (
+  OUT BDAT_STRUCTURE **BdatHeaderStructPtr,
+  IN UINT32          BdatSize,
+  IN UINT16          NumberOfSchema
+  )
+{
+  EFI_TIME                      EfiTime;
+  UINT64                        Address = 0xffffffff;
+  EFI_STATUS                    Status = EFI_SUCCESS;
+
+  //
+  // Allocating RealTime Memory for BDAT.
+  //
+
+  Status = gBS->AllocatePages (
+    AllocateMaxAddress,
+    EfiACPIMemoryNVS,
+    EFI_SIZE_TO_PAGES(BdatSize),
+    &Address
+  );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // The memory location where the HOB's are to be copied to
+  //
+  ZeroMem ((VOID *)Address, BdatSize);
+
+  *BdatHeaderStructPtr = (BDAT_STRUCTURE *)Address;
+
+  DEBUG ((DEBUG_VERBOSE, "\nBDAT Allocated Address = %x\n", Address));
+
+  //
+  // Create BIOS Data Signature
+  //
+  (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[0] = 'B';
+  (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[1] = 'D';
+  (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[2] = 'A';
+  (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[3] = 'T';
+  (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[4] = 'H';
+  (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[5] = 'E';
+  (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[6] = 'A';
+  (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[7] = 'D';
+  //
+  // Structure size
+  //
+  (*BdatHeaderStructPtr)->BdatHeader.BiosDataStructSize = BdatSize;
+  //
+  // Primary Version
+  //
+  (*BdatHeaderStructPtr)->BdatHeader.PrimaryVersion = BDAT_PRIMARY_VER;
+  //
+  // Secondary Version
+  //
+  (*BdatHeaderStructPtr)->BdatHeader.SecondaryVersion = BDAT_SECONDARY_VER;
+  //
+  // CRC16 value of the BDAT_STRUCTURE
+  //
+  (*BdatHeaderStructPtr)->BdatHeader.Crc16 = 0;
+  Status = CalculateCrc16 (
+    (VOID *)(*BdatHeaderStructPtr),
+    BdatSize,
+    &(*BdatHeaderStructPtr)->BdatHeader.Crc16
+  );
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    (*BdatHeaderStructPtr)->BdatHeader.Crc16 = 0xFFFF;
+  }
+  (*BdatHeaderStructPtr)->BdatSchemas.SchemaListLength = NumberOfSchema;
+  (*BdatHeaderStructPtr)->BdatSchemas.Reserved = 0;
+  (*BdatHeaderStructPtr)->BdatSchemas.Reserved1 = 0;
+  //
+  // Initialize the Time parameters in the SCHEMA_LIST_STRUCTURE
+  //
+  Status = gRT->GetTime (&EfiTime, NULL);
+  if (!EFI_ERROR (Status)) {
+    (*BdatHeaderStructPtr)->BdatSchemas.Year = EfiTime.Year;
+    (*BdatHeaderStructPtr)->BdatSchemas.Month = EfiTime.Month;
+    (*BdatHeaderStructPtr)->BdatSchemas.Day = EfiTime.Day;
+    (*BdatHeaderStructPtr)->BdatSchemas.Hour = EfiTime.Hour;
+    (*BdatHeaderStructPtr)->BdatSchemas.Minute = EfiTime.Minute;
+    (*BdatHeaderStructPtr)->BdatSchemas.Second = EfiTime.Second;
+  }
+  return Status;
+}
+
+/**
+  Dump BDAT Table to serial log
+
+  Example 1: There are 2 schema: BSSA RMT and EWL.
+
+  Print BDAT Table
+  Address     0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
+  00000000 0x42 0x44 0x41 0x54 0x48 0x45 0x41 0x44 0x30 0x18 0x00 0x00 0xD7 0x7A 0x00 0x00
+  00000010 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+  00000020 0x02 0x00 0x00 0x00 0xE4 0x07 0x08 0x0E 0x00 0x29 0x03 0x00 0x34 0x00 0x00 0x00
+  00000030 0xFA 0x07 0x00 0x00 0x28 0xE9 0xF4 0x08 0x5F 0x0F 0xD4 0x46 0x84 0x10 0x47 0x9F
+  00000040 0xDA 0x27 0x9D 0xB6 0xC6 0x07 0x00 0x00 0x57 0x7F 0x00 0x00 0x00 0x00 0x00 0xA5
+  00000050 0x98 0x88 0xFE 0x4C 0x00 0x00 0x00 0x0D 0xEB 0x7A 0x47 0x07 0xDE 0x77 0x42 0xA4
+  00000060 0xE7 0x87 0x81 0x0B 0x10 0x00 0x31 0xF1 0x98 0x88 0xFE 0xF2 0x45 0x81 0xD9 0xF4
+  ...
+  ...
+  000007F0 0x00 0x00 0x00 0x5A 0xA5 0x5A 0xA5 0x5A 0xA5 0x5A 0x2F 0x53 0xFE 0xBF 0x3B 0xCA
+  00000800 0x6C 0x41 0xA0 0xF6 0xFF 0xE4 0xE7 0x1E 0x3A 0x0D 0x36 0x10 0x00 0x00 0x9F 0xEF
+  00000810 0x70 0x33 0x71 0x75 0x05 0x38 0xB0 0x46 0x9F 0xED 0x60 0xF2 0x82 0x48 0x6C 0xFC
+  00000820 0x20 0x10 0x00 0x00 0x12 0x00 0x00 0x00 0x2E 0x81 0x50 0x51 0x00 0x00 0x00 0x00
+  00000830 0x01 0x00 0x00 0x00 0x12 0x00 0x01 0x00 0x00 0x00 0x7E 0x07 0x17 0x18 0x01 0xFF
+  00000840 0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+
+  Example 2: There is 1 schema: EWL
+  Address     0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
+  00000000 0x42 0x44 0x41 0x54 0x48 0x45 0x41 0x44 0x66 0x10 0x00 0x00 0xA9 0x44 0x00 0x00
+  00000010 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+  00000020 0x01 0x00 0x00 0x00 0xE4 0x07 0x08 0x0E 0x01 0x0F 0x2C 0x00 0x30 0x00 0x00 0x00
+  00000030 0x2F 0x53 0xFE 0xBF 0x3B 0xCA 0x6C 0x41 0xA0 0xF6 0xFF 0xE4 0xE7 0x1E 0x3A 0x0D
+  00000040 0x36 0x10 0x00 0x00 0x9F 0xEF 0x70 0x33 0x71 0x75 0x05 0x38 0xB0 0x46 0x9F 0xED
+  00000050 0x60 0xF2 0x82 0x48 0x6C 0xFC 0x20 0x10 0x00 0x00 0x12 0x00 0x00 0x00 0x2E 0x81
+  00000060 0x50 0x51 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x12 0x00 0x01 0x00 0x00 0x00
+  00000070 0x7E 0x07 0x17 0x18 0x01 0xFF 0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+  00000080 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+
+  @param[out] BdatHeaderStructPtr - Pointer to BDAT Structure
+  @param[in]  BdatSize            - Size of BDAT Structure
+
+  @retval None
+**/
+VOID
+DumpBdatTable(
+  IN BDAT_STRUCTURE **BdatHeaderStructPtr,
+  IN UINT32 BdatSize
+)
+{
+  UINT32  i = 0;
+  UINT8   *Table = NULL;
+
+  Table = (UINT8 *)(*BdatHeaderStructPtr);
+  DEBUG ((DEBUG_VERBOSE, "\nPrint BDAT Table\n"));
+
+  //
+  // Print address header
+  //
+  DEBUG ((DEBUG_VERBOSE, "Address "));
+  for (i = 0; i < 16; i++) {
+    DEBUG ((DEBUG_VERBOSE, "    %01x", i));
+  }
+
+  i = 0;
+  while (i < BdatSize) {
+    if ((i % 16) == 0) {
+      DEBUG ((DEBUG_VERBOSE, "\n%08x ", (i / 16) * 16));
+    } else {
+      DEBUG ((DEBUG_VERBOSE, " "));
+    }
+
+    DEBUG ((DEBUG_VERBOSE, "0x%02x", Table[i]));
+
+    if (i == BdatSize - 1) {
+      DEBUG ((DEBUG_VERBOSE, "\n"));
+    }
+
+    i++;
+
+  }
+  DEBUG ((DEBUG_VERBOSE, "\n"));
+}
+
+/**
+  Copy BDAT Table pointer to scratchpad 5 register
+
+  @param[in] BdatAddress - Bdat Table Address to be copied to Scratchpad 5 register
+
+  @retval None
+**/
+VOID
+CopyBdatPointerToScratchPad5 (
+  IN UINT64 BdatAddress
+  )
+{
+  UINT8                           Socket = 0;
+  EFI_STATUS                      Status = EFI_SUCCESS;
+  DYNAMIC_SI_LIBARY_PROTOCOL      *DynamicSiLibraryProtocol = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &DynamicSiLibraryProtocol);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return;
+  }
+
+  //
+  // Copy BDAT base address to ScratchPad5
+  //
+  for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+    if (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].Valid) {
+      DynamicSiLibraryProtocol->WriteScratchpad5 (Socket, (UINT32) BdatAddress);
+      DEBUG ((DEBUG_VERBOSE, "Scratchpad_Debug PatchBdaAcpiTable: Verify Non Sticky Scratchpad5 0x%08x\n", BdatAddress));
+    }
+  }
+}
+
+/**
+    Update the BDAT ACPI table: Multiple instances of the BDAT DATA HOB are placed into one contiguos memory range
+
+    @param *TableHeader   - The table to be set
+
+    @retval EFI_SUCCESS -  Returns Success
+**/
+EFI_STATUS
+PatchBdatAcpiTable (
+  IN OUT  EFI_ACPI_COMMON_HEADER  *Table
+  )
+{
+  EFI_STATUS                        Status = EFI_SUCCESS;
+  EFI_PHYSICAL_ADDRESS              Address = 0;
+  UINT32                            Idx = 0;
+  UINT8                             Checksum = 0;
+  BDAT_STRUCTURE                    *BdatHeaderStructPtr = NULL;
+  UINT32                            TotalBDATstructureSize = 0;
+  UINT32                            BdatHeaderSize = 0;
+  EFI_HOB_GUID_TYPE                 *GuidHob = NULL;
+  UINT16                            NumberBssaSchemas = 0;
+  UINT16                            TotalNumberSchemas = 0;
+  UINT32                            BssaSchemaSize = 0;
+  EFI_BDAT_ACPI_DESCRIPTION_TABLE   *BdatAcpiTable = NULL;
+  EWL_PRIVATE_DATA                  *EwlPrivateData = NULL;
+  EFI_GUID                          EWLDataGuid = EWL_ID_GUID;
+  UINT32                            EwlSchemaSize = 0;
+  MEM_TRAINING_DATA_STRUCTURE       *MemTrainingData = NULL;
+  MEM_TRAINING_DATA_HOB_HEADER      *TrainingDataHobHeader = NULL;
+  UINT32                            TrainingDataSchemaSize = 0;
+  UINT32                            RemainingSchemaSpace = 0;
+  UINT32                            SpdDataSize = 0;
+  UINT32                            SpdSchemaSize = 0;
+  UINT8                             SchemaIndex = 0;
+  UINT32                            SpaceUsed = 0;
+  UINT32                            LastSchemaSpaceUsed = 0;
+  UINT32                            OffsetFromLastSchema = 0;
+
+  BdatAcpiTable = (EFI_BDAT_ACPI_DESCRIPTION_TABLE *)Table;
+  DEBUG ((DEBUG_INFO, "\nPatchBdatAcpiTable Started\n"));
+
+  //
+  // Gather BSSA schema info
+  //
+  NumberBssaSchemas = GetNumberOfSchemasFromBssaHob ();
+
+  BssaSchemaSize = mSystemMemoryMap->Reserved6 + (NumberBssaSchemas * sizeof (BDAT_SCHEMA_HEADER_STRUCTURE)); //Total size of all HOBs created by SaveToBdat() + NumberBssaSchemas*headerPerSchema
+  DEBUG ((DEBUG_VERBOSE, "NumberBssaSchemas = %d, total BSSA schema size: %d\n", NumberBssaSchemas, BssaSchemaSize));
+
+  TotalNumberSchemas = NumberBssaSchemas;
+
+  TotalBDATstructureSize += BssaSchemaSize;
+
+  //
+  // Gather EWL schema info
+  //
+  GuidHob = GetFirstGuidHob (&EWLDataGuid);
+  if (GuidHob != NULL) {
+    DEBUG ((DEBUG_VERBOSE, "Found EWL with GUID  %g\n", &EWLDataGuid));
+
+    TotalNumberSchemas += 1;
+
+    EwlPrivateData = GET_GUID_HOB_DATA (GuidHob);
+
+    EwlSchemaSize = sizeof (BDAT_SCHEMA_HEADER_STRUCTURE) + EwlPrivateData->status.Header.Size;
+
+    DEBUG ((DEBUG_VERBOSE, "EWL schema size: %d\n", EwlSchemaSize));
+
+    TotalBDATstructureSize += EwlSchemaSize;
+  }
+
+  //
+  // Gather SPD schema info
+  //
+  SpdSchemaSize = 0;
+  if (PcdGetBool (SaveSpdToBdat)) {
+    SpdDataSize = GetSpdDataSize ();
+
+    if (SpdDataSize > 0) {
+      TotalNumberSchemas += 1;
+      SpdSchemaSize = sizeof (BDAT_SCHEMA_HEADER_STRUCTURE) + SpdDataSize;
+      DEBUG ((DEBUG_VERBOSE, "SPD data schema size: %d\n", SpdSchemaSize));
+
+      TotalBDATstructureSize += SpdSchemaSize;
+    }
+  } // PcdGetBool (SaveSpdToBdat)
+
+  //
+  // Gather Memory training data schema info
+  //
+  TrainingDataSchemaSize = 0;
+  if (PcdGetBool (SaveMrcTrainingDataToBdat)) {
+    GuidHob = GetFirstGuidHob (&gMemTrainingDataHobGuid);
+    if (GuidHob != NULL) {
+      DEBUG ((DEBUG_VERBOSE, "Found memory training data HOB with GUID  %g\n", &gMemTrainingDataHobGuid));
+
+      TotalNumberSchemas += 1;
+
+      TrainingDataHobHeader = GET_GUID_HOB_DATA (GuidHob);
+
+      MemTrainingData = (MEM_TRAINING_DATA_STRUCTURE *)((EFI_PHYSICAL_ADDRESS)TrainingDataHobHeader + sizeof (MEM_TRAINING_DATA_HOB_HEADER));
+
+      TrainingDataSchemaSize = sizeof (BDAT_SCHEMA_HEADER_STRUCTURE) + MemTrainingData->Header.Size;
+
+      DEBUG ((DEBUG_VERBOSE, "Memory training data schema size: %d\n", TrainingDataSchemaSize));
+
+      TotalBDATstructureSize += TrainingDataSchemaSize;
+    }
+  } // PcdGetBool (SaveMrcTrainingDataToBdat)
+
+  BdatHeaderSize = sizeof (BDAT_STRUCTURE) + (TotalNumberSchemas * (sizeof (UINT32)));
+  TotalBDATstructureSize += BdatHeaderSize;
+
+  //
+  // This variable is used to keep track the remain space in the BDAT payload (schema section) to
+  // prevent overflow the allocated RT BDAT buffer.
+  //
+  RemainingSchemaSpace = TotalBDATstructureSize - BdatHeaderSize;
+
+  DEBUG ((DEBUG_INFO, "Total BDAT size:%d, BDAT header size: %d, Total schema:%d \n", TotalBDATstructureSize, BdatHeaderSize, TotalNumberSchemas));
+
+  Status = CreateBdatHeader (&BdatHeaderStructPtr, TotalBDATstructureSize, TotalNumberSchemas);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  DEBUG ((DEBUG_INFO, "BdatRegionAddress = 0x%x\n", (UINT64)BdatHeaderStructPtr));
+  CopyBdatPointerToScratchPad5 ((UINT64)BdatHeaderStructPtr);
+
+  //
+  // Update BDAT ACPI table
+  //
+  BdatAcpiTable->BdatGas.Address = (UINT64)BdatHeaderStructPtr;
+
+  //
+  // Starting address of the first schema
+  //
+  Address = (EFI_PHYSICAL_ADDRESS)BdatHeaderStructPtr + BdatHeaderSize;
+
+  //
+  // Saving to RT Memory BDAT Data received from HOBs generated due to BSSA call/calls to SaveToBdat()
+  //
+  SpaceUsed = 0;
+
+  //
+  // The first schema starts right after the BDAT header structure
+  //
+  LastSchemaSpaceUsed = BdatHeaderSize;  // It will used as the OffsetFromLastSchema for the next schema if BSSA is not available
+  OffsetFromLastSchema = BdatHeaderSize;
+
+  if (BssaSchemaSize > 0) {
+
+    Status = SaveBssaResultsToBdat (BdatHeaderStructPtr, OffsetFromLastSchema, &Address, &SchemaIndex, BssaSchemaSize, &SpaceUsed, &LastSchemaSpaceUsed);
+    if (Status != EFI_SUCCESS) {
+      DEBUG ((DEBUG_ERROR, "Faield to add BSSA result to BDAT\n"));
+    }
+  }
+
+  //
+  // Update the starting address of next schema and remaining space.
+  //
+  Address += SpaceUsed;
+  RemainingSchemaSpace -= SpaceUsed;
+  OffsetFromLastSchema = LastSchemaSpaceUsed;
+
+  //
+  // Saving to RT Memory BDAT Data received from EWL HOB
+  //
+  SpaceUsed = 0;
+
+  if (EwlSchemaSize > 0) {
+
+    if (RemainingSchemaSpace < EwlSchemaSize) {
+      DEBUG ((DEBUG_ERROR, "Not enough space to add EWL schema.\n"));
+      goto End;
+    }
+
+    Status = SaveEwlToBdat (BdatHeaderStructPtr, OffsetFromLastSchema ,&Address, &SchemaIndex, &SpaceUsed);
+
+    if (Status != EFI_SUCCESS) {
+      DEBUG ((DEBUG_ERROR, "Failed to add EWL to BDAT.\n"));
+    }
+
+  }
+
+  //
+  // Update the starting address of next schema and remaining space.
+  //
+  Address += SpaceUsed;
+  RemainingSchemaSpace -= SpaceUsed;
+  OffsetFromLastSchema = SpaceUsed;
+
+  //
+  // Add SPD schema
+  //
+  SpaceUsed = 0;
+
+  if (SpdSchemaSize > 0) {
+
+    if (RemainingSchemaSpace < SpdSchemaSize) {
+      DEBUG ((DEBUG_ERROR, "Not enough space to add SPD schema.\n"));
+      goto End;
+    }
+
+    Status = SaveSpdToBdat (BdatHeaderStructPtr, OffsetFromLastSchema, &Address, &SchemaIndex, &SpaceUsed);
+
+    if (Status != EFI_SUCCESS) {
+      DEBUG ((DEBUG_ERROR, "Failed to add SPD to BDAT.\n"));
+    }
+
+  }
+
+  //
+  // Update the starting address of next schema and remaining space.
+  //
+  Address += SpaceUsed;
+  RemainingSchemaSpace -= SpaceUsed;
+  OffsetFromLastSchema = SpaceUsed;
+
+  //
+  // Add memory training data schema
+  //
+  SpaceUsed = 0;
+
+  if (TrainingDataSchemaSize > 0) {
+
+    if (RemainingSchemaSpace < TrainingDataSchemaSize) {
+      DEBUG ((DEBUG_ERROR, "Not enough space to add memory training data schema.\n"));
+      goto End;
+    }
+
+    Status = SaveTrainingDataToBdat (BdatHeaderStructPtr, OffsetFromLastSchema, &Address, &SchemaIndex, &SpaceUsed);
+
+    if (Status != EFI_SUCCESS) {
+      DEBUG ((DEBUG_ERROR, "Failed to add memory training data to BDAT.\n"));
+    }
+  }
+
+  //
+  // Update the starting address of next schema and remaining space.
+  //
+  Address += SpaceUsed;
+  RemainingSchemaSpace -= SpaceUsed;
+  OffsetFromLastSchema = SpaceUsed;
+
+  DEBUG ((DEBUG_VERBOSE, "Final SchemaIndex:%d RemainingSchemaSpace:%d\n", SchemaIndex, RemainingSchemaSpace));
+
+  End:
+
+  //
+  // Update checksum
+  //
+  BdatAcpiTable->Header.Checksum = 0;
+  Checksum = 0;
+  for(Idx = 0; Idx < sizeof(EFI_BDAT_ACPI_DESCRIPTION_TABLE); Idx++) {
+    Checksum = Checksum + (UINT8) (((UINT8 *)(BdatAcpiTable))[Idx]);
+  }
+  BdatAcpiTable->Header.Checksum = (UINT8) (0 - Checksum);
+
+  DumpBdatTable (&BdatHeaderStructPtr, TotalBDATstructureSize);
+
+  return Status;
+}
+
+
+/**
+  Displays SPD content for debugging.
+
+  @param[in] Address  - The starting address of the SPD entry
+
+  @retval N/A
+**/
+VOID
+DisplaySpdContents (
+  IN EFI_PHYSICAL_ADDRESS  Address
+  )
+{
+  UINT16                  Index;
+  MEM_SPD_ENTRY_TYPE0    *EntryHeaderPtr;
+
+  EntryHeaderPtr = (MEM_SPD_ENTRY_TYPE0  *)Address;
+
+  //
+  // Print the Socket, Channel and Dimm information.
+  //
+  DEBUG ((DEBUG_VERBOSE, "START_PRINT_SPD S%dC%dD%d:\n",
+    EntryHeaderPtr->MemoryLocation.Socket,
+    EntryHeaderPtr->MemoryLocation.Channel,
+    EntryHeaderPtr->MemoryLocation.Dimm));
+
+  //
+  // Print the Column Number of the SPD data.
+  //
+  for (Index = 0; Index < 0x10; Index++) {
+    DEBUG ((DEBUG_VERBOSE, " %02x", Index));
+  }
+
+  Address += sizeof (MEM_SPD_ENTRY_TYPE0);
+
+  for (Index = 0; Index < EntryHeaderPtr->NumberOfBytes; Index++) {
+
+    //
+    // Print the Carriage Return and Byte Index of SPD data.
+    //
+    if ((Index % 0x10) == 0) {
+
+      //
+      // Split the SPD data for every 256 bytes
+      //
+      if (((Index % 0x100) == 0) && (Index != 0)) {
+        DEBUG ((DEBUG_VERBOSE, "\n"));
+      }
+
+      DEBUG ((DEBUG_VERBOSE, "\n%02x:", (UINT8) (Index & 0x00F0)));
+    }
+
+    DEBUG ((DEBUG_VERBOSE, " %02x", *(UINT8 *)(Address + (EFI_PHYSICAL_ADDRESS)Index)));
+  }
+
+  DEBUG ((DEBUG_VERBOSE, "\n"));
+
+
+  DEBUG ((DEBUG_VERBOSE, "STOP_PRINT_SPD\n"));
+
+} // DisplaySpdContents
+
+/**
+  Get the size of SPD data structure not include the SPD BDAT schema header.
+
+  @retval UINT32 - Size of SPD data structure in bytes
+**/
+UINT32
+GetSpdDataSize (
+  VOID
+  )
+{
+  UINT32  SchemaSize = 0;
+  UINT8   Socket;
+  UINT8   Channel;
+  UINT8   Dimm;
+  UINT32  SpdBytesPerDimm = 0;
+  UINT8   NumberOfDimmPresent = 0;
+
+  EFI_STATUS                  Status = EFI_SUCCESS;
+  DYNAMIC_SI_LIBARY_PROTOCOL  *DynamicSiLibraryProtocol = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &DynamicSiLibraryProtocol);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return 0;
+  }
+
+  if (mSystemMemoryMap == NULL) {
+    mSystemMemoryMap = DynamicSiLibraryProtocol->GetSystemMemoryMapData ();
+  }
+
+  if (mSystemMemoryMap == NULL) {
+    return 0;
+  }
+
+  ASSERT (mSystemMemoryMap->DramType == SPD_TYPE_DDR4);
+  SpdBytesPerDimm = MAX_SPD_BYTE_DDR4;
+
+  for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+    for (Channel = 0; Channel < MAX_CH; Channel++) {
+      for (Dimm = 0; Dimm < MAX_DIMM; Dimm++) {
+        if (mSystemMemoryMap->Socket[Socket].ChannelInfo[Channel].DimmInfo[Dimm].Present != 0) {
+          NumberOfDimmPresent += 1;
+        }
+      }
+    }
+  }
+
+  //
+  // Total entries
+  //
+  SchemaSize = (SpdBytesPerDimm + sizeof (MEM_SPD_ENTRY_TYPE0)) * NumberOfDimmPresent;
+
+  //
+  // Add the SPD raw data header
+  //
+  SchemaSize += sizeof (MEM_SPD_RAW_DATA_HEADER);
+
+  return SchemaSize;
+
+}
+
+
+/**
+  Read the SPD data for one dimm and fill up SPD entry inside SPD BDAT schema space.
+
+  @param[out] Address           - Start Address of the buffer where the SPD entry to be filled
+  @param[in]  Socket            - Socket number
+  @param[in]  Channel           - Channel number inside the Socket
+  @param[in]  Dimm              - Dimm slot number
+  @param[in]  MaxSpdByteOffset  - The max SPD byte offset. DDR4 is 512
+
+  @retval EFI_SUCCESS  - SPD Structure filled successfully
+  @retval !EFI_SUCCESS - SPD structure creation failed
+**/
+EFI_STATUS
+FillSpdPerDimmEntry (
+  OUT EFI_PHYSICAL_ADDRESS    Address,
+  IN UINT8                    Socket,
+  IN UINT8                    Channel,
+  IN UINT8                    Dimm,
+  IN UINT16                   MaxSpdByteOffset
+  )
+{
+  UINT16               SpdByteOffset = 0;
+  UINT8                SpdData = 0;
+  MEM_SPD_ENTRY_TYPE0  *EntryHeaderPtr;
+  EFI_STATUS           Status = EFI_SUCCESS;
+
+  DYNAMIC_SI_LIBARY_PROTOCOL2  *DynamicSiLibraryProtocol2 = NULL;
+
+  DEBUG ((DEBUG_VERBOSE, "Fill Spd entry for Socket:%d Channel:%d Dimm:%d at location:0x%x \n", Socket, Channel, Dimm, Address));
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  EntryHeaderPtr = (MEM_SPD_ENTRY_TYPE0  *)Address;
+
+  //
+  // Add the entry header. We use type 0.
+  //
+  EntryHeaderPtr->Header.Type = MemSpdDataType0;
+  EntryHeaderPtr->Header.Size = sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByteOffset;
+
+  EntryHeaderPtr->MemoryLocation.Socket = Socket;
+  EntryHeaderPtr->MemoryLocation.Channel = Channel;
+  EntryHeaderPtr->MemoryLocation.Dimm = Dimm;
+
+  EntryHeaderPtr->NumberOfBytes = MaxSpdByteOffset;
+
+  Address += sizeof (MEM_SPD_ENTRY_TYPE0);
+
+  for (SpdByteOffset = 0; SpdByteOffset < MaxSpdByteOffset; SpdByteOffset++) {
+    Status = DynamicSiLibraryProtocol2->SpdReadByte (Socket, Channel, Dimm, SpdByteOffset, &SpdData);
+
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_WARN, "Failed to read SPD data at Socket:%d Channel:%d Dimm:%d SpdByteOffset:%d Status:0x%x\n",
+        Socket, Channel, Dimm, SpdByteOffset, Status));
+      return Status;
+    }
+
+    *(UINT8 *)Address = SpdData;
+    Address += 1;
+  } // SpdByteOffset
+
+  return Status;
+}
+
+/**
+  Fill the SPD data structure inside the BDAT schema space.
+
+  @param[out] StartAddress           - Start Address of the buffer where SPD data structure to be filled
+  @param[in]  SpdDataSize            - Size of SPD data structure includes the header
+
+  @retval EFI_SUCCESS  - SPD Structure filled successfully
+  @retval !EFI_SUCCESS - SPD structure creation failed
+**/
+EFI_STATUS
+FillSpdSchema (
+  OUT EFI_PHYSICAL_ADDRESS    StartAddress,
+  IN UINT32                   SpdDataSize
+  )
+{
+  UINT8                   Socket;
+  UINT8                   Channel;
+  UINT8                   Dimm;
+  UINT16                  MaxSpdByteOffset = 0;
+  UINT32                  RemainedSpace;
+  EFI_PHYSICAL_ADDRESS    Address;
+  MEM_SPD_RAW_DATA_HEADER *SpdDataHeaderStructPtr;
+  EFI_STATUS              Status = EFI_SUCCESS;
+
+  DYNAMIC_SI_LIBARY_PROTOCOL  *DynamicSiLibraryProtocol = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &DynamicSiLibraryProtocol);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  if (mSystemMemoryMap == NULL) {
+    mSystemMemoryMap = DynamicSiLibraryProtocol->GetSystemMemoryMapData ();
+  }
+
+  if (mSystemMemoryMap == NULL) {
+    return EFI_DEVICE_ERROR;;
+  }
+  if (StartAddress == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RemainedSpace = SpdDataSize;
+  Address = StartAddress;
+  SpdDataHeaderStructPtr = (MEM_SPD_RAW_DATA_HEADER *)StartAddress;
+
+  //
+  // Fill up the header of the SPD data strcuture
+  //
+  SpdDataHeaderStructPtr->MemSpdGuid = gSpdVersion1Guid;
+  SpdDataHeaderStructPtr->Size = SpdDataSize;
+  SpdDataHeaderStructPtr->Reserved = 0;
+
+  Address += sizeof (MEM_SPD_RAW_DATA_HEADER);
+  RemainedSpace -= sizeof (MEM_SPD_RAW_DATA_HEADER);
+
+  ASSERT (mSystemMemoryMap->DramType == SPD_TYPE_DDR4);
+  MaxSpdByteOffset = MAX_SPD_BYTE_DDR4;
+
+  //
+  // Iterate through all populated DIMMs and add them
+  //
+  for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+    for (Channel = 0; Channel < MAX_CH; Channel++) {
+      for (Dimm = 0; Dimm < MAX_DIMM; Dimm++) {
+
+        if (mSystemMemoryMap->Socket[Socket].ChannelInfo[Channel].DimmInfo[Dimm].Present != 0) {
+
+          if (RemainedSpace < sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByteOffset) {
+            DEBUG ((DEBUG_ERROR, "Run out of allocated SPD data space. RemainedSpace:%d required space:%d\n",
+              RemainedSpace, sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByteOffset));
+            return RETURN_OUT_OF_RESOURCES;
+          }
+
+          Status = FillSpdPerDimmEntry (Address, Socket, Channel, Dimm, MaxSpdByteOffset);
+          if (EFI_ERROR (Status)) {
+            DEBUG ((DEBUG_ERROR, "Failed to read SPD data at Socket:%d Channel:%d Dimm:%d Status:0x%x.\n",  Socket, Channel, Dimm, Status));
+            return Status;
+          }
+
+          DisplaySpdContents (Address);
+
+          Address += sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByteOffset;
+          RemainedSpace -= sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByteOffset;
+
+        }
+      } // Dimm
+    } // Channel
+  } // Socket
+
+  //
+  // Update CRC
+  //
+  SpdDataHeaderStructPtr->Crc = 0;
+  SpdDataHeaderStructPtr->Crc = CalculateCrc32 ((VOID *) SpdDataHeaderStructPtr, SpdDataHeaderStructPtr->Size);
+
+  return EFI_SUCCESS;
+
+}
+
+/**
+  Save BSSA results to BDAT
+
+  @param[in,out]   BdatHeaderStructPtr - Pointer to BDAT Structure
+  @param[in]       OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
+  @param[in]       SchemaStartAddress  - Starting address where the BSSA result schema will be added
+  @param[in, out]  SchemaIndex         - Current schema index inside the BDAT. Need it to update the schema offsets array.
+  @param[in]       SchemaSize          - The size of the BSSA results schema.
+  @param[out]      SchemaSpaceUsed     - The numebr bytes were filled in all schema
+  @param[out]      LastSchemaSpaceUsed - The numebr bytes were filled in the last schema
+
+  @retval EFI_SUCCESS  - BSSA BDAT scehma created successfully
+  @retval !EFI_SUCCESS - BSSA BDAT scehma creation failed
+**/
+EFI_STATUS
+SaveBssaResultsToBdat (
+  IN OUT BDAT_STRUCTURE          *BdatHeaderStructPtr,
+  IN     UINT32                  OffsetFromLastSchema,
+  IN     EFI_PHYSICAL_ADDRESS    *SchemaStartAddress,
+  IN OUT UINT8                   *SchemaIndex,
+  IN     UINT32                  SchemaSize,
+  OUT    UINT32                  *SchemaSpaceUsed,
+  OUT    UINT32                  *LastSchemaSpaceUsed
+  )
+{
+  EFI_STATUS                        Status                      = EFI_SUCCESS;
+  UINT32                            *SchemaAddrLocationArray    = NULL;
+  UINT32                            CurrentHobSize              = 0;
+  EFI_HOB_GUID_TYPE                 *GuidHob                    = NULL;
+  VOID                              *HobData                    = NULL;
+  UINT32                            PreviousSchemaSize          = 0;
+  EFI_GUID                          gEfiMemoryMapDataHobBdatBssaGuid  = {0};
+  UINT32                            GuidIdx                     = 0;
+  UINT32                            HobIdx                      = 0;
+  UINT32                            RemainingHobSizeBssaSchema  = 0;
+  BDAT_SCHEMA_HEADER_STRUCTURE      *BssaSchemaHeaderPtr        = NULL;
+  EFI_PHYSICAL_ADDRESS              Address                     = 0;
+
+  if ((BdatHeaderStructPtr == NULL) || (SchemaStartAddress == NULL) || (SchemaIndex == NULL) || (SchemaSpaceUsed == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RemainingHobSizeBssaSchema = SchemaSize;
+  Address = *SchemaStartAddress;
+  *SchemaSpaceUsed = 0;
+
+  //
+  // Update the schema offset array for its first BSSA schema
+  //
+  SchemaAddrLocationArray = (UINT32 *)((EFI_PHYSICAL_ADDRESS)BdatHeaderStructPtr + sizeof(BDAT_STRUCTURE));
+
+  if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength) {
+    if (*SchemaIndex == 0) {
+      SchemaAddrLocationArray[*SchemaIndex] = OffsetFromLastSchema;
+    }
+    else {
+      SchemaAddrLocationArray[*SchemaIndex] = SchemaAddrLocationArray[*SchemaIndex - 1] + OffsetFromLastSchema;
+    }
+  }
+
+  for (GuidIdx = 0; GuidIdx < mSystemMemoryMap->Reserved9; GuidIdx++) {
+
+    gEfiMemoryMapDataHobBdatBssaGuid  = mSystemMemoryMap->Reserved8[GuidIdx]; //get first GUID instance
+    GuidHob = GetFirstGuidHob (&gEfiMemoryMapDataHobBdatBssaGuid);
+
+    for (HobIdx = 0; HobIdx < mSystemMemoryMap->Reserved7[GuidIdx]; HobIdx++) { //looping through all HOBs linked to that GUID
+
+      ASSERT (GuidHob != NULL);
+      if (GuidHob == NULL) {
+        return EFI_NOT_FOUND;
+      }
+
+      HobData = GET_GUID_HOB_DATA (GuidHob);
+      CurrentHobSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
+      DEBUG ((DEBUG_VERBOSE, "Initial HOB size  %d; remaining HOB size %d\n", CurrentHobSize, RemainingHobSizeBssaSchema));
+
+      //
+      // Setting the header first
+      //
+      if (RemainingHobSizeBssaSchema < sizeof(BDAT_SCHEMA_HEADER_STRUCTURE)) {
+        //
+        // Nothing we can do, break execution
+        //
+        DEBUG ((DEBUG_WARN, "Not enough space to add schema header to BIOS SSA result\n"));
+        RemainingHobSizeBssaSchema = 0;
+        break;
+      }
+
+      //
+      // Each HOB has a header added to it (BDAT_SCHEMA_HEADER_STRUCTURE)
+      //
+      Address = Address + (EFI_PHYSICAL_ADDRESS)PreviousSchemaSize;
+
+      BssaSchemaHeaderPtr = (BDAT_SCHEMA_HEADER_STRUCTURE *)Address;
+      BssaSchemaHeaderPtr->SchemaId = gEfiMemoryMapDataHobBdatBssaGuid;
+      RemainingHobSizeBssaSchema -= sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
+      *SchemaSpaceUsed = *SchemaSpaceUsed + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
+
+      Address = Address + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
+
+      //
+      // CRC16 value of the BDAT_SCHEMA_HEADER_STRUCTURE
+      //
+      BssaSchemaHeaderPtr->Crc16 = 0;
+      Status = CalculateCrc16 (
+        (VOID *) BssaSchemaHeaderPtr,
+        sizeof (BDAT_SCHEMA_HEADER_STRUCTURE),
+        &BssaSchemaHeaderPtr->Crc16
+        );
+      ASSERT_EFI_ERROR (Status);
+      if (EFI_ERROR (Status)) {
+        BssaSchemaHeaderPtr->Crc16 = 0xFFFF;
+      }
+
+      if (RemainingHobSizeBssaSchema < CurrentHobSize) {
+        DEBUG ((DEBUG_WARN, "Not enough space to add complete BIOS SSA result\n"));
+        CurrentHobSize = RemainingHobSizeBssaSchema;
+      }
+
+      //
+      // HOB size won't overflow a UINT32.
+      //
+      BssaSchemaHeaderPtr->DataSize = (UINT32)CurrentHobSize + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
+      DEBUG ((DEBUG_VERBOSE, "Setting schema %g size to %d\n", &(BssaSchemaHeaderPtr->SchemaId), BssaSchemaHeaderPtr->DataSize));
+      //
+      // HOB size won't overflow a UINT32.
+      //
+      PreviousSchemaSize = (UINT32)CurrentHobSize + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
+
+      //
+      // Copy HOB to RT Memory
+      //
+      CopyMem ((VOID *)Address, (VOID *)HobData, (UINT32)CurrentHobSize);
+      //
+      // HOB size won't overflow a UINT32.
+      //
+      DEBUG ((DEBUG_VERBOSE, "HOB size  %d; remaining SSA HOB size %d\n", CurrentHobSize, RemainingHobSizeBssaSchema));
+      RemainingHobSizeBssaSchema -= (UINT32)CurrentHobSize;
+      *SchemaSpaceUsed = *SchemaSpaceUsed + (UINT32)CurrentHobSize;
+
+      *SchemaIndex = *SchemaIndex + 1;
+
+      if (RemainingHobSizeBssaSchema == 0) {
+        break;
+      }
+
+      GuidHob = GET_NEXT_HOB (GuidHob); // Increment to next HOB
+      GuidHob = GetNextGuidHob (&gEfiMemoryMapDataHobBdatBssaGuid, GuidHob);  // Now search for next instance of the BDAT HOB
+      if (GuidHob == NULL) {
+        break;
+      }
+
+      //
+      // Update the schema offset arrary
+      //
+      if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength) {
+        SchemaAddrLocationArray[*SchemaIndex] = SchemaAddrLocationArray[*SchemaIndex - 1] + PreviousSchemaSize;
+      }
+    }
+
+    if (RemainingHobSizeBssaSchema == 0) {
+      break;
+    }
+
+  }
+
+  *LastSchemaSpaceUsed = PreviousSchemaSize;
+
+  return EFI_SUCCESS;
+} // SaveBssaResultsToBdat
+
+
+/**
+  Save EWL results to BDAT
+
+  @param[in,out]   BdatHeaderStructPtr - Pointer to BDAT Structure
+  @param[in]       OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
+  @param[in]       SchemaStartAddress  - Starting address where the EWL schema will be added
+  @param[in, out]  SchemaIndex         - Current schema index inside the BDAT. Need it to update the schema offsets array.
+  @param[out]      SchemaSpaceUsed     - The numebr bytes were filled
+
+  @retval EFI_SUCCESS  - EWL BDAT scehma created successfully
+  @retval !EFI_SUCCESS - EWL BDAT scehma creation failed
+**/
+EFI_STATUS
+SaveEwlToBdat (
+  IN OUT BDAT_STRUCTURE          *BdatHeaderStructPtr,
+  IN     UINT32                  OffsetFromLastSchema,
+  IN     EFI_PHYSICAL_ADDRESS    *SchemaStartAddress,
+  IN OUT UINT8                   *SchemaIndex,
+  OUT    UINT32                  *SchemaSpaceUsed
+  )
+{
+  EFI_STATUS                        Status                      = EFI_SUCCESS;
+  UINT32                            *SchemaAddrLocationArray    = NULL;
+  EFI_HOB_GUID_TYPE                 *GuidHob                    = NULL;
+  EFI_PHYSICAL_ADDRESS              Address                     = 0;
+  EWL_PRIVATE_DATA                  *EwlPrivateData             = NULL;
+  EFI_GUID                          EWLDataGuid                 = EWL_ID_GUID;
+  BDAT_SCHEMA_HEADER_STRUCTURE      *EwlSchemaHeaderPtr         = NULL;
+  UINT32                            EwlSize                     = 0;
+
+  if ((BdatHeaderStructPtr == NULL) || (SchemaStartAddress == NULL) || (SchemaIndex == NULL) || (SchemaSpaceUsed == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Address = *SchemaStartAddress;
+  *SchemaSpaceUsed = 0;
+
+  DEBUG ((DEBUG_VERBOSE, "\nStarting to copy EWL schema at Address = 0x%x\n", Address));
+
+  //
+  // Update the schema offset arrary
+  //
+  SchemaAddrLocationArray = (UINT32 *)((EFI_PHYSICAL_ADDRESS)BdatHeaderStructPtr + sizeof(BDAT_STRUCTURE));
+
+  if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength) {
+    if (*SchemaIndex == 0) {
+      SchemaAddrLocationArray[*SchemaIndex] = OffsetFromLastSchema;
+    }
+    else {
+      SchemaAddrLocationArray[*SchemaIndex] = SchemaAddrLocationArray[*SchemaIndex - 1] + OffsetFromLastSchema;
+    }
+  }
+
+  EwlSchemaHeaderPtr = (BDAT_SCHEMA_HEADER_STRUCTURE *)Address;
+  EwlSchemaHeaderPtr->SchemaId = gEwlBdatSchemaGuid;
+  *SchemaSpaceUsed = *SchemaSpaceUsed + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
+
+  //
+  // CRC16 value of the BDAT_SCHEMA_HEADER_STRUCTURE
+  //
+  EwlSchemaHeaderPtr->Crc16 = 0;
+  Status = CalculateCrc16 (
+    (VOID *)EwlSchemaHeaderPtr,
+    sizeof(BDAT_SCHEMA_HEADER_STRUCTURE),
+    &EwlSchemaHeaderPtr->Crc16
+  );
+
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    EwlSchemaHeaderPtr->Crc16 = 0xFFFF;
+  }
+
+  GuidHob = GetFirstGuidHob (&EWLDataGuid);
+  EwlPrivateData = GET_GUID_HOB_DATA (GuidHob);
+
+  EwlSize = EwlPrivateData->status.Header.Size;
+
+  EwlSchemaHeaderPtr->DataSize = EwlSize + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
+
+  //
+  // Copy EWL HOB to RT Memory
+  //
+  Address = Address + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
+  CopyMem ((VOID *)Address, (VOID *)&(EwlPrivateData->status), EwlSize);
+  *SchemaSpaceUsed = *SchemaSpaceUsed + EwlSize;
+
+  *SchemaIndex = *SchemaIndex + 1;
+
+  return EFI_SUCCESS;
+} //SaveEwlToBdat
+
+/**
+  Check if current boot is slow boot or not
+
+  @retval TRUE  - Slow boot path
+  @retval FALSE - not slow boot path
+  **/
+BOOLEAN
+IsSlowBoot (
+  VOID
+  )
+{
+  EFI_STATUS                      Status = EFI_SUCCESS;
+  DYNAMIC_SI_LIBARY_PROTOCOL2     *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return TRUE;
+  }
+
+  return DynamicSiLibraryProtocol2->IsSlowBoot ();
+} // IsSlowBoot
+
+/**
+  Save SPD date structure to BDAT
+
+  @param[in,out]   BdatHeaderStructPtr - Pointer to BDAT Structure
+  @param[in]       OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
+  @param[in]       SchemaStartAddress  - Starting address where the SPD data schema will be added
+  @param[in, out]  SchemaIndex         - Current schema index inside the BDAT. Need it to update the schema offsets array.
+  @param[out]      SchemaSpaceUsed     - The numebr bytes were filled
+
+  @retval EFI_SUCCESS  - SPD BDAT scehma created successfully
+  @retval !EFI_SUCCESS - SPD BDAT scehma creation failed
+**/
+EFI_STATUS
+SaveSpdToBdat (
+  IN OUT BDAT_STRUCTURE          *BdatHeaderStructPtr,
+  IN     UINT32                  OffsetFromLastSchema,
+  IN     EFI_PHYSICAL_ADDRESS    *SchemaStartAddress,
+  IN OUT UINT8                   *SchemaIndex,
+  OUT    UINT32                  *SchemaSpaceUsed
+  )
+{
+  EFI_STATUS                        Status                      = EFI_SUCCESS;
+  UINT32                            *SchemaAddrLocationArray    = NULL;
+  UINT32                            SpdDataSize                 = 0;
+  EFI_PHYSICAL_ADDRESS              Address                     = 0;
+  BDAT_SCHEMA_HEADER_STRUCTURE      *SpdSchemaHeaderPtr         = NULL;
+//  UINT16                            *SpdVariableName            = L"SpdData";
+  VOID                              *VariableData               = NULL;
+  BOOLEAN                           SaveToVariable              = TRUE;
+  UINTN                             CompareValue;
+
+  if ((BdatHeaderStructPtr == NULL) || (SchemaStartAddress == NULL) || (SchemaIndex == NULL) || (SchemaSpaceUsed == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Address = *SchemaStartAddress;
+  *SchemaSpaceUsed = 0;
+
+  //
+  // Add SPD schema
+  //
+  DEBUG ((DEBUG_VERBOSE, "\nStarting to add SPD schema  at Address = 0x%x\n", Address));
+
+  //
+  // Update the schema offset arrary
+  //
+  SchemaAddrLocationArray = (UINT32 *)((EFI_PHYSICAL_ADDRESS)BdatHeaderStructPtr + sizeof(BDAT_STRUCTURE));
+
+  if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength) {
+    if (*SchemaIndex == 0) {
+      SchemaAddrLocationArray[*SchemaIndex] = OffsetFromLastSchema;
+    }
+    else {
+      SchemaAddrLocationArray[*SchemaIndex] = SchemaAddrLocationArray[*SchemaIndex - 1] + OffsetFromLastSchema;
+    }
+  }
+
+  SpdSchemaHeaderPtr = (BDAT_SCHEMA_HEADER_STRUCTURE *)Address;
+  SpdSchemaHeaderPtr->SchemaId = gSpdBdatSchemaGuid;
+
+  //
+  // CRC16 value of the BDAT_SCHEMA_HEADER_STRUCTURE
+  //
+  SpdSchemaHeaderPtr->Crc16 = 0;
+  Status = CalculateCrc16 (
+    (VOID *)SpdSchemaHeaderPtr,
+    sizeof(BDAT_SCHEMA_HEADER_STRUCTURE),
+    &SpdSchemaHeaderPtr->Crc16
+  );
+
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    SpdSchemaHeaderPtr->Crc16 = 0xFFFF;
+  }
+
+  Address = Address + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
+  *SchemaSpaceUsed = *SchemaSpaceUsed + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
+
+  SpdDataSize = GetSpdDataSize ();
+
+  if (IsSlowBoot ()) {
+    //
+    // Read SPD via Smbus, fill up the SPD data structure.
+    //
+    FillSpdSchema (Address, SpdDataSize);
+
+    //
+    // Save the SPD data structure to EFI variables to save fast boot time
+    //
+    // Before save variable, read and comapre to current data. If they are the same, then
+    // don't save it.
+    // If fail to read the variable(the variable doesn't exist), save variable.
+    //
+
+    SaveToVariable = TRUE;
+
+    VariableData = AllocatePool (SpdDataSize);
+    if (VariableData == NULL) {
+      DEBUG ((DEBUG_ERROR, "Not able to allocate space to store SPD variable data.\n"));
+      Status = EFI_OUT_OF_RESOURCES;
+      goto End;
+    }
+
+//    Status = LoadCompressedVariable (SpdVariableName, gSpdVariableGuid, VariableData, SpdDataSize);
+
+    if (!EFI_ERROR (Status)) {
+      CompareValue = CompareMem ((VOID *)Address, VariableData, SpdDataSize);
+      if (CompareValue == 0) {
+        SaveToVariable = FALSE;
+        DEBUG ((DEBUG_VERBOSE, "No change to the SPD data, don't save variable.\n"));
+      }
+    }
+
+    if (SaveToVariable) {
+//      Status = CompressAndSaveToVariable (SpdVariableName, gSpdVariableGuid, (VOID *)Address, SpdDataSize);
+
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "Failed to save SPD data to variable.\n"));
+        goto End;
+      }
+
+      DEBUG ((DEBUG_VERBOSE, "Save SPD data to EFI variable.\n"));
+    }
+  } else {
+    //
+    // Fast boot, read the SPD data from vaiable
+    //
+//    Status = LoadCompressedVariable (SpdVariableName, gSpdVariableGuid, (VOID *)Address, SpdDataSize);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Failed to load SPD data from variable.\n"));
+      goto End;
+    }
+    DEBUG ((DEBUG_VERBOSE, "Fill with SPD data from EFI variable.\n"));
+  }
+
+  End:
+
+  if (VariableData != NULL) {
+    FreePool (VariableData);
+  }
+
+  SpdSchemaHeaderPtr->DataSize = SpdDataSize + sizeof (BDAT_SCHEMA_HEADER_STRUCTURE);
+  *SchemaSpaceUsed = *SchemaSpaceUsed + SpdDataSize;
+
+  *SchemaIndex = *SchemaIndex + 1;
+  return Status;
+} //SaveSpdToBdat
+
+/**
+  Save memory training date structure to BDAT
+
+  @param[in,out]   BdatHeaderStructPtr - Pointer to BDAT Structure
+  @param[in]       OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
+  @param[in]       SchemaStartAddress  - Starting address where the memory training data schema will be added
+  @param[in, out]  SchemaIndex         - Current schema index inside the BDAT. Need it to update the schema offsets array.
+  @param[out]      SchemaSpaceUsed     - The numebr bytes were filled
+
+  @retval EFI_SUCCESS  - Memory training data BDAT scehma created successfully
+  @retval !EFI_SUCCESS - Memory training data BDAT scehma creation failed
+**/
+EFI_STATUS
+SaveTrainingDataToBdat (
+  IN OUT BDAT_STRUCTURE          *BdatHeaderStructPtr,
+  IN     UINT32                  OffsetFromLastSchema,
+  IN     EFI_PHYSICAL_ADDRESS    *SchemaStartAddress,
+  IN OUT UINT8                   *SchemaIndex,
+  OUT    UINT32                  *SchemaSpaceUsed
+  )
+{
+  EFI_STATUS                        Status                      = EFI_SUCCESS;
+  UINT32                            *SchemaAddrLocationArray    = NULL;
+  EFI_HOB_GUID_TYPE                 *GuidHob                    = NULL;
+  EFI_PHYSICAL_ADDRESS              Address                     = 0;
+  MEM_TRAINING_DATA_HEADER          *TrainingDataHeader         = NULL;
+  MEM_TRAINING_DATA_HOB_HEADER      *TrainingDataHobHeader      = NULL;
+  EFI_GUID                          TrainingDataGuid            = gMemTrainingDataHobGuid;
+  BDAT_SCHEMA_HEADER_STRUCTURE      *SchemaHeaderPtr            = NULL;
+  INT32                             RemainingDataSize           = 0;
+  UINT32                            HobSize                     = 0;
+  UINT32                            TrainingDataSize            = 0;
+  UINT8                             HobIndex                    = 0;
+
+  if ((BdatHeaderStructPtr == NULL) || (SchemaStartAddress == NULL) || (SchemaIndex == NULL) || (SchemaSpaceUsed == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Address = *SchemaStartAddress;
+  *SchemaSpaceUsed = 0;
+
+  DEBUG ((DEBUG_VERBOSE, "\nStarting to copy memory training data schema at Address = 0x%x\n", Address));
+
+  //
+  // Update the schema offset arrary
+  //
+  SchemaAddrLocationArray = (UINT32 *)((EFI_PHYSICAL_ADDRESS)BdatHeaderStructPtr + sizeof(BDAT_STRUCTURE));
+
+  if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength) {
+    if (*SchemaIndex == 0) {
+      SchemaAddrLocationArray[*SchemaIndex] = OffsetFromLastSchema;
+    }
+    else {
+      SchemaAddrLocationArray[*SchemaIndex] = SchemaAddrLocationArray[*SchemaIndex - 1] + OffsetFromLastSchema;
+    }
+  }
+
+  SchemaHeaderPtr = (BDAT_SCHEMA_HEADER_STRUCTURE *)Address;
+  SchemaHeaderPtr->SchemaId = gMemTrainingDataBdatSchemaGuid;
+  *SchemaSpaceUsed = *SchemaSpaceUsed + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
+
+  //
+  // CRC16 value of the BDAT_SCHEMA_HEADER_STRUCTURE
+  //
+  SchemaHeaderPtr->Crc16 = 0;
+  Status = CalculateCrc16 (
+    (VOID *)SchemaHeaderPtr,
+    sizeof(BDAT_SCHEMA_HEADER_STRUCTURE),
+    &SchemaHeaderPtr->Crc16
+  );
+
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    SchemaHeaderPtr->Crc16 = 0xFFFF;
+  }
+
+  GuidHob = GetFirstGuidHob (&TrainingDataGuid);
+
+  ASSERT (GuidHob != NULL);
+  if (GuidHob == NULL) {
+    DEBUG ((DEBUG_ERROR, "Not found training data HOB with GUID:%g\n", &TrainingDataGuid));
+    return EFI_NOT_FOUND;
+  }
+
+  TrainingDataHobHeader = GET_GUID_HOB_DATA (GuidHob);
+  TrainingDataSize = TrainingDataHobHeader->Size - sizeof (MEM_TRAINING_DATA_HOB_HEADER); // This is the size of data to copy to the RT memory.
+
+  TrainingDataHeader = (MEM_TRAINING_DATA_HEADER *)((EFI_PHYSICAL_ADDRESS)TrainingDataHobHeader + sizeof (MEM_TRAINING_DATA_HOB_HEADER));
+
+  HobSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
+  ASSERT (TrainingDataSize <= HobSize);
+
+  HobIndex += 1;
+  DEBUG ((DEBUG_VERBOSE, "Memory training data structre size:%d\n", TrainingDataHeader->Size));
+  SchemaHeaderPtr->DataSize = TrainingDataHeader->Size + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
+
+  //
+  // This is the total data size in the training data structure.
+  //
+  RemainingDataSize = (INT32) TrainingDataHeader->Size;
+
+  DEBUG ((DEBUG_VERBOSE, "Remaining training data:%d\n", RemainingDataSize));
+  //
+  // Copy training data HOBs to RT Memory
+  //
+  Address = Address + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
+  CopyMem ((VOID *)Address, (VOID *)TrainingDataHeader, TrainingDataSize);
+
+  *SchemaSpaceUsed = *SchemaSpaceUsed + TrainingDataSize;
+
+  Address = Address + TrainingDataSize;
+  RemainingDataSize -= TrainingDataSize;
+
+ while (RemainingDataSize > 0) {
+
+    GuidHob = GET_NEXT_HOB (GuidHob); // Increment to next HOB
+    GuidHob = GetNextGuidHob (&TrainingDataGuid, GuidHob);  // Now search for next instance of the BDAT HOB
+
+    ASSERT (GuidHob != NULL);
+    if (GuidHob == NULL) {
+      DEBUG ((DEBUG_ERROR, "Not found training data HOB with GUID:%g\n", &TrainingDataGuid));
+      return EFI_NOT_FOUND;
+    }
+
+    TrainingDataHobHeader = GET_GUID_HOB_DATA (GuidHob);
+    TrainingDataSize = TrainingDataHobHeader->Size - sizeof (MEM_TRAINING_DATA_HOB_HEADER); // This is the size of data to copy to the RT memory.
+
+    HobSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
+    ASSERT (TrainingDataSize <= HobSize);
+
+    HobIndex += 1;
+
+    //
+    // Copy training data HOBs to RT Memory
+    //
+    CopyMem ((VOID *)Address, (VOID *)((EFI_PHYSICAL_ADDRESS)TrainingDataHobHeader + sizeof (MEM_TRAINING_DATA_HOB_HEADER)), TrainingDataSize);
+
+    *SchemaSpaceUsed = *SchemaSpaceUsed + TrainingDataSize;
+
+    Address = Address + TrainingDataSize;
+    RemainingDataSize -= TrainingDataSize;
+    DEBUG ((DEBUG_VERBOSE, "Remaining training data:%d after copying Hob:%d \n", RemainingDataSize, HobIndex));
+  }
+
+  //
+  // Update training data header structure CRC, after all the training data were copied from HOBs to a RT contiguous memory region.
+  //
+  TrainingDataHeader->Crc = 0;
+  TrainingDataHeader->Crc = CalculateCrc32 ((VOID *) TrainingDataHeader, TrainingDataHeader->Size);
+
+  *SchemaIndex = *SchemaIndex + 1;
+
+  return EFI_SUCCESS;
+} //SaveTrainingDataToBdat
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibDsdt.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibDsdt.c
new file mode 100644
index 0000000000..29722c1269
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibDsdt.c
@@ -0,0 +1,673 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatformLibLocal.h"
+
+
+#define CPM_MMIO_SIZE           0x100000000         // 4G MMIO resource for CPM
+#define HQM_MMIO_SIZE           0x400000000         // 16G MMIO resource for HQM
+
+extern BIOS_ACPI_PARAM             *mAcpiParameter;
+extern struct SystemMemoryMapHob   *mSystemMemoryMap;
+extern EFI_IIO_UDS_PROTOCOL        *mIioUds;
+extern CPU_CSR_ACCESS_VAR          *mCpuCsrAccessVarPtr;
+
+extern SOCKET_MP_LINK_CONFIGURATION  mSocketMpLinkConfiguration;
+extern SOCKET_IIO_CONFIGURATION     mSocketIioConfiguration;
+extern SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanagementConfiguration;
+
+extern BOOLEAN      mCpuOrderSorted;
+extern UINT32       mApicIdMap[MAX_SOCKET][MAX_CORE * MAX_THREAD];
+extern UINT32       mNumOfBitShift;
+extern CPU_ID_ORDER_MAP             mCpuApicIdOrderTable[MAX_CPU_NUM];
+
+
+AML_OFFSET_TABLE_ENTRY            *mAmlOffsetTablePointer = NULL;
+
+/**
+    Check current thread status
+
+    @param ApicId - current thread ApicId
+
+    @retval EFI_SUCCESS     Returns Success if current thread is active
+    @retval EFI_UNSUPPORTED Table is not supported
+**/
+EFI_STATUS
+CheckCurrentThreadStatus (
+  UINT32 ApicId
+  )
+{
+  UINT32 Index;
+
+  for (Index = 0; Index < MAX_CPU_NUM; Index++) {
+    if ((mCpuApicIdOrderTable[Index].Flags == 1) && (mCpuApicIdOrderTable[Index].ApicId == ApicId)) {
+      return EFI_SUCCESS;
+    }
+  }
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+  Get socket, stack and optionaly port index from PCI device path.
+
+  The PCI device path is typically:
+  '_SB_.PCxy.FIXz' for PCIe stack object
+  '_SB_.UCxy.FIXz' for UBOX stack object
+  '_SB_.PCxy.RPya' for PCIe bridge root port object
+  where x and y are hex digits, and 'a' is a letter like 'A', 'B',..,'H'.
+
+  NOTE: 'xy' is decimal number of subsequent PCIe stack, not including UBOX.
+        For UBOX UCxy, 'x' is socket, 'y' is stack.
+
+  @param[in]  DevPathPtr - PCI device path, e.g. '_SB_.PC00.FIX1'
+  @param[out] SocketPtr  - Buffer for socket index.
+  @param[out] StackPtr   - Buffer for stack index.
+  @param[out] PortkPtr   - Buffer for port index.
+**/
+VOID
+AcpiPciDevPath2SktStkPort (
+  IN  CHAR8  *DevPathPtr,
+  OUT UINT8  *SocketPtr,
+  OUT UINT8  *StackPtr,
+  OUT UINT8  *PortPtr
+  )
+{
+  UINT16 SysStackNo;
+  UINT8  SocketNo = 0xFF;
+  UINT8  StackNo = 0xFF;
+  UINT8  PortNo = 0xFF;
+
+  if (PortPtr != NULL) {
+    //
+    // Device path should contain bridge root port object, let's verify.
+    //
+    if (AsciiStrLen (DevPathPtr) < 3*4 + 2 ||
+        DevPathPtr[10]  != 'R' || DevPathPtr[12]  != 'P' || DevPathPtr[13]  < 'A' || DevPathPtr[13]  > 'H') {
+
+      goto ErrExit;
+    }
+    PortNo = DevPathPtr[13] - 'A';
+  }
+  if (AsciiStrLen (DevPathPtr) < 2*4 + 1 || DevPathPtr[7]  < '0' || DevPathPtr[8]  < '0') {
+
+    goto ErrExit;
+  }
+  switch (DevPathPtr[5] << 8 | DevPathPtr[6]) {
+
+    case ('P' << 8 | 'C'):
+      if (DevPathPtr[7] > '9' || DevPathPtr[8] > '9') {
+
+        goto ErrExit;
+      }
+      SysStackNo = (DevPathPtr[7] - '0') * 10;
+      SysStackNo += DevPathPtr[8] - '0';
+      SocketNo = (UINT8)(SysStackNo / MAX_IIO_STACK);
+      StackNo = (UINT8)(SysStackNo % MAX_IIO_STACK);
+      break;
+
+    case ('U' << 8 | 'C'):
+      if (DevPathPtr[7] <= '9') {
+
+        SocketNo = DevPathPtr[7] - '0';
+
+      } else if (DevPathPtr[7] <= 'F') {
+
+        if (DevPathPtr[7] < 'A') {
+
+          goto ErrExit;
+        }
+        SocketNo = 10 + DevPathPtr[7] - 'A';
+
+      } else if (DevPathPtr[7] <= 'f') {
+
+        if (DevPathPtr[7] < 'a') {
+
+          goto ErrExit;
+        }
+        SocketNo = 10 + DevPathPtr[7] - 'a';
+
+      } else {
+        goto ErrExit;
+      }
+      if (DevPathPtr[8] <= '9') {
+
+        StackNo = DevPathPtr[8] - '0';
+
+      } else if (DevPathPtr[8] <= 'F') {
+
+        if (DevPathPtr[8] < 'A') {
+
+          goto ErrExit;
+        }
+        StackNo = 10 + DevPathPtr[8] - 'A';
+
+      } else {
+        goto ErrExit;
+      }
+      break;
+
+    default:
+    ErrExit:
+      DEBUG ((DEBUG_ERROR, "[ACPI] ERROR: String '%a' is not valid PCI stack name, ", DevPathPtr));
+      DEBUG ((DEBUG_ERROR, "expect _SB_.PCxy.FIXz, or _SB_.UCxv.FIXz, or _SB_.PCxy.RPya\n"));
+      break;
+  }
+  if (SocketPtr != NULL) {
+    *SocketPtr = SocketNo;
+  }
+  if (StackPtr != NULL) {
+    *StackPtr = StackNo;
+  }
+  if (PortPtr != NULL) {
+    *PortPtr = PortNo;
+  }
+  return;
+}
+
+
+/**
+  Update the DSDT table
+
+  @param[in,out] *Table   - The table to be set
+
+  @retval EFI_SUCCESS - DSDT updated
+  @retval EFI_INVALID_PARAMETER - DSDT not updated
+**/
+EFI_STATUS
+PatchDsdtTable (
+  IN OUT EFI_ACPI_COMMON_HEADER   *Table
+  )
+{
+  EFI_STATUS Status;
+  UINT8                         *DsdtPointer;
+  UINT32                        *Signature;
+  UINT32                        *Signature2;
+  UINT32                        Fixes;
+  UINT32                        NodeIndex;
+  UINT8                         Counter;
+  UINT16                        i;  // DSDT_PLATEXRP_OffsetTable LUT entries extends beyond 256!
+  UINT8                         BusBase = 0, BusLimit = 0;
+  UINT16                        IoBase  = 0, IoLimit  = 0;
+  UINT32                        MemBase32 = 0, MemLimit32 = 0;
+  UINT64                        MemBase64 = 0, MemLimit64 = 0;
+  AML_RESOURCE_ADDRESS16        *AmlResourceAddress16Pointer;
+  AML_RESOURCE_ADDRESS32        *AmlResourceAddress32Pointer;
+  AML_RESOURCE_ADDRESS64        *AmlResourceAddress64Pointer;
+  EFI_ACPI_DESCRIPTION_HEADER   *TableHeader;
+  UINT32                        AdjustSize = 0;
+  UINT32                        CpuSkt = 0;
+  UINT32                        CpuIndex = 0;
+  ACPI_NAMEPACK_DWORD           *NamePtr;
+  UINT8                         *CurrPtr;
+  UINT8                         *EndPtr;
+  const UINT32                  *ApicMapPtr;
+  UINT8                         Socket;
+  UINT8                         Stack;
+  UINT8                         UboxStack;
+  UINT8                         PropagateSerrOption;
+  UINT8                         PropagatePerrOption;
+
+  Status = GetOptionData (&gEfiSetupVariableGuid, OFFSET_OF(SYSTEM_CONFIGURATION, PropagateSerr), &PropagateSerrOption, sizeof(PropagateSerrOption));
+  if (EFI_ERROR (Status)) {
+    mAcpiParameter->PropagateSerrOption = 1;
+  } else {
+    mAcpiParameter->PropagateSerrOption = PropagateSerrOption;
+  }
+
+  Status = GetOptionData (&gEfiSetupVariableGuid, OFFSET_OF(SYSTEM_CONFIGURATION, PropagatePerr), &PropagatePerrOption, sizeof(PropagatePerrOption));
+  if (EFI_ERROR (Status)) {
+    mAcpiParameter->PropagatePerrOption = 1;
+  } else {
+    mAcpiParameter->PropagatePerrOption = PropagatePerrOption;
+  }
+
+  TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *)Table;
+
+  if (mAmlOffsetTablePointer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  mAcpiParameter->SocketBitMask = mCpuCsrAccessVarPtr->socketPresentBitMap;
+
+  for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+    if (!mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].Valid) {
+      mAcpiParameter->IioPresentBitMask[Socket] = 0;
+      continue;
+    }
+    mAcpiParameter->IioPresentBitMask[Socket] = mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap;
+    for (Stack = 0; Stack < MAX_LOGIC_IIO_STACK; Stack++) {
+
+      mAcpiParameter->BusBase[Socket][Stack] = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].BusBase;
+      DEBUG ((DEBUG_INFO, "[ACPI](DSDT) [%d.%d] BusBase: 0x%02X\n", Socket, Stack, mAcpiParameter->BusBase[Socket][Stack]));
+    }
+  } // for (Socket...)
+
+  //
+  // Update IIO PCIe Root Port PCIe Capability offset
+  // for 10nm process CPUs with PCIe GEN4/GEN5 controller, PCIe Capability offset is at 0x40
+  //
+  mAcpiParameter->IioPcieRpCapOffset = 0x40;
+
+  //
+  // Initialize TsegSize - 1MB aligned.
+  //
+  Fixes = 0;
+  //
+  // Loop through the AML looking for values that we must fix up.
+  //
+  for (i = 0; mAmlOffsetTablePointer[i].Pathname != 0; i++) {
+    //
+    // Point to offset in DSDT for current item in AmlOffsetTable.
+    //
+    DsdtPointer = (UINT8 *) (TableHeader) + mAmlOffsetTablePointer[i].Offset;
+
+    if (mAmlOffsetTablePointer[i].Opcode == AML_DWORD_PREFIX) {
+      //
+      // If Opcode is 0x0C, then operator is Name() or OperationRegion().
+      // (TableHeader + AmlOffsetTable.Offset) is at offset for value to change.
+      //
+      // The assert below confirms that AML structure matches the offsets table.
+      // If not then patching the AML would just corrupt it and result in OS failure.
+      // If you encounter this assert something went wrong in *.offset.h files
+      // generation. Remove the files and rebuild.
+      //
+      ASSERT (DsdtPointer[-1] == mAmlOffsetTablePointer[i].Opcode);
+      //
+      // AmlOffsetTable.Value has FIX tag, so check that to decide what to modify.
+      //
+      Signature = (UINT32 *) (&mAmlOffsetTablePointer[i].Value);
+      switch (*Signature) {
+        //
+        // Due to iASL compiler change and DSDT patch design change, if these items need support
+        // then the ASI files will need to conform to the format requires for iASL to add the items
+        // to the offset table, and we will need to filter them out when iASL is executed.
+        //
+        // "FIX0" OperationRegion() in Acpi\AcpiTables\Dsdt\CommonPlatform.asi
+        //
+        case (SIGNATURE_32 ('F', 'I', 'X', '0')):
+          *(UINT32*)DsdtPointer = (UINT32)(UINTN)mAcpiParameter;
+          Fixes++;
+          break;
+
+        default:
+          DEBUG ((DEBUG_ERROR, "[ACPI](DSDT) WARNING: Object '%a' with opcode 0x%02X not patched\n",
+                  mAmlOffsetTablePointer[i].Pathname, mAmlOffsetTablePointer[i].Opcode));
+          break;
+      }
+    } else if (mAmlOffsetTablePointer[i].Opcode == AML_INDEX_OP) {
+      //
+      // If Opcode is 0x88, then operator is WORDBusNumber() or WORDIO().
+      // (TableHeader + AmlOffsetTable.Offset) must be cast to AML_RESOURCE_ADDRESS16 to change values.
+      //
+      AmlResourceAddress16Pointer = (AML_RESOURCE_ADDRESS16 *) (DsdtPointer);
+      //
+      // The assert below confirms that AML structure matches the offsets table.
+      // If not then patching the AML would just corrupt it and result in OS failure.
+      // If you encounter this assert something went wrong in *.offset.h files
+      // generation. Remove the files and rebuild.
+      //
+      ASSERT (AmlResourceAddress16Pointer->DescriptorType == mAmlOffsetTablePointer[i].Opcode);
+
+      //
+      // Last 4 chars of AmlOffsetTable.Pathname has FIX tag.
+      //
+      Signature = (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + AsciiStrLen(mAmlOffsetTablePointer[i].Pathname) - 4);
+      Signature2 = (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + AsciiStrLen(mAmlOffsetTablePointer[i].Pathname) - 9);
+      switch (*Signature) {
+        //
+        // "FIX1" BUS resource for PCXX in Acpi\AcpiTables\Dsdt\SysBus.asi and PCXX.asi
+        //
+        case (SIGNATURE_32 ('F', 'I', 'X', '1')):
+          AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &Socket, &Stack, NULL);
+
+          BusBase = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].BusBase;
+          BusLimit = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].BusLimit;
+
+          AmlResourceAddress16Pointer->Granularity = 0;
+          if ((BusLimit > BusBase)) {
+            AmlResourceAddress16Pointer->Minimum = (UINT16) BusBase;
+            AmlResourceAddress16Pointer->Maximum = (UINT16) BusLimit;
+            AmlResourceAddress16Pointer->AddressLength = (UINT16) (BusLimit - BusBase + 1);
+          }
+
+          Fixes++;
+          break;
+
+        //
+        // "FIXB" BUS resource for FpgaKtiXX in Acpi\AcpiTables\Dsdt\FpgaKtiXX.asi
+        //
+        case (SIGNATURE_32 ('F', 'I', 'X', 'B')):
+          break;
+
+        //
+        // "FIX2" IO resource for for PCXX in Acpi\AcpiTables\Dsdt\SysBus.asi and PCXX.asi
+        //
+        case (SIGNATURE_32 ('F', 'I', 'X', '2')):
+          AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &Socket, &Stack, NULL);
+
+          IoBase = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceIoBase;
+          IoLimit = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceIoLimit;
+          if (IoLimit > IoBase) {
+            AmlResourceAddress16Pointer->Minimum = (UINT16) IoBase;
+            AmlResourceAddress16Pointer->Maximum = (UINT16) IoLimit;
+            AmlResourceAddress16Pointer->AddressLength = (UINT16) (IoLimit - IoBase + 1);
+          }
+          AmlResourceAddress16Pointer->Granularity = 0;
+
+          Fixes++;
+          break;
+
+        //
+        // "FIX9" BUS resource for UNXX in Acpi\AcpiTables\Dsdt\Uncore.asi
+        //
+        case (SIGNATURE_32('F', 'I', 'X', '9')) :
+          AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &Socket, &Stack, NULL);
+          UboxStack = UBOX_STACK;
+          BusBase = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[UboxStack].BusBase;
+          BusLimit = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[UboxStack].BusLimit;
+          if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[UboxStack].Personality != TYPE_UBOX ||
+              BusBase > BusLimit) {
+
+            DEBUG ((DEBUG_ERROR, "[ACPI](DSDT) ERROR: Stack [%d.%d] of type %d is not UBOX, '%a' not patched\n",
+                    Socket, UboxStack, mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[UboxStack].Personality,
+                    mAmlOffsetTablePointer[i].Pathname));
+            break;
+          }
+          AmlResourceAddress16Pointer->Granularity = 0;
+          if (Stack & 1) {
+            AmlResourceAddress16Pointer->Minimum = BusLimit;
+            AmlResourceAddress16Pointer->Maximum = BusLimit;
+          } else {
+            AmlResourceAddress16Pointer->Minimum = BusBase;
+            AmlResourceAddress16Pointer->Maximum = BusBase;
+          }
+          AmlResourceAddress16Pointer->AddressLength = 1;
+          mAcpiParameter->BusBase[Socket][Stack] = (UINT8)AmlResourceAddress16Pointer->Minimum;
+          mAcpiParameter->IioPresentBitMask[Socket] |= 1 << Stack;
+          Fixes++;
+          break;
+
+        //
+        // "FIX6" IO resource for PCXX in Acpi\AcpiTables\Dsdt\PCXX.asi
+        //
+        case (SIGNATURE_32 ('F', 'I', 'X', '6')):
+          AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &Socket, &Stack, NULL);
+          AmlResourceAddress16Pointer->Granularity = 0;
+          if ((mSocketMpLinkConfiguration.LegacyVgaSoc == Socket) &&
+              (mSocketMpLinkConfiguration.LegacyVgaStack == Stack)){
+
+            AmlResourceAddress16Pointer->Minimum = (UINT16) 0x03b0;
+            AmlResourceAddress16Pointer->Maximum = (UINT16) 0x03bb;
+            AmlResourceAddress16Pointer->AddressLength = (UINT16) 0x000C;
+          }
+          Fixes++;
+         break;
+
+        //
+        // "FIX7" IO resource for PCXX in Acpi\AcpiTables\Dsdt\PCXX.asi
+        //
+        case (SIGNATURE_32 ('F', 'I', 'X', '7')):
+          AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &Socket, &Stack, NULL);
+          AmlResourceAddress16Pointer->Granularity = 0;
+          if ((mSocketMpLinkConfiguration.LegacyVgaSoc == Socket) &&
+              (mSocketMpLinkConfiguration.LegacyVgaStack == Stack)) {
+
+            AmlResourceAddress16Pointer->Minimum = (UINT16) 0x03c0;
+            AmlResourceAddress16Pointer->Maximum = (UINT16) 0x03df;
+            AmlResourceAddress16Pointer->AddressLength = (UINT16) 0x0020;
+          }
+          Fixes++;
+          break;
+
+        default:
+          DEBUG ((DEBUG_ERROR, "[ACPI](DSDT) WARNING: Object '%a' with opcode 0x%02X not patched\n",
+                  mAmlOffsetTablePointer[i].Pathname, mAmlOffsetTablePointer[i].Opcode));
+          break;
+      }
+    } else if (mAmlOffsetTablePointer[i].Opcode == AML_SIZE_OF_OP) {
+      //
+      // If Opcode is 0x87, then operator is DWORDMemory().
+      // (TableHeader + AmlOffsetTable.Offset) must be cast to AML_RESOURCE_ADDRESS32 to change values.
+      //
+      AmlResourceAddress32Pointer = (AML_RESOURCE_ADDRESS32 *) (DsdtPointer);
+      //
+      // The assert below confirms that AML structure matches the offsets table.
+      // If not then patching the AML would just corrupt it and result in OS failure.
+      // If you encounter this assert something went wrong in *.offset.h files
+      // generation. Remove the files and rebuild.
+      //
+      ASSERT (AmlResourceAddress32Pointer->DescriptorType == mAmlOffsetTablePointer[i].Opcode);
+      //
+      // Last 4 chars of AmlOffsetTable.Pathname has FIX tag.
+      //
+      Signature = (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + AsciiStrLen(mAmlOffsetTablePointer[i].Pathname) - 4);
+      Signature2 = (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + AsciiStrLen(mAmlOffsetTablePointer[i].Pathname) - 9);
+      switch (*Signature) {
+        //
+        // "FIX3" PCI32 resource for PCXX in Acpi\AcpiTables\Dsdt\SysBus.asi and PCXX.asi
+        //
+        case (SIGNATURE_32 ('F', 'I', 'X', '3')):
+          AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &Socket, &Stack, NULL);
+
+          MemBase32 = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem32Base;
+          MemLimit32 = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem32Limit;
+
+          if (MemLimit32 > MemBase32) {
+            AmlResourceAddress32Pointer->Minimum = (UINT32) MemBase32;
+            AmlResourceAddress32Pointer->Maximum = (UINT32) MemLimit32;
+            AmlResourceAddress32Pointer->AddressLength = (UINT32) (MemLimit32 - MemBase32 + 1);
+          }
+          AmlResourceAddress32Pointer->Granularity = 0;
+
+          Fixes++;
+          break;
+
+        //
+        // "FIX5" IO resource for PCXX in Acpi\AcpiTables\Dsdt\PCXX.asi
+        //
+        case (SIGNATURE_32 ('F', 'I', 'X', '5')):
+          AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &Socket, &Stack, NULL);
+          AmlResourceAddress32Pointer->Granularity = 0;
+          if ((mSocketMpLinkConfiguration.LegacyVgaSoc == Socket) &&
+              (mSocketMpLinkConfiguration.LegacyVgaStack == Stack)) {
+              AmlResourceAddress32Pointer->Minimum = 0x000a0000;
+              AmlResourceAddress32Pointer->Maximum = 0x000bffff;
+              AmlResourceAddress32Pointer->AddressLength = 0x00020000;
+          }
+          Fixes++;
+          break;
+
+        //
+        // "FIXZ" IO resource for FpgaBusXX in Acpi\AcpiTables\Dsdt\FpgaBusXX.asi
+        //
+        case (SIGNATURE_32 ('F', 'I', 'X', 'Z')):
+          break;
+
+        default:
+          DEBUG ((DEBUG_ERROR, "[ACPI](DSDT) WARNING: Object '%a' with opcode 0x%02X not patched\n",
+                  mAmlOffsetTablePointer[i].Pathname, mAmlOffsetTablePointer[i].Opcode));
+          break;
+      }
+    } else if (mAmlOffsetTablePointer[i].Opcode == AML_CREATE_DWORD_FIELD_OP) {
+      //
+      // If Opcode is 0x8A, then operator is QWORDMemory().
+      // (TableHeader + AmlOffsetTable.Offset) must be cast to AML_RESOURCE_ADDRESS64 to change values.
+      //
+      AmlResourceAddress64Pointer = (AML_RESOURCE_ADDRESS64 *) (DsdtPointer);
+      //
+      // The assert below confirms that AML structure matches the offsets table.
+      // If not then patching the AML would just corrupt it and result in OS failure.
+      // If you encounter this assert something went wrong in *.offset.h files
+      // generation. Remove the files and rebuild.
+      //
+      ASSERT (AmlResourceAddress64Pointer->DescriptorType == mAmlOffsetTablePointer[i].Opcode);
+      //
+      // Last 4 chars of AmlOffsetTable.Pathname has FIX tag.
+      //
+      Signature = (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + AsciiStrLen(mAmlOffsetTablePointer[i].Pathname) - 4);
+      Signature2 = (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + AsciiStrLen(mAmlOffsetTablePointer[i].Pathname) - 9);
+      switch (*Signature) {
+        //
+        // "FIX4" PCI64 resource for PCXX in Acpi\AcpiTables\Dsdt\SysBus.asi and PCXX.asi
+        //
+        case (SIGNATURE_32 ('F', 'I', 'X', '4')):
+          if (mSocketIioConfiguration.Pci64BitResourceAllocation) {
+
+            AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &Socket, &Stack, NULL);
+            MemBase64 = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem64Base;
+            MemLimit64 = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem64Limit;
+            if (MemLimit64 > MemBase64) {
+              AmlResourceAddress64Pointer->Granularity = 0;
+              AmlResourceAddress64Pointer->Minimum = (UINT64) MemBase64;
+              AmlResourceAddress64Pointer->Maximum = (UINT64) MemLimit64;
+              AmlResourceAddress64Pointer->AddressLength = (UINT64) (MemLimit64 - MemBase64 + 1);
+            }
+
+            Fixes++;
+          }
+          break;
+
+        default:
+          DEBUG ((DEBUG_ERROR, "[ACPI](DSDT) WARNING: Object '%a' with opcode 0x%02X not patched\n",
+                  mAmlOffsetTablePointer[i].Pathname, mAmlOffsetTablePointer[i].Opcode));
+          break;
+      }
+    } else {
+      DEBUG ((DEBUG_ERROR, "[ACPI](DSDT) WARNING: Object '%a' with opcode 0x%02X not patched\n",
+              mAmlOffsetTablePointer[i].Pathname, mAmlOffsetTablePointer[i].Opcode));
+    }
+  }
+
+  // CurrPtr = beginning of table
+  //
+  CurrPtr = (UINT8 *) TableHeader;
+
+  // EndPtr = beginning of table + length of table
+  //
+  EndPtr = (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length);
+
+  // Subtract from End Ptr the largest data item we read from table
+  //  so we don't try to access data beyond end of table
+  //
+  EndPtr -= 9;
+
+  for (DsdtPointer = CurrPtr; DsdtPointer <= EndPtr; DsdtPointer++) {
+
+    //
+    // fix CpuMemHp.asi, force no same ASL code string as it...
+    //
+    if ((DsdtPointer[0] == 'C') && (DsdtPointer[6] == 0x4)  && (DsdtPointer[5] == 0x10)) {
+      if (mCpuOrderSorted) {
+        CpuSkt = (UINT32) DsdtPointer[4];
+        AdjustSize = 0;
+        if ((DsdtPointer[1] > '0') && (DsdtPointer[1] <= '9')) {
+          AdjustSize = (UINT32) ((DsdtPointer[1] -'0') * 0x100);
+        } else if ((DsdtPointer[1] >= 'A') && (DsdtPointer[1] <= 'F')) {
+          AdjustSize = (UINT32) ((DsdtPointer[1] -'A' + 10) * 0x100);
+        }
+
+        CpuIndex = AdjustSize;
+
+        AdjustSize = 0;
+        if ((DsdtPointer[2] > '0') && (DsdtPointer[2] <= '9')) {
+          AdjustSize = (UINT32) ((DsdtPointer[2] -'0') * 0x10);
+        } else if ((DsdtPointer[2] >= 'A') && (DsdtPointer[2] <= 'F')) {
+          AdjustSize = (UINT32) ((DsdtPointer[2] -'A' + 10) * 0x10);
+        }
+
+        CpuIndex += AdjustSize;
+
+        AdjustSize = 0;
+        if ((DsdtPointer[3] > '0') && (DsdtPointer[3] <= '9')) {
+          AdjustSize = (UINT32) (DsdtPointer[3] -'0');
+        } else if ((DsdtPointer[3] >= 'A') && (DsdtPointer[3] <= 'F')) {
+          AdjustSize = (UINT32) (DsdtPointer[3] -'A' + 10);
+        }
+
+        CpuIndex += AdjustSize;
+
+        NodeIndex = (UINT32) (CpuSkt << mNumOfBitShift) + mApicIdMap[CpuSkt][CpuIndex] ;
+
+        DsdtPointer[4] = (UINT8) 0xFF;
+        if (((mCpuCsrAccessVarPtr->socketPresentBitMap >> CpuSkt) & BIT0) == 1) {
+          if (CheckCurrentThreadStatus (NodeIndex) == EFI_SUCCESS) {
+            DsdtPointer[4] = (UINT8) (NodeIndex & 0xFF);
+          }
+        }
+
+        //
+        // Update IO Address
+        //
+        *(UINT16 *)(DsdtPointer+5) = (UINT16)(PM_BASE_ADDRESS + 0x10);
+      }
+    }
+
+    for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+
+      if ((mCpuCsrAccessVarPtr->socketPresentBitMap & (BIT0 << Socket)) == 0) {
+        continue;
+      }
+      //
+      // Find APT##socket name
+      //
+      if ((DsdtPointer[0] == 'A') && (DsdtPointer[1] == 'P') && (DsdtPointer[2] == 'T') && (DsdtPointer[3] == '0' + Socket)) {
+        NamePtr = ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (DsdtPointer);
+        ApicMapPtr = mApicIdMap[Socket];
+        if (NamePtr->StartByte != AML_NAME_OP) {
+          continue;
+        }
+
+        Counter = DsdtPointer[8];
+        ASSERT (Counter >= (UINT32) (MAX_THREAD * MAX_CORE));
+        DEBUG ((DEBUG_INFO, "\n::ACPI::  Found 'APT%x'...Counter = DsdtPointer[7] = %x\n\n", Socket, Counter));
+         for (i = 0; i < (MAX_THREAD * MAX_CORE); i++) {
+           DEBUG ((DEBUG_VERBOSE, "Before override, DsdtPointer[%x] = %x,   ", i, DsdtPointer[i+9]));
+           DsdtPointer[i+9] = (UINT8)ApicMapPtr[i];
+           DEBUG ((DEBUG_VERBOSE, "Then override value = %x \n", DsdtPointer[i+9]));
+         }
+      }
+    }
+    //
+    // Fix up _S3
+    //
+    if ((DsdtPointer[0] == '_') && (DsdtPointer[1] == 'S') && (DsdtPointer[2] == '3')) {
+      NamePtr = ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (DsdtPointer);
+      if (NamePtr->StartByte != AML_NAME_OP) {
+        continue;
+      }
+
+      if (!mSocketPowermanagementConfiguration.AcpiS3Enable) {
+        //
+        // S3 disabled
+        //
+        DsdtPointer[0] = 'D';
+      }
+    }
+    //
+    // Fix up _S4
+    //
+    if ((DsdtPointer[0] == '_') && (DsdtPointer[1] == 'S') && (DsdtPointer[2] == '4')) {
+      NamePtr = ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (DsdtPointer);
+      if (NamePtr->StartByte != AML_NAME_OP) {
+        continue;
+      }
+      if (!mSocketPowermanagementConfiguration.AcpiS4Enable) {
+        //
+        // S4 disabled
+        //
+        DsdtPointer[0] = 'D';
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibFadt.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibFadt.c
new file mode 100644
index 0000000000..4cdb540a6a
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibFadt.c
@@ -0,0 +1,75 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2018 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatformLibLocal.h"
+#include <Library/PchPcieRpLib.h>
+
+extern UINT8                 mKBPresent;
+extern UINT8                 mMousePresent;
+extern SOCKET_PROCESSORCORE_CONFIGURATION   mSocketProcessorCoreConfiguration;
+extern SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanagementConfiguration;
+
+
+EFI_STATUS
+PatchFadtTable (
+   IN OUT   EFI_ACPI_COMMON_HEADER  *Table
+   )
+{
+  UINT16                                    LegacyDevice;
+  EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader;
+  EFI_STATUS                                Status;
+  UINT8                                     PcieGlobalAspm;
+
+  Status = GetOptionData (&gEfiSocketIioVariableGuid, OFFSET_OF(SOCKET_IIO_CONFIGURATION, PcieGlobalAspm), &PcieGlobalAspm, sizeof(UINT8));
+  if (EFI_ERROR (Status)) {
+    PcieGlobalAspm = 0x2;
+  }
+
+  //
+  // Patch FADT for legacy free
+  //
+  LegacyDevice  = 0;
+  FadtHeader    = (EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE *) Table;
+
+  //
+  // Control of setting ASPM disabled bit in FADT
+  //
+  switch (mSocketPowermanagementConfiguration.NativeAspmEnable) {
+
+  case 0:
+    LegacyDevice |= (1 << 4);
+    break;
+
+  case 1:
+    LegacyDevice &= ~(1 << 4);
+    break;
+
+  case 2:
+    if (PcieGlobalAspm == 0) {
+      LegacyDevice |= (1 << 4);
+    } else {
+      LegacyDevice &= ~(1 << 4);
+    }
+    break;
+
+  default:
+    LegacyDevice &= ~(1 << 4);
+    DEBUG ((DEBUG_ERROR, "\n Native ASPM = %d is not valid (expected values are 0, 1, 2). \n", mSocketPowermanagementConfiguration.NativeAspmEnable ));
+    ASSERT (0);
+    break;
+  }
+
+  FadtHeader->IaPcBootArch = LegacyDevice;
+  FadtHeader->Flags |= (mSocketProcessorCoreConfiguration.ForcePhysicalModeEnable) ? EFI_ACPI_6_2_FORCE_APIC_PHYSICAL_DESTINATION_MODE : 0;
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibHmat.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibHmat.c
new file mode 100644
index 0000000000..277c956196
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibHmat.c
@@ -0,0 +1,1710 @@
+/** @file
+  ACPI Platform Library HMAT
+
+  @copyright
+  Copyright 2016 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatformLibLocal.h"
+#include <Library/MemTypeLib.h>
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/SmBios.h>
+
+//
+// The represented latency/bandwidth in 'System Locality Latency and Bandwidth
+// Information Structure' is expressed in multiples of Entry Base Unit.
+// Unit of latency is picoseconds and bandwidth is megabytes per second
+// Below #defines are be base units and values for calcualting the latency/bandwidth
+// For example: read latency of DDRT is 180ns which is 180000 picoseconds.
+// This is expressed as DDRT_LATENCY_BASE_UNIT of 1000 and DDRT_READ_LATENCY of 180
+//
+
+#define MEMORY_LATENCY_BASE_UNIT 100
+#define MEMORY_BANDWIDTH_BASE_UNIT 1
+#define DDR2LMCACHE_LATENCY_BASE_UNIT 100
+#define DDR2LMCACHE_BANDWIDTH_BASE_UNIT 1
+
+#define XSOCKET_LATENCY_BASE_UNIT 100
+#define XSOCKET_BANDWIDTH_BASE_UNIT 1
+
+//
+// DDRT values
+//
+#define DDRT_ACCESS_LATENCY 0
+#define DDRT_1LM_READ_LATENCY 2535
+#define DDRT_2LM_READ_LATENCY 3285
+#define DDRT_1LM_WRITE_LATENCY 2535
+#define DDRT_2LM_WRITE_LATENCY 3285
+#define DDRT_ACCESS_BANDWIDTH 0
+#define DDRT_1LM_READ_BANDWIDTH 4625
+#define DDRT_2LM_READ_BANDWIDTH 4625
+#define DDRT_1LM_WRITE_BANDWIDTH 1375
+#define DDRT_2LM_WRITE_BANDWIDTH 1375
+
+//
+// X-SOCKET values
+//
+#define XSOCKET_DDRT_1LM_ACCESS_LATENCY 0
+#define XSOCKET_DDRT_1LM_READ_LATENCY 3160
+#define XSOCKET_DDRT_1LM_WRITE_LATENCY 3160
+#define XSOCKET_DDRT_1LM_ACCESS_BANDWIDTH 0
+#define XSOCKET_DDRT_1LM_READ_BANDWIDTH 4625
+#define XSOCKET_DDRT_1LM_WRITE_BANDWIDTH 1375
+
+#define XSOCKET_DDRT_2LM_ACCESS_LATENCY 0
+#define XSOCKET_DDRT_2LM_READ_LATENCY 3885
+#define XSOCKET_DDRT_2LM_WRITE_LATENCY 3885
+#define XSOCKET_DDRT_2LM_ACCESS_BANDWIDTH 0
+#define XSOCKET_DDRT_2LM_READ_BANDWIDTH 4625
+#define XSOCKET_DDRT_2LM_WRITE_BANDWIDTH 1375
+
+//
+// DDR values 1LM or flat mode
+//
+#define DDR_ACCESS_LATENCY 0
+#define DDR_READ_LATENCY 760
+#define DDR_WRITE_LATENCY 760
+#define DDR_ACCESS_BANDWIDTH 0
+#define DDR_READ_BANDWIDTH 17900
+#define DDR_WRITE_BANDWIDTH 19100
+
+//
+// X-Socket DDR values 1LM or flat mode
+//
+#define XSOCKET_DDR_ACCESS_LATENCY 0
+#define XSOCKET_DDR_READ_LATENCY 1356
+#define XSOCKET_DDR_WRITE_LATENCY 1356
+#define XSOCKET_DDR_ACCESS_BANDWIDTH 0
+#define XSOCKET_DDR_READ_BANDWIDTH 17900
+#define XSOCKET_DDR_WRITE_BANDWIDTH 19100
+
+//
+// DDR/X-Socket DDR values 2LM when acting as cache
+//
+#define DDR2LMCACHE_ACCESS_LATENCY 0
+#define DDR2LMCACHE_READ_LATENCY 760
+#define DDR2LMCACHE_WRITE_LATENCY 760
+#define DDR2LMCACHE_ACCESS_BANDWIDTH 0
+#define DDR2LMCACHE_READ_BANDWIDTH 17900
+#define DDR2LMCACHE_WRITE_BANDWIDTH 12691
+
+
+extern struct SystemMemoryMapHob    *mSystemMemoryMap;
+extern EFI_IIO_UDS_PROTOCOL         *mIioUds;
+extern SOCKET_MEMORY_CONFIGURATION  mSocketMemoryConfiguration;
+extern CPU_CSR_ACCESS_VAR           *mCpuCsrAccessVarPtr;
+
+UINT8   SkippedEntries = 0;
+
+typedef enum {
+  DDR = 0x00,
+  DDRT,
+  DDR2LMCACHE
+} MemoryType;
+
+
+/**
+  Dump HMAT Header
+
+  @param [in]      HdrPtr       Pointer to HMAT Header
+
+  @retval None
+**/
+VOID
+DumpHeader (
+  EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER *HdrPtr
+  )
+{
+  DEBUG ((DEBUG_INFO, "=========== HMAT header ==========\n"));
+  DEBUG ((DEBUG_INFO, " Signature:          %.4a\n",  (CHAR8 *)&HdrPtr->Header.Signature));
+  DEBUG ((DEBUG_INFO, " Length:             %d\n",    HdrPtr->Header.Length));
+  DEBUG ((DEBUG_INFO, " Revision:           %Xh\n",   HdrPtr->Header.Revision));
+  DEBUG ((DEBUG_INFO, " Checksum:           N/A - CHECKSUM ADDED LATER\n"));
+  DEBUG ((DEBUG_INFO, " OemId:              %.6a\n",  HdrPtr->Header.OemId));
+  DEBUG ((DEBUG_INFO, " OemTableId:         %.8a\n",  (CHAR8 *)&HdrPtr->Header.OemTableId));
+  DEBUG ((DEBUG_INFO, " OemRevision:        %Xh\n",   HdrPtr->Header.OemRevision));
+  DEBUG ((DEBUG_INFO, " CreatorId:          %.4a\n",  (CHAR8 *)&HdrPtr->Header.CreatorId));
+  DEBUG ((DEBUG_INFO, " CreatorRevision:    %Xh\n",   HdrPtr->Header.CreatorRevision));
+  DEBUG ((DEBUG_INFO, "==================================\n"));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+/**
+  Dump MSARS Structure
+
+  @param [in]      MsarsPtr       Pointer to MSARS Structure
+
+  @retval None
+**/
+VOID
+DumpMsars (
+  MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE *MsarsPtr
+  )
+{
+  DEBUG ((DEBUG_INFO, "=========== MSARS Table =============================\n"));
+  DEBUG ((DEBUG_INFO, " Type:                               %d\n",    MsarsPtr->Type));
+  DEBUG ((DEBUG_INFO, " Length:                             %d\n",    MsarsPtr->Length));
+  DEBUG ((DEBUG_INFO, " ProcessorDomainValid:               %d\n",    MsarsPtr->Flags.Bits.ProcessorDomainValid));
+  DEBUG ((DEBUG_INFO, " MemoryDomainValid:                  %d\n",    MsarsPtr->Flags.Bits.MemoryDomainValid));
+  DEBUG ((DEBUG_INFO, " ReservationHint:                    %d\n",    MsarsPtr->Flags.Bits.ReservationHint));
+  DEBUG ((DEBUG_INFO, " ProcessorProximityDomain:           %Xh\n",   MsarsPtr->ProcessorProximityDomain));
+  DEBUG ((DEBUG_INFO, " MemoryProximityDomain:              %Xh\n",   MsarsPtr->MemoryProximityDomain));
+  DEBUG ((DEBUG_INFO, " SystemPhysicalAddressRangeBase:     %llXh\n", MsarsPtr->AddrBase));
+  DEBUG ((DEBUG_INFO, " SystemPhysicalAddressRangeLength:   %llXh\n", MsarsPtr->AddrLength));
+  DEBUG ((DEBUG_INFO, "=====================================================\n"));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+/**
+  Dump HSCIS Structure
+
+  @param [in]      MscisPtr       Pointer to HSCIS Structure
+
+  @retval None
+**/
+VOID
+DumpMscis (
+  MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE *MscisPtr
+  )
+{
+  UINT8     SmbiosHandleIndex;
+
+  DEBUG ((DEBUG_INFO, "=========== MSCIS Table =============================\n"));
+  DEBUG ((DEBUG_INFO, " Type:                               %d\n",    MscisPtr->Type));
+  DEBUG ((DEBUG_INFO, " Length:                             %d\n",    MscisPtr->Length));
+  DEBUG ((DEBUG_INFO, " MemoryProximityDomain:              %Xh\n",   MscisPtr->MemoryProximityDomain));
+  DEBUG ((DEBUG_INFO, " MemorySideCacheSize:                %llXh\n", MscisPtr->MemorySideCacheSize));
+  DEBUG ((DEBUG_INFO, " TotalCacheLevels:                   %d\n",    MscisPtr->CacheAttributes.Bits.TotalCacheLevels));
+  DEBUG ((DEBUG_INFO, " CacheLevel:                         %d\n",    MscisPtr->CacheAttributes.Bits.CacheLevel));
+  DEBUG ((DEBUG_INFO, " CacheAssociativity:                 %d\n",    MscisPtr->CacheAttributes.Bits.CacheAssociativity));
+  DEBUG ((DEBUG_INFO, " WritePolicy:                        %d\n",    MscisPtr->CacheAttributes.Bits.WritePolicy));
+  DEBUG ((DEBUG_INFO, " CacheLineSize:                      %d\n",    MscisPtr->CacheAttributes.Bits.CacheLineSize));
+  DEBUG ((DEBUG_INFO, " NumSmbiosHandles:                   %d\n",    MscisPtr->NumSmbiosHandles));
+
+  for (SmbiosHandleIndex = 0; SmbiosHandleIndex < MscisPtr->NumSmbiosHandles; SmbiosHandleIndex++) {
+    DEBUG ((DEBUG_INFO, " SmbiosHandle[%d]:                    %xh\n",   SmbiosHandleIndex + 1 ,MscisPtr->SmbiosHandles[SmbiosHandleIndex]));
+  }
+  DEBUG ((DEBUG_INFO, "=====================================================\n"));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+/**
+  Dump LBIS Structure
+
+  @param [in]      LbisPtr        Pointer to LBIS Structure
+
+  @retval None
+**/
+VOID
+DumpLbis (
+  LATENCY_BANDWIDTH_INFO_STRUCTURE *LbisPtr
+  )
+{
+  UINTN Index, Index1;
+  UINT32  *TargetProximityDomainList;
+  UINT16  *Entry;
+
+  DEBUG ((DEBUG_INFO, "=========== MLBIS Table =============================\n"));
+  DEBUG ((DEBUG_INFO, " Type:                               %d\n",    LbisPtr->Type));
+  DEBUG ((DEBUG_INFO, " Length:                             %d\n",    LbisPtr->Length));
+  DEBUG ((DEBUG_INFO, " Flags:                              %d\n",    LbisPtr->Flags));
+  DEBUG ((DEBUG_INFO, " DataType:                           %d\n",    LbisPtr->DataType));
+  DEBUG ((DEBUG_INFO, " InitiatorProximityDomainsNumber:    %d\n",    LbisPtr->InitiatorProximityDomainsNumber));
+  DEBUG ((DEBUG_INFO, " TargetProximityDomainsNumber:       %d\n",    LbisPtr->TargetProximityDomainsNumber));
+  DEBUG ((DEBUG_INFO, " EntryBaseUnit:                      %lXh\n",  LbisPtr->EntryBaseUnit));
+  DEBUG ((DEBUG_INFO, " InitiatorProximityDomainList:\n"));
+
+  for (Index = 0; Index < LbisPtr->InitiatorProximityDomainsNumber; Index++) {
+    DEBUG ((DEBUG_INFO, " %d ",  LbisPtr->InitiatorProximityDomainList[Index]));
+  }
+  TargetProximityDomainList = (UINT32*)&(LbisPtr->InitiatorProximityDomainList[Index]);
+  DEBUG ((DEBUG_INFO, "\n"));
+
+  DEBUG ((DEBUG_INFO, " TargetProximityDomainList:\n"));
+  for (Index = 0; Index < LbisPtr->TargetProximityDomainsNumber; Index++) {
+    DEBUG ((DEBUG_INFO, " %d ",  TargetProximityDomainList[Index]));
+  }
+  Entry = (UINT16*)(TargetProximityDomainList + Index);
+  DEBUG ((DEBUG_INFO, "\n"));
+
+  DEBUG ((DEBUG_INFO, "RelativeDistanceEntry:\n"));
+  for (Index = 0; Index < LbisPtr->InitiatorProximityDomainsNumber; Index++) {
+    for (Index1 = 0; Index1 < LbisPtr->TargetProximityDomainsNumber; Index1++) {
+      DEBUG ((DEBUG_INFO, " %d ",  *(Entry + (Index * LbisPtr->TargetProximityDomainsNumber) + Index1)));
+    }
+    DEBUG ((DEBUG_INFO, "\n"));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+  DEBUG ((DEBUG_INFO, "=====================================================\n"));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+
+/**
+  Dump HMAT table
+
+  @param [in]      HmatAcpiTable       Pointer to HMAT table.
+
+  @retval None
+**/
+VOID
+DumpHmat (
+  EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE *HmatAcpiTable
+  )
+{
+  UINT32  TotalLength = HmatAcpiTable->HmatHeader.Header.Length;
+  UINT8   *Table = (UINT8 *)HmatAcpiTable;
+  UINT32  Length;
+  UINT16  Type;
+
+  DumpHeader (&HmatAcpiTable->HmatHeader);
+  Length = sizeof (EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER);
+
+  Table += Length;
+  TotalLength -= Length;
+
+  //
+  // Dump tables
+  //
+  while (TotalLength) {
+    Type = ((MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE *)Table)->Type;
+    //
+    // For HBM will need to add LBIS structure
+    //
+    if (Type == MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE_TYPE) {
+      DumpMsars ((MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE *)Table);
+    } else if (Type == MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE_TYPE)  {
+      DumpMscis ((MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE *)Table);
+    } else {
+      DumpLbis ((LATENCY_BANDWIDTH_INFO_STRUCTURE *)Table);
+    }
+
+    //
+    // Goto next entry
+    //
+    Length = ((MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE *)Table)->Length;
+    Table += Length;
+    TotalLength -= Length;
+  }
+}
+
+/**
+  Update SMBIOS handles and number of SMBIOS handles which is related to specified NodeId to MEMORY_DOMAIN_LIST_INFO
+
+  SMBIOS Type 17 handles are formed in sequence order. First handle is S0 C0 D0, Second handle is S0 C0 D1 and so on.
+  So we loop in this order to find the handles of DDR which is part of the specific 2LM cache memory.
+
+  @param [in]  HmatData    Points to HMAT structure
+  @param [in]  NodeId      SMBIOS handles related to this NodeId will be retrieved
+
+  @retval None
+**/
+VOID
+UpdateSmbiosHandles(
+  IN HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData,
+  IN UINT32                               NodeId,
+  IN UINT8                                Socket,
+  IN UINT32                               ImcBitMap
+  )
+{
+  EFI_STATUS                          Status;
+  STATIC  EFI_SMBIOS_PROTOCOL         *Smbios = NULL;
+  SMBIOS_TABLE_TYPE17                 *Type17Record;
+  EFI_SMBIOS_TABLE_HEADER             *SmbiosRecord;
+  EFI_SMBIOS_HANDLE                   SmbiosHandle;
+  EFI_SMBIOS_TYPE                     SmbiosType;
+  UINT8                               Loop = 1;
+  UINT8                               SlotsPerImc = MAX_DIMM * MAX_MC_CH;
+  UINT8                               DimmsPerImc = 0;
+
+  Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios);
+  if (EFI_ERROR (Status)) {
+    return ;
+  }
+
+  SmbiosHandle  = SMBIOS_HANDLE_PI_RESERVED;
+  SmbiosType    = 17;
+
+  //
+  // Adjust ImcBitMap according to the socket number
+  //
+  if (Socket != 0) {
+    ImcBitMap <<= (Socket * SlotsPerImc);
+  }
+
+  if (!PcdGetBool (PcdHalfWidth)) {
+    DimmsPerImc = SlotsPerImc;
+  } else {
+    DimmsPerImc = SlotsPerImc - 1;
+  }
+
+  do {
+    Status = Smbios->GetNext(Smbios, &SmbiosHandle, &SmbiosType, &SmbiosRecord, NULL);
+    if (!EFI_ERROR (Status) && (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED)) {
+      Type17Record = (SMBIOS_TABLE_TYPE17 *)SmbiosRecord;
+
+      //
+      // 1) check whether the Memory device of this record is cache capable(ie, 2LM DDR cache) and
+      // 2) this memory handle is to the current looping IMC
+      //
+      if ((Type17Record->TypeDetail.CacheDram) && (ImcBitMap & BIT0)) {
+          HmatData->MemoryDomainList[NodeId].SmbiosHandles[HmatData->MemoryDomainList[NodeId].NumSmbiosHandles] = Type17Record->Hdr.Handle ;
+          HmatData->MemoryDomainList[NodeId].NumSmbiosHandles++;
+      }
+    }
+    //
+    // if loop done for this IMC then move for next
+    //
+    if (Loop % DimmsPerImc == 0) {
+      ImcBitMap >>= 1;
+    }
+    ++Loop;
+  } while (!EFI_ERROR (Status) && (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED) && (ImcBitMap != 0));
+}
+
+/**
+  Remove slack by moving this substructure lower which removes unused memory.
+
+  @param [in]  SlackSize       Points to cumulative unused memory size
+  @param [in]  Src             Points to memory to move
+  @param [in]  SrcLen          Size of memory to move
+
+  @retval None
+**/
+VOID
+RemoveSlack (
+  IN     UINTN  *SlackSize,
+  IN     VOID   *Src,
+  IN     UINTN  SrcLen
+  )
+{
+  VOID *Dst;
+
+  Dst = (UINT8 *)Src - (*SlackSize);
+  CopyMem (Dst, Src, SrcLen);
+}
+
+/**
+  Calculate the Memory Proximity Domain Number and generate its associate list.
+
+  @param [in, out]  HmatData             Pointer to HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be filled
+
+  @retval       None.
+**/
+VOID
+GetMemoryDomains (
+  IN OUT  HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE  *HmatData
+)
+{
+  UINT64  MemorySideCacheSize;
+  UINT32  NodeId;
+  UINT32  LastDomainId = 0;
+  UINT8   Index;
+  UINT8   PrevIndex;
+  UINT8   LastIndex = 0;
+  UINT8   Mc;
+  UINT8   Socket;
+  UINT8   McBitmap[EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS];
+  UINT32  PmemEntry[EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS];
+  UINT64  MemoryAddressStore[EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS];
+  UINT64  MemoryAddress;
+  UINT8   MaxEnabledImc = 0;
+  UINTN   ImcIndex;
+  UINT8   MemSocketBitmap = 0;
+  UINT8   NoMemSocketBitmap;
+  BOOLEAN SkipEntry;
+  BOOLEAN UpdateSmbiosHandle = FALSE;
+
+  EFI_STATUS                  Status = EFI_SUCCESS;
+  DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return;
+  }
+
+  HmatData->MemoryDomainNumber = 0;
+
+  ZeroMem (McBitmap, sizeof(McBitmap));
+  ZeroMem (MemoryAddressStore, sizeof(MemoryAddressStore));
+
+  //
+  // Memory Proximity Domain must match the Domain in the SRAT Memory Affinity structure
+  //
+  for (Index = 0; Index < mSystemMemoryMap->numberEntries; Index++) {
+    //
+    // Skip any memory region marked reserved
+    //
+    if (DynamicSiLibraryProtocol2->IsMemTypeReserved (mSystemMemoryMap->Element[Index].Type)) {
+      continue;
+    }
+
+    if (!DynamicSiLibraryProtocol2->IsMemTypeVolatile (mSystemMemoryMap->Element[Index].Type)) {
+      //
+      // Skip all non volatile regions
+      //
+      PmemEntry[SkippedEntries] = Index;
+      SkippedEntries++;
+      continue;
+    }
+
+    SkipEntry = FALSE;
+
+    MemoryAddress = LShiftU64 (mSystemMemoryMap->Element[Index].BaseAddress, MEM_ADDR_SHFT_VAL);
+
+    //
+    // Skip duplicate entries
+    //
+    if (Index) {
+      for (PrevIndex = 0; PrevIndex < Index; PrevIndex++) {
+        if (MemoryAddress == MemoryAddressStore[PrevIndex]) {
+          SkipEntry = TRUE;
+          break;
+        }
+      }
+    }
+    if (SkipEntry) {
+      continue;
+    }
+
+    MemoryAddressStore[Index] = MemoryAddress;
+    LastIndex = Index;
+
+    for (ImcIndex = 0, MaxEnabledImc = 0; ImcIndex < MAX_IMC; ImcIndex++) {
+      if (mSystemMemoryMap->Socket[mSystemMemoryMap->Element[Index].SocketId].imcEnabled[ImcIndex] != 0) {
+        MaxEnabledImc ++;
+      }
+    }
+
+    //
+    // Update bitmap for sockets with memory populated
+    //
+    MemSocketBitmap |= BIT0 << mSystemMemoryMap->Element[Index].SocketId;
+
+    //
+    // Get memory domain (must match SRAT memory domain)
+    //
+    NodeId = ProximityDomainOf (
+                mSystemMemoryMap->Element[Index].SocketId,
+                mSystemMemoryMap->Element[Index].Type,
+                MaxEnabledImc,
+                HmatData->SncEnabled,
+                HmatData->SncNumOfCluster,
+                mSystemMemoryMap->Element[Index].ImcInterBitmap,
+                mSystemMemoryMap->volMemMode,
+                LastDomainId
+                );
+
+    NodeId = (NodeId * HmatData->VirtualNumOfCluster) + (Index % HmatData->VirtualNumOfCluster);
+
+    if (LastDomainId < NodeId) {
+      LastDomainId = NodeId;
+    }
+
+    if (NodeId >= EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS) {
+      DEBUG ((DEBUG_ERROR, "[ACPI] (HMAT) ERROR: Invalid Memory Proximity Domain (0x%x)\n", NodeId));
+      ASSERT (FALSE);
+    }
+
+    //
+    // Update map of indexes included in this memory domain
+    //
+    HmatData->MemoryDomainList[NodeId].MemMapIndexMap |= LShiftU64 (BIT0, Index);
+
+    //
+    // Update Memory domain count and set domain to valid
+    // Prevent counting repeated entries with the same Proximity Domain ID
+    //
+    if ((Index == 0) || (HmatData->MemoryDomainList[NodeId].Valid == 0)) {
+      HmatData->MemoryDomainNumber++;
+      HmatData->MemoryDomainList[NodeId].PhysicalSocketId = mSystemMemoryMap->Element[Index].SocketId;
+      HmatData->MemoryDomainList[NodeId].Valid = 1;
+      McBitmap[NodeId] = 0;
+    }
+
+    if (HmatData->MemoryDomainList[NodeId].Valid) {
+      if (mSystemMemoryMap->Element[Index].Type == MemType2lmDdrCacheMemoryMode) {
+        //
+        // Set up side cache info for 2LM
+        //
+        HmatData->MemoryDomainList[NodeId].Cacheable = 1;
+
+        //
+        // Calculate MemorySideCacheSize
+        // MemorySideCacheSize for each MC is the DDR4 memSize
+        //
+        MemorySideCacheSize = 0;
+        UpdateSmbiosHandle = FALSE;
+
+        for (Mc = 0; Mc < MAX_IMC; Mc++) {
+          if ((mSystemMemoryMap->Element[Index].ImcInterBitmap & (BIT0 << Mc)) && !(McBitmap[NodeId] & (BIT0 << Mc))) {
+            UpdateSmbiosHandle = TRUE;
+            if (mSystemMemoryMap->volMemMode == VOL_MEM_MODE_2LM) {
+              MemorySideCacheSize += mSystemMemoryMap->Socket[mSystemMemoryMap->Element[Index].SocketId].imc[Mc].MemSize;
+            } else{ // VOL_MEM_MODE_MIX_1LM2LM
+              MemorySideCacheSize += mSystemMemoryMap->DdrCacheSize[mSystemMemoryMap->Element[Index].SocketId][Mc];
+            }
+          }
+        }
+
+        if (UpdateSmbiosHandle) {
+          UpdateSmbiosHandles (
+            HmatData,
+            NodeId,
+            mSystemMemoryMap->Element[Index].SocketId,
+            mSystemMemoryMap->Element[Index].ImcInterBitmap
+            );
+        }
+        HmatData->MemoryDomainList[NodeId].MemorySideCacheSize += MemorySideCacheSize;
+      }
+      McBitmap[NodeId] |= mSystemMemoryMap->Element[Index].ImcInterBitmap;
+    }
+
+    DEBUG ((DEBUG_INFO, "MemoryDomainList[%x] Valid = %x Cacheable = %x MemorySideCacheSize = %x\n",
+      NodeId,
+      HmatData->MemoryDomainList[NodeId].Valid,
+      HmatData->MemoryDomainList[NodeId].Cacheable,
+      HmatData->MemoryDomainList[NodeId].MemorySideCacheSize
+      ));
+  }
+
+  //
+  // Update LastDomainId for enabled sockets with no memory
+  //
+  NoMemSocketBitmap = mCpuCsrAccessVarPtr->socketPresentBitMap & ~MemSocketBitmap;
+  for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+    if ((BIT0 << Socket) & NoMemSocketBitmap) {
+      LastDomainId += HmatData->SncNumOfCluster;
+    }
+  }
+
+  //
+  // Add skipped entries
+  //
+  for (Index = 0; Index < SkippedEntries; Index++) {
+    SkipEntry = FALSE;
+    MemoryAddress = LShiftU64 (mSystemMemoryMap->Element[PmemEntry[Index]].BaseAddress, MEM_ADDR_SHFT_VAL);
+
+    //
+    // Skip duplicate entries
+    //
+    for (PrevIndex = 0; PrevIndex < LastIndex; PrevIndex++) {
+      if (MemoryAddress == MemoryAddressStore[PrevIndex]) {
+        SkipEntry = TRUE;
+        break;
+      }
+    }
+    if (SkipEntry) {
+      continue;
+    }
+
+    MemoryAddressStore[LastIndex++] = MemoryAddress;
+
+    //
+    // Get memory domain (must match SRAT memory domain)
+    //
+    NodeId = ProximityDomainOf (
+                mSystemMemoryMap->Element[PmemEntry[Index]].SocketId,
+                mSystemMemoryMap->Element[PmemEntry[Index]].Type,
+                MaxEnabledImc,
+                HmatData->SncEnabled,
+                HmatData->SncNumOfCluster,
+                mSystemMemoryMap->Element[PmemEntry[Index]].ImcInterBitmap,
+                mSystemMemoryMap->volMemMode,
+                LastDomainId
+                );
+    NodeId = (NodeId * HmatData->VirtualNumOfCluster) + (Index % HmatData->VirtualNumOfCluster);
+
+    if (LastDomainId < NodeId) {
+      LastDomainId = NodeId;
+    }
+
+    if (NodeId >= EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS) {
+      DEBUG ((DEBUG_ERROR, "[ACPI] (HMAT) ERROR: Invalid Memory Proximity Domain (0x%x)\n", NodeId));
+      ASSERT (FALSE);
+    }
+
+    //
+    // Update map of indexes included in this memory domain
+    //
+    HmatData->MemoryDomainList[NodeId].MemMapIndexMap |= LShiftU64 (BIT0, PmemEntry[Index]);
+
+    //
+    // Update Memory domain count and set domain to valid
+    // Prevent counting repeated entries with the same Proximity Domain ID
+    //
+    if ((PmemEntry[Index] == 0) || (HmatData->MemoryDomainList[NodeId].Valid == 0)) {
+      HmatData->MemoryDomainNumber++;
+      HmatData->MemoryDomainList[NodeId].PhysicalSocketId = mSystemMemoryMap->Element[PmemEntry[Index]].SocketId;
+      HmatData->MemoryDomainList[NodeId].Valid = 1;
+    }
+
+    DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) MemoryDomainList[%x] Valid = %x Cacheable = %x MemorySideCacheSize = %x\n",
+      NodeId,
+      HmatData->MemoryDomainList[NodeId].Valid,
+      HmatData->MemoryDomainList[NodeId].Cacheable,
+      HmatData->MemoryDomainList[NodeId].MemorySideCacheSize
+      ));
+  }
+}
+
+/**
+  Calculate the Processor Proximity Domain Number and generate its associate list.
+
+  @param [in, out]  HmatData             Pointer to HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be filled
+
+  @retval       None.
+**/
+VOID
+GetProcessorDomains (
+  IN OUT  HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE  *HmatData
+  )
+{
+  UINT32  NodeId;
+  UINT8   Index;
+  INTN    FirstImc;
+  UINT8   SocketId;
+  UINT8   SocketLogicalId;
+  UINT8   MemSocketBitmap;
+  UINT8   NoMemSocketBitmap;
+
+  EFI_STATUS                  Status = EFI_SUCCESS;
+  DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return;
+  }
+
+  MemSocketBitmap = 0;
+  NoMemSocketBitmap = 0;
+  HmatData->ProcessorDomainNumber = 0;
+
+  //
+  // Processor Proximity Domain must match the Domain in the SRAT APIC or X2APIC Affinity Structure
+  //
+  for (Index = 0; Index < mSystemMemoryMap->numberEntries; Index++) {
+    //
+    // Skip any memory region marked reserved or FPGA
+    //
+    if (DynamicSiLibraryProtocol2->IsMemTypeReserved (mSystemMemoryMap->Element[Index].Type) || DynamicSiLibraryProtocol2->IsMemTypeFpga (mSystemMemoryMap->Element[Index].Type)) {
+      continue;
+    }
+
+    SocketId = mSystemMemoryMap->Element[Index].SocketId;
+    SocketLogicalId = GetSocketLogicalId (SocketId);
+
+    //
+    // Get processor proximity domain
+    //
+    if (HmatData->SncEnabled || HmatData->VirtualNumaEnabled) {
+      FirstImc = LowBitSet32 (mSystemMemoryMap->Element[Index].ImcInterBitmap);
+      if (FirstImc == -1) {
+        FirstImc = 0;
+      }
+      //
+      // Find the 1st IMC according the interbitmap
+      //
+      if (MAX_IMC <= HmatData->SncNumOfCluster) {
+        NodeId = (SocketLogicalId * HmatData->SncNumOfCluster) + (UINT32)FirstImc;
+      } else {
+        NodeId = (SocketLogicalId * HmatData->SncNumOfCluster) + ((UINT32)FirstImc) / HmatData->SncNumOfCluster;
+      }
+
+      NodeId = (NodeId * HmatData->VirtualNumOfCluster) + (Index % HmatData->VirtualNumOfCluster);
+
+      DEBUG ((DEBUG_INFO, "%a: SocketId: 0x%x SncNumOfCluster: 0x%x ImcInterBitmap:0x%x and  NodeId:0x%x\n",
+          __FUNCTION__, mSystemMemoryMap->Element[Index].SocketId, HmatData->SncNumOfCluster, mSystemMemoryMap->Element[Index].ImcInterBitmap, NodeId));
+    } else {
+      NodeId = SocketLogicalId;
+    }
+
+    if (NodeId >= EFI_ACPI_HMAT_NUMBER_OF_PROCESSOR_DOMAINS) {
+      DEBUG ((DEBUG_ERROR, "[ACPI] (HMAT) ERROR: Invalid Processor Proximity Domain (0x%x)\n", NodeId));
+      return;
+    }
+
+    //
+    // Update processor domain count and set domain to valid
+    // Prevent counting repeated entries with the same Proximity Domain ID
+    //
+    if ((Index == 0) || (HmatData->ProcessorDomainList[NodeId] == 0)) {
+      HmatData->ProcessorDomainNumber++;
+      HmatData->ProcessorDomainSocketIdList[NodeId] = SocketId;
+      HmatData->ProcessorDomainList[NodeId] = 1; // Domain is valid
+      MemSocketBitmap |= (BIT0 << mSystemMemoryMap->Element[Index].SocketId);
+    }
+
+    DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) ProcessorDomainList[%x] Valid = %x\n", NodeId, HmatData->ProcessorDomainList[NodeId]));
+  }
+
+  //
+  // Update processor domain for enabled sockets without memory
+  //
+  NoMemSocketBitmap = mCpuCsrAccessVarPtr->socketPresentBitMap & ~MemSocketBitmap;
+  for (SocketId = 0; SocketId < MAX_SOCKET; SocketId++) {
+    if ((BIT0 << SocketId) & NoMemSocketBitmap) {
+      for (Index = 0; Index < (HmatData->SncNumOfCluster * HmatData->VirtualNumOfCluster); Index++) {
+        NodeId = GetSocketLogicalId (SocketId) * HmatData->SncNumOfCluster * HmatData->VirtualNumOfCluster + Index;
+        HmatData->ProcessorDomainNumber++;
+        HmatData->ProcessorDomainSocketIdList[NodeId] = SocketId;
+        HmatData->ProcessorDomainList[NodeId] = 1;
+      }
+    }
+  }
+}
+
+/**
+  Initialize HMAT Data to be consumed when populating tables.
+  This Functions allocates buffer for HMAT Data, so it is caller responsibility to free it.
+
+  @param            None.
+
+  @retval           Pointer to allocated HMAT Data if it was initialized correctly.
+  @retval           NULL if not allocated and not initialized correctly.
+**/
+UINTN *
+InitializeHmatData (
+  VOID
+)
+{
+  HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE  *HmatData = NULL;
+
+  HmatData = AllocateZeroPool (sizeof (HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE));
+  if (HmatData == NULL) {
+    DEBUG ((DEBUG_ERROR, "[ACPI] (HMAT) ERROR: Could not allocate HmatData structure pointer\n"));
+    return (UINTN *) HmatData;
+  }
+
+  if (mIioUds->IioUdsPtr->SystemStatus.OutSncEn) {
+    HmatData->SncEnabled = 1;
+    HmatData->SncNumOfCluster = mIioUds->IioUdsPtr->SystemStatus.OutNumOfCluster;
+  } else {
+    HmatData->SncNumOfCluster = 1;
+  }
+
+  if (mSystemMemoryMap->VirtualNumaEnable) {
+    HmatData->VirtualNumaEnabled = 1;
+    HmatData->VirtualNumOfCluster = mSystemMemoryMap->VirtualNumOfCluster;
+  } else {
+    HmatData->VirtualNumOfCluster = 1;
+  }
+
+  GetProcessorDomains (HmatData);
+  GetMemoryDomains (HmatData);
+
+  return (UINTN *)HmatData;
+}
+
+/**
+  Patch HMAT MSARS substructure.
+
+  @param [in, out]  HmatAcpiTable   Points to HMAT table to be modified
+  @param [in, out]  SlackSize       Points to cumulative slack size
+  @param [in]       HmatData        HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be consumed
+
+  @retval None
+**/
+VOID
+PatchHmatMsars (
+  IN OUT EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE  *HmatAcpiTable,
+  IN OUT UINTN                                          *SlackSize,
+  IN     HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE           *HmatData
+  )
+{
+  UINT32  Index;
+  UINT32  PrevIndex;
+  UINT32  MemoryNodeId;
+  UINT32  ProcessorNodeId;
+  UINT32  Count = 0;
+  UINT32  UnusedCount;
+  UINT8   MemoryNodeValid;
+  UINT16  ProcessorNodeValid;
+  UINT64  MemoryAddress;
+  BOOLEAN SkipEntry;
+  INTN    FirstImc;
+  UINT8   SocketLogicalId;
+
+  EFI_STATUS                  Status = EFI_SUCCESS;
+  DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return;
+  }
+
+
+  DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) Populating Memory Subsystem Address Range Structure\n"));
+  for (Index = 0; Index < mSystemMemoryMap->numberEntries; Index++) {
+    //
+    // Skip any memory region marked reserved
+    //
+    DEBUG ((DEBUG_INFO, "[ACPI] mSystemMemoryMap->Element[%d].Type = 0x%x\n",Index, mSystemMemoryMap->Element[Index].Type));
+    if (DynamicSiLibraryProtocol2->IsMemTypeReserved (mSystemMemoryMap->Element[Index].Type)) {
+      continue;
+    }
+
+    if (Count >= EFI_ACPI_HMAT_MSARS_COUNT) {
+      DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) Invalid MSARS entry with Index = 0x%x\n", Count));
+      ASSERT (FALSE);
+      break;
+    }
+
+    SkipEntry = FALSE;
+
+    //
+    // Skip duplicate entries
+    //
+    MemoryAddress = LShiftU64 (mSystemMemoryMap->Element[Index].BaseAddress, MEM_ADDR_SHFT_VAL);
+    if (Count) {
+      for (PrevIndex = 0; PrevIndex < Count; PrevIndex++) {
+        if (MemoryAddress == HmatAcpiTable->Msars[PrevIndex].AddrBase) {
+          SkipEntry = TRUE;
+          break;
+        }
+      }
+    }
+    if (SkipEntry) {
+      continue;
+    }
+
+    //
+    // Find memory domain for this index
+    //
+    for (MemoryNodeId = 0; MemoryNodeId < EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS; MemoryNodeId++) {
+      if (HmatData->MemoryDomainList[MemoryNodeId].MemMapIndexMap & LShiftU64(BIT0, Index)) {
+        break;
+      }
+    }
+
+    //
+    // Fill in valid field
+    //
+    if (MemoryNodeId < EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS) {
+      MemoryNodeValid = HmatData->MemoryDomainList[MemoryNodeId].Valid;
+    } else {
+      MemoryNodeValid = 0;
+    }
+
+    //
+    // Get processor domain for this index
+    //
+    if (DynamicSiLibraryProtocol2->IsMemTypeFpga (mSystemMemoryMap->Element[Index].Type)) {
+      ProcessorNodeValid = 0;  // There is no processor for FPGA.
+      ProcessorNodeId = 0;     // This field will be ingored for FPGA.
+    } else {
+      SocketLogicalId = GetSocketLogicalId (mSystemMemoryMap->Element[Index].SocketId);
+      if (HmatData->SncEnabled || HmatData->VirtualNumaEnabled) {
+        FirstImc = LowBitSet32 (mSystemMemoryMap->Element[Index].ImcInterBitmap);
+        if (FirstImc == -1) {
+          FirstImc = 0;
+        }
+        //
+        // Find the 1st IMC according the interbitmap
+        //
+        if (MAX_IMC <= HmatData->SncNumOfCluster) {
+          ProcessorNodeId = (SocketLogicalId * HmatData->SncNumOfCluster) + (UINT32)FirstImc;
+        } else {
+          ProcessorNodeId = (SocketLogicalId * HmatData->SncNumOfCluster) + ((UINT32)FirstImc) / HmatData->SncNumOfCluster;
+        }
+        ProcessorNodeId = (ProcessorNodeId * HmatData->VirtualNumOfCluster) + (Index % HmatData->VirtualNumOfCluster);
+        DEBUG ((DEBUG_INFO, "%a: SocketId: 0x%x SncNumOfCluster: 0x%x ImcInterBitmap:0x%x and  NodeId:0x%x \n",
+          __FUNCTION__, mSystemMemoryMap->Element[Index].SocketId, HmatData->SncNumOfCluster, mSystemMemoryMap->Element[Index].ImcInterBitmap, ProcessorNodeId));
+      } else {
+        ProcessorNodeId = SocketLogicalId;
+      }
+
+      //
+      // Fill in valid field
+      //
+      if (ProcessorNodeId < EFI_ACPI_HMAT_NUMBER_OF_PROCESSOR_DOMAINS) {
+        ProcessorNodeValid = HmatData->ProcessorDomainList[ProcessorNodeId];
+      } else {
+        ProcessorNodeValid = 0;
+      }
+    }
+
+    //
+    // The HOB has base addr in 64 MB chunks
+    //
+    HmatAcpiTable->Msars[Count].AddrBase  = MemoryAddress;
+    HmatAcpiTable->Msars[Count].AddrLength = LShiftU64 (mSystemMemoryMap->Element[Index].ElementSize, MEM_ADDR_SHFT_VAL);
+
+    HmatAcpiTable->Msars[Count].Flags.Value = 0;
+
+    //
+    // Fill in Proximity Domains
+    //
+    HmatAcpiTable->Msars[Count].ProcessorProximityDomain = ProcessorNodeId;
+    HmatAcpiTable->Msars[Count].Flags.Bits.ProcessorDomainValid = ProcessorNodeValid;
+    HmatAcpiTable->Msars[Count].MemoryProximityDomain = MemoryNodeId;
+    HmatAcpiTable->Msars[Count].Flags.Bits.MemoryDomainValid = MemoryNodeValid;
+
+    DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) MSARS[%x] AddrBase = 0x%lx, AddrLength = 0x%lx, MemDomain = %x, ProcDomain = %x\n",
+      Count,
+      HmatAcpiTable->Msars[Count].AddrBase,
+      HmatAcpiTable->Msars[Count].AddrLength,
+      MemoryNodeId,
+      ProcessorNodeId
+      ));
+    Count++;
+  }
+
+  //
+  // Update SlackSize for unused MSARS entries
+  //
+  UnusedCount = EFI_ACPI_HMAT_MSARS_COUNT - Count;
+  *SlackSize += UnusedCount * sizeof(HmatAcpiTable->Msars[0]);
+}
+
+/**
+  Prints HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE for debug purposes.
+
+  @param [in]       Lbis        Points to HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE to be printed.
+
+  @retval None.
+**/
+VOID
+PrintLbisHmat (
+  IN     LATENCY_BANDWIDTH_INFO_STRUCTURE  *Lbis
+  )
+{
+  UINT32  Row = 0;
+  UINT32  Col = 0;
+  UINT32  RowBaseIndex = 0;
+  UINT16  *Entry;
+
+  Entry = (UINT16 *) Lbis->RelativeDistanceEntry;
+  DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) SLLBIS Data: "));
+  DEBUG ((DEBUG_INFO, "InitiatorNumber = %d, TargetNumber = %d. ", Lbis->InitiatorProximityDomainsNumber, Lbis->TargetProximityDomainsNumber));
+  DEBUG ((DEBUG_INFO, "Entry Base Unit = %d \n", Lbis->EntryBaseUnit));
+
+  DEBUG ((DEBUG_INFO, "    "));
+  for (Col = 0; Col < Lbis->TargetProximityDomainsNumber; Col++) {
+    DEBUG ((DEBUG_INFO, "%02d        ", Lbis->TargetProximityDomainList[Col]));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+  for (Row = 0; Row < Lbis->InitiatorProximityDomainsNumber; Row++) {
+    RowBaseIndex = Row * Lbis->TargetProximityDomainsNumber;
+    DEBUG ((DEBUG_INFO, "%02d  ", Lbis->InitiatorProximityDomainList[Row]));
+    for (Col = 0; Col < Lbis->TargetProximityDomainsNumber; Col++) {
+      DEBUG ((DEBUG_INFO, "%08d  ", Entry[RowBaseIndex + Col]));
+    }
+    DEBUG ((DEBUG_INFO, "\n"));
+  }
+}
+
+/**
+  Get the Read/Write/Access bandwidth value of the memory type.
+
+  @param [in]       DataType         Type of bandwidth value that is required. (Read/Write/Access)
+  @param [in]       Type             Type of memory for which Bandwidth is required. (DDR/DDRT)
+
+  @retval Value of the bandwidth associated with memory type.
+  @retval 0xFF   Input parameters are invalid.
+**/
+
+UINT16
+GetMemoryBandWidth (
+  IN     UINT8                                 DataType,
+  IN     MemoryType                            Type,
+  IN     UINT8                                 volMemMode
+  )
+{
+  if (Type == DDRT) {  // MemoryType == DDRT
+    switch (DataType) {
+      case EFI_ACPI_HMAT_ACCESS_BANDWIDTH :
+        return DDRT_ACCESS_BANDWIDTH;
+      case EFI_ACPI_HMAT_READ_BANDWIDTH :
+        if (volMemMode == VOL_MEM_MODE_1LM) {
+          return DDRT_1LM_READ_BANDWIDTH;
+        } else {
+          return DDRT_2LM_READ_BANDWIDTH;
+        }
+      case EFI_ACPI_HMAT_WRITE_BANDWIDTH :
+        if (volMemMode == VOL_MEM_MODE_1LM) {
+          return DDRT_1LM_WRITE_BANDWIDTH;
+        } else {
+          return DDRT_2LM_WRITE_BANDWIDTH;
+        }
+      default:
+        return 0xFF;
+    }
+  } else if (Type == DDR2LMCACHE) {
+    switch (DataType) {
+      case EFI_ACPI_HMAT_ACCESS_BANDWIDTH :
+        return DDR2LMCACHE_ACCESS_BANDWIDTH;
+      case EFI_ACPI_HMAT_READ_BANDWIDTH :
+        return DDR2LMCACHE_READ_BANDWIDTH;
+      case EFI_ACPI_HMAT_WRITE_BANDWIDTH :
+        return DDR2LMCACHE_WRITE_BANDWIDTH;
+      default:
+        return 0xFF;
+    }
+  } else {
+    switch (DataType) {
+      case EFI_ACPI_HMAT_ACCESS_BANDWIDTH :
+        return DDR_ACCESS_BANDWIDTH;
+      case EFI_ACPI_HMAT_READ_BANDWIDTH :
+        return DDR_READ_BANDWIDTH;
+      case EFI_ACPI_HMAT_WRITE_BANDWIDTH :
+        return DDR_WRITE_BANDWIDTH;
+      default:
+        return 0xFF;
+    }
+  }
+}
+
+/**
+  Get the Read/Write/Access bandwidth value of the memory type across sockets.
+
+  @param [in]       DataType         Type of bandwidth value that is required. (Read/Write/Access)
+  @param [in]       Type             Type of memory for which Bandwidth is required. (DDR/DDRT)
+
+  @retval Value of the bandwidth associated with memory type.
+  @retval 0xFF   Input parameters are invalid.
+**/
+UINT16
+GetXSocketMemoryBandWidth (
+  IN     UINT8                                 DataType,
+  IN     MemoryType                            Type,
+  IN     UINT8                                 volMemMode
+)
+{
+  if (Type == DDRT) {  // MemoryType == DDRT
+    switch (DataType) {
+      case EFI_ACPI_HMAT_ACCESS_BANDWIDTH:
+        return DDRT_ACCESS_BANDWIDTH;
+      case EFI_ACPI_HMAT_READ_BANDWIDTH:
+        if (volMemMode == VOL_MEM_MODE_1LM) {
+          return XSOCKET_DDRT_1LM_READ_BANDWIDTH;
+        } else {
+          return XSOCKET_DDRT_2LM_READ_BANDWIDTH;
+        }
+      case EFI_ACPI_HMAT_WRITE_BANDWIDTH:
+        if (volMemMode == VOL_MEM_MODE_1LM) {
+          return XSOCKET_DDRT_1LM_WRITE_BANDWIDTH;
+        } else {
+          return XSOCKET_DDRT_2LM_WRITE_BANDWIDTH;
+        }
+      default:
+        return 0xFF;
+    }
+  } else if (Type == DDR2LMCACHE) {
+    switch (DataType) {
+      case EFI_ACPI_HMAT_ACCESS_BANDWIDTH:
+        return DDR2LMCACHE_ACCESS_BANDWIDTH;
+      case EFI_ACPI_HMAT_READ_BANDWIDTH:
+        return DDR2LMCACHE_READ_BANDWIDTH;
+      case EFI_ACPI_HMAT_WRITE_BANDWIDTH:
+        return DDR2LMCACHE_WRITE_BANDWIDTH;
+      default:
+        return 0xFF;
+    }
+  } else {
+    switch (DataType) {
+      case EFI_ACPI_HMAT_ACCESS_BANDWIDTH:
+        return XSOCKET_DDR_ACCESS_BANDWIDTH;
+      case EFI_ACPI_HMAT_READ_BANDWIDTH:
+        return XSOCKET_DDR_READ_BANDWIDTH;
+      case EFI_ACPI_HMAT_WRITE_BANDWIDTH:
+        return XSOCKET_DDR_WRITE_BANDWIDTH;
+      default:
+        return 0xFF;
+    }
+  }
+}
+
+/**
+  Get the Read/Write/Access Latency value of the memory type.
+
+  @param [in]       DataType         Type of latency value that is required (Read/Write/Access)
+  @param [in]       Type             Type of memory for which Latency is required. (DDR/DDRT)
+
+  @retval Value of the Latency associated with memory type.
+  @retval 0xFF   Input parameters are invalid.
+**/
+UINT16
+GetMemoryLatency (
+  IN     UINT8                                 DataType,
+  IN     MemoryType                            Type,
+  IN     UINT8                                 volMemMode
+ )
+{
+  if (Type == DDRT) {  // MemoryType == DDRT
+    switch (DataType) {
+      case EFI_ACPI_HMAT_ACCESS_LATENCY :
+        return DDRT_ACCESS_LATENCY;
+
+      case EFI_ACPI_HMAT_READ_LATENCY :
+        if (volMemMode == VOL_MEM_MODE_1LM) {
+          return DDRT_1LM_READ_LATENCY;
+        } else {
+          return DDRT_2LM_READ_LATENCY;
+        }
+
+      case EFI_ACPI_HMAT_WRITE_LATENCY :
+        if (volMemMode == VOL_MEM_MODE_1LM) {
+          return DDRT_1LM_WRITE_LATENCY;
+        } else {
+          return DDRT_2LM_WRITE_LATENCY;
+        }
+
+      default:
+        return 0xFF;
+    }
+  } else if (Type == DDR2LMCACHE){
+    switch (DataType) {
+      case EFI_ACPI_HMAT_ACCESS_LATENCY :
+        return DDR2LMCACHE_ACCESS_LATENCY;
+
+      case EFI_ACPI_HMAT_READ_LATENCY :
+        return DDR2LMCACHE_READ_LATENCY;
+
+      case EFI_ACPI_HMAT_WRITE_LATENCY :
+        return DDR2LMCACHE_WRITE_LATENCY;
+
+      default:
+        return 0xFF;
+    }
+  } else {
+    switch (DataType) {
+      case EFI_ACPI_HMAT_ACCESS_LATENCY :
+        return DDR_ACCESS_LATENCY;
+
+      case EFI_ACPI_HMAT_READ_LATENCY :
+        return DDR_READ_LATENCY;
+
+      case EFI_ACPI_HMAT_WRITE_LATENCY :
+        return DDR_WRITE_LATENCY;
+
+      default:
+        return 0xFF;
+    }
+  }
+}
+
+/**
+  Get the Read/Write/Access Latency value of the memory type between sockets.
+
+  @param [in]       DataType         Type of latency value that is required (Read/Write/Access)
+  @param [in]       Type             Type of memory for which Latency is required. (DDR/DDRT)
+
+  @retval Value of the Latency associated with memory type.
+  @retval 0xFF   Input parameters are invalid.
+**/
+UINT16
+GetXSocketMemoryLatency (
+  IN     UINT8                                 DataType,
+  IN     MemoryType                            Type,
+  IN     UINT8                                 volMemMode
+  )
+{
+  if (Type == DDRT) {  // MemoryType == DDRT
+    switch (DataType) {
+
+      case EFI_ACPI_HMAT_ACCESS_LATENCY :
+        return DDRT_ACCESS_LATENCY;
+
+      case EFI_ACPI_HMAT_READ_LATENCY :
+        if (volMemMode == VOL_MEM_MODE_1LM) {
+          return XSOCKET_DDRT_1LM_READ_LATENCY;
+        } else {
+          return XSOCKET_DDRT_2LM_READ_LATENCY;
+        }
+
+      case EFI_ACPI_HMAT_WRITE_LATENCY :
+        if (volMemMode == VOL_MEM_MODE_1LM) {
+          return XSOCKET_DDRT_1LM_WRITE_LATENCY;
+        } else {
+          return XSOCKET_DDRT_2LM_WRITE_LATENCY;
+        }
+
+      default:
+        return 0xFF;
+    }
+  } else if (Type == DDR2LMCACHE){
+    switch (DataType) {
+
+      case EFI_ACPI_HMAT_ACCESS_LATENCY :
+        return DDR2LMCACHE_ACCESS_LATENCY;
+
+      case EFI_ACPI_HMAT_READ_LATENCY :
+        return DDR2LMCACHE_READ_LATENCY;
+
+      case EFI_ACPI_HMAT_WRITE_LATENCY :
+        return DDR2LMCACHE_WRITE_LATENCY;
+
+      default:
+        return 0xFF;
+    }
+  } else {
+    switch (DataType) {
+
+      case EFI_ACPI_HMAT_ACCESS_LATENCY :
+        return XSOCKET_DDR_ACCESS_LATENCY;
+
+      case EFI_ACPI_HMAT_READ_LATENCY :
+        return XSOCKET_DDR_READ_LATENCY;
+
+      case EFI_ACPI_HMAT_WRITE_LATENCY :
+        return XSOCKET_DDR_WRITE_LATENCY;
+
+      default:
+        return 0xFF;
+    }
+  }
+}
+
+/**
+  Patch HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE structure.
+
+  @param [in]       Lbis             Points to HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE to be modified
+  @param [in, out]  LibsSlackSize    Points to cummulative LIBS slack size
+  @param [in]       HmatData         HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be consumed
+
+  @retval None
+**/
+VOID
+PatchBandWidthLbis (
+  IN     LATENCY_BANDWIDTH_INFO_STRUCTURE      **LbisPtr,
+  IN OUT UINTN                                 *LibsSlackSize,
+  IN     HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE  *HmatData,
+  IN     UINT8                                 DataType,
+  IN     MemoryType                            Type,
+  IN     UINT8                                 volMemMode
+  )
+{
+  UINT32  Row = 0;
+  UINT32  Col = 0;
+  UINT32  RowSocketId = 0;
+  UINT32  ColSocketId = 0;
+  UINT32  RowBaseIndex = 0;
+  UINT32  StructSize = 0;
+  UINT32  InitiatorIndex = 0;
+  UINT32  TargetIndex = 0;
+  LATENCY_BANDWIDTH_INFO_STRUCTURE *Lbis  = *LbisPtr;
+  UINT32  *InitiatorProximityDomainList   = (UINT32*)Lbis;
+  UINT32  *TargetProximityDomainList      = (UINT32*)Lbis;
+  UINT16  *RelativeDistanceEntry          = (UINT16*)Lbis;
+
+  Lbis->Type = SYSTEM_LOCALITY_LATENCY_BANDWIDTH_INFORMATION_STRUCTURE_TYPE;
+  Lbis->DataType = DataType;
+  Lbis->InitiatorProximityDomainsNumber = HmatData->ProcessorDomainNumber;
+  Lbis->TargetProximityDomainsNumber = HmatData->MemoryDomainNumber;
+
+  switch (Type) {
+
+    case DDR2LMCACHE:
+     Lbis->EntryBaseUnit = DDR2LMCACHE_BANDWIDTH_BASE_UNIT;
+     Lbis->Flags = EFI_ACPI_HMAT_MEMORY_HIERACHY_LAST_LEVEL_MEMORY;
+     break;
+
+    default:
+    Lbis->EntryBaseUnit = MEMORY_BANDWIDTH_BASE_UNIT;
+    Lbis->Flags = EFI_ACPI_HMAT_MEMORY_HIERACHY_MEMORY;
+  }
+
+  InitiatorProximityDomainList = (UINT32*)&(Lbis->InitiatorProximityDomainList[0]);
+  StructSize = (UINT32)((UINT8*)InitiatorProximityDomainList - (UINT8*)Lbis);
+  StructSize += (Lbis->InitiatorProximityDomainsNumber * (sizeof (UINT32)));
+  TargetProximityDomainList = (UINT32*)((UINT8*)TargetProximityDomainList + StructSize);
+  StructSize += (Lbis->TargetProximityDomainsNumber * (sizeof (UINT32)));
+  RelativeDistanceEntry = (UINT16*)((UINT8*)RelativeDistanceEntry + StructSize);
+  StructSize += (Lbis->InitiatorProximityDomainsNumber * Lbis->TargetProximityDomainsNumber * (sizeof (UINT16)));
+
+  Lbis->Length = StructSize;
+
+  for (Row = 0; Row < Lbis->InitiatorProximityDomainsNumber; Row++) {
+    *(InitiatorProximityDomainList + Row)  = Row;
+  }
+  for (Row = 0; Row < Lbis->TargetProximityDomainsNumber; Row++) {
+    *(TargetProximityDomainList + Row) = Row;
+  }
+  Row = 0;
+  for (InitiatorIndex = 0; InitiatorIndex < EFI_ACPI_HMAT_NUMBER_OF_PROCESSOR_DOMAINS; InitiatorIndex++) {
+    if (HmatData->ProcessorDomainList[InitiatorIndex] == 1) {
+      RowSocketId = HmatData->ProcessorDomainSocketIdList[InitiatorIndex];
+      RowBaseIndex = Row * Lbis->TargetProximityDomainsNumber;
+      Col = 0;
+      for (TargetIndex = 0; TargetIndex < EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS; TargetIndex++) {
+        if (HmatData->MemoryDomainList[TargetIndex].Valid == 1) {
+          ColSocketId = HmatData->MemoryDomainList[TargetIndex].PhysicalSocketId;
+          if (Type == DDR2LMCACHE) {
+            //
+            // DDR acting as cache for DDRT
+            //SocketsLinked
+            //
+            if (SocketsLinked (RowSocketId, ColSocketId)) {
+              RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryBandWidth (DataType, Type, volMemMode);
+            } else {
+              RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryBandWidth (DataType, Type, volMemMode);
+            }
+          } else if (mSystemMemoryMap->volMemMode == VOL_MEM_MODE_2LM) {
+            //
+            // Add only details for DDRT as entire DDR is acting as Cache
+            //
+            if (SocketsLinked (RowSocketId, ColSocketId)) {
+              RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryBandWidth (DataType, DDRT, volMemMode);
+            } else {
+              RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryBandWidth (DataType, DDRT, volMemMode);
+            }
+          } else {
+            //
+            // Neither cache nor 2LM, we need to add details for both DDR and DDRT
+            //
+            if ((Col / (HmatData->MemoryDomainNumber- SkippedEntries)) == 0) {
+              //
+              // DDR entries
+              //
+              if (SocketsLinked (RowSocketId, ColSocketId)) {
+                RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryBandWidth (DataType, DDR, volMemMode);
+              } else {
+                RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryBandWidth (DataType, DDR, volMemMode);
+              }
+            } else  {
+              //
+              // DDRT entries
+              //
+              if (SocketsLinked (RowSocketId, ColSocketId)) {
+                RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryBandWidth (DataType, DDRT, volMemMode);
+              } else {
+                RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryBandWidth (DataType, DDRT, volMemMode);
+              }
+            }
+          }
+          Col++;
+        } //if (HmatData->MemoryDomainList[TargetIndex].Valid == 1)
+      } // for (TargetIndex)
+      Row++;
+    } // if (HmatData->ProcessorDomainList[InitiatorIndex] == 1)
+  } //for (InitiatorIndex)
+
+  *LibsSlackSize += StructSize;
+  *LbisPtr = (LATENCY_BANDWIDTH_INFO_STRUCTURE *)((UINT8*)Lbis + StructSize);
+}
+
+/**
+  Patch HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE structure.
+
+  @param [in]       Lbis        Points to HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE to be modified
+  @param [in, out]  LibsSlackSize   Points to cumulative LIBS slack size
+  @param [in]       HmatData    HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be consumed
+
+  @retval None
+**/
+VOID
+PatchMemoryLatencyLbis (
+  IN     LATENCY_BANDWIDTH_INFO_STRUCTURE      **LbisPtr,
+  IN OUT UINTN                                 *LibsSlackSize,
+  IN     HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE  *HmatData,
+  IN     UINT8                                 DataType,
+  IN     MemoryType                            Type,
+  IN     UINT8                                 volMemMode
+  )
+{
+  UINT32  Row = 0;
+  UINT32  Col = 0;
+  UINT32  RowSocketId = 0;
+  UINT32  ColSocketId = 0;
+  UINT32  RowBaseIndex = 0;
+  UINT32  StructSize = 0;
+  UINT32  InitiatorIndex = 0;
+  UINT32  TargetIndex = 0;
+  LATENCY_BANDWIDTH_INFO_STRUCTURE *Lbis  = *LbisPtr;
+  UINT32  *InitiatorProximityDomainList   = (UINT32*)Lbis;
+  UINT32  *TargetProximityDomainList      = (UINT32*)Lbis;
+  UINT16  *RelativeDistanceEntry          = (UINT16*)Lbis;
+
+  Lbis->Type = SYSTEM_LOCALITY_LATENCY_BANDWIDTH_INFORMATION_STRUCTURE_TYPE;
+  Lbis->DataType = DataType;
+  Lbis->InitiatorProximityDomainsNumber = HmatData->ProcessorDomainNumber;
+  Lbis->TargetProximityDomainsNumber = HmatData->MemoryDomainNumber;
+
+  switch (Type) {
+
+    case DDR2LMCACHE:
+      Lbis->EntryBaseUnit = DDR2LMCACHE_BANDWIDTH_BASE_UNIT;
+      Lbis->Flags = EFI_ACPI_HMAT_MEMORY_HIERACHY_LAST_LEVEL_MEMORY;
+      break;
+
+    default:
+      Lbis->EntryBaseUnit = MEMORY_LATENCY_BASE_UNIT;
+      Lbis->Flags = EFI_ACPI_HMAT_MEMORY_HIERACHY_MEMORY;
+  }
+
+  InitiatorProximityDomainList = (UINT32*)&(Lbis->InitiatorProximityDomainList[0]);
+  StructSize = (UINT32)((UINT8*)InitiatorProximityDomainList - (UINT8*)Lbis);
+  StructSize += (Lbis->InitiatorProximityDomainsNumber * (sizeof (UINT32)));
+  TargetProximityDomainList = (UINT32*)((UINT8*)TargetProximityDomainList + StructSize);
+  StructSize += (Lbis->TargetProximityDomainsNumber * (sizeof (UINT32)));
+  RelativeDistanceEntry = (UINT16*)((UINT8*)RelativeDistanceEntry + StructSize);
+  StructSize += (Lbis->InitiatorProximityDomainsNumber * Lbis->TargetProximityDomainsNumber * (sizeof (UINT16)));
+
+  Lbis->Length = StructSize;
+
+  for (Row = 0; Row < Lbis->InitiatorProximityDomainsNumber; Row++) {
+    *(InitiatorProximityDomainList + Row)  = Row;
+  }
+  for (Row = 0; Row < Lbis->TargetProximityDomainsNumber; Row++) {
+    *(TargetProximityDomainList + Row) = Row;
+  }
+  Row = 0;
+  for (InitiatorIndex = 0; InitiatorIndex < EFI_ACPI_HMAT_NUMBER_OF_PROCESSOR_DOMAINS; InitiatorIndex++) {
+    if (HmatData->ProcessorDomainList[InitiatorIndex] == 1) {
+      RowSocketId = HmatData->ProcessorDomainSocketIdList[InitiatorIndex];
+      RowBaseIndex = Row * Lbis->TargetProximityDomainsNumber;
+      Col = 0;
+      for (TargetIndex = 0; TargetIndex < EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS; TargetIndex++) {
+        if (HmatData->MemoryDomainList[TargetIndex].Valid == 1) {
+          ColSocketId = HmatData->MemoryDomainList[TargetIndex].PhysicalSocketId;
+          if (Type == DDR2LMCACHE) {
+            //
+            // DDR acting as cache for DDRT
+            //
+            if (SocketsLinked (RowSocketId, ColSocketId)) {
+              RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryLatency (DataType, Type, volMemMode);
+            } else {
+              RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryLatency (DataType, Type, volMemMode);
+            }
+          } else if (mSystemMemoryMap->volMemMode == VOL_MEM_MODE_2LM) {
+            //
+            // Add only details for DDRT as entire DDR is acting as Cache
+            //
+            if (SocketsLinked (RowSocketId, ColSocketId)) {
+              RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryLatency (DataType, DDRT, volMemMode);
+            } else {
+              RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryLatency (DataType, DDRT, volMemMode);
+            }
+          } else {
+            //
+            // Neither cache nor 2LM, we need to add details for both DDR and DDRT
+            //
+            if ((Col / (HmatData->MemoryDomainNumber - SkippedEntries)) == 0) {
+              //
+              // DDR entries
+              //
+              if (SocketsLinked (RowSocketId, ColSocketId)) {
+                RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryLatency (DataType, DDR, volMemMode);
+              } else {
+                RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryLatency (DataType, DDR, volMemMode);
+              }
+            } else  {
+              //
+              // DDRT entries
+              //
+              if (SocketsLinked (RowSocketId, ColSocketId)) {
+                RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryLatency (DataType, DDRT, volMemMode);
+              } else {
+                RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryLatency (DataType, DDRT, volMemMode);
+              }
+            }
+          }
+          Col++;
+        } //if (HmatData->MemoryDomainList[TargetIndex].Valid == 1)
+      } // for (TargetIndex)
+      Row++;
+    } // if (HmatData->ProcessorDomainList[InitiatorIndex] == 1)
+  } //for (InitiatorIndex)
+
+  *LibsSlackSize += StructSize;
+  *LbisPtr = (LATENCY_BANDWIDTH_INFO_STRUCTURE *)((UINT8*)Lbis + StructSize);
+}
+
+/**
+  Patch HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE structure.
+
+  @param [in]       Lbis        Points to HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE to be modified
+  @param [in, out]  SlackSize   Points to cummulative slack size
+  @param [in]       HmatData    HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be consumed
+
+  @retval None
+**/
+VOID
+PatchHmatLbis (
+  IN     LATENCY_BANDWIDTH_INFO_STRUCTURE      *Lbis,
+  IN OUT UINTN                                 *SlackSize,
+  IN     HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE  *HmatData
+  )
+{
+  UINTN    LibsStructSize=0;
+  UINT8    volMemMode;
+  LATENCY_BANDWIDTH_INFO_STRUCTURE *OrginalLbis = Lbis;
+
+  volMemMode = mSystemMemoryMap->volMemMode;
+
+  DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) Populating System Locality Latency and Bandwidth Information Structure\n"));
+
+  PatchMemoryLatencyLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_READ_LATENCY, DDR, volMemMode);
+  PatchMemoryLatencyLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_WRITE_LATENCY, DDR, volMemMode);
+  PatchBandWidthLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_READ_BANDWIDTH, DDR, volMemMode);
+  PatchBandWidthLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_WRITE_BANDWIDTH, DDR, volMemMode);
+
+  if (mSystemMemoryMap->volMemMode != VOL_MEM_MODE_1LM) {
+    PatchMemoryLatencyLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_READ_LATENCY, DDR2LMCACHE, volMemMode);
+    PatchMemoryLatencyLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_WRITE_LATENCY, DDR2LMCACHE, volMemMode);
+    PatchBandWidthLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_READ_BANDWIDTH, DDR2LMCACHE, volMemMode);
+    PatchBandWidthLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_WRITE_BANDWIDTH, DDR2LMCACHE, volMemMode);
+  }
+
+  RemoveSlack (SlackSize, OrginalLbis, LibsStructSize);
+  *SlackSize += EFI_ACPI_HMAT_LBIS_COUNT * sizeof(Lbis[0]) - LibsStructSize;
+}
+
+/**
+  Get Type 17 Handles for HBM devices used as cache.
+
+  @param [in, out]  SmbiosHandles    Points to SmbiosHandles array to be modified
+  @param [in]       NumaNode         Value for NUMA Node whose memory is being cached for the specific HBM devices
+  @retval None
+**/
+VOID
+GetHbmCacheHandles (
+  IN     UINT16   *SmbiosHandles,
+  IN     UINT8    NumaNode
+  )
+{
+  EFI_STATUS                              Status = EFI_SUCCESS;
+  SMBIOS_TABLE_TYPE17                     *SmbiosType17Record;
+  EFI_SMBIOS_HANDLE                       SmbiosHandle = 0;
+  EFI_SMBIOS_PROTOCOL                     *mSmbios;
+  EFI_SMBIOS_TYPE                         SmbiosType = EFI_SMBIOS_TYPE_MEMORY_DEVICE;
+  EFI_SMBIOS_TABLE_HEADER                 *SmbiosRecord;
+  UINT8                                   HbmHandleCount = 0;
+
+  Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &mSmbios);
+  if (!(EFI_ERROR (Status))) {
+    while ((!(EFI_ERROR (Status))) && (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED) ){
+      Status = mSmbios->GetNext (mSmbios, &SmbiosHandle, &SmbiosType, &SmbiosRecord, NULL);
+      SmbiosType17Record = (SMBIOS_TABLE_TYPE17 *) SmbiosRecord;
+      if ((SmbiosType17Record->TypeDetail.CacheDram == 1)  && (SmbiosType17Record->DeviceSet == NumaNode) ) {
+        SmbiosHandles[HbmHandleCount] = SmbiosType17Record->Hdr.Handle;
+        HbmHandleCount++;
+      }
+    }
+  }
+}
+
+/**
+  Patch HMAT MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE substructure.
+
+  @param [in, out]  Mscis        Points to HMAT MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE to be modified
+  @param [in, out]  SlackSize    Points to cumulative slack size
+  @param [in]       HmatData     HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be consumed
+
+  @retval None
+**/
+VOID
+PatchHmatMscis (
+  IN OUT MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE  *Mscis,
+  IN OUT UINTN                                    *SlackSize,
+  IN      HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE    *HmatData
+  )
+{
+  UINT32  Index;
+  UINT32  Count = 0;
+  UINT32  UnusedCount;
+  UINT8   SmbiosHandleIndex;
+
+  DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) Populating Memory Side Cache Information Structure\n"));
+
+  for (Index = 0; Index < EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS; Index++) {
+    if ((HmatData->MemoryDomainList[Index].Valid == 0) || (HmatData->MemoryDomainList[Index].Cacheable == 0)) {
+      continue;
+    }
+
+    //
+    // Fill in fields for Cached Memory Domains
+    //
+    Mscis[Count].MemoryProximityDomain = Index;
+    Mscis[Count].CacheAttributes.Bits.TotalCacheLevels = EFI_ACPI_HMAT_ONE_LEVEL_CACHE;
+    Mscis[Count].CacheAttributes.Bits.CacheLevel = EFI_ACPI_HMAT_ONE_LEVEL_CACHE;
+    Mscis[Count].CacheAttributes.Bits.CacheLineSize = DDR4_CACHE_LINE_SIZE;
+    Mscis[Count].CacheAttributes.Bits.CacheAssociativity = EFI_ACPI_HMAT_CACHE_ASSOCIATIVITY_DIRECT_MAPPED;
+    Mscis[Count].CacheAttributes.Bits.WritePolicy = EFI_ACPI_HMAT_WRITE_POLICY_WB;
+    Mscis[Count].MemorySideCacheSize = LShiftU64 (HmatData->MemoryDomainList[Index].MemorySideCacheSize, MEM_ADDR_SHFT_VAL);
+    Mscis[Count].NumSmbiosHandles = HmatData->MemoryDomainList[Index].NumSmbiosHandles;
+    for(SmbiosHandleIndex = 0 ; SmbiosHandleIndex < HmatData->MemoryDomainList[Index].NumSmbiosHandles; SmbiosHandleIndex++){
+      Mscis[Count].SmbiosHandles[SmbiosHandleIndex] = HmatData->MemoryDomainList[Index].SmbiosHandles[SmbiosHandleIndex];
+    }
+
+    DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) MSCIS[%x] MemorySideCacheSize = 0x%lx, ProximityDomain = %x\n", Count, Mscis[Count].MemorySideCacheSize, Index));
+
+    Count++;
+  }
+
+  //
+  // Move MSCIS entries up to replace removed MSARS entries
+  //
+  if (*SlackSize && Count) {
+    RemoveSlack (SlackSize, Mscis, Count * sizeof(Mscis[0]));
+  }
+
+  //
+  // Update SlackSize for unused MSCIS entries
+  //
+  UnusedCount = EFI_ACPI_HMAT_MSCIS_COUNT - Count;
+  *SlackSize += UnusedCount * sizeof(Mscis[0]);
+}
+
+/**
+  Update the HMAT table.
+
+  @param [in, out]      HmatAcpiTable       The table to be set.
+
+  @retval EFI SUCCESS   Procedure returned successfully.
+**/
+EFI_STATUS
+PatchHmatAcpiTable (
+  IN OUT  EFI_ACPI_COMMON_HEADER  *Table
+  )
+{
+  UINTN                                         SlackSize = 0;
+  HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE          *HmatData = NULL;
+  EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE *HmatAcpiTable;
+
+  if (mSystemMemoryMap == NULL) {
+
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  HmatAcpiTable = (EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE *)Table;
+
+  HmatData = (HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *) InitializeHmatData ();
+  if (HmatData == NULL) {
+    DEBUG ((DEBUG_ERROR, "ACPI (HMAT) HMAT Data could not be initialized... skipping HMAT Patch\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Patch the MSARS, SLLBIS, and MSCIS Structure from HMAT Table.
+  //
+  PatchHmatMsars (HmatAcpiTable, &SlackSize, HmatData);
+  PatchHmatLbis (HmatAcpiTable->Lbis, &SlackSize, HmatData);
+  PatchHmatMscis (HmatAcpiTable->MemSideCache, &SlackSize, HmatData);
+
+  if (HmatData != NULL) {
+    FreePool (HmatData);
+  }
+
+  //
+  // Update HMAT table size
+  //
+  HmatAcpiTable->HmatHeader.Header.Length -= (UINT32)SlackSize;
+
+  //
+  // Dump HMAT
+  //
+  DumpHmat (HmatAcpiTable);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibLocal.h b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibLocal.h
new file mode 100644
index 0000000000..4e0d9eaa8f
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibLocal.h
@@ -0,0 +1,441 @@
+/** @file
+
+  @copyright
+  Copyright 1999 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_PLATFORM__LIB_LOCAL_H_
+#define _ACPI_PLATFORM__LIB_LOCAL_H_
+
+//
+// Statements that include other header files
+//
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/AcpiPlatformLib.h>
+#include <Library/CpuConfigLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/SetupLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BuildAcpiTablesLib.h>
+
+#include <Guid/PlatformInfo.h>
+#include <Guid/MemoryMapData.h>
+#include <Guid/GlobalVariable.h>
+
+#include <Protocol/AcpiTable.h>
+#include <Protocol/Smbios.h>
+#include <Protocol/SuperIo.h>
+#include <Protocol/NfitTableUpdateProtocol.h>
+#include <DataTypes.h>
+#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+#include <IioRegs.h>
+#include <Platform.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Protocol/IioUds.h>
+#include <SystemBoard.h>
+#include <Protocol/SerialIo.h>
+#include <Protocol/DevicePath.h>
+#include <Register/ArchitecturalMsr.h>
+#include <PpmPolicyPeiDxeCommon.h>
+#include <Acpi/Bdat.h>
+#include <Acpi/Hpet.h>
+#include <Acpi/Mcfg.h>
+#include <Acpi/Msct.h>
+#include <Acpi/Slit.h>
+#include <Acpi/Srat.h>
+#include <Acpi/Migt.h>
+#include <Acpi/Nfit.h>
+#include <Acpi/Pcat.h>
+#include <Acpi/Pmtt.h>
+#include <Acpi/Hmat.h>
+#include <Acpi/Wsmt.h>
+#include <Acpi/amlresrc.h> // came from https://acpica.org/downloads/source_code.php acpica-win-20130214.zip/source/include
+#include <IndustryStandard/AcpiAml.h>
+
+#include <Guid/SocketMpLinkVariable.h>
+#include <Guid/SocketIioVariable.h>
+#include <Guid/SocketPowermanagementVariable.h>
+#include <Guid/SocketCommonRcVariable.h>
+
+#include <Guid/FpgaSocketVariable.h>
+#include <Fpga.h>
+#include <Register/Cpuid.h>
+#include <Protocol/DynamicSiLibraryProtocol.h>
+#include <Protocol/DynamicSiLibraryProtocol2.h>
+#include <Upi/KtiHost.h>
+
+#define OEM1_SSDT_TABLE_SIGNATURE  SIGNATURE_32('O', 'E', 'M', '1')
+#define OEM2_SSDT_TABLE_SIGNATURE  SIGNATURE_32('O', 'E', 'M', '2')
+#define OEM3_SSDT_TABLE_SIGNATURE  SIGNATURE_32('O', 'E', 'M', '3')
+#define OEM4_SSDT_TABLE_SIGNATURE  SIGNATURE_32('O', 'E', 'M', '4')
+
+#define AML_NAME_OP           0x08
+#define AML_NAME_PREFIX_SIZE  0x06
+#define AML_NAME_DWORD_SIZE   0x0C
+
+#ifndef AML_EXTERNAL_OP
+#define AML_EXTERNAL_OP       0x15 /* ACPI 6.0 */
+#endif
+
+#define GPSS_FVID_MAX_STATES  40  // Greater Than 16 p-state support
+
+//
+// mCpuPCPSInfo usage
+//
+#define B_PCPS_DISABLE                     (1 << 17) // Bit 17
+#define B_PCPS_HT_ENABLE                   (1 << 16) // Bit 16
+#define PCIE_BUS_0         0x00
+#define PCIE_BUS_1         0x01
+#define PCIE_BUS_2         0x02
+#define PCIE_BUS_3         0x03
+#define PCIE_BUS_4         0x04
+#define PCIE_BUS_5         0x05
+
+#define PCIE_PORT_ALL_FUNC 0x00
+
+#define PCIE_PORT_0_DEV    0x00
+
+#define PCIE_PORT_1A_DEV   0x00
+#define PCIE_PORT_1B_DEV   0x01
+#define PCIE_PORT_1C_DEV   0x02
+#define PCIE_PORT_1D_DEV   0x03
+
+#define PCIE_PORT_2A_DEV   0x00
+#define PCIE_PORT_2B_DEV   0x01
+#define PCIE_PORT_2C_DEV   0x02
+#define PCIE_PORT_2D_DEV   0x03
+
+#define PCIE_PORT_3A_DEV   0x00
+#define PCIE_PORT_3B_DEV   0x01
+#define PCIE_PORT_3C_DEV   0x02
+#define PCIE_PORT_3D_DEV   0x03
+
+#define PCIE_PORT_4A_DEV   0x00
+#define PCIE_PORT_4B_DEV   0x01
+#define PCIE_PORT_4C_DEV   0x02
+#define PCIE_PORT_4D_DEV   0x03
+
+#define PCIE_PORT_5_DEV   0x00
+
+#define MAX_IO_APICS_10NM   1
+
+//
+// Define flag bits
+//
+#define POLARITY_ACTIVE_HIGH   0x01
+#define POLARITY_ACTIVE_LOW    0x03
+#define TRIGGERMODE_EDGE       0x04
+#define TRIGGERMODE_LEVEL      0x0C
+
+#pragma pack(1)
+typedef struct {
+  UINT32   AcpiProcessorId;
+  UINT32   ApicId;
+  UINT32   Flags;
+  UINT32   SocketNum;
+} CPU_ID_ORDER_MAP;
+
+typedef struct {
+  UINT8   AcpiProcessorId;
+  UINT8   ApicId;
+  UINT16  Flags;
+} CPU_ID_MAP;
+
+typedef struct {
+  UINT8   StartByte;
+  UINT32  NameStr;
+  UINT8   Size;
+  UINT32  Value;
+} ACPI_NAMEPACK_DWORD;
+
+typedef struct {
+  UINT8   StartByte;
+  UINT32  NameStr;
+  UINT8   OpCode;
+  UINT16  Size;                     // Hardcode to 16bit width because the table we use is fixed size
+  UINT8   NumEntries;
+} ACPI_NAME_COMMAND;
+
+typedef struct {
+  UINT8   PackageOp;
+  UINT8   PkgLeadByte;
+  UINT8   NumEntries;
+  UINT8   DwordPrefix0;
+  UINT32  CoreFreq;
+  UINT8   DwordPrefix1;
+  UINT32  Power;
+  UINT8   DwordPrefix2;
+  UINT32  TransLatency;
+  UINT8   DwordPrefix3;
+  UINT32  BMLatency;
+  UINT8   DwordPrefix4;
+  UINT32  Control;
+  UINT8   DwordPrefix5;
+  UINT32  Status;
+} PSS_PACKAGE;
+
+typedef struct {
+  UINT8     NameOp;           // 08h ;First opcode is a NameOp.
+  UINT32    PackageName;      // PSDC/PSDE
+  UINT8     Length;
+  UINT8     DwordPrefix1;
+  UINT8     Revision;
+  UINT8     PackageOp;
+  UINT8     PackageLen;
+  UINT8     PackLen;
+  UINT16    WordValue1;
+  UINT16    WordValue2;
+  UINT8     BytePrefix2;
+  UINT32    Domain;
+  UINT8     BytePrefix3;
+  UINT8     CoordType;        // 0xFC(SW_ALL), 0xFE(HW_ALL)
+  UINT8     BytePrefix4;
+  UINT32    NumProcessors;
+} PSD_PACKAGE_LAYOUT;
+
+struct CpcRegPack {
+  UINT8    ResourceOp;           // 11h
+  UINT8    Length;               // 14h
+  UINT32   FFixedHW;
+  UINT32   RegisterBitsUsage;
+  UINT32   RegisterBitsShift;
+  UINT32   RegisterOffset;
+  UINT32   RegisterByteSize;
+};
+
+typedef struct {
+  UINT8  ExternalOp;
+  UINT8  RootChar;
+  UINT8  MultiNamePrefix;
+  UINT8  SegCount;
+  UINT32 NameStr[0];
+} EXTERNAL_OBJECT_DECL;
+
+#define ACPI_NAME_COMMAND_FROM_NAME_STR(a)  BASE_CR (a, ACPI_NAME_COMMAND, NameStr)
+#define ACPI_NAME_COMMAND_FROM_NAMEPACK_STR(a)  BASE_CR (a, ACPI_NAMEPACK_DWORD, NameStr)
+#define ACPI_EXTERNAL_OBJECT_DECL_FROM_NAME_STR(a) BASE_CR (a, EXTERNAL_OBJECT_DECL, NameStr)
+
+//
+// Private Driver Data
+//
+//
+// Define Union of IO APIC & Local APIC structure;
+//
+typedef union {
+  EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_STRUCTURE AcpiLocalApic;
+  EFI_ACPI_6_2_IO_APIC_STRUCTURE              AcpiIoApic;
+  EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_STRUCTURE AcpiLocalx2Apic;
+  struct {
+    UINT8 Type;
+    UINT8 Length;
+  } AcpiApicCommon;
+} ACPI_APIC_STRUCTURE_PTR;
+
+#pragma pack()
+
+EFI_STATUS
+PatchBdatAcpiTable (
+  IN OUT  EFI_ACPI_COMMON_HEADER  *Table
+  );
+
+/**
+  Build from scratch and install the MADT.
+
+  @retval EFI_SUCCESS           The MADT was installed successfully.
+  @retval EFI_OUT_OF_RESOURCES  Could not allocate required structures.
+**/
+EFI_STATUS
+InstallMadtFromScratch (
+  VOID
+  );
+
+EFI_STATUS
+InstallSratTable (
+  VOID
+  );
+
+EFI_STATUS
+PatchFadtTable(
+   IN OUT   EFI_ACPI_COMMON_HEADER  *Table
+   );
+
+EFI_STATUS
+PatchDsdtTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER   *Table
+  );
+
+EFI_STATUS
+PatchMcfgAcpiTable (
+  IN OUT  EFI_ACPI_COMMON_HEADER  *Table
+  );
+
+EFI_STATUS
+PatchSLitTable(
+   IN OUT   EFI_ACPI_COMMON_HEADER  *Table
+   );
+
+EFI_STATUS
+InstallSlitTable(
+   VOID
+   );
+
+/**
+  Finds the Proximity Domain which the element in the Memory Map belongs to.
+
+  @param [in]  SocketId        SocketId which the element belongs to.
+  @param [in]  MemType         MemType of the element.
+  @param [in]  SncEnabled      Bit to indicate if SNC is enabled in the setup options.
+  @param [in]  ImcInterBitmap  IMC interleave bitmap for this element.
+  @param [in]  MemMode         Current memory mode. 1LM, 2LM etc.
+  @param [in]  LastDomainId    Last Domain ID.
+
+  @retval Proximity Domain.
+
+**/
+UINT32
+ProximityDomainOf (
+  UINT8  SocketId,
+  UINT16 MemType,
+  UINT8  MaxEnabledImc,
+  UINT8  SncEnabled,
+  UINT8  SncNumOfCluster,
+  UINT8  ImcInterBitmap,
+  UINT8  MemMode,
+  UINT32 LastDomainId
+  );
+
+EFI_STATUS
+PatchSratTable (
+   IN OUT   STATIC_RESOURCE_AFFINITY_TABLE  *Table
+   );
+
+EFI_STATUS
+PatchSsdtTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER   *Table,
+  IN OUT EFI_ACPI_TABLE_VERSION     *Version
+  );
+
+EFI_STATUS
+PatchCpuPmSsdtTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER   *Table
+  );
+
+EFI_STATUS
+PatchOem1SsdtTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER   *Table
+  );
+
+EFI_STATUS
+PatchOem2SsdtTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER   *Table
+  );
+
+EFI_STATUS
+PatchOem3SsdtTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER   *Table
+  );
+
+EFI_STATUS
+PatchOem4SsdtTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER   *Table
+  );
+
+EFI_STATUS
+UpdateNfitTable (
+   IN OUT   EFI_ACPI_COMMON_HEADER  *Table
+   );
+
+EFI_STATUS
+UpdatePcatTable (
+   IN OUT   EFI_ACPI_COMMON_HEADER  *Table
+   );
+
+/**
+  Detect the APICID map and initialize the module global pointer.
+**/
+VOID
+DetectApicIdMap (
+  VOID
+  );
+
+/**
+  Sort CPU Local APIC Information.
+
+  This function gets the CPU local APIC information from the MP service
+  protocol into the local table structure, and sorts it based on APIC ID.
+
+  @retval EFI_SUCCESS   Local APIC information was successfully sorted.
+**/
+EFI_STATUS
+SortCpuLocalApicInTable (
+  VOID
+  );
+
+/**
+  Get the socket logical index.
+
+  This function convert the socket physical index to logical index (0 based).
+  If the specified physical socket is not enabled, an invalid logical index 0xff
+  will be returned. The socket physical index and logical index will be the same
+  if the indexes of enabled sockets are continuous.
+
+  @param[in] SocketPhysicalId    Socket physical index.
+
+  @retval Socket logical index.
+**/
+UINT8
+GetSocketLogicalId (
+  IN UINT8  SocketPhysicalId
+  );
+
+/**
+  Get the socket physical index.
+
+  This function convert the socket logical index to physical index (0 based).
+  If the specified logical socket does not exist, an invalid physical index 0xff
+  will be returned. The socket physical index and logical index will be the same
+  if the indexes of enabled sockets are continuous.
+
+  @param[in] SocketLogicalId    Socket logical index.
+
+  @retval Socket physical index.
+**/
+UINT8
+GetSocketPhysicalId (
+  IN UINT8  SocketlogicId
+  );
+
+/**
+  Verifies whether sockets are linked
+
+  @param[in]      SourceSocket  Source Socket ID
+  @param[in]      TargetSocket  Targer Socket ID
+
+  @retval TRUE link between source socket and target socket was found
+          FALSE otherwise
+
+**/
+BOOLEAN
+SocketsLinked (
+  IN UINT32  SourceSocket,
+  IN UINT32  TargetSocket
+  );
+
+//
+// AcpiPlatformTableLib private share
+//
+extern EFI_MP_SERVICES_PROTOCOL    *mMpService;
+extern BOOLEAN                     mCpuOrderSorted;
+extern CPU_ID_ORDER_MAP            mCpuApicIdOrderTable[];
+extern UINTN                       mNumberOfCPUs;
+extern UINTN                       mNumberOfEnabledCPUs;
+extern AML_OFFSET_TABLE_ENTRY      *mAmlOffsetTablePointer;
+extern CPU_CONFIG_CONTEXT_BUFFER  *mCpuConfigLibConfigContextBuffer;
+
+
+#endif
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMcfg.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMcfg.c
new file mode 100644
index 0000000000..dfe2425648
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMcfg.c
@@ -0,0 +1,134 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2015 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatformLibLocal.h"
+
+
+extern BIOS_ACPI_PARAM              *mAcpiParameter;
+extern EFI_IIO_UDS_PROTOCOL         *mIioUds;
+extern CPU_CSR_ACCESS_VAR           *mCpuCsrAccessVarPtr;
+extern SYSTEM_CONFIGURATION         mSystemConfiguration;
+
+EFI_STATUS
+PatchMcfgAcpiTable (
+  IN OUT  EFI_ACPI_COMMON_HEADER  *Table
+  )
+{
+  UINT8     NodeId;
+  UINT8     NodeCount;
+  EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE *McfgTable;
+
+  McfgTable = (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE *)Table;
+
+  //
+  // mAcpiParameter memory buffer has been zero'ed out, so mAcpiParameter->PcieSegNum[] are 0's
+  // Patch \_SB.PSYS.SGEN with User Setup Option data
+  //
+  //
+  // dynamically allow multi-seg support
+  //
+  mAcpiParameter->PcieMultiSegSupport = 0;
+  for (NodeId = 0; NodeId < MAX_SOCKET; NodeId++) {
+    if ((UINT16) (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[NodeId].PcieSegment) > 0) {
+      mAcpiParameter->PcieMultiSegSupport = 1;
+      break;
+    }
+  }
+
+  //
+  // Update MCFG table entries (segment number, base addr and start/end bus numbers)
+  //
+  if (mAcpiParameter->PcieMultiSegSupport == 0) {
+
+    //
+    // Original code for single  PCIe segment start
+    //
+    McfgTable->Segment[0].BaseAddress = mIioUds->IioUdsPtr->PlatformData.PciExpressBase;
+    McfgTable->Segment[0].EndBusNumber = (UINT8)RShiftU64 (mIioUds->IioUdsPtr->PlatformData.PciExpressSize, 20) - 1;
+    //
+    // Original code for single  PCIe segment end
+    //
+
+    //
+    // Single segment with segment number as 0
+    //
+    McfgTable->Segment[0].PciSegmentGroupNumber = 0;
+    NodeCount = 1;
+
+  } else {
+    //
+    // PCIe Multi-Segment handling - Assume each CPU socket as a segment, and copy Segement info from IioUds HOB to MCFG table entries
+    //
+
+    //
+    // Segment count = 0
+    //
+    NodeCount = 0;
+
+    for (NodeId = 0; NodeId < MAX_SOCKET; NodeId++) {
+
+      //
+      // Skip a socket if it does not exist or does not contain valid bus range data
+      //
+      if ( (UINT8)(mCpuCsrAccessVarPtr->SocketLastBus[NodeId]) ==
+            (UINT8)(mCpuCsrAccessVarPtr->SocketFirstBus[NodeId]) ) {
+        continue;
+      }
+
+      //
+      // Copy PCIe Segement info from IioUds HOB to MCFG table entries
+      //
+      McfgTable->Segment[NodeCount].PciSegmentGroupNumber = (UINT16)(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[NodeId].PcieSegment);
+
+      McfgTable->Segment[NodeCount].BaseAddress = \
+        LShiftU64 (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[NodeId].SegMmcfgBase.hi, 32) + \
+        (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[NodeId].SegMmcfgBase.lo);
+
+      McfgTable->Segment[NodeCount].StartBusNumber = (UINT8)(mCpuCsrAccessVarPtr->SocketFirstBus[NodeId]);
+
+      McfgTable->Segment[NodeCount].EndBusNumber = (UINT8)(mCpuCsrAccessVarPtr->SocketLastBus[NodeId]);
+
+      //
+      // Update segment number returned by AML  _SEG() .  It resides in mAcpiParameter region now.
+      //
+      mAcpiParameter->PcieSegNum[NodeId] = (UINT8)(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[NodeId].PcieSegment);
+
+      //
+      // Update count of valid segments
+      //
+      NodeCount++;
+    }
+  }
+
+  //
+  // Set MCFG table "Length" field based on the number of PCIe segments enumerated so far
+  //
+  McfgTable->Header.Header.Length = \
+    sizeof (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER) + \
+    sizeof (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE) * NodeCount;
+
+  //
+  // Debug dump of MCFG table
+  //
+  DEBUG ((DEBUG_ERROR, "ACPI MCFG table @ address 0x%x\n", Table ));
+  DEBUG ((DEBUG_ERROR, "  Multi-Seg Support = %x\n", mAcpiParameter->PcieMultiSegSupport));
+  DEBUG ((DEBUG_ERROR, "  Number of Segments (sockets): %2d\n", NodeCount ));
+  DEBUG ((DEBUG_ERROR, "  Table Length = 0x%x\n\n", McfgTable->Header.Header.Length ));
+  for (NodeId = 0; NodeId < NodeCount; NodeId ++) {
+    DEBUG ((DEBUG_ERROR, "   Segment[%2d].BaseAddress = %x\n",  NodeId, McfgTable->Segment[NodeId].BaseAddress));
+    DEBUG ((DEBUG_ERROR, "   Segment[%2d].PciSegmentGroupNumber = %x\n", NodeId, McfgTable->Segment[NodeId].PciSegmentGroupNumber));
+    DEBUG ((DEBUG_ERROR, "   Segment[%2d].StartBusNumber = %x\n", NodeId, McfgTable->Segment[NodeId].StartBusNumber));
+    DEBUG ((DEBUG_ERROR, "   Segment[%2d].EndBusNumber = %x\n\n", NodeId, McfgTable->Segment[NodeId].EndBusNumber));
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMigt.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMigt.c
new file mode 100644
index 0000000000..603fe57cec
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMigt.c
@@ -0,0 +1,69 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2018 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatformLibLocal.h"
+
+extern BIOS_ACPI_PARAM      *mAcpiParameter;
+
+/**
+    Update the MIGT ACPI table
+
+    @param *TableHeader   - The table to be set
+
+    @retval EFI_SUCCESS -  Returns Success
+**/
+EFI_STATUS
+PatchMigtAcpiTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER   *Table
+  )
+{
+  EFI_STATUS        Status;
+  UINT64            Address;
+  UINTN             idx;
+  UINT8             checksum;
+  EFI_MIGT_ACPI_DESCRIPTION_TABLE *MigtAcpiTable;
+
+  MigtAcpiTable = (EFI_MIGT_ACPI_DESCRIPTION_TABLE *)Table;
+  Address = 0xffffffff;
+
+  Status  = gBS->AllocatePages (
+                   AllocateMaxAddress,
+                   EfiACPIMemoryNVS,
+                   1,     //page
+                   &Address
+                   );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // update MIGT ACPI table
+  //
+  MigtAcpiTable->ActionRegion.Address = Address;
+
+  //
+  // update checksum
+  //
+  MigtAcpiTable->Header.Checksum = 0;
+  checksum = 0;
+  for(idx = 0; idx < sizeof(EFI_MIGT_ACPI_DESCRIPTION_TABLE); idx++) {
+    checksum = checksum + (UINT8) (((UINT8 *)(MigtAcpiTable))[idx]);
+  }
+  MigtAcpiTable->Header.Checksum = (UINT8) (0 - checksum);
+
+  //
+  // Update Migration Action Region GAS address
+  //
+  mAcpiParameter->MigrationActionRegionAddress = Address;
+
+  return Status;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMsct.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMsct.c
new file mode 100644
index 0000000000..1755325d61
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMsct.c
@@ -0,0 +1,101 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatformLibLocal.h"
+
+/**
+  Update the MSCT ACPI table
+
+  @param *MsctAcpiTable - The table to be set
+
+  @retval EFI_SUCCESS -  Returns Success
+**/
+EFI_STATUS
+PatchMsctAcpiTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER   *Table
+  )
+{
+  UINTN                       idx;
+  UINT8                       checksum;
+  UINT32                      MaxPhysicalAddressBit;
+  EFI_CPUID_REGISTER          CpuidLeafInfo;
+  EFI_ACPI_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE *MsctAcpiTable = NULL;
+  UINT32                      MaxThreadCapacity;
+  UINT32                      MaxSocketCount;
+  EFI_STATUS                  Status = EFI_SUCCESS;
+  DYNAMIC_SI_LIBARY_PROTOCOL2  *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  MsctAcpiTable = (EFI_ACPI_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE *)Table;
+
+  //
+  // If SNC is enabled set the Maximum number of Proximity domains accordingly
+  //
+  MaxSocketCount = FixedPcdGet32 (PcdMaxCpuSocketCount);
+
+  if (DynamicSiLibraryProtocol2->GetNumOfClusterPerSystem () != 0) {
+    MsctAcpiTable->MaxNumProxDom = MaxSocketCount * DynamicSiLibraryProtocol2->GetNumOfClusterPerSystem () - 1;
+  }
+
+  //
+  // Update Maximum Physical Address
+  // Get the number of address lines; Maximum Physical Address is 2^MaxPhysicalAddressBit - 1.
+  // If CPUID does not support reporting the max physical address, then use a max value of 36 as per SDM 3A, 4.1.4.
+  //
+  AsmCpuid (CPUID_EXTENDED_FUNCTION, &CpuidLeafInfo.RegEax, NULL, NULL, NULL);
+  MaxPhysicalAddressBit = 36;
+  if (CpuidLeafInfo.RegEax >= (UINT32) CPUID_VIR_PHY_ADDRESS_SIZE) {
+    AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &CpuidLeafInfo.RegEax, NULL, NULL, NULL);
+    MaxPhysicalAddressBit = (UINT8) CpuidLeafInfo.RegEax;
+  }
+
+  MsctAcpiTable->MaxPhysicalAddress = (LShiftU64 (0x01, MaxPhysicalAddressBit) - 1);
+
+  MaxPhysicalAddressBit = DynamicSiLibraryProtocol2->GetMaxPhysicalAddrBits ();
+
+  MsctAcpiTable->MaxPhysicalAddress = (LShiftU64 (0x01, MaxPhysicalAddressBit) - 1);
+
+  //
+  // First Proximity Domain Information Structure reports characteristics for all proximity domains,
+  // since the characteristics are the same for all proximity domains.
+  //
+  MsctAcpiTable->ProxDomInfoStructure[0].ProxDomRangeLow  = 0;
+  MsctAcpiTable->ProxDomInfoStructure[0].ProxDomRangeHigh = MsctAcpiTable->MaxNumProxDom;
+
+  //
+  // Max Number of Threads that the processor can have MaxThreadCapacity
+  //
+  AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 1, NULL, &MaxThreadCapacity, NULL, NULL);
+  MsctAcpiTable->ProxDomInfoStructure[0].MaxProcessorCapacity = MaxThreadCapacity;
+
+  //
+  // Max Memory capacity per proximity domain
+  //
+  MsctAcpiTable->ProxDomInfoStructure[0].MaxMemoryCapacity = MsctAcpiTable->MaxPhysicalAddress;
+
+  //
+  // Update Checksum
+  //
+  MsctAcpiTable->Header.Checksum = 0;
+  checksum = 0;
+  for(idx = 0; idx < sizeof(EFI_ACPI_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE); idx++) {
+    checksum = checksum + (UINT8) (((UINT8 *)(MsctAcpiTable))[idx]);
+  }
+  MsctAcpiTable->Header.Checksum = (UINT8) (0 - checksum);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibNfit.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibNfit.c
new file mode 100644
index 0000000000..cc65d575c3
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibNfit.c
@@ -0,0 +1,45 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2019 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatformLibLocal.h"
+
+/**
+  This function locates the CrystalRidge protocol and JedecNvdimm protocol
+  and calls the update ACPI tables functions defined there to update/build
+  the NVDIMM F/W Interface Table (NFIT). It builds the NFIT table which gets
+  published in ACPI XSDT.
+
+  @param[in,out] Table      Pointer to NFIT which will be build in
+                            CR Protocol and will be publised in ACPI XSDT.
+
+  @retval EFI_SUCCESS       Table successfully updated.
+  @retval EFI_UNSUPPORTED   Table not updated.
+**/
+EFI_STATUS
+UpdateNfitTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER  *Table
+  )
+{
+  EFI_NFIT_TABLE_UPDATE_PROTOCOL    *NfitTableUpdateProtocol = NULL;
+  EFI_STATUS                        Status;
+
+  Status = gBS->LocateProtocol (&gEfiNfitTableUpdateProtocolGuid, NULL, &NfitTableUpdateProtocol);
+
+  if (!EFI_ERROR (Status)) {
+    Status = NfitTableUpdateProtocol->UpdateAcpiTable ((UINT64*) Table);
+  } else {
+    DEBUG ((DEBUG_ERROR, "Cannot find NfitTableUpdateProtocol\n"));
+  }
+  DEBUG ((DEBUG_INFO, "NFIT Update Status: 0x%x\n", Status));
+
+  return Status;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPcat.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPcat.c
new file mode 100644
index 0000000000..515e8ffd1d
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPcat.c
@@ -0,0 +1,42 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2016 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatformLibLocal.h"
+
+/**
+  This function  locates the CrystalRidge Protocol and calls
+  into one of its interface function (UpdateAcpiPcatTable) to
+  update/build the PCAT (Platform Capability Attribute Table).
+  And this table gets published in ACPI XSDT.
+
+  @param *Table       - Pointer to PCAT table which will be
+          build in CR Protocol and will be publised in ACPI
+          XSDT.
+  @retval Status      - Return Status
+**/
+EFI_STATUS
+UpdatePcatTable (
+   IN OUT   EFI_ACPI_COMMON_HEADER  *Table
+   )
+{
+  EFI_STATUS                      Status;
+  DYNAMIC_SI_LIBARY_PROTOCOL2     *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  Status = DynamicSiLibraryProtocol2->UpdatePcatTable (Table);
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPmtt.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPmtt.c
new file mode 100644
index 0000000000..dd9807c899
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPmtt.c
@@ -0,0 +1,267 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 2016 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "AcpiPlatformLibLocal.h"
+#include <Protocol/SmbiosMemInfo.h>
+
+extern struct SystemMemoryMapHob   *mSystemMemoryMap;
+
+/******************************************************************************
+ * Definitions.
+ ******************************************************************************/
+//#define PMTTDEBUG_ENABLED 1
+#if PMTTDEBUG_ENABLED
+#define PMTTDEBUG(Expr) _DEBUG(Expr)
+#else
+#define PMTTDEBUG(Expr)
+#endif
+#ifndef NELEMENTS
+#define NELEMENTS(Array) (sizeof(Array)/sizeof((Array)[0]))
+#endif
+
+
+//
+// PMTT GUID variables
+//
+const EFI_GUID  gEfiPmttTypeDieGuid = PMTT_TYPE_DIE_GUID;
+const EFI_GUID  gEfiPmttTypeChannelGuid = PMTT_TYPE_CHANNEL_GUID;
+const EFI_GUID  gEfiPmttTypeSlotGuid = PMTT_TYPE_SLOT_GUID;
+
+/******************************************************************************
+ * Functions.
+ ******************************************************************************/
+
+EFI_STATUS
+PatchPlatformMemoryTopologyTable (
+  IN OUT EFI_ACPI_COMMON_HEADER       *Table
+  )
+{
+  UINT8                                Socket;
+  UINT8                                Die;
+  UINT8                                Imc;
+  UINT8                                Channel;
+  UINT8                                ChannelIndex;
+  UINT8                                Dimm;
+  SMBIOS_DIMM_INFO                     DimmInfo;
+  SMBIOS_MEM_INFO_PROTOCOL             *SmbiosInfoProtocol;
+  EFI_STATUS                           Status;
+  ACPI_PLATFORM_MEMORY_TOPOLOGY_TABLE  *PmttTable = (ACPI_PLATFORM_MEMORY_TOPOLOGY_TABLE*)Table;
+  UINT8                                MaxImc;
+  UINT8                                MaxChPerImc;
+  UINT8                                DieCnt;
+
+  DYNAMIC_SI_LIBARY_PROTOCOL2         *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  MaxImc = DynamicSiLibraryProtocol2->GetMaxImc ();
+  MaxChPerImc = DynamicSiLibraryProtocol2->GetNumChannelPerMc ();
+
+  ASSERT (PmttTable->Header.Signature == ACPI_PMTT_TABLE_SIGNATURE);
+
+  Status = gBS->LocateProtocol (&gSmbiosMemInfoProtocolGuid, NULL, (VOID**)&SmbiosInfoProtocol);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[ACPI] (PMTT) Cannot locate SmbiosMemInfoProtocol! (%r)\n", Status));
+    ASSERT_EFI_ERROR (Status);
+    SmbiosInfoProtocol = NULL;
+  }
+
+  for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+
+    PmttTable->Socket[Socket].Type      = ACPI_TOP_LEVEL_SOCKET;
+    PmttTable->Socket[Socket].SckIdent  = Socket;
+    PmttTable->Socket[Socket].Length    = sizeof(PmttTable->Socket[Socket]) - sizeof(ACPI_PMTT_DIE_DEVICE);
+    PmttTable->Socket[Socket].Flag      = 0;
+    PmttTable->Socket[Socket].NumOfMemoryDevices = 0;
+
+    if (mSystemMemoryMap->Socket[Socket].SocketEnabled) {
+      PmttTable->Socket[Socket].Flag |= (PMTT_TOP_LEVEL_AGGREGATOR_DEVICE | PMTT_PHYSICAL_ELEMENT_OF_TOPOLOGY);
+      PmttTable->NumOfMemoryDevices++;
+    } else {
+      continue;
+    }
+
+    DieCnt =   DynamicSiLibraryProtocol2->GetAcpiDieCount (Socket);
+    for (Die = 0; Die < DieCnt; Die++) {
+
+      PmttTable->Socket[Socket].Die[Die].Type = ACPI_TOP_LEVEL_VENDOR_SPECIFIC_DEVICE;
+      PmttTable->Socket[Socket].Die[Die].Length = sizeof(PmttTable->Socket[Socket].Die[Die]) - MAX_IMC * sizeof(ACPI_PMTT_IMC_DEVICE);
+      PmttTable->Socket[Socket].Die[Die].Flag = 0;
+      PmttTable->Socket[Socket].Die[Die].Flag |= PMTT_PHYSICAL_ELEMENT_OF_TOPOLOGY;
+      PmttTable->Socket[Socket].Die[Die].NumOfMemoryDevices = 0;
+      PmttTable->Socket[Socket].Die[Die].DieId = Die;
+      CopyGuid (&PmttTable->Socket[Socket].Die[Die].TypeUuid, &gEfiPmttTypeDieGuid);
+
+      PmttTable->Socket[Socket].NumOfMemoryDevices++;
+
+      for (Imc = 0; Imc < MaxImc; Imc++) {
+
+        PmttTable->Socket[Socket].Die[Die].Imc[Imc].Type = ACPI_TOP_LEVEL_IMC;
+        PmttTable->Socket[Socket].Die[Die].Imc[Imc].Length = sizeof(PmttTable->Socket[Socket].Die[Die].Imc[Imc]) - MAX_MC_CH * sizeof(ACPI_PMTT_CHANNEL_DEVICE);
+        PmttTable->Socket[Socket].Die[Die].Imc[Imc].Flag = 0;
+        PmttTable->Socket[Socket].Die[Die].Imc[Imc].NumOfMemoryDevices = 0;
+        PmttTable->Socket[Socket].Die[Die].Imc[Imc].ImcId = Imc;
+
+        if (mSystemMemoryMap->Socket[Socket].imcEnabled[Imc]) {
+          PmttTable->Socket[Socket].Die[Die].Imc[Imc].Flag |= PMTT_PHYSICAL_ELEMENT_OF_TOPOLOGY;
+          PmttTable->Socket[Socket].Die[Die].NumOfMemoryDevices++;
+        } else {
+          continue;
+        }
+
+        for (Channel = 0; Channel < MaxChPerImc; Channel++) {
+
+          ChannelIndex = MEM_IMCCH_TO_SKTCH(Imc, Channel);
+          PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Type = ACPI_TOP_LEVEL_VENDOR_SPECIFIC_DEVICE;
+          PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Length = sizeof(PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel]) - MAX_DIMM * sizeof(ACPI_PMTT_SLOT_DEVICE);
+          PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Flag = 0;
+          PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].NumOfMemoryDevices = 0;
+          PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].ChannelId = Channel;
+          CopyGuid (&(PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].TypeUuid), &gEfiPmttTypeChannelGuid);
+
+          if (mSystemMemoryMap->Socket[Socket].ChannelInfo[ChannelIndex].Enabled) {
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Flag |= PMTT_PHYSICAL_ELEMENT_OF_TOPOLOGY;
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].NumOfMemoryDevices++;
+          } else {
+            continue;
+          }
+
+          for (Dimm = 0; Dimm < MAX_DIMM; Dimm++) {
+            //
+            // Looping through the each DIMM on the IMC.
+            //
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Type = ACPI_TOP_LEVEL_VENDOR_SPECIFIC_DEVICE;
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Length = sizeof(PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm]) - sizeof(ACPI_PMTT_DIMM_DEVICE);
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Flag |= PMTT_PHYSICAL_ELEMENT_OF_TOPOLOGY;
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].NumOfMemoryDevices = 0;
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].SlotId = Dimm;
+            CopyGuid (&PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].TypeUuid, &gEfiPmttTypeSlotGuid);
+
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.Type = PHYSICAL_COMPONENT_IDENTIFIER_TYPE_DIMM;
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.Length = sizeof(PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm);
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.NumOfMemoryDevices = 0;
+
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.Flag = 0;
+
+            if (!mSystemMemoryMap->Socket[Socket].ChannelInfo[ChannelIndex].DimmInfo[Dimm].Present) {
+              continue;
+            }
+
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.Flag |= PMTT_PHYSICAL_ELEMENT_OF_TOPOLOGY;
+
+            if (mSystemMemoryMap->Socket[Socket].ChannelInfo[ChannelIndex].DimmInfo[Dimm].DcpmmPresent) {
+              PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.Flag |= PMTT_AEP_DIMM;
+            }
+            //
+            // Get SMBIOS handle for the DIMM. If handle not found use FFFFFFFFh.
+            //
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.SmbiosHandle = (UINT32)-1;
+            if (SmbiosInfoProtocol != NULL) {
+
+              DimmInfo.Socket = Socket;
+              DimmInfo.Imc = Imc;
+              DimmInfo.Channel = Channel;
+              DimmInfo.Dimm = Dimm;
+              Status = SmbiosInfoProtocol->SmbiosGetDimmByLocation (SmbiosInfoProtocol, &DimmInfo);
+              if (!EFI_ERROR (Status)) {
+                PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.SmbiosHandle = DimmInfo.Type17Handle;
+              }
+            }
+
+            if (!mSystemMemoryMap->Socket[Socket].ChannelInfo[ChannelIndex].DimmInfo[Dimm].Enabled) {
+              continue;
+            }
+
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].NumOfMemoryDevices++;
+            PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].NumOfMemoryDevices++;
+          } // for (Dimm...)
+        } // for (Channel...)
+      } // for (Imc...)
+    } // for (Die...)
+  } // for (Skt...)
+  //
+  // Dump the strucutre for debug purpose
+  //
+  PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) Signature:       0x%08X\n", PmttTable->Header.Signature));
+  PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) Length:          %d\n", PmttTable->Header.Length));
+  PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) Revision:        %d\n", PmttTable->Header.Revision));
+  PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) Checksum:         %d\n", PmttTable->Header.Checksum));
+  PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) OemId:           '%c%c%c%c%c%c'\n",
+              PmttTable->Header.OemId[0], PmttTable->Header.OemId[1], PmttTable->Header.OemId[2],
+              PmttTable->Header.OemId[3], PmttTable->Header.OemId[4], PmttTable->Header.OemId[5]));
+  PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) OemTableId:      0x%08X\n", PmttTable->Header.OemTableId));
+  PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) OemRevision:     %d\n", PmttTable->Header.OemRevision));
+  PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) CreatorId:       0x%08X\n", PmttTable->Header.CreatorId));
+  PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) CreatorRevision: %d\n", PmttTable->Header.OemRevision));
+  PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) NumOfMemoryDevices: %d\n", PmttTable->NumOfMemoryDevices));
+
+  PMTTDEBUG ((DEBUG_INFO, "\n"));
+  for (Socket = 0; Socket < NELEMENTS (PmttTable->Socket); Socket++) {
+
+    PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d] Type:        0x%02X\n", Socket, PmttTable->Socket[Socket].Type));
+    PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d] Length:      %d\n", Socket, PmttTable->Socket[Socket].Length));
+    PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d] Flags:       0x%04X\n", Socket, PmttTable->Socket[Socket].Flag));
+    PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d] SocketId:    %d\n", Socket, PmttTable->Socket[Socket].SckIdent));
+    PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d] NumOfMemoryDevices:    %d\n", Socket, PmttTable->Socket[Socket].NumOfMemoryDevices));
+
+    PMTTDEBUG ((DEBUG_INFO, "\n"));
+    for (Die = 0; Die < NELEMENTS(PmttTable->Socket[Socket].Die); Die++) {
+
+      PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d] Type:        0x%02X\n", Socket, Die, PmttTable->Socket[Socket].Die[Die].Type));
+      PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d] Length:      %d\n", Socket, Die, PmttTable->Socket[Socket].Die[Die].Length));
+      PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d] Flags:       0x%04X\n", Socket, Die, PmttTable->Socket[Socket].Die[Die].Flag));
+      PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d] DieId:       %d\n", Socket, Die, PmttTable->Socket[Socket].Die[Die].DieId));
+      PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d] TypeUuid:    %g\n", Socket, Die, PmttTable->Socket[Socket].Die[Die].TypeUuid));
+      PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d] NumOfMemoryDevices:       %d\n", Socket, Die, PmttTable->Socket[Socket].Die[Die].NumOfMemoryDevices));
+
+      PMTTDEBUG ((DEBUG_INFO, "\n"));
+      for (Imc = 0; Imc < NELEMENTS(PmttTable->Socket[Socket].Die[Die].Imc); Imc++) {
+
+        PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d] Type:                   0x%02X\n", Socket, Die, Imc, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Type));
+        PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d] Length:                 %d\n", Socket, Die, Imc, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Length));
+        PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d] Flags:                  0x%04X\n", Socket, Die, Imc, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Flag));
+        PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d] ImcId:                  %d\n", Socket, Die, Imc, PmttTable->Socket[Socket].Die[Die].Imc[Imc].ImcId));
+        PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d] NumOfMemoryDevices:     %d\n", Socket, Die, Imc, PmttTable->Socket[Socket].Die[Die].Imc[Imc].NumOfMemoryDevices));
+
+        PMTTDEBUG ((DEBUG_INFO, "\n"));
+        for (Channel = 0; Channel < NELEMENTS(PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel); Channel++) {
+
+          PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d] Type:                   0x%02X\n", Socket, Die, Imc, Channel, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Type));
+          PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d] Length:                 %d\n", Socket, Die, Imc, Channel, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Length));
+          PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d] Flags:                  0x%04X\n", Socket, Die, Imc, Channel, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Flag));
+          PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d] ChannelId:              %d\n", Socket, Die, Imc, Channel, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].ChannelId));
+          PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d] TypeUuid:               %g\n", Socket, Die, Imc, Channel, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].TypeUuid));
+          PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d] NumOfMemoryDevices:     %d\n", Socket, Die, Imc, Channel, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].NumOfMemoryDevices));
+
+          PMTTDEBUG ((DEBUG_INFO, "\n"));
+          for (Dimm = 0; Dimm < NELEMENTS(PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot); Dimm++) {
+
+            PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d] Type:                   0x%02X\n", Socket, Die, Imc, Channel, Dimm, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Type));
+            PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d] Length:                 %d\n", Socket, Die, Imc, Channel, Dimm, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Length));
+            PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d] Flags:                  0x%04X\n", Socket, Die, Imc, Channel, Dimm, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Flag));
+            PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d] SlotId:                 %d\n", Socket, Die, Imc, Channel, Dimm, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].SlotId));
+            PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d] TypeUuid:               %g\n", Socket, Die, Imc, Channel, Dimm, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].TypeUuid));
+            PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d] NumOfMemoryDevices:     %d\n", Socket, Die, Imc, Channel, Dimm, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].NumOfMemoryDevices));
+
+            PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d][%d] Type:                0x%02X\n", Socket, Die, Imc, Channel, Dimm, Dimm, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.Type));
+            PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d][%d] Length:              %d\n", Socket, Die, Imc, Channel, Dimm, Dimm, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.Length));
+            PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d][%d] Flags:               0x%04X\n", Socket, Die, Imc, Channel, Dimm, Dimm, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.Flag));
+            PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d][%d] SmbiosHandle:        0x%08X\n", Socket, Die, Imc, Channel, Dimm, Dimm, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.SmbiosHandle));
+            PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d][%d] NumOfMemoryDevices:  %d\n", Socket, Die, Imc, Channel, Dimm, Dimm, PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.NumOfMemoryDevices));
+          } // for (Dimm...)
+        } // for (Channel...)
+      } // for (Imc...)
+    } // for (Die...)
+  } // for (Skt...)
+  return EFI_SUCCESS;
+} // PatchPlatformMemoryTopologyTable ()
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSlit.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSlit.c
new file mode 100644
index 0000000000..a8ac046aea
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSlit.c
@@ -0,0 +1,1153 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatformLibLocal.h"
+
+extern SYSTEM_MEMORY_MAP_HOB        *mSystemMemoryMap;
+extern EFI_IIO_UDS_PROTOCOL         *mIioUds;
+extern EFI_ACPI_TABLE_PROTOCOL      *mAcpiTable;
+extern CPU_CSR_ACCESS_VAR           *mCpuCsrAccessVarPtr;
+
+EFI_ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE_PMEM_INFO mSlitPmemInfo[EFI_ACPI_SLIT_PMEM_INFO_CNT];
+
+
+/**
+  Displays System Locality Distance Information Table (SLIT)
+
+  @param None
+
+  @retval None
+**/
+VOID
+DisplayEntries (
+  IN ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *SlitPtr
+  )
+{
+  UINT16                                     EntryIdx = 0;
+  UINT16                                     MaxTableEntries;
+  UINT8                                      NodeCount;
+
+  if (SlitPtr == NULL) {
+
+    ASSERT (SlitPtr != NULL);
+    return;
+  }
+  NodeCount = (UINT8)SlitPtr->Header.NumberOfSystemLocalities;
+  MaxTableEntries = NodeCount * NodeCount;
+
+  DEBUG ((DEBUG_INFO, "SLIT: Dump table (size %d):\n", NodeCount));
+
+  while (EntryIdx < MaxTableEntries) {
+
+    DEBUG ((DEBUG_INFO, "%02X ", SlitPtr->NumSlit[EntryIdx].Entry));
+    if ((EntryIdx % NodeCount) == (NodeCount - 1)) {
+      DEBUG ((DEBUG_INFO, "\n"));
+    }
+    EntryIdx++;
+  }
+}
+
+
+/**
+  Stores correlation between AEP PMEM NUMA node and socket
+
+  @param[in] Pmem   AEP PMEM NUMA node number
+  @param[in] Socket Socket number
+
+  @retval None
+
+**/
+VOID
+SavePmemInfo (
+  IN UINT8 Pmem,
+  IN UINT8 Socket,
+  MEM_TYPE Type
+  )
+{
+  if (Pmem < EFI_ACPI_SLIT_PMEM_INFO_CNT) {
+
+    DEBUG ((DEBUG_INFO, "SLIT: Found PMem %d at socket %d (mem type 0x%X)\n", Pmem, Socket, Type));
+    mSlitPmemInfo[Pmem].Pmem = Pmem;
+    mSlitPmemInfo[Pmem].Socket = Socket;
+    mSlitPmemInfo[Pmem].Valid = TRUE;
+    return;
+  }
+
+  DEBUG ((DEBUG_ERROR, "SLIT: Error - Number of PMem nodes (%d) exceed PMem info data table size (%d)\n",
+      Pmem, EFI_ACPI_SLIT_PMEM_INFO_CNT));
+  ASSERT (FALSE);
+}
+
+/**
+  Retrieves socket correlated with given AEP PMEM NUMA node
+
+  @param[in] Pmem AEP PMEM Numa node
+
+  @retval Socket correlated with given AEP PMEM NUMA node
+
+**/
+UINT8
+GetSocketForPmem (
+  IN UINT8 Pmem
+  )
+{
+  UINT8 PmemInfoEntry;
+
+  for (PmemInfoEntry = 0; PmemInfoEntry < EFI_ACPI_SLIT_PMEM_INFO_CNT; PmemInfoEntry++) {
+    if (mSlitPmemInfo[PmemInfoEntry].Valid && mSlitPmemInfo[PmemInfoEntry].Pmem == Pmem) {
+      return mSlitPmemInfo[PmemInfoEntry].Socket;
+    }
+  }
+
+  DEBUG ((DEBUG_ERROR, "SLIT: Error - PMem node (%d) is not associated with any socket\n", Pmem));
+  ASSERT (FALSE);
+  return PMEM_INVALID_SOCKET;
+}
+
+/**
+  This function gets the physical node index for given FPGA NUMA node.
+  If the given FPGA NUMA node doesn't exist, an invalid physical node
+  index 0xff will be returned.
+
+  @param[in] FpgaNumaNodeId      FPGA NUMA node index (0 based).
+
+  @retval Physical node index of given FPGA NUMA node (0 based).
+
+**/
+UINT8
+GetPhyNodeIdForFpga (
+  IN UINT8  FpgaNumaNodeId
+  )
+{
+  UINT32    FpgaPresentBitMap;
+  UINT8     PhyNodeId;
+
+  PhyNodeId = 0;
+  FpgaPresentBitMap = mCpuCsrAccessVarPtr->FpgaPresentBitMap;
+
+  while ((FpgaNumaNodeId != (UINT8) -1) && (FpgaPresentBitMap != 0)) {
+    if ((FpgaPresentBitMap & BIT0) != 0) {
+      FpgaNumaNodeId--;
+    }
+    FpgaPresentBitMap >>= 1;
+    PhyNodeId++;
+  }
+
+  if ((FpgaPresentBitMap == 0) && (FpgaNumaNodeId != (UINT8) -1)) {
+    return (UINT8) -1;
+  }
+
+  return PhyNodeId - 1;
+}
+
+/**
+  Retrieves number of FPGA Presents
+
+  @retval Number of FPGA Presents in the system
+
+**/
+UINT8
+GetFpgaCount (
+  VOID)
+{
+  UINT8   FpgaCount = 0;
+  UINT32  FpgaPresentBitMap = mCpuCsrAccessVarPtr->FpgaPresentBitMap;
+
+  while (FpgaPresentBitMap) {
+    if (FpgaPresentBitMap & BIT0) {
+      FpgaCount++;
+    }
+    FpgaPresentBitMap >>= 1;
+  }
+  return FpgaCount;
+}
+
+/**
+  Retrieves number of AEP PMEM NUMA nodes
+
+  @retval Number of AEP PMEM NUMA nodes
+
+**/
+UINT8
+GetPmemNodeCount (
+  VOID
+  )
+{
+  UINT8 Socket;
+  UINT8 SadRule;
+  UINT8 PmemNodeCount = 0;
+
+  EFI_STATUS                  Status = EFI_SUCCESS;
+  DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return 0;
+  }
+
+  for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+    if ((mCpuCsrAccessVarPtr->socketPresentBitMap & (BIT0 << Socket)) == 0) {
+      continue;
+    }
+    for (SadRule = 0; SadRule < MAX_SAD_RULES; SadRule++) {
+      //
+      // Only local SADs of PMEM type should be taken into consideration.
+      // Skip any memory region marked reserved.
+      //
+      if (mSystemMemoryMap->Socket[Socket].SAD[SadRule].local &&
+          DynamicSiLibraryProtocol2->IsMemTypeAppDirect (mSystemMemoryMap->Socket[Socket].SAD[SadRule].type) &&
+          !DynamicSiLibraryProtocol2->IsMemTypeReserved (mSystemMemoryMap->Socket[Socket].SAD[SadRule].type)) {
+
+        SavePmemInfo (PmemNodeCount++, Socket, mSystemMemoryMap->Socket[Socket].SAD[SadRule].type);
+      }
+    }
+  }
+
+  return PmemNodeCount;
+}
+
+/**
+  Retrieves number of clusters in the system if system is in SNC mode. If system is not
+  in SNC mode, the return 1.
+
+  @return Number of clusters in the system in SNC mode or 1 if system is not in SNC mode.
+
+**/
+UINT8
+GetNumClusters (
+  VOID
+  )
+{
+  UINT8 NumClusters;
+
+  NumClusters = mIioUds->IioUdsPtr->SystemStatus.OutNumOfCluster;
+  if ((NumClusters == 0) || (mIioUds->IioUdsPtr->SystemStatus.OutSncEn == 0)) {
+    NumClusters = 1; // For non-SNC mode, we should also return 1.
+  }
+  if (mSystemMemoryMap->VirtualNumaEnable) {
+    NumClusters = NumClusters * mSystemMemoryMap->VirtualNumOfCluster;
+  }
+
+  return NumClusters;
+}
+
+/**
+  Retrieves number of enabled CPUs in the system
+
+  @param None
+
+  @retval Number of enabled CPUs in the system
+
+**/
+UINT8
+GetNumCpus (
+  VOID
+  )
+{
+  return mIioUds->IioUdsPtr->SystemStatus.numCpus;
+}
+
+/**
+  Calculates total number of nodes
+
+  @param[in]      NumCpus       Number of CPUs
+  @param[in]      NumClusters   Number of clusters
+  @param[in]      PmemNodeCount Number of AEP PMEM NUMA nodes
+
+  @retval Total number of nodes
+
+**/
+UINT8
+GetNodeCount (
+  IN UINT8  NumCpus,
+  IN UINT8  NumClusters,
+  IN UINT8  PmemNodeCount,
+  IN UINT8 FpgaCount
+  )
+{
+  UINT8 NodeCount;
+
+  if (mSystemMemoryMap->volMemMode == VOL_MEM_MODE_MIX_1LM2LM) {
+    NodeCount = ((NumCpus * NumClusters * EFI_ACPI_SLIT_DOMAINS_NODES_MAX_CNT) + PmemNodeCount + FpgaCount);
+  } else {
+    NodeCount = ((NumCpus * NumClusters) + PmemNodeCount + FpgaCount);
+  }
+  if ((NodeCount * NodeCount) < EFI_ACPI_SYSTEM_LOCALITIES_ENTRY_COUNT) {
+    return NodeCount;
+  }
+
+  DEBUG ((DEBUG_ERROR, "SLIT: Error - Nodes distances info data size (%d) exceed SLIT distances info table size (%d)\n",
+    (NodeCount * NodeCount), EFI_ACPI_SYSTEM_LOCALITIES_ENTRY_COUNT));
+  ASSERT (FALSE);
+  return 0;
+}
+
+/**
+  Verifies whether sockets are linked
+
+  @param[in]      SourceSocket  Source Socket ID
+  @param[in]      TargetSocket  Targer Socket ID
+
+  @retval TRUE link between source socket and target socket was found
+          FALSE otherwise
+
+**/
+BOOLEAN
+SocketsLinked (
+  IN UINT32  SourceSocket,
+  IN UINT32  TargetSocket
+  )
+{
+  UINT8 PeerSocket;
+  UINT8 LinkValid;
+  UINT8 PeerSocId;
+
+  EFI_STATUS                  Status = EFI_SUCCESS;
+  DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return FALSE;
+  }
+
+  //
+  // Validate sockets ids
+  //
+  if ((SourceSocket < MAX_SOCKET) && (TargetSocket < MAX_SOCKET)) {
+    //
+    // Do not process when source socket is the same as target socket
+    //
+    if (SourceSocket != TargetSocket) {
+      for (PeerSocket = 0; PeerSocket < (DynamicSiLibraryProtocol2->GetKtiPortCnt()); PeerSocket++) {
+        LinkValid = mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[SourceSocket].PeerInfo[PeerSocket].Valid;
+        PeerSocId = mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[SourceSocket].PeerInfo[PeerSocket].PeerSocId;
+        if (LinkValid && (PeerSocId == TargetSocket)) {
+          //
+          // Link found
+          //
+          return TRUE;
+        }
+      }
+    }
+    //
+    // Link not found
+    //
+    return FALSE;
+  }
+
+  DEBUG ((DEBUG_ERROR, "SLIT: Error when checking if sockets are linked (source socket id %d, target socket id %d)\n", SourceSocket, TargetSocket));
+  return FALSE;
+}
+
+/**
+  Initializes SLIT Table entries
+
+  @param[in,out] Table Pointer to SLIT ACPI tables
+
+  @retval EFI_SUCCESS  operation completed successfully
+
+**/
+EFI_STATUS
+InitEntries (
+  IN OUT ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *SlitPtr
+  )
+{
+  if (SlitPtr == NULL) {
+    ASSERT (SlitPtr != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+  SetMem (&SlitPtr->NumSlit[0].Entry, EFI_ACPI_SYSTEM_LOCALITIES_ENTRY_COUNT, 0xFF);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Processes socket nodes
+
+  @param[in,out]  Table         Pointer to SLIT ACPI tables
+  @param[in]      NumCpus       Number of CPUs
+  @param[in]      NumClusters   Number of clusters
+  @param[in]      PmemNodeCount Number of AEP PMEM NUMA nodes
+  @param[in]      FpgaCount     Number of FPGA NUMA nodes
+  @param[in]      NodeCount     Number of all nodes
+
+  @retval EFI_SUCCESS  operation completed successfully
+
+**/
+EFI_STATUS
+ProcessSockets (
+  IN OUT EFI_ACPI_COMMON_HEADER *Table,
+  IN UINT8                      NumCpus,
+  IN UINT8                      NumClusters,
+  IN UINT8                      PmemNodeCount,
+  IN UINT8                      FpgaCount,
+  IN UINT8                      NodeCount
+  )
+{
+  ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE  *SlitAcpiTable;
+  UINT16                                  EntryIdx;
+  UINT8                                   SourceNode;
+  UINT8                                   SourceSocket;
+  UINT8                                   SourceCluster;
+  UINT8                                   TargetSocket;
+  UINT8                                   TargetCluster;
+  UINT8                                   VirtualNumaFactor;
+
+  if (NULL == Table) {
+    DEBUG ((DEBUG_ERROR, "SLIT: Error in SLIT update with data about nodes on same socket\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+  VirtualNumaFactor = 1;
+  if (mSystemMemoryMap->VirtualNumaEnable) {
+    VirtualNumaFactor = mSystemMemoryMap->VirtualNumOfCluster;
+  }
+
+  DEBUG ((DEBUG_INFO, "SLIT: Update with data about nodes on same socket\n"));
+
+  SlitAcpiTable = (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table;
+
+  for (SourceNode = 0; SourceNode < (NodeCount - PmemNodeCount - FpgaCount) ; SourceNode++) {
+    SourceSocket = SourceNode / NumClusters;
+    SourceCluster = SourceNode % NumClusters;
+    for (TargetSocket = 0; TargetSocket < NumCpus; TargetSocket++) {
+      for (TargetCluster = 0; TargetCluster < NumClusters; TargetCluster++) {
+        if (SourceSocket == TargetSocket) {
+          EntryIdx = (SourceNode * (NodeCount)) + (TargetSocket * NumClusters) + TargetCluster;
+          //
+          // Source and target are nodes on same socket
+          //
+          if ((SourceCluster / VirtualNumaFactor) == (TargetCluster / VirtualNumaFactor)) {
+            //
+            // a) Same socket same physical cluster
+            //
+            SlitAcpiTable->NumSlit[EntryIdx].Entry = ZERO_HOP;
+          } else {
+            //
+            // b) Same socket different cluster
+            //
+            SlitAcpiTable->NumSlit[EntryIdx].Entry = ZERO_ONE;
+          }
+        }
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Processes socket nodes
+
+  @param[in,out]  Table         Pointer to SLIT ACPI tables
+  @param[in]      NumCpus       Number of CPUs
+  @param[in]      NumClusters   Number of clusters
+  @param[in]      PmemNodeCount Number of AEP PMEM NUMA nodes
+  @param[in]      FpgaCount     Number of FPGA NUMA nodes
+  @param[in]      NodeCount     Number of all nodes
+
+  @retval EFI_SUCCESS  operation completed successfully
+
+**/
+EFI_STATUS
+ProcessMixedModeSockets (
+  IN OUT EFI_ACPI_COMMON_HEADER *Table,
+  IN UINT8                      NumCpus,
+  IN UINT8                      NumClusters,
+  IN UINT8                      PmemNodeCount,
+  IN UINT8                      FpgaCount,
+  IN UINT8                      NodeCount
+  )
+{
+  ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE  *SlitAcpiTable;
+  UINT16                                  EntryIdx1LM;
+  UINT16                                  EntryIdx2LM;
+  UINT8                                   SourceNode;
+  UINT8                                   SourceSocket;
+  UINT8                                   SourceCluster;
+  UINT8                                   TargetSocket;
+  UINT8                                   TargetCluster;
+  BOOLEAN                                 Is2LM;
+
+  if (NULL == Table) {
+    DEBUG ((DEBUG_ERROR, "SLIT: Error in SLIT update with data about nodes on same socket for Mixed Mode\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DEBUG ((DEBUG_INFO, "SLIT: Update with data about nodes on same socket for Mixed Mode\n"));
+
+  SlitAcpiTable = (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table;
+
+  for (SourceNode = 0; SourceNode < (NodeCount - PmemNodeCount - FpgaCount) ; SourceNode++) {
+    Is2LM = (SourceNode >= NumCpus * NumClusters) ? TRUE : FALSE;
+    SourceSocket = (SourceNode - NumCpus * NumClusters * (Is2LM ? 1 : 0)) / NumClusters;
+    SourceCluster = (SourceNode - NumCpus * NumClusters * (Is2LM ? 1 : 0)) % NumClusters;
+
+    TargetSocket = SourceSocket;
+    for (TargetCluster = 0; TargetCluster < NumClusters; TargetCluster++) {
+      EntryIdx1LM = (UINT16)((SourceNode * NodeCount) + (TargetSocket * NumClusters) + TargetCluster);
+      EntryIdx2LM = EntryIdx1LM + NumCpus * NumClusters;
+
+      if ((SourceCluster == TargetCluster) && (Is2LM == FALSE)) {
+        //
+        // CPU -> 1LM at the same socket, the same cluster
+        //
+        SlitAcpiTable->NumSlit[EntryIdx1LM].Entry = ZERO_HOP;
+        //
+        // CPU -> 2LM at the same socket, the same cluster
+        //
+        SlitAcpiTable->NumSlit[EntryIdx2LM].Entry = ZERO_ONE;
+      } else if ((SourceCluster == TargetCluster) && (Is2LM == TRUE)) {
+        //
+        // CPU -> 2LM at the same socket, the same cluster
+        //
+        SlitAcpiTable->NumSlit[EntryIdx1LM].Entry = ZERO_ONE;
+        //
+        // not effective
+        //
+        SlitAcpiTable->NumSlit[EntryIdx2LM].Entry = ZERO_HOP;
+      } else if ((SourceCluster != TargetCluster) && (Is2LM == FALSE)) {
+        //
+        // CPU -> 1LM at the same socket, different cluster
+        //
+        SlitAcpiTable->NumSlit[EntryIdx1LM].Entry = ZERO_ONE;
+        //
+        // CPU -> 2LM at the same socket, different cluster
+        //
+        SlitAcpiTable->NumSlit[EntryIdx2LM].Entry = ZERO_TWO;
+      } else {
+        //
+        // branch condition: ((SourceCluster != TargetCluster) && (Is2LM == TRUE))
+        // CPU -> 2LM at the same socket, different cluster
+        //
+        SlitAcpiTable->NumSlit[EntryIdx1LM].Entry = ZERO_TWO;
+        //
+        // not effective
+        //
+        SlitAcpiTable->NumSlit[EntryIdx2LM].Entry = ZERO_TWO;
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Processes connections between sockets to retrieve valid distances
+
+  @param[in,out]  Table         Pointer to SLIT ACPI tables
+  @param[in]      NumCpus       Number of CPUs
+  @param[in]      NumClusters   Number of clusters
+  @param[in]      PmemNodeCount Number of AEP PMEM NUMA nodes
+  @param[in]      FpgaCount     Number of FPGA NUMA nodes
+  @param[in]      NodeCount     Number of all nodes
+
+  @retval EFI_SUCCESS  operation completed successfully
+
+**/
+EFI_STATUS
+ProcessSocketsLinks (
+  IN OUT EFI_ACPI_COMMON_HEADER *Table,
+  IN UINT8                      NumCpus,
+  IN UINT8                      NumClusters,
+  IN UINT8                      PmemNodeCount,
+  IN UINT8                      FpgaCount,
+  IN UINT8                      NodeCount
+  )
+{
+  ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE  *SlitAcpiTable;
+  UINT8                                   SourceNode;
+  UINT8                                   SourceSocket;
+  UINT8                                   SourceCluster;
+  UINT8                                   TargetSocket;
+
+  if (NULL == Table) {
+    DEBUG ((DEBUG_ERROR, "SLIT: Error in processing links between sockets\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DEBUG ((DEBUG_INFO, "SLIT: Update table with links between sockets\n"));
+
+  SlitAcpiTable = (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table;
+
+  for (SourceNode = 0; SourceNode < (NodeCount - PmemNodeCount - FpgaCount); SourceNode++) {
+    SourceSocket = SourceNode / NumClusters;
+    SourceCluster = SourceNode % NumClusters;
+    for (TargetSocket = 0; TargetSocket < NumCpus; TargetSocket++) {
+      if (SocketsLinked (GetSocketPhysicalId (SourceSocket), GetSocketPhysicalId (TargetSocket))) {
+        SetMem (&SlitAcpiTable->NumSlit[(SourceNode * NodeCount) + (TargetSocket * NumClusters)].Entry,
+                NumClusters, ONE_HOP);
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Processes connections between sockets to retrieve valid distances
+
+  @param[in,out]  Table         Pointer to SLIT ACPI tables
+  @param[in]      NumCpus       Number of CPUs
+  @param[in]      NumClusters   Number of clusters
+  @param[in]      PmemNodeCount Number of AEP PMEM NUMA nodes
+  @param[in]      FpgaCount     Number of FPGA NUMA nodes
+  @param[in]      NodeCount     Number of all nodes
+
+  @retval EFI_SUCCESS  operation completed successfully
+
+**/
+EFI_STATUS
+ProcessMixedModeSocketsLinks (
+  IN OUT EFI_ACPI_COMMON_HEADER *Table,
+  IN UINT8                      NumCpus,
+  IN UINT8                      NumClusters,
+  IN UINT8                      PmemNodeCount,
+  IN UINT8                      FpgaCount,
+  IN UINT8                      NodeCount
+  )
+{
+  ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE  *SlitAcpiTable;
+  UINT16                                  EntryIdx1LM;
+  UINT16                                  EntryIdx2LM;
+  UINT8                                   SourceNode;
+  UINT8                                   SourceSocket;
+  UINT8                                   SourceCluster;
+  UINT8                                   TargetSocket;
+  UINT8                                   TargetCluster;
+  BOOLEAN                                 Is2LM;
+
+  if (NULL == Table) {
+    DEBUG ((DEBUG_ERROR, "SLIT: Error in processing links between sockets in Mixed Mode\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DEBUG ((DEBUG_INFO, "SLIT: Update table with links between sockets in Mixed Mode\n"));
+
+  SlitAcpiTable = (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table;
+
+  for (SourceNode = 0; SourceNode < (NodeCount - PmemNodeCount - FpgaCount); SourceNode++) {
+    Is2LM = (SourceNode >= NumCpus * NumClusters) ? TRUE : FALSE;
+    SourceSocket = (SourceNode - NumCpus * NumClusters * (Is2LM ? 1 : 0)) / NumClusters;
+    SourceCluster = (SourceNode - NumCpus * NumClusters * (Is2LM ? 1 : 0)) % NumClusters;
+
+    for (TargetSocket = 0; TargetSocket < NumCpus; TargetSocket++) {
+      if (SocketsLinked (GetSocketPhysicalId (SourceSocket), GetSocketPhysicalId (TargetSocket))) {
+        //
+        // If both sockets are linked by KTI and not the same socket.
+        //
+        for (TargetCluster = 0; TargetCluster < NumClusters; TargetCluster++) {
+          EntryIdx1LM = (UINT16)((SourceNode * NodeCount) + (TargetSocket * NumClusters) + TargetCluster);
+          EntryIdx2LM = EntryIdx1LM + NumCpus * NumClusters;
+
+          if (Is2LM == FALSE) {
+            //
+            // CPU -> 1LM at different socket
+            //
+            SlitAcpiTable->NumSlit[EntryIdx1LM].Entry = ONE_HOP;
+            //
+            // CPU -> 2LM at different socket
+            //
+            SlitAcpiTable->NumSlit[EntryIdx2LM].Entry = ONE_ONE;
+          } else {
+            //
+            // branch condition: (Is2LM == TRUE)
+            // CPU -> 2LM at different socket
+            //
+            SlitAcpiTable->NumSlit[EntryIdx1LM].Entry = ONE_ONE;
+            //
+            // not effective
+            //
+            SlitAcpiTable->NumSlit[EntryIdx2LM].Entry = ONE_TWO;
+          }
+        }
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Processes all AEP PMEM NUMA nodes
+
+  @param[in,out]  Table         Pointer to SLIT ACPI tables
+  @param[in]      NumCpus       Number of CPUs
+  @param[in]      NumClusters   Number of clusters
+  @param[in]      PmemNodeCount Number of AEP PMEM NUMA nodes
+  @param[in]      FpgaCount     Number of FPGA NUMA nodes
+  @param[in]      NodeCount     Number of all nodes
+
+  @retval EFI_SUCCESS  operation completed successfully
+
+**/
+EFI_STATUS
+ProcessPmems (
+  IN OUT EFI_ACPI_COMMON_HEADER *Table,
+  IN UINT8                      NumCpus,
+  IN UINT8                      NumClusters,
+  IN UINT8                      PmemNodeCount,
+  IN UINT8                      FpgaCount,
+  IN UINT8                      NodeCount
+  )
+{
+  ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE  *SlitAcpiTable;
+  UINT16                                  EntryIdx;
+  UINT8                                   SourceNode;
+  UINT8                                   TargetNode;
+  UINT8                                   SourceSocket;
+  UINT8                                   TargetCluster;
+  UINT8                                   TargetSocket;
+  UINT8                                   SourcePmem;
+  UINT8                                   TargetPmem;
+  UINT8                                   SourcePmemSocket;
+  UINT8                                   TargetPmemSocket;
+  UINT8                                   TotalVolMemNodes;
+
+  if (NULL == Table) {
+    DEBUG ((DEBUG_ERROR, "SLIT: Error in processing PMems\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (mSystemMemoryMap->volMemMode == VOL_MEM_MODE_MIX_1LM2LM) {
+    TotalVolMemNodes = NumCpus * NumClusters * EFI_ACPI_SLIT_DOMAINS_NODES_MAX_CNT;
+  } else {
+    TotalVolMemNodes = NumCpus * NumClusters;
+  }
+
+  DEBUG ((DEBUG_INFO, "SLIT: Include PMem NUMA nodes\n"));
+
+  if (PmemNodeCount > 0) {
+
+    SlitAcpiTable = (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table;
+
+    //
+    // 1) AEP PMEM nodes to AEP PMEM nodes distances
+    //
+    for (SourceNode = (NodeCount - PmemNodeCount - FpgaCount); SourceNode < (NodeCount - FpgaCount); SourceNode++) {
+      SourcePmem = SourceNode - TotalVolMemNodes;
+      for (TargetPmem = 0; TargetPmem < PmemNodeCount; TargetPmem++) {
+        TargetNode = TargetPmem + TotalVolMemNodes;
+        EntryIdx = (SourceNode * NodeCount) + TargetNode;
+        if (SourcePmem == TargetPmem) {
+          SlitAcpiTable->NumSlit[EntryIdx].Entry = PMEM_ZERO_HOP;
+        } else {
+          //
+          // Retrieve sockets associated with PMEMs
+          //
+          SourcePmemSocket = GetSocketForPmem (SourcePmem);
+          TargetPmemSocket = GetSocketForPmem (TargetPmem);
+
+          if (SourcePmemSocket == TargetPmemSocket) {
+            //
+            // PMEMs are on the same socket
+            //
+            SlitAcpiTable->NumSlit[EntryIdx].Entry = PMEM_ONE_ONE;
+          } else {
+            //
+            // Assign 2 hop and process with PeerInfo checking
+            //
+            SlitAcpiTable->NumSlit[EntryIdx].Entry = PMEM_TWO_HOP;
+
+            //
+            // Examine PeerInfo to look for link between AEP PMEM source socket and AEP PMEM target socket
+            //
+            if (SocketsLinked (SourcePmemSocket, TargetPmemSocket)) {
+              //
+              // Link found assign 1 hop
+              //
+              SlitAcpiTable->NumSlit[EntryIdx].Entry = PMEM_ONE_HOP;
+            }
+          }
+        }
+      }
+    }
+
+    //
+    // 2) Sockets to AEP PMEM nodes distances
+    //
+    for (SourceNode = 0; SourceNode < (NodeCount - PmemNodeCount - FpgaCount); SourceNode++) {
+      SourceSocket = GetSocketPhysicalId (SourceNode / NumClusters);
+      for (TargetPmem = 0; TargetPmem < PmemNodeCount; TargetPmem++) {
+        TargetPmemSocket = GetSocketForPmem (TargetPmem);
+        TargetNode = TargetPmem + TotalVolMemNodes;
+        EntryIdx = (SourceNode * NodeCount) + TargetNode;
+        if (SourceSocket == TargetPmemSocket) {
+          SlitAcpiTable->NumSlit[EntryIdx].Entry = PMEM_ONE_ONE;
+        } else {
+          //
+          // Assign 2 hop and process with PeerInfo checking
+          //
+          SlitAcpiTable->NumSlit[EntryIdx].Entry = PMEM_TWO_HOP;
+
+          //
+          // Examine PeerInfo to look for link between source socket and AEP PMEM socket
+          //
+          if (SocketsLinked (SourceSocket, TargetPmemSocket)) {
+            //
+            // Link found assign 1 hop
+            //
+            SlitAcpiTable->NumSlit[EntryIdx].Entry = PMEM_ONE_HOP;
+          }
+        }
+      }
+    }
+
+    //
+    // 3) AEP PMEM nodes to sockets distances
+    //
+    for (SourceNode = (NodeCount - PmemNodeCount - FpgaCount); SourceNode < (NodeCount - FpgaCount); SourceNode++) {
+      SourcePmem = SourceNode - TotalVolMemNodes;
+      SourcePmemSocket = GetSocketForPmem (SourcePmem);
+      for (TargetSocket = 0; TargetSocket < NumCpus; TargetSocket++) {
+        for (TargetCluster = 0; TargetCluster < NumClusters; TargetCluster++) {
+          EntryIdx = (SourceNode * NodeCount) + (TargetSocket * NumClusters) + TargetCluster;
+          if(SourcePmemSocket == GetSocketPhysicalId (TargetSocket)) {
+            SlitAcpiTable->NumSlit[EntryIdx].Entry = PMEM_ONE_ONE;
+          } else {
+            //
+            // Assign 2 hop and process with PeerInfo checking
+            //
+            SlitAcpiTable->NumSlit[EntryIdx].Entry = PMEM_TWO_HOP;
+
+            //
+            // Examine PeerInfo to look for link between source socket and AEP PMEM socket
+            //
+            if (SocketsLinked (SourcePmemSocket, GetSocketPhysicalId (TargetSocket))) {
+              //
+              // Link found assign 1 hop
+              //
+              SlitAcpiTable->NumSlit[EntryIdx].Entry = PMEM_ONE_HOP;
+            }
+          }
+        }
+      }
+    }
+  } else {
+    DEBUG ((DEBUG_INFO, "SLIT: PMem NUMA nodes not present\n"));
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function processes all FPGA NUMA nodes.
+
+  @param[in,out] Table             Pointer to SLIT ACPI tables.
+  @param[in] NumClusters           Number of clusters.
+  @param[in] PmemNodeCount         Number of AEP PMEM NUMA nodes.
+  @param[in] FpgaCount             Number of FPGA NUMA nodes.
+  @param[in] NodeCount             Number of all nodes.
+
+  @retval EFI_SUCCESS              This function is executed successfully.
+  @retval EFI_INVALID_PARAMETER    Some of input parameters are invalid.
+**/
+EFI_STATUS
+ProcessFpgaNodes (
+  IN OUT EFI_ACPI_COMMON_HEADER *Table,
+  IN UINT8                      NumClusters,
+  IN UINT8                      PmemNodeCount,
+  IN UINT8                      FpgaCount,
+  IN UINT8                      NodeCount
+  )
+{
+  ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE  *SlitAcpiTable;
+  UINT8                                   SourceNode;
+  UINT8                                   TargetNode;
+  UINT8                                   SourceSocket;
+  UINT8                                   TargetSocket;
+
+  if (Table == NULL) {
+    DEBUG ((DEBUG_ERROR, "SLIT: Error in processing FPGA nodes\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (FpgaCount == 0) {
+    return EFI_SUCCESS;
+  }
+
+  SlitAcpiTable = (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table;
+
+  for (SourceNode = (NodeCount - FpgaCount); SourceNode < NodeCount; SourceNode++) {
+    SourceSocket = GetPhyNodeIdForFpga (SourceNode - (NodeCount - FpgaCount));
+
+    for (TargetNode = 0; TargetNode < NodeCount; TargetNode++) {
+      if (TargetNode < (NodeCount- PmemNodeCount - FpgaCount)) {
+        TargetSocket = GetSocketPhysicalId (TargetNode / NumClusters);             // Normal nodes
+      } else if (TargetNode < (NodeCount - FpgaCount)) {
+        TargetSocket = GetSocketForPmem (TargetNode - (NodeCount - PmemNodeCount - FpgaCount));  // PMEM nodes
+      } else {
+        TargetSocket = GetPhyNodeIdForFpga (TargetNode - (NodeCount - FpgaCount)); // FPGA nodes
+      }
+
+      if (SourceSocket == TargetSocket) {
+        SlitAcpiTable->NumSlit[SourceNode * NodeCount + TargetNode].Entry = ZERO_HOP;
+      } else if (SocketsLinked (SourceSocket, TargetSocket)) {
+        SlitAcpiTable->NumSlit[SourceNode * NodeCount + TargetNode].Entry = ONE_HOP;
+        SlitAcpiTable->NumSlit[TargetNode * NodeCount + SourceNode].Entry = ONE_HOP;
+      } else {
+        SlitAcpiTable->NumSlit[SourceNode * NodeCount + TargetNode].Entry = TWO_HOP;
+        SlitAcpiTable->NumSlit[TargetNode * NodeCount + SourceNode].Entry = TWO_HOP;
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Processes all remaining valid SLIT nodes
+
+  @param[in,out] Table  pointer to SLIT ACPI tables
+
+  @retval EFI_SUCCESS  operation completed successfully
+
+**/
+EFI_STATUS
+ProcessRemainingNodes (
+  IN OUT EFI_ACPI_COMMON_HEADER *Table
+  )
+{
+  ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE  *SlitAcpiTable;
+  UINT16                                  EntryIdx = 0;
+  UINT16                                  MaxTableEntries;
+  UINT8                                   NodeCount;
+
+  if (NULL == Table) {
+    DEBUG ((DEBUG_ERROR, "SLIT: Error while processing remaining valid nodes\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DEBUG ((DEBUG_INFO, "SLIT: Fill in the rest of the SLIT table\n"));
+
+  SlitAcpiTable = (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table;
+
+  NodeCount = (UINT8)SlitAcpiTable->Header.NumberOfSystemLocalities;
+  MaxTableEntries = NodeCount * NodeCount;
+
+  while (EntryIdx < MaxTableEntries) {
+    if (SlitAcpiTable->NumSlit[EntryIdx].Entry == 0xFF) {
+      //
+      // This entry has not been filled yet, assign 2 hop to this table entry
+      //
+      SlitAcpiTable->NumSlit[EntryIdx].Entry = TWO_HOP;
+    }
+
+    if ((EntryIdx % NodeCount) == 0) {
+      DEBUG ((DEBUG_INFO, "[%2d - %2d] ", EntryIdx/NodeCount, EntryIdx%NodeCount));
+    }
+    EntryIdx++;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Processes unused SLIT nodes
+
+  @param[in,out] Table  pointer to SLIT ACPI tables
+
+  @retval EFI_SUCCESS  operation completed successfully
+
+**/
+EFI_STATUS
+ProcessUnusedNodes (
+  IN OUT EFI_ACPI_COMMON_HEADER *Table
+  )
+{
+  ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE  *SlitAcpiTable;
+  UINT16                                  MaxTableEntries;
+  UINT8                                   NodeCount;
+
+  if (NULL == Table) {
+    DEBUG ((DEBUG_ERROR, "SLIT: Error while processing unused nodes\n"));
+    return EFI_INVALID_PARAMETER;
+
+  }
+
+  DEBUG ((DEBUG_INFO, "SLIT: Zero out the unused nodes\n"));
+
+  SlitAcpiTable = (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table;
+
+  NodeCount = (UINT8)SlitAcpiTable->Header.NumberOfSystemLocalities;
+  MaxTableEntries = NodeCount * NodeCount;
+
+  SetMem (&SlitAcpiTable->NumSlit[MaxTableEntries],
+         (UINTN)&SlitAcpiTable->NumSlit[EFI_ACPI_SYSTEM_LOCALITIES_ENTRY_COUNT] - (UINTN)&SlitAcpiTable->NumSlit[MaxTableEntries], 0);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Updates System Locality Distance Information Table (SLIT)
+
+  @param[in,out] Table  pointer to SLIT ACPI tables
+
+  @retval EFI_SUCCESS  operation completed successfully
+  @retval EFI_ABORTED  operation not completed due to processing error
+
+**/
+EFI_STATUS
+PatchSLitTable (
+   IN OUT EFI_ACPI_COMMON_HEADER  *Table
+   )
+{
+  ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE  *SlitAcpiTable;
+  EFI_STATUS                              Status;
+  UINT8                                   NodeCount;
+  UINT8                                   NumCpus;
+  UINT8                                   NumClusters;
+  UINT8                                   PmemNodeCount;
+  UINT8                                   FpgaCount;
+
+  NumCpus = GetNumCpus ();
+  NumClusters = GetNumClusters ();
+  PmemNodeCount = GetPmemNodeCount ();
+  FpgaCount = GetFpgaCount();
+  NodeCount = GetNodeCount (NumCpus, NumClusters, PmemNodeCount, FpgaCount);
+
+  DEBUG ((DEBUG_INFO, "SLIT: NumCpus %d, NumClusters %d, PmemNodeCount %d -> NodeCount %d FpgaCount %d\n",
+                             NumCpus, NumClusters, PmemNodeCount, NodeCount,FpgaCount));
+
+  SlitAcpiTable = (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table;
+  SlitAcpiTable->Header.NumberOfSystemLocalities = NodeCount;
+
+  //
+  // 1) Initialize all entries to 0xFF
+  //
+  Status = InitEntries (SlitAcpiTable);
+
+  //
+  // 2) Update SLIT table with data about nodes on same socket
+  //
+  if (!EFI_ERROR(Status)) {
+    if (mSystemMemoryMap->volMemMode == VOL_MEM_MODE_MIX_1LM2LM) {
+      Status = ProcessMixedModeSockets (Table, NumCpus, NumClusters, PmemNodeCount, FpgaCount, NodeCount);
+    } else {
+      Status = ProcessSockets (Table, NumCpus, NumClusters, PmemNodeCount, FpgaCount, NodeCount);
+    }
+  }
+
+  //
+  // 3) Update table with links between sockets by examining PeerInfo structure
+  //
+  if (!EFI_ERROR (Status)) {
+    if (mSystemMemoryMap->volMemMode == VOL_MEM_MODE_MIX_1LM2LM) {
+      Status = ProcessMixedModeSocketsLinks (Table, NumCpus, NumClusters, PmemNodeCount, FpgaCount, NodeCount);
+    } else {
+      Status = ProcessSocketsLinks (Table, NumCpus, NumClusters, PmemNodeCount, FpgaCount, NodeCount);
+    }
+  }
+
+  //
+  // 4) Update table with PMEMs
+  //
+  if (!EFI_ERROR (Status)) {
+    Status = ProcessPmems (Table, NumCpus, NumClusters, PmemNodeCount, FpgaCount, NodeCount);
+  }
+
+  //
+  // 5 Update table with FPGA
+  //
+  if (!EFI_ERROR (Status)) {
+    Status = ProcessFpgaNodes (Table, NumClusters, PmemNodeCount, FpgaCount, NodeCount);
+  }
+
+  //
+  // 6) Fill in the rest of the Slit table, 2 hops between any remaining valid nodes
+  //
+  if (!EFI_ERROR (Status)) {
+    Status = ProcessRemainingNodes (Table);
+  }
+
+  //
+  // 7) Zero out the unused nodes
+  //
+  if (!EFI_ERROR (Status)) {
+    Status = ProcessUnusedNodes (Table);
+  }
+
+  //
+  // 8) Print the entire SLIT table
+  //
+  if (!EFI_ERROR (Status)) {
+    DisplayEntries (SlitAcpiTable);
+  }
+
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
+/**
+  Allocate memory and fill SLIT information to this buffer, then
+  install this table to ACPI table.
+
+  @retval EFI_SUCCESS           Install table success.
+  @retval EFI_OUT_OF_RESOURCES  Out of memory.
+
+**/
+EFI_STATUS
+InstallSlitTable (
+   VOID
+   )
+{
+  ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *Table;
+  UINTN                                  TableSize;
+  UINT8                                  NumClusters;
+  UINTN                                  TableHandle = 0;
+  EFI_STATUS                             Status;
+
+  NumClusters = GetNumClusters ();
+
+  TableSize = sizeof (EFI_ACPI_6_2_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER) +
+              sizeof (ACPI_SYSTEM_LOCALITIES_STRUCTURE) * EFI_ACPI_SYSTEM_LOCALITIES_ENTRY_COUNT;
+
+  Table = (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *) AllocateZeroPool (TableSize);
+  if (Table == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Table->Header.Header.Signature = EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE;
+  Table->Header.Header.Length = (UINT32) TableSize;
+  Table->Header.Header.Revision = EFI_ACPI_6_2_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION;
+  Table->Header.Header.OemRevision = EFI_ACPI_OEM_SLIT_REVISION;
+  CopyMem (Table->Header.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->Header.Header.OemId));
+  Table->Header.Header.OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
+  Table->Header.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
+  Table->Header.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
+
+  //
+  // All node init with 0 before pass to patcher
+  //
+  PatchSLitTable ((EFI_ACPI_COMMON_HEADER *)&Table->Header.Header);
+
+  //
+  // Publish SLIT Structure to ACPI
+  //
+
+  Status = mAcpiTable->InstallAcpiTable (
+                          mAcpiTable,
+                          Table,
+                          Table->Header.Header.Length,
+                          &TableHandle
+                          );
+
+  //
+  // Free memory
+  //
+  if (Table != NULL) {
+    FreePool (Table);
+  }
+
+  return Status;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSrat.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSrat.c
new file mode 100644
index 0000000000..c19c942274
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSrat.c
@@ -0,0 +1,952 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatformLibLocal.h"
+#include <Library/CpuConfigLib.h>
+#include <IndustryStandard/Acpi.h>
+#include <Protocol/AcpiPlatformProtocol.h>
+#include <Library/MemTypeLib.h>
+
+extern BOOLEAN                      mX2ApicEnabled;
+extern struct SystemMemoryMapHob    *mSystemMemoryMap;
+extern EFI_IIO_UDS_PROTOCOL         *mIioUds;
+extern SOCKET_MEMORY_CONFIGURATION  mSocketMemoryConfiguration;
+extern UINT32                       mNumOfBitShift;
+extern UINT32                       mApicIdMap[MAX_SOCKET][MAX_CORE * MAX_THREAD];
+extern UINTN                        mNumberOfCPUs;
+extern CPU_ID_ORDER_MAP             mCpuApicIdOrderTable[];
+extern EFI_ACPI_TABLE_PROTOCOL      *mAcpiTable;
+extern CPU_CSR_ACCESS_VAR           *mCpuCsrAccessVarPtr;
+
+UINT32 mPackageChaTotal[MAX_SOCKET];
+
+CPU_LOGICAL_THREAD_ID_TABLE mCpuThreadIdMsrTable[MAX_CPU_NUM];
+
+static ACPI_PLATFORM_PROTOCOL   mAcpiPlatformProtocol;
+
+struct _ACPI_PLATFORM_UTILS_MEM_AFF_DATA {
+  EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE AcpiMemAffData[MEMORY_AFFINITY_STRUCTURE_COUNT];
+  BOOLEAN                                AcpiMemAffDataValid;
+} mAcpiPlatformMemAffData;
+
+
+VOID
+CollectThreadIdMsrData (
+  IN UINT8        SncEnabled,
+  IN UINT8        SncNumOfCluster
+  );
+
+UINT32
+GetProximityDomainForSNC (
+  UINT32 ApicId
+  );
+
+
+/**
+  This function counts the number of bits set in a 32-bit unsigned integer.
+
+  @param[in] Value     The 32-bit unsigned integer to count.
+
+  @retval The number of set bits.
+**/
+UINT8
+BitCount32 (
+  IN UINT32   Value
+  )
+{
+  UINT8    Count;
+
+  Count = 0;
+  while (Value != 0) {
+    Value &= Value - 1;
+    Count++;
+  }
+
+  return Count;
+}
+
+/**
+  Get the socket logical index.
+
+  This function convert the socket physical index to logical index (0 based).
+  If the specified physical socket is not enabled, an invalid logical index 0xff
+  will be returned. The socket physical index and logical index will be the same
+  if the indexes of enabled sockets are continuous.
+
+  @param[in] SocketPhysicalId    Socket physical index.
+
+  @retval Socket logical index.
+**/
+UINT8
+GetSocketLogicalId (
+  IN UINT8  SocketPhysicalId
+  )
+{
+  UINT32    SocketBitMap;
+
+  if ((mCpuCsrAccessVarPtr->socketPresentBitMap & (BIT0 << SocketPhysicalId)) == 0) {
+    return (UINT8) -1;
+  }
+
+  SocketBitMap = mCpuCsrAccessVarPtr->socketPresentBitMap & ((BIT0 << SocketPhysicalId) - 1);
+  return BitCount32 (SocketBitMap);
+}
+
+/**
+  Get the socket physical index.
+
+  This function convert the socket logical index to physical index (0 based).
+  If the specified logical socket does not exist, an invalid physical index 0xff
+  will be returned. The socket physical index and logical index will be the same
+  if the indexes of enabled sockets are continuous.
+
+  @param[in] SocketLogicalId    Socket logical index.
+
+  @retval Socket physical index.
+**/
+UINT8
+GetSocketPhysicalId (
+  IN UINT8  SocketlogicId
+  )
+{
+  UINT32    SocketBitMap;
+
+  SocketBitMap = mCpuCsrAccessVarPtr->socketPresentBitMap;
+
+  while (SocketlogicId != 0) {
+    SocketBitMap &= SocketBitMap - 1;
+    SocketlogicId--;
+  }
+
+  if (SocketBitMap == 0) {
+    return (UINT8) -1;
+  }
+
+  return BitCount32 (SocketBitMap ^ (SocketBitMap - 1)) - 1;
+}
+
+/**
+
+    Update the SRAT APIC IDs.
+
+    @param *SRAAcpiTable   - The table to be set
+
+    @retval EFI_SUCCESS -  Returns Success
+
+**/
+EFI_STATUS
+PatchSratAllApicIds(
+   IN OUT   STATIC_RESOURCE_AFFINITY_TABLE  *SRAAcpiTable
+   )
+{
+  UINT16                      ThreadIndex;   // Support more than 256 threads (8S case)
+  UINT8                       *ApicTablePtr;
+  UINT8                       socket;
+  UINT8                       Index;
+
+  ThreadIndex = 0;
+  for (socket = 0; socket < MAX_SOCKET; socket++) {
+    ApicTablePtr = (UINT8*)mApicIdMap[socket];
+    //
+    // Even IDs must be list first
+    //
+    for (Index = 0; Index < MAX_CORE * MAX_THREAD; Index += 2) {
+      SRAAcpiTable->Apic[ThreadIndex].ApicId = (UINT8)ApicTablePtr[Index] + (socket << mNumOfBitShift);
+      SRAAcpiTable->Apic[ThreadIndex].ProximityDomain7To0 = socket; //as ProxDomain are all 0, or we can come up some algorithm if there is any dependency
+      if ((UINT8)ApicTablePtr[Index] != 0xff) {
+        SRAAcpiTable->Apic[ThreadIndex].Flags = EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED;
+      }
+      ThreadIndex++;
+    }  //end of for coreThreadIndex
+  } //end for socket
+
+  for (socket = 0; socket < MAX_SOCKET; socket++) {
+    //
+    // for odd APICID and must be after all even APICIDs
+    //
+    ApicTablePtr = (UINT8*)mApicIdMap[socket];
+    for (Index = 1; Index < MAX_CORE * MAX_THREAD; Index += 2) {
+      SRAAcpiTable->Apic[ThreadIndex].ApicId = (UINT8)ApicTablePtr[Index] + (socket << mNumOfBitShift);
+      SRAAcpiTable->Apic[ThreadIndex].ProximityDomain7To0 = socket; //as ProxDomain are all 0, or we can come up some algorithm if there is any dependency
+      if ((UINT8)ApicTablePtr[Index] != 0xff) {
+        SRAAcpiTable->Apic[ThreadIndex].Flags = EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED;
+      }
+      ThreadIndex++;
+    }
+  }  //end of for coreThreadIndex
+  ASSERT (ThreadIndex == MAX_CPU_NUM);
+  return EFI_SUCCESS;
+}
+
+UINT32
+ProximityDomainOf (
+  UINT8   SocketId,
+  UINT16  MemType,
+  UINT8   MaxEnabledImc,
+  UINT8   SncEnabled,
+  UINT8   SncNumOfCluster,
+  UINT8   ImcInterBitmap,
+  UINT8   MemMode,
+  UINT32  LastDomainId
+  )
+{
+  UINT32  DomainId = (UINT16)~0;
+  INTN    FirstImc;
+  UINT8   ImcPerCluster;
+  UINT8   NumSockets = mIioUds->IioUdsPtr->SystemStatus.numCpus;
+  UINT8   SocketLogicalId;
+
+  EFI_STATUS                      Status = EFI_SUCCESS;
+  DYNAMIC_SI_LIBARY_PROTOCOL2     *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  if (SncEnabled == 0) {
+    SncNumOfCluster = 1;
+  }
+
+  if (!DynamicSiLibraryProtocol2->IsMemTypeVolatile (MemType)) {
+    //
+    // Persistent memory nodes and FPGA nodes are just pending behinds volatile memories
+    //
+    DomainId = LastDomainId + 1;
+  } else {
+    SocketLogicalId = GetSocketLogicalId (SocketId);
+    //
+    // Process volatile memory nodes
+    //
+    if (SncEnabled == 0) {
+      DomainId = SocketLogicalId;
+    } else {
+      //
+      // Find the cluster ID using ImcInterBitmap
+      //
+      ImcPerCluster = MAX_IMC / SncNumOfCluster;
+      FirstImc = LowBitSet32 (ImcInterBitmap);
+      if (FirstImc == -1) {
+        FirstImc = 0;
+      }
+      if (MaxEnabledImc <= SncNumOfCluster) {
+        DomainId = (SocketLogicalId * SncNumOfCluster) + (UINT32) (FirstImc / ImcPerCluster);
+      } else {
+        DomainId = (SocketLogicalId * SncNumOfCluster) + ((UINT32) FirstImc) / ImcPerCluster;
+      }
+    }
+    if (MemMode == VOL_MEM_MODE_MIX_1LM2LM) {
+      //
+      // 2LM nodes follow the completion of iteration of all 1LM nodes
+      //
+      DomainId += (UINT32)((DynamicSiLibraryProtocol2->IsMemType2lm (MemType) ? 1 : 0) * NumSockets * SncNumOfCluster);
+    }
+  }
+
+  DEBUG ((DEBUG_INFO, "SocketId = %d, SncEnabled = %d, SncNumOfCluster = %d, ImcInterBitmap = 0x%x, ",
+           SocketId, SncEnabled, SncNumOfCluster, ImcInterBitmap));
+
+  DEBUG ((DEBUG_INFO, "MemType = %d, MemMode = %d, Physical DomainId = %d\n",
+           MemType, MemMode, DomainId));
+
+  return DomainId;
+}
+
+VOID
+PatchMemorySratEntries (
+  IN OUT STATIC_RESOURCE_AFFINITY_TABLE       *SratTable,
+  UINT8                                       SncEnabled,
+  UINT8                                       SncNumOfCluster,
+  UINT8                                       *LastIndexUsed
+  )
+{
+  UINT8   LegacyNodeId;
+  UINT8   NodeId;
+  UINT8   Index;
+  UINT8   TableIndex = 0;
+  UINT8   Socket;
+  UINT32  LastDomainId = 0;
+  UINT64  MemoryAddress;
+  UINT64  MemorySize;
+  UINT8   Pass;
+  UINT8   PrevIndex;
+  BOOLEAN SkipEntry;
+  UINT8   MaxEnabledImc = 0;
+  UINTN   ImcIndex;
+  UINT8   MemSocketBitmap = 0;
+  UINT8   NoMemSocketBitmap;
+  UINT32  ProximityDomain;
+  UINT8   PhysicalClusters;
+  UINT8   VirtualClusters;
+
+  EFI_STATUS                  Status = EFI_SUCCESS;
+  DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return;
+  }
+
+  LegacyNodeId = 0xFF;
+  DEBUG ((DEBUG_INFO, "\nSRAT: Updating SRAT memory information!\n"));
+  DEBUG ((DEBUG_INFO, "Idx  Base              Length           Proximity Flags\n"));
+
+  if (mSystemMemoryMap->VirtualNumaEnable) {
+    PhysicalClusters = SncNumOfCluster / mSystemMemoryMap->VirtualNumOfCluster;
+    VirtualClusters = mSystemMemoryMap->VirtualNumOfCluster;
+  } else {
+    PhysicalClusters = SncNumOfCluster;
+    VirtualClusters = 1;
+  }
+
+  //
+  // Looping the System Memory Map elements twice
+  // Fist loop creates domains for all volatile regions based on socket
+  // The second loop creates domains for all persistent memory ranges
+  //
+  for (Pass = 1; Pass < 3; Pass++ ) {
+    TableIndex = 0;
+    for (Index = 0; Index < mSystemMemoryMap->numberEntries; Index++ ) {
+      SkipEntry = FALSE;
+      NodeId = mSystemMemoryMap->Element[Index].NodeId;
+      ASSERT (NodeId < MC_MAX_NODE);
+
+      if (TableIndex >= MEMORY_AFFINITY_STRUCTURE_COUNT) {
+        ASSERT (0);
+        break;
+      }
+
+      //
+      // Skip any memory region marked reserved
+      //
+      if (DynamicSiLibraryProtocol2->IsMemTypeReserved (mSystemMemoryMap->Element[Index].Type)) {
+        continue;
+      }
+
+      //
+      // As the HOB has base addr in 64 MB chunks
+      //
+      MemoryAddress = ((UINT64)mSystemMemoryMap->Element[Index].BaseAddress << MEM_ADDR_SHFT_VAL);
+
+      //
+      // Skip duplicate entries if applicable
+      //
+      if (TableIndex) {
+        for (PrevIndex = 0; PrevIndex < TableIndex; PrevIndex++) {
+          if (MemoryAddress == ((UINT64)SratTable->Memory[PrevIndex].AddressBaseHigh << 32) + SratTable->Memory[PrevIndex].AddressBaseLow) {
+            SkipEntry = TRUE;
+            break;
+          }
+        }
+      }
+      if (SkipEntry) {
+        continue;
+      }
+
+      //
+      // Update bitmap for sockets with memory populated
+      //
+      if (DynamicSiLibraryProtocol2->IsMemTypeVolatile (mSystemMemoryMap->Element[Index].Type)) {
+        MemSocketBitmap |= BIT0 << mSystemMemoryMap->Element[Index].SocketId;
+      }
+
+      SratTable->Memory[TableIndex].AddressBaseLow = (UINT32)(MemoryAddress & 0xFFFFFFFF);
+      SratTable->Memory[TableIndex].AddressBaseHigh  = (UINT32)((UINTN)MemoryAddress >> 32);
+
+      //
+      // As the HOB has Length in 64 MB chunks
+      //
+      MemorySize  = ((UINT64)mSystemMemoryMap->Element[Index].ElementSize << MEM_ADDR_SHFT_VAL);
+      SratTable->Memory[TableIndex].LengthLow = (UINT32)(MemorySize & 0xFFFFFFFF);
+      SratTable->Memory[TableIndex].LengthHigh = (UINT32)((UINTN)MemorySize >> 32);
+
+      if ((Pass == 2) || DynamicSiLibraryProtocol2->IsMemTypeVolatile (mSystemMemoryMap->Element[Index].Type)) {
+
+        //
+        // Get max enabled IMC for this socket
+        //
+        for (ImcIndex = 0, MaxEnabledImc = 0; ImcIndex < MAX_IMC; ImcIndex++) {
+          if (mSystemMemoryMap->Socket[mSystemMemoryMap->Element[Index].SocketId].imcEnabled[ImcIndex] != 0) {
+            MaxEnabledImc ++;
+          }
+        }
+
+        ProximityDomain = ProximityDomainOf (
+                           mSystemMemoryMap->Element[Index].SocketId,
+                           mSystemMemoryMap->Element[Index].Type,
+                           MaxEnabledImc,
+                           SncEnabled,
+                           PhysicalClusters,
+                           mSystemMemoryMap->Element[Index].ImcInterBitmap,
+                           mSystemMemoryMap->volMemMode,
+                           LastDomainId
+                           );
+        SratTable->Memory[TableIndex].ProximityDomain = (ProximityDomain * VirtualClusters) + (Index % VirtualClusters);
+        if (LastDomainId < SratTable->Memory[TableIndex].ProximityDomain) {
+          LastDomainId = SratTable->Memory[TableIndex].ProximityDomain;
+        }
+        if ((MemoryAddress == 0) && (MemorySize > 0)) {
+          LegacyNodeId = NodeId;
+        }
+
+        //
+        // Enable the Memory structure
+        //
+        if ((LegacyNodeId == NodeId) || (!mSocketMemoryConfiguration.SratMemoryHotPlug) ) {
+          SratTable->Memory[TableIndex].Flags = EFI_ACPI_6_2_MEMORY_ENABLED;
+        } else {
+          SratTable->Memory[TableIndex].Flags = EFI_ACPI_6_2_MEMORY_ENABLED | EFI_ACPI_6_2_MEMORY_HOT_PLUGGABLE;
+        }
+        if (!DynamicSiLibraryProtocol2->IsMemTypeVolatile (mSystemMemoryMap->Element[Index].Type) &&
+            !DynamicSiLibraryProtocol2->IsMemTypeFpga (mSystemMemoryMap->Element[Index].Type)) {
+          SratTable->Memory[TableIndex].Flags |= EFI_ACPI_6_2_MEMORY_NONVOLATILE;
+        }
+
+        if (Pass == 2) {
+          DEBUG ((DEBUG_INFO, "%3d  %08x%08x, %08x%08x %2x         %x\n",
+                 TableIndex,
+                 SratTable->Memory[TableIndex].AddressBaseHigh,
+                 SratTable->Memory[TableIndex].AddressBaseLow,
+                 SratTable->Memory[TableIndex].LengthHigh,
+                 SratTable->Memory[TableIndex].LengthLow,
+                 SratTable->Memory[TableIndex].ProximityDomain,
+                 SratTable->Memory[TableIndex].Flags));
+        }
+      }
+      TableIndex++;
+    }
+    //
+    // Update LastDomainId for enabled sockets with no memory
+    //
+    NoMemSocketBitmap = mCpuCsrAccessVarPtr->socketPresentBitMap & ~MemSocketBitmap;
+    if (Pass == 1) {
+      for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+        if ((BIT0 << Socket) & NoMemSocketBitmap) {
+          LastDomainId += SncNumOfCluster;
+        }
+      }
+    }
+  }
+
+  *LastIndexUsed = TableIndex;
+}
+
+EFI_STATUS
+PatchSratTable (
+  IN OUT STATIC_RESOURCE_AFFINITY_TABLE  *SratTable
+  )
+{
+  UINT8                                     Index;
+  UINT8                                     NewIndex;
+  UINT16                                    ThreadIndex;   // Support more than 256 threads (8S case)
+  UINT8                                     NodeId;
+  UINTN                                     HighTopMemory;
+  UINTN                                     HotPlugBase;
+  UINTN                                     HotPlugLen;
+  UINT8                                     SncEnabled;
+  UINT8                                     SncNumOfCluster;
+
+  SncEnabled      = mIioUds->IioUdsPtr->SystemStatus.OutSncEn;
+  SncNumOfCluster = mIioUds->IioUdsPtr->SystemStatus.OutNumOfCluster;
+
+  if (mSystemMemoryMap != NULL) {
+    if (mSystemMemoryMap->VirtualNumaEnable) {
+     if (SncEnabled) {
+      SncNumOfCluster = SncNumOfCluster * mSystemMemoryMap->VirtualNumOfCluster;
+     } else {
+       //
+       // If Virtual NUMA enabled without SNC, use the number of Virtual NUMA clusters.
+       // Do not multiply by "OutNumOfCluster" if the system is in a UMA Based Clustering mode (e.g. Hemisphere).
+       //
+       SncNumOfCluster = mSystemMemoryMap->VirtualNumOfCluster;
+       SncEnabled = 1;
+     }
+    }
+  }
+
+  if (SncNumOfCluster == 0) {
+    SncNumOfCluster = 1;
+  }
+
+  CollectThreadIdMsrData (SncEnabled, SncNumOfCluster);
+
+  if (mSocketMemoryConfiguration.SratCpuHotPlug) {
+    PatchSratAllApicIds (SratTable);
+  } else {
+    DEBUG (( DEBUG_INFO, "-------- SRAT TABLE ---------- %x\n",  PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE_COUNT));
+
+    for (ThreadIndex = 0; ThreadIndex < PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE_COUNT; ThreadIndex++) {
+      if (ThreadIndex < mNumberOfCPUs) {
+
+        //
+        // Use mCpuThreadIdMsrTable.ApicId by sorting SRAT sequentially to fix proximity domain grouping of threads in OSes
+        //
+        if (mX2ApicEnabled) {
+          SratTable->x2Apic[ThreadIndex].ProximityDomain = GetProximityDomainForSNC (mCpuThreadIdMsrTable[ThreadIndex].ApicId);
+          SratTable->x2Apic[ThreadIndex].X2ApicId = mCpuThreadIdMsrTable[ThreadIndex].ApicId;
+          SratTable->x2Apic[ThreadIndex].Flags = EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED;
+        } else {
+          //
+          // If SNC is enabled and 2 clusters, there is 1 extra Proximity Domain per socket
+          // SNC cannot exist unless all HA's have memory
+          //
+          SratTable->Apic[ThreadIndex].ProximityDomain7To0 = (UINT8)GetProximityDomainForSNC (mCpuThreadIdMsrTable[ThreadIndex].ApicId);
+          SratTable->Apic[ThreadIndex].ApicId = (UINT8)mCpuThreadIdMsrTable[ThreadIndex].ApicId;
+          SratTable->Apic[ThreadIndex].Flags = EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED;
+        }
+      } else {
+        if (mX2ApicEnabled) {
+          SratTable->x2Apic[ThreadIndex].X2ApicId = (UINT32)-1;
+        } else {
+          SratTable->Apic[ThreadIndex].ApicId = 0xFF;
+        }
+      }
+      if (mX2ApicEnabled) {
+          DEBUG (( DEBUG_INFO, "\nSRAT: CpuThreadIndex\t%x, ApicId\t%x,  Flags\t%x!\n",
+                ThreadIndex, SratTable->x2Apic[ThreadIndex].X2ApicId, SratTable->x2Apic[ThreadIndex].Flags));
+      } else {
+          DEBUG (( DEBUG_INFO, "\nSRAT: CpuThreadIndex\t%x, ApicId\t%x,  Flags\t%x, ProximityDomain\t%x!\n",
+                ThreadIndex, SratTable->Apic[ThreadIndex].ApicId, SratTable->Apic[ThreadIndex].Flags,
+                SratTable->Apic[ThreadIndex].ProximityDomain7To0));
+      }
+    }
+  }
+
+  if (mSystemMemoryMap != NULL) {
+
+    PatchMemorySratEntries (SratTable, SncEnabled, SncNumOfCluster, &Index);
+
+    HotPlugBase = 0x100;
+    if (mSocketMemoryConfiguration.MemoryHotPlugBase == 0) { // Auto
+      //
+      // Read the actual TOHM and set it as the hot memory base
+      //
+      HighTopMemory  = (UINT64)mIioUds->IioUdsPtr->SystemStatus.tohmLimit << 26;
+      HotPlugBase = (HighTopMemory >> 32);
+      if ((UINT32)HighTopMemory > 0) {
+        HotPlugBase++;
+      }
+    } else if (mSocketMemoryConfiguration.MemoryHotPlugBase) { // Number
+      HotPlugBase = mSocketMemoryConfiguration.MemoryHotPlugBase * 0x80;
+    }
+    HotPlugLen = (mSocketMemoryConfiguration.MemoryHotPlugLen + 1) * 0x10;
+
+    if (mSocketMemoryConfiguration.SratMemoryHotPlug) {
+      DEBUG (( DEBUG_INFO, "SRAT: Updating SRAT hotplug memory information!\n" ));
+      for (NodeId = 0; NodeId < MC_MAX_NODE; NodeId++) {
+        NewIndex = Index + NodeId;
+        if (NewIndex >= MEMORY_AFFINITY_STRUCTURE_COUNT) {
+          ASSERT (0);
+          break;
+        }
+        //
+        // As the HOB has base addr in 1 GB chunks
+        //
+        SratTable->Memory[NewIndex].ProximityDomain = (NodeId >> 1);
+        SratTable->Memory[NewIndex].AddressBaseLow  = 0;
+        SratTable->Memory[NewIndex].AddressBaseHigh = (UINT32)(HotPlugBase +  NodeId * HotPlugLen);
+        SratTable->Memory[NewIndex].LengthLow  = 0;
+        SratTable->Memory[NewIndex].LengthHigh = (UINT32)HotPlugLen;
+        SratTable->Memory[NewIndex].Flags = EFI_ACPI_6_2_MEMORY_ENABLED | EFI_ACPI_6_2_MEMORY_HOT_PLUGGABLE;
+
+        DEBUG ((DEBUG_INFO, "%3d  %08x%08x  %08x%08x %x %x\n", NewIndex,
+                SratTable->Memory[Index].AddressBaseHigh,
+                SratTable->Memory[Index].AddressBaseLow,
+                SratTable->Memory[Index].LengthHigh,
+                SratTable->Memory[Index].LengthLow,
+                SratTable->Memory[Index].ProximityDomain,
+                SratTable->Memory[NewIndex].Flags));
+      }
+    }
+    //
+    // Copy SRAT memory affinity data to ACPI platform protocol
+    //
+    DEBUG ((DEBUG_INFO, "ACPI Platform Protocol - Memory Affinity Data updated\n"));
+    ZeroMem (&mAcpiPlatformMemAffData, sizeof (mAcpiPlatformMemAffData));
+    CopyMem (&mAcpiPlatformMemAffData.AcpiMemAffData[0], &SratTable->Memory[0], sizeof (mAcpiPlatformMemAffData.AcpiMemAffData));
+    mAcpiPlatformMemAffData.AcpiMemAffDataValid = TRUE;
+  }
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Routine Description:
+    Collect ThreadIdMsr Value for all the AP's and sorts it by the ThreadIdMsr Value.
+    The Sorted Table, for every socket the first half of the threads will be Mapped to 1st HA
+    The second half f threads in every socket will mapped to 2nd HA.
+
+  Arguments:
+    NONE
+
+  Returns:
+    NONE
+**/
+VOID
+CollectThreadIdMsrData (
+  IN UINT8        SncEnabled,
+  IN UINT8        SncNumOfCluster
+  )
+{
+  UINT32                      SocketIndex;
+  UINT32                      ThreadIndex;
+  UINTN                       NumOfChaPerCluster;
+  BOOLEAN                     CollocatedChaIdPresent;
+  UINT32                      NumberOfThreads;
+  UINT8                       SocketLogicalId;
+
+  NumOfChaPerCluster = 0;
+  CollocatedChaIdPresent = FALSE;
+  AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, NULL, &NumberOfThreads, NULL, NULL);
+
+  //
+  // Get total number of CHAs per socket
+  //
+  for(SocketIndex = 0; SocketIndex < MAX_SOCKET; SocketIndex++) {
+    mPackageChaTotal[SocketIndex] = mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[SocketIndex].TotCha;
+  }
+
+  //
+  // Determine whether collocated CHA ID is encoded in upper 32 bits of MSR 0x53 LOGICAL_THREAD_ID
+  //
+  if (SncEnabled) {
+    for(ThreadIndex = 0; ThreadIndex < (MAX_CORE * MAX_THREAD); ThreadIndex++) {
+      if (mCpuThreadIdMsrTable[ThreadIndex].CollocatedChaId != 0) {
+        if (mCpuThreadIdMsrTable[ThreadIndex].CollocatedChaId != 0xFF) {
+          CollocatedChaIdPresent = TRUE;
+        }
+        break;
+      }
+    }
+    if (!CollocatedChaIdPresent) {
+      DEBUG ((DEBUG_WARN, "ERROR: Collocated CHA ID is not found! Correct SNC Proximity Domain programming not guaranteed.\n"));
+    }
+  }
+
+  //
+  // Set SNC Proximity Domain variables for each thread
+  //
+  for(ThreadIndex = 0; ThreadIndex < MAX_CPU_NUM; ThreadIndex++) {
+    if (mCpuThreadIdMsrTable[ThreadIndex].ThreadIdValue == 0xff) {
+      continue;
+    }
+
+    //
+    // We divide cores in group by number of clusters.
+    // CHA number is used instead of active threads to account for when cores or
+    // threads are disabled.
+    //
+    SocketIndex = mCpuConfigLibConfigContextBuffer->CollectedDataBuffer[ThreadIndex].ProcessorLocation.Package;
+    SocketLogicalId = GetSocketLogicalId ((UINT8) SocketIndex);
+    if (!SncEnabled) {
+      mCpuThreadIdMsrTable[ThreadIndex].SNCProximityDomain = SocketLogicalId;
+    } else {
+      NumOfChaPerCluster = mPackageChaTotal[SocketIndex]/SncNumOfCluster;
+      if (CollocatedChaIdPresent) {
+        mCpuThreadIdMsrTable[ThreadIndex].SNCProximityDomain = (UINT32)((SocketLogicalId * SncNumOfCluster) + (mCpuThreadIdMsrTable[ThreadIndex].CollocatedChaId / (NumOfChaPerCluster)));
+      } else {
+        mCpuThreadIdMsrTable[ThreadIndex].SNCProximityDomain = (UINT32)((SocketLogicalId * SncNumOfCluster) + (mCpuThreadIdMsrTable[ThreadIndex].ThreadIdValue / (NumOfChaPerCluster*NumberOfThreads)));
+      }
+      DEBUG ((DEBUG_INFO, "ThreadIndex=%x, SncNumOfCluster=%x, NumOfChaPerCluster=%x, SNCProximityDomain=%x\n", ThreadIndex, SncNumOfCluster, NumOfChaPerCluster, mCpuThreadIdMsrTable[ThreadIndex].SNCProximityDomain));
+      DEBUG ((DEBUG_INFO, "ThreadIdValue=%x\n", mCpuThreadIdMsrTable[ThreadIndex].ThreadIdValue));
+    }
+  }
+}
+
+/**
+  Return the Domain Flag value of the specific APICID
+  Proximity Domain Flag
+    0 Denotes upper half of the sorted thread needs to be mapped to 1st HA.
+    1 Denotes lower half and mapped to 2nd HA
+
+  @retval      Proximity Domain Value for the thread within a Socket.
+**/
+UINT32
+GetProximityDomainForSNC (
+  IN  UINT32 ApicId
+  )
+{
+  UINT32 ThreadIndex     = 0;
+  static UINT32 SncIndex = 0;
+
+  //
+  // The ApicIds are in order. Saving the index will reduce loop iterations
+  //
+  for (ThreadIndex = SncIndex; ThreadIndex < MAX_CPU_NUM; ThreadIndex++) {
+    if (mCpuThreadIdMsrTable[ThreadIndex].ApicId == ApicId){
+      SncIndex = ThreadIndex + 1;
+      return mCpuThreadIdMsrTable[ThreadIndex].SNCProximityDomain;
+    } else if (mCpuThreadIdMsrTable[ThreadIndex].ApicId == (UINT32) -1) {
+      //
+      // We have reached the end of the populated threads
+      //
+      break;
+    }
+  }
+
+  //
+  // Start again from the beginning if we made it to the end of the array
+  //
+  for (ThreadIndex = 0; ThreadIndex < MAX_CPU_NUM; ThreadIndex++) {
+    if (mCpuThreadIdMsrTable[ThreadIndex].ApicId == ApicId){
+      SncIndex = ThreadIndex + 1;
+      return mCpuThreadIdMsrTable[ThreadIndex].SNCProximityDomain;
+    }
+  }
+
+  DEBUG ((DEBUG_ERROR, "APICID not found in CpuThreadIdMsrValueTable\n"));
+  ASSERT (FALSE);
+  ThreadIndex--;
+  return mCpuThreadIdMsrTable[ThreadIndex].SNCProximityDomain;
+}
+
+/**
+  Function retrieves selected data of ACPI SRAT Memory Affinity Structures
+  (please note that data will not be available until SRAT table installation)
+
+  @param[out] *MemAffData         ACPI Memory Affinity Data
+  @param[out] *MemAffDataLength   ACPI Memory Affinity Data Length
+
+  @retval EFI_SUCCESS             ACPI Memory Affinity Data retrieved successfully
+  @retval EFI_NOT_FOUND           ACPI Memory Affinity Data not found (SRAT ACPI table was not published)
+  @retval EFI_INVALID_PARAMETER   One or more of input arguments is NULL
+**/
+EFI_STATUS
+GetAcpiMemoryAffinityData (
+  OUT ACPI_MEMORY_AFFINITY_DATA **MemAffData,
+  OUT UINTN                     *MemAffDataLength
+  )
+{
+  if (MemAffData == NULL || MemAffDataLength == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!mAcpiPlatformMemAffData.AcpiMemAffDataValid) {
+    return EFI_NOT_FOUND;
+  }
+
+  *MemAffData = mAcpiPlatformMemAffData.AcpiMemAffData;
+  *MemAffDataLength = (UINT8)MEMORY_AFFINITY_STRUCTURE_COUNT;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Function initialize and install ACPI Platform Protocol
+
+  @param None
+
+  @retval EFI_SUCCESS Operation completed successfully
+**/
+EFI_STATUS
+InstallAcpiPlatformProtocol (
+  VOID
+  )
+{
+  EFI_HANDLE Handle = NULL;
+
+  ZeroMem (&mAcpiPlatformProtocol, sizeof(mAcpiPlatformProtocol));
+  mAcpiPlatformProtocol.GetAcpiMemoryAffinityData = GetAcpiMemoryAffinityData;
+
+  return gBS->InstallProtocolInterface (&Handle, &gAcpiPlatformProtocolGuid, EFI_NATIVE_INTERFACE, &mAcpiPlatformProtocol);
+}
+
+VOID
+PrintSratTable (
+  IN EFI_ACPI_DESCRIPTION_HEADER *Header
+  )
+{
+  EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER          *Table;
+  EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE  *SubType;
+  UINTN                                                       TotalLength;
+  UINT8                                                       *TempPtr;
+  EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE  *ApicType;
+  EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE                      *MemType;
+  EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE      *x2ApicType;
+  UINTN                                                       TempLength;
+
+  Table = (EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *) Header;
+  if (Table->Header.Signature != EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE) {
+    DEBUG ((DEBUG_ERROR, "[SRAT] Not SRAT table, skip!\n"));
+    return;
+  }
+
+  TotalLength = Table->Header.Length;
+
+  DEBUG ((DEBUG_INFO, "----------------------------[SRAT Table] --------------------\n"));
+  DEBUG ((DEBUG_INFO, "----Header-----\n"));
+  DEBUG ((DEBUG_INFO, "Length          :  %d\n", Table->Header.Length));
+  DEBUG ((DEBUG_INFO, "Revision        :  %d\n", Table->Header.Revision));
+  DEBUG ((DEBUG_INFO, "Checksum        :  %2X\n", Table->Header.Checksum));
+  DEBUG ((DEBUG_INFO, "OemTableId      :  %X\n", Table->Header.OemTableId));
+  DEBUG ((DEBUG_INFO, "OemRevision     :  %d\n", Table->Header.OemRevision));
+  DEBUG ((DEBUG_INFO, "CreatorId       :  %X\n", Table->Header.CreatorId));
+  DEBUG ((DEBUG_INFO, "CreatorRevision :  %X\n", Table->Header.CreatorRevision));
+  DEBUG ((DEBUG_INFO, "\n"));
+
+  TempPtr = (UINT8 *)Table;
+  TempPtr += sizeof(EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER);
+  TempLength = ((EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE *) TempPtr)->Length;
+  while (TempPtr < ((UINT8 *)Table + TotalLength)){
+    SubType = (EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE *) TempPtr;
+    if (SubType->Type == EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY) {
+      ApicType = SubType;
+      DEBUG ((DEBUG_INFO, "APIC Type            :  %d\n", ApicType->Type));
+      DEBUG ((DEBUG_INFO, "Length               :  %d\n", ApicType->Length));
+      DEBUG ((DEBUG_INFO, "ProximityDomain7To0  :  %d\n", ApicType->ProximityDomain7To0));
+      DEBUG ((DEBUG_INFO, "ApicId               :  %X\n", ApicType->ApicId));
+      DEBUG ((DEBUG_INFO, "Flags                :  %X\n", ApicType->Flags));
+      DEBUG ((DEBUG_INFO, "LocalSapicEid        :  %d\n", ApicType->LocalSapicEid));
+      DEBUG ((DEBUG_INFO, "ProximityDomain31To8 :  %d\n", (*(UINT32 *)ApicType->ProximityDomain31To8) & 0xFFFFFF));
+      DEBUG ((DEBUG_INFO, "ClockDomain          :  %d\n", ApicType->ClockDomain));
+
+    } else if (SubType->Type == EFI_ACPI_6_2_MEMORY_AFFINITY) {
+      MemType = (EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE *)SubType;
+      DEBUG ((DEBUG_INFO, "Mem Type        :  %d\n", MemType->Type));
+      DEBUG ((DEBUG_INFO, "Length          :  %d\n", MemType->Length));
+      DEBUG ((DEBUG_INFO, "ProximityDomain :  %d\n", MemType->ProximityDomain));
+      DEBUG ((DEBUG_INFO, "AddressBaseLow  :  %X\n", MemType->AddressBaseLow));
+      DEBUG ((DEBUG_INFO, "AddressBaseHigh :  %X\n", MemType->AddressBaseHigh));
+      DEBUG ((DEBUG_INFO, "LengthLow       :  %X\n", MemType->LengthLow));
+      DEBUG ((DEBUG_INFO, "LengthHigh      :  %X\n", MemType->LengthHigh));
+      DEBUG ((DEBUG_INFO, "Flags           :  %X\n", MemType->Flags));
+
+    } else if (SubType->Type == EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY) {
+      x2ApicType = (EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE *) SubType;
+      DEBUG ((DEBUG_INFO, "x2APIC Type     :  %d\n", x2ApicType->Type));
+      DEBUG ((DEBUG_INFO, "Length          :  %d\n", x2ApicType->Length));
+      DEBUG ((DEBUG_INFO, "ProximityDomain :  %d\n", x2ApicType->ProximityDomain));
+      DEBUG ((DEBUG_INFO, "X2ApicId        :  %X\n", x2ApicType->X2ApicId));
+      DEBUG ((DEBUG_INFO, "Flags           :  %X\n", x2ApicType->Flags));
+      DEBUG ((DEBUG_INFO, "ClockDomain     :  %d\n", x2ApicType->ClockDomain));
+
+    } else {
+      DEBUG ((DEBUG_INFO, "Unknown Type : %d\n", SubType->Type));
+      DEBUG ((DEBUG_INFO, "Length : %d\n", SubType->Length));
+    }
+    if (SubType->Length < 10) {
+      DEBUG ((DEBUG_ERROR, "Error in Length %d, try previous length.\n", SubType->Length));
+      TempPtr += TempLength;
+    } else {
+      TempPtr += SubType->Length;
+      TempLength = SubType->Length;
+    }
+    DEBUG ((DEBUG_INFO, "\n"));
+  }
+}
+
+/**
+  Build from scratch and install the SRAT.
+
+  @retval EFI_SUCCESS           The SRAT was installed successfully.
+  @retval EFI_OUT_OF_RESOURCES  Could not allocate required structures.
+**/
+EFI_STATUS
+InstallSratTable (
+  VOID
+  )
+{
+  EFI_STATUS                                          Status;
+  UINTN                                               Index;
+  UINTN                                               TableHandle;
+  UINTN                                               TableSize;
+  STATIC_RESOURCE_AFFINITY_TABLE                      *SratTable;
+
+  Status = EFI_SUCCESS;
+  TableHandle = 0;
+
+  if (mSocketMemoryConfiguration.Srat == 0)  {
+    return EFI_SUCCESS;
+  }
+
+  if  (mSystemMemoryMap == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  SratTable = (STATIC_RESOURCE_AFFINITY_TABLE *) AllocateZeroPool (sizeof(STATIC_RESOURCE_AFFINITY_TABLE));
+  if (SratTable == NULL) {
+    DEBUG ((DEBUG_ERROR, "InstallSratTable: allocate SRAT table failed \n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  TableSize = sizeof (EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER) +
+              sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE) * PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE_COUNT +
+              sizeof (EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE) * MEMORY_AFFINITY_STRUCTURE_COUNT +
+              sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE) * X2APIC_AFFINITY_STRUCTURE_COUNT ;
+
+  SratTable->SratHeader = (EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *) AllocateZeroPool (TableSize);
+  if (SratTable->SratHeader == NULL) {
+    DEBUG ((DEBUG_ERROR, "InstallSratTable: Create SratHeader has failed \n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  SratTable->Apic = (EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE *) (UINTN)((UINTN)SratTable->SratHeader +
+                      (UINTN)sizeof(EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER));
+
+  SratTable->Memory = (EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE *) (UINTN)((UINTN)SratTable->Apic +
+                      (UINTN)sizeof(EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE) * PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE_COUNT);
+
+  SratTable->x2Apic = (EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE *) (UINTN)((UINTN)SratTable->Memory +
+                      (UINTN)sizeof(EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE)* MEMORY_AFFINITY_STRUCTURE_COUNT);
+
+
+  SratTable->SratHeader->Header.Signature = EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE;
+  SratTable->SratHeader->Header.Length = (UINT32) TableSize;
+  SratTable->SratHeader->Header.Revision = EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION;
+  CopyMem (SratTable->SratHeader->Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (SratTable->SratHeader->Header.OemId));
+  SratTable->SratHeader->Header.OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
+  SratTable->SratHeader->Header.OemRevision = EFI_ACPI_OEM_SRAT_REVISION;
+  SratTable->SratHeader->Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
+  SratTable->SratHeader->Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
+
+  SratTable->SratHeader->Reserved1 = EFI_ACPI_SRAT_RESERVED_FOR_BACKWARD_COMPATIBILITY;
+  SratTable->SratHeader->Reserved2 = EFI_ACPI_RESERVED_QWORD;
+
+  for (Index = 0; Index < PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE_COUNT; Index++) {
+    SratTable->Apic[Index].Type = EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY;
+    SratTable->Apic[Index].Length = sizeof(EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE);
+    SratTable->Apic[Index].ApicId = 0xFF;
+  }
+
+  for (Index = 0; Index < MEMORY_AFFINITY_STRUCTURE_COUNT; Index++) {
+    SratTable->Memory[Index].Type = EFI_ACPI_6_2_MEMORY_AFFINITY;
+    SratTable->Memory[Index].Length = sizeof(EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE);
+  }
+
+  for (Index = 0; Index < X2APIC_AFFINITY_STRUCTURE_COUNT; Index++) {
+    SratTable->x2Apic[Index].Type = EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY;
+    SratTable->x2Apic[Index].Length = sizeof(EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE);
+    SratTable->x2Apic[Index].X2ApicId = 0xFFFFFFFF;
+  }
+
+  PatchSratTable (SratTable);
+  PrintSratTable (&SratTable->SratHeader->Header);
+
+  //
+  // Publish SRAT Structure to ACPI
+  //
+  Status = mAcpiTable->InstallAcpiTable (
+                          mAcpiTable,
+                          SratTable->SratHeader,
+                          SratTable->SratHeader->Header.Length,
+                          &TableHandle
+                          );
+
+
+  FreePool (SratTable->SratHeader);
+  FreePool (SratTable);
+
+  InstallAcpiPlatformProtocol ();
+
+  return Status;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSsdt.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSsdt.c
new file mode 100644
index 0000000000..cb8b2b24be
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSsdt.c
@@ -0,0 +1,1004 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatformLibLocal.h"
+#include <Protocol/DynamicSiLibraryProtocol2.h>
+
+extern BIOS_ACPI_PARAM             *mAcpiParameter;
+extern EFI_IIO_UDS_PROTOCOL        *mIioUds;
+
+extern SOCKET_MEMORY_CONFIGURATION mSocketMemoryConfiguration;
+extern SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanagementConfiguration;
+
+extern BOOLEAN      mCpuOrderSorted;
+extern UINT32       mApicIdMap[MAX_SOCKET][MAX_CORE * MAX_THREAD];
+extern UINT32       mNumOfBitShift;
+
+extern UINT32       mEnabledProcessor[MAX_SOCKET];
+
+extern EFI_CPU_CSR_ACCESS_PROTOCOL *mCpuCsrAccess;
+UINT32 mCpuPCPSInfo[MAX_SOCKET];
+UINT32 mNcpuValue[MAX_SOCKET];
+
+extern CPU_ID_ORDER_MAP             mCpuApicIdOrderTable[];
+extern UINT8                        mPStateEnable;
+
+#ifndef MSR_MISC_ENABLES
+#define MSR_MISC_ENABLES         0x01A0
+#endif
+
+/**
+  This function detects PCPS Info
+
+  mCpuPCPSInfo usage:
+    Bit[15:0]: Enabled processors in current socket
+    Bit[16]: Hyperthreading enable
+    Bit[17]: PCPS disable in system
+
+  @param None
+
+  @retval VOID
+
+**/
+VOID
+DetectPcpsInfo (
+  VOID
+  )
+{
+  UINT8                   Socket;
+  UINT32                  CpuPCPSInfo = 0;
+  UINT32                  SmtDisable = 0;
+  UINT32                  Csr;
+
+  EFI_STATUS                      Status = EFI_SUCCESS;
+  DYNAMIC_SI_LIBARY_PROTOCOL2     *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return;
+  }
+
+  for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+    if (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].Valid) {
+      SmtDisable = DynamicSiLibraryProtocol2->PcuGetDesiredCoreSmtDis (Socket);
+
+      Csr = mCpuCsrAccess->ReadCpuCsr (Socket, 0, 0x04320084);
+
+      if (!SmtDisable && !(Csr & (1 << 12))) {
+        mCpuPCPSInfo[Socket] |= B_PCPS_HT_ENABLE;
+      }
+      CpuPCPSInfo = mCpuPCPSInfo[Socket];
+
+      //
+      // Update NCPU
+      //
+      mNcpuValue[Socket] = mCpuPCPSInfo[Socket] & 0xFF;
+
+      if (((CpuPCPSInfo & B_PCPS_DISABLE) == 0)) {
+        if (CpuPCPSInfo & B_PCPS_HT_ENABLE) {
+          mNcpuValue[Socket] = 2;
+        } else {
+          mNcpuValue[Socket] = 1;
+        }
+      }
+    }
+  }
+
+  for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+    if (mCpuPCPSInfo[Socket] == 0) {
+      mCpuPCPSInfo[Socket] = CpuPCPSInfo;
+      mNcpuValue[Socket] = mNcpuValue[0];
+    }
+  }
+}
+
+/**
+  Find APICID in mCpuApicIdOrderTable
+
+  @param SocketIndex      - In: Acpi thread number
+  @param ThreadIndex      - In: Acpi thread number
+
+  @retval APICID     - If not found, return 0xFFFFFFFF
+**/
+UINT32
+LocateApicIdInfo (
+  IN   UINT32                 SocketIndex,
+  IN   UINT32                 ThreadIndex
+  )
+{
+  if (mApicIdMap[SocketIndex][ThreadIndex] == (UINT32) -1) {
+    return (UINT32) -1;
+  }
+
+  return (mApicIdMap[SocketIndex][ThreadIndex] + (SocketIndex << mNumOfBitShift));
+}
+
+/**
+  Gather the EIST information
+
+  @param ThreadId       - In: Acpi thread number
+  @param CpuMiscData    - In/Out: Pointer to thread's CPU_MISC_DTAT struct
+
+  @retval EFI_SUCCESS   - EIST info retrieved
+**/
+EFI_STATUS
+LocateCpuEistInfo (
+  IN   UINT32                        CpuIndex,
+  OUT  CPU_MISC_DATA                 **CpuMiscData
+  )
+{
+  UINTN                       Index;
+  UINT32                      Socket;
+  UINT32                      ApicId;
+  const UINT32                *ApicMapPtr;
+
+  Socket = CpuIndex / (MAX_CORE * MAX_THREAD);
+  Index  = CpuIndex % (MAX_CORE * MAX_THREAD);
+  ApicMapPtr = mApicIdMap[Socket];
+
+  ApicId = mAcpiParameter->ProcessorApicIdBase[Socket] + ApicMapPtr[Index];
+
+  for (Index = 0; Index < mCpuConfigLibConfigContextBuffer->NumberOfProcessors; ++Index) {
+    if (mCpuConfigLibConfigContextBuffer->CollectedDataBuffer[Index].CpuMiscData.ApicID == ApicId) {
+      *CpuMiscData = &mCpuConfigLibConfigContextBuffer->CollectedDataBuffer[Index].CpuMiscData;
+      break;
+    }
+  }
+
+  if (*CpuMiscData == NULL) {  //use SBSP's data
+    *CpuMiscData = &mCpuConfigLibConfigContextBuffer->CollectedDataBuffer[0].CpuMiscData;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Determine turbo mode status
+
+  @param None
+
+  @retval TRUE if turbo enabled, FALSE if disabled
+**/
+BOOLEAN
+IsTurboModeEnabled (
+  VOID
+  )
+{
+  EFI_CPUID_REGISTER     CpuidRegisters;
+  BOOLEAN                Status;
+  UINT64                 MiscEnable;
+
+  Status = FALSE;
+  AsmCpuid (CPUID_THERMAL_POWER_MANAGEMENT, &CpuidRegisters.RegEax, &CpuidRegisters.RegEbx, &CpuidRegisters.RegEcx, &CpuidRegisters.RegEdx);
+  if (((CPUID_THERMAL_POWER_MANAGEMENT_EAX*)&CpuidRegisters.RegEax)->Bits.TurboBoostTechnology != 0) {
+    //
+    // Turbo mode is supported on this processor (Available)
+    //
+
+    MiscEnable = AsmReadMsr64 (MSR_MISC_ENABLES);
+    if ((RShiftU64 (MiscEnable, 38) & 1) == 0) { // Bit 38 is TurboModeDisable
+      //
+      // Turbo mode is supported on this processor (Available)
+      //
+      Status = TRUE;
+    }
+  }
+
+  return Status;
+}
+
+/**
+  Finds the actual beginning of a CPU SSDT table, skips the If(Zero) { External() ... } opcode
+  auto-generated by the iASL 6.1 compiler
+
+  From iASL/6.1/changes.txt
+  "Completed full support for the ACPI 6.0 External() AML opcode. The
+  compiler emits an external AML opcode for each ASL External statement.
+  This opcode is used by the disassembler to assist with the disassembly of
+  external control methods by specifying the required number of arguments
+  for the method. AML interpreters do not use this opcode. To ensure that
+  interpreters do not even see the opcode, a block of one or more external
+  opcodes is surrounded by an "If(0)" construct. As this feature becomes
+  commonly deployed in BIOS code, the ability of disassemblers to correctly
+  disassemble AML code will be greatly improved."
+
+  The AML code contains external (_SB_SCKxCyyy) opcodes within a If(Zero) statement;
+  we have to ignore this opcodes and start patching from the actual table begin marker, i.e., "TBST"
+
+  @param[in] BeginPtr a pointer to the begin of a SSDT table
+  @param[in] EndPtr   a pointer to the end of a SSDT table
+
+  @retval       beginning of the part of SSDT table past external _SB_ opcodes
+**/
+static inline
+UINT8 *
+SkipExternalSbOpcodes(
+  IN UINT8  *BeginPtr,
+  IN UINT8  *EndPtr,
+  IN UINT32 ExternSbExpected
+  )
+{
+  UINT8  *CurPtr = BeginPtr;
+  UINT32 ExternSbFound = 0;
+
+  ASSERT (BeginPtr < EndPtr);
+
+  DEBUG ((DEBUG_VERBOSE, "SkipExternalSbOpcodes start\n"));
+
+  for (CurPtr = BeginPtr; CurPtr < EndPtr; ++CurPtr) {
+    UINT32 Signature = *(UINT32 *) CurPtr;
+
+    if (SIGNATURE_32 ('_', 'S', 'B', '_') == Signature) {
+      CONST EXTERNAL_OBJECT_DECL *ExternDecl = ACPI_EXTERNAL_OBJECT_DECL_FROM_NAME_STR (CurPtr);
+
+      ASSERT (BeginPtr < (UINT8 *)ExternDecl);
+
+      if ((AML_EXTERNAL_OP == ExternDecl->ExternalOp ) &&
+          (AML_ROOT_CHAR == ExternDecl->RootChar) &&
+          (AML_MULTI_NAME_PREFIX == ExternDecl->MultiNamePrefix) &&
+          (0x3 <= ExternDecl->SegCount)) {
+        ++ExternSbFound;
+      } else {
+        break;
+      }
+    }
+  }
+
+  DEBUG ((DEBUG_ERROR, "ExternSbExpected: %d, ExternSbFound: %d\n"));
+
+  ASSERT ((ExternSbFound % ExternSbExpected) == 0);
+
+  DEBUG ((DEBUG_VERBOSE, "SkipExternalSbOpcodes end\n"));
+
+  return CurPtr;
+}
+
+/**
+  Update the CPU PM SSDT table
+
+  @param[in,out]  TableHeader     The table to be set
+
+  @retval         EFI_SUCCESS     Returns Success
+  @retval         EFI_UNSUPPORTED Table is not supported
+**/
+EFI_STATUS
+PatchCpuPmSsdtTable (
+  IN OUT  EFI_ACPI_COMMON_HEADER      *Table
+  )
+{
+  UINT8                       *CurrPtr;
+  UINT8                       *EndPtr;
+  UINT8                       *SsdtPointer;
+  UINT32                      Signature;
+  UINT32                      CpuFixes;
+  UINT32                      CpuSkt;
+  UINT32                      CpuIndex;
+  UINT32                      ThreadIndex;
+  UINT32                      AdjustSize;
+  ACPI_NAMEPACK_DWORD         *NamePtr;
+  UINT32                      DomnValue;
+  ACPI_NAME_COMMAND           *PsdPackage;
+  PSD_PACKAGE_LAYOUT          *PsdPackageItemPtr;
+  CPU_MISC_DATA               *CpuMiscData;
+
+  DEBUG ((DEBUG_INFO, "Patching SSDT PatchCpuPmSsdtTable\n"));
+
+  //
+  // Loop through the ASL looking for values that we must fix up.
+  //
+  DomnValue = 0;
+  CpuFixes  = 0;
+  CpuSkt    = 0;
+  CpuIndex  = 0;
+  ThreadIndex = 0;
+  CurrPtr = (UINT8 *) Table;
+  EndPtr  = (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length);
+  CpuMiscData = NULL;
+
+  DetectPcpsInfo ();
+
+  //
+  // CurrPtr = beginning of table to search
+  //
+  CurrPtr = SkipExternalSbOpcodes (CurrPtr, EndPtr, (UINT32) MAX_CPU_NUM);
+
+  //
+  // Subtract 11 from EndPtr - this is the size of the largest data item we will search for
+  //  so that we do not try to read past the end of the table
+  //
+  EndPtr -= 11;
+
+  for (SsdtPointer = CurrPtr; SsdtPointer <= EndPtr; ++SsdtPointer) {
+    Signature = *(UINT32 *) SsdtPointer;
+    CpuIndex  = 0;
+    AdjustSize  = 0;
+
+    switch (Signature) {
+
+    //
+    // The AML code contains strings in the form of _SB_SCKxCyyy where x is the socket number
+    // and yyy is the thread number in hexadecimal, this first case parses that string and saves
+    // the socket number into CpuSkt and the thread number into CpuIndex.
+    //
+    case SIGNATURE_32 ('_', 'S', 'B', '_'):
+      //
+      // SKTX
+      //
+      CpuSkt = *(SsdtPointer + 7);
+      if ((CpuSkt < '0') || ((CpuSkt - '0') > MAX_SOCKET)) {
+        CpuSkt = '0';
+      }
+      CpuSkt -= '0';
+
+      if ((*(SsdtPointer + 8) != 'C')) {
+        continue;
+      }
+
+      if ((*(SsdtPointer + 11) > '0') && (*(SsdtPointer + 11) <= '9')) {
+        CpuIndex = (*(SsdtPointer + 11) -'0');
+      } else if ((*(SsdtPointer + 11) >= 'A') && (*(SsdtPointer + 11) <= 'F')) {
+        CpuIndex = (*(SsdtPointer + 11) -'A' + 10);
+      }
+
+      if ((*(SsdtPointer + 10) > '0') && ( *(SsdtPointer + 10) <= '9')) {
+        AdjustSize = (*(SsdtPointer + 10) -'0') * 0x10;
+      } else if ((*(SsdtPointer + 10) >= 'A') && (*(SsdtPointer + 10) <= 'F')) {
+        AdjustSize = (*(SsdtPointer + 10) -'A' + 10) * 0x10;
+      }
+
+      CpuIndex += AdjustSize;
+      AdjustSize  = 0;
+
+      if ((*(SsdtPointer + 9) > '0') && (*(SsdtPointer + 9) <= '9')) {
+        AdjustSize = (*(SsdtPointer + 9) -'0') * 0x100;
+      } else if ((*(SsdtPointer + 9) >= 'A') && (*(SsdtPointer + 9) <= 'F')) {
+        AdjustSize = (*(SsdtPointer + 9) -'A' + 10) * 0x100;
+      }
+
+      CpuIndex += AdjustSize;
+      ThreadIndex  = CpuIndex;
+
+      //
+      // PCPS - Update DOMN
+      //
+      DomnValue = (UINT8) CpuSkt;
+
+      if ((mCpuPCPSInfo[CpuSkt] & B_PCPS_DISABLE) == 0) {
+        DomnValue = LocateApicIdInfo (CpuSkt, ThreadIndex);
+
+        if (mNcpuValue[CpuSkt] == 2) {
+          DomnValue = (DomnValue >> 1);
+        }
+      }
+
+      DEBUG ((
+        DEBUG_INFO,
+        ":ACPI: PatchCpuPmSsdtTable(): CpuSkt: %d ThreadIndex: %d, NcpuValue: %d, DomnValue: %d\n",
+        CpuSkt,
+        ThreadIndex,
+        mNcpuValue[CpuSkt],
+        DomnValue
+        ));
+      ++CpuFixes;
+      CpuMiscData = NULL;
+      LocateCpuEistInfo (0, &CpuMiscData);  // use CPU0 for update NPSS and SPSS
+      break;
+
+    case SIGNATURE_32 ('D', 'O', 'M', 'N'):
+      NamePtr = ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer);
+      if (NamePtr->StartByte != AML_NAME_OP) {
+        continue;
+      }
+
+      if (NamePtr->Size != AML_NAME_DWORD_SIZE) {
+        continue;
+      }
+
+      NamePtr->Value = DomnValue;
+      break;
+
+    case SIGNATURE_32 ('N', 'C', 'P', 'U'):
+      NamePtr = ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer);
+      if (NamePtr->StartByte != AML_NAME_OP) {
+        continue;
+      }
+
+      if (NamePtr->Size != AML_NAME_DWORD_SIZE) {
+        continue;
+      }
+
+      NamePtr->Value = (UINT32) mNcpuValue[CpuSkt];
+      break;
+
+    case SIGNATURE_32 ('P', 'S', 'D', 'C'):
+    case SIGNATURE_32 ('P', 'S', 'D', 'E'):
+      PsdPackage = ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer);
+      if (PsdPackage->StartByte != AML_NAME_OP) {
+        continue;
+      }
+
+      PsdPackageItemPtr       = (PSD_PACKAGE_LAYOUT *) ((UINT8 *) PsdPackage);
+      DEBUG ((
+        DEBUG_VERBOSE,
+        "PatchCpuPmSsdtTable(): PsdPackageItemPtr table: %x is detected...\n",
+        PsdPackage->NameStr
+        ));
+      DEBUG ((
+        DEBUG_VERBOSE,
+        "   Initial Values:     Domain = %x,    CoordType = %x,   NumProcessors = %x\n",
+        PsdPackageItemPtr->Domain,
+        PsdPackageItemPtr->CoordType,
+        PsdPackageItemPtr->NumProcessors
+        ));
+
+      PsdPackageItemPtr->Domain = DomnValue;
+      PsdPackageItemPtr->NumProcessors = (UINT32) mNcpuValue[CpuSkt];
+      DEBUG ((
+        DEBUG_VERBOSE,
+        "   PsdPackage = %x,    PsdPackageItemPtr = %x,   SsdtPointer = %x\n",
+        (UINT8 *)PsdPackage,
+        (UINT8 *)PsdPackageItemPtr,
+        (UINT8 *)SsdtPointer
+        ));
+      DEBUG ((
+        DEBUG_VERBOSE,
+        "   Updated PSD Domain = %x,    CoordType = %x,   NumProcessors = %x\n",
+        PsdPackageItemPtr->Domain,
+        PsdPackageItemPtr->CoordType,
+        PsdPackageItemPtr->NumProcessors
+        ));
+      break;
+
+    default:
+      break;
+    } // switch
+  } // for
+
+  //
+  // N fixes together currently
+  //
+  ASSERT (CpuFixes == (UINT32) MAX_CPU_NUM);
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+    Update the OEM1 P-State SSDT table (EIST)
+
+    @param *TableHeader   - The table to be set
+
+    @retval EFI_SUCCESS -  Returns Success
+
+**/
+EFI_STATUS
+PatchOem1SsdtTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER  *Table
+  )
+{
+  EFI_STATUS                  Status;
+  UINT8                       *CurrPtr;
+  UINT8                       *EndPtr;
+  UINT8                       *SsdtPointer;
+  UINT32                      Signature;
+  UINT32                      CpuFixes;
+  UINT32                      NpssFixes;
+  UINT32                      GpssFixes;
+  UINT32                      CpuSkt;
+  UINT32                      CpuIndex;
+  UINT32                      ThreadIndex;
+  UINT32                      PackageSize;
+  UINT32                      NewPackageSize;
+  UINT32                      AdjustSize;
+  UINTN                       TableIndex;
+  ACPI_NAME_COMMAND           *PssTable;
+  PSS_PACKAGE                 *PssTableItemPtr;
+  CPU_MISC_DATA               *CpuMiscData;
+  FVID_ENTRY                  *PssState;
+
+  DEBUG ((DEBUG_INFO, "Patching SSDT PatchOem1SsdtTable\n"));
+
+  //
+  // Loop through the ASL looking for values that we must fix up.
+  //
+  NpssFixes = 0;
+  GpssFixes = 0;
+  CpuFixes  = 0;
+  CpuSkt    = 0;
+  CpuIndex  = 0;
+  ThreadIndex  = 0;
+  CurrPtr = (UINT8 *) Table;
+  EndPtr  = (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length);
+  CpuMiscData = NULL;
+
+  Status = LocateCpuEistInfo (0, &CpuMiscData);   // get BSP's data
+  if( (EFI_ERROR (Status)) || (CpuMiscData == NULL ) ){
+    DEBUG ((DEBUG_WARN, " PatchGv3SsdtTable - EIST info for BSP index not found \n"));
+    return Status;
+  }
+
+  mPStateEnable = 1;
+
+  //
+  // CurrPtr = beginning of table to search
+  //
+  CurrPtr = SkipExternalSbOpcodes (CurrPtr, EndPtr, (UINT32) MAX_CPU_NUM);
+
+  //
+  // Subtract 11 from EndPtr - this is the size of the larget data item we will search for
+  // so that we do not try to read past the end of the table
+  //
+  EndPtr -= 11;
+
+  for (SsdtPointer = CurrPtr; SsdtPointer <= EndPtr; ++SsdtPointer) {
+    Signature = *(UINT32 *) SsdtPointer;
+    CpuIndex  = 0;
+    AdjustSize  = 0;
+
+    switch (Signature) {
+      case SIGNATURE_32 ('_', 'S', 'B', '_'):
+        //
+        // SKTX
+        //
+        CpuSkt = *(SsdtPointer + 7);
+        if ((CpuSkt < '0') || ((CpuSkt - '0') > MAX_SOCKET)) {
+          CpuSkt = '0';
+        }
+
+        CpuSkt -= '0';
+
+        if ((*(SsdtPointer + 11) > '0') && (*(SsdtPointer + 11) <= '9')) {
+          CpuIndex = (*(SsdtPointer + 11) -'0');
+        } else if ((*(SsdtPointer + 11) >= 'A') && (*(SsdtPointer + 11) <= 'F')) {
+          CpuIndex = (*(SsdtPointer + 11) -'A' + 10);
+        }
+
+        if ((*(SsdtPointer + 10) > '0') && ( *(SsdtPointer + 10) <= '9')) {
+          AdjustSize = (*(SsdtPointer + 10) -'0') * 0x10;
+        } else if ((*(SsdtPointer + 10) >= 'A') && (*(SsdtPointer + 10) <= 'F')) {
+          AdjustSize = (*(SsdtPointer + 10) -'A' + 10) * 0x10;
+        }
+
+        CpuIndex += AdjustSize;
+        AdjustSize  = 0;
+
+        if ((*(SsdtPointer + 9) > '0') && (*(SsdtPointer + 9) <= '9')) {
+          AdjustSize = (*(SsdtPointer + 9) -'0') * 0x100;
+        } else if ((*(SsdtPointer + 9) >= 'A') && (*(SsdtPointer + 9) <= 'F')) {
+          AdjustSize = (*(SsdtPointer + 9) -'A' + 10) * 0x100;
+        }
+
+        CpuIndex += AdjustSize;
+        ThreadIndex  = CpuIndex;
+
+        ++CpuFixes;
+        CpuMiscData = NULL;
+        LocateCpuEistInfo (0, &CpuMiscData);  // use CPU0 for update NPSS and SPSS
+        break;
+
+      case SIGNATURE_32 ('N', 'P', 'S', 'S'):
+      case SIGNATURE_32 ('S', 'P', 'S', 'S'):
+
+        PssTable = ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer);
+        if (PssTable->StartByte != AML_NAME_OP) {
+          continue;
+        }
+
+        ASSERT (CpuMiscData != NULL);
+        PssState = CpuMiscData->FvidTable;
+
+        AdjustSize  = PssTable->NumEntries * sizeof (PSS_PACKAGE);
+        AdjustSize -= (UINT32)(CpuMiscData->NumberOfPStates * sizeof (PSS_PACKAGE));
+        PackageSize     = (PssTable->Size & 0xF) + ((PssTable->Size & 0xFF00) >> 4);
+        NewPackageSize  = PackageSize - AdjustSize;
+        PssTable->Size  = (UINT16) ((NewPackageSize & 0xF) + ((NewPackageSize & 0x0FF0) << 4));
+
+        //
+        // Set most significant two bits of byte zero to 01, meaning two bytes used
+        //
+        PssTable->Size |= 0x40;
+
+        //
+        // Set unused table to Noop Code
+        //
+        SetMem (
+          (UINT8 *) PssTable + NewPackageSize + AML_NAME_PREFIX_SIZE,
+          AdjustSize,
+          AML_NOOP_OP
+          );
+        PssTable->NumEntries  = (UINT8) CpuMiscData->NumberOfPStates;
+        PssTableItemPtr       = (PSS_PACKAGE *) ((UINT8 *) PssTable + sizeof (ACPI_NAME_COMMAND));
+
+        //
+        // Update the size
+        //
+
+        if (CpuMiscData->NumberOfPStates == 1) {
+          mPStateEnable = 0;
+        }
+
+        for (TableIndex = 0; TableIndex < CpuMiscData->NumberOfPStates; ++TableIndex) {
+          PssTableItemPtr->CoreFreq = (UINT32) (CpuMiscData->IntendedFsbFrequency * PssState[TableIndex].Ratio);
+          if (mSocketPowermanagementConfiguration.TurboMode && (TableIndex == 0) && IsTurboModeEnabled ()) {
+            PssTableItemPtr->CoreFreq = (UINT32)((CpuMiscData->IntendedFsbFrequency * PssState[TableIndex + 1].Ratio) + 1);
+          }
+
+
+          PssTableItemPtr->Power    =  (UINT32)(PssState[TableIndex].Power); // when calulate Tdp already make it mW;
+          if (PssTable->NameStr == SIGNATURE_32 ('N', 'P', 'S', 'S')) {
+            PssTableItemPtr->TransLatency = (UINT32)(PssState[TableIndex].TransitionLatency);
+              PssTableItemPtr->Control  = (UINT32)(PssState[TableIndex].Ratio << 8);
+              PssTableItemPtr->Status   = (UINT32)(PssState[TableIndex].Ratio << 8);
+          } else {
+            //
+            // This method should be supported by SMM PPM Handler
+            //
+            // Status is simply the state number.
+            // Use the state number w/ OS command value so that the
+            // legacy interface may be used.  Latency for SMM is 100 + BM latency.
+            PssTableItemPtr->Status   = (UINT32)TableIndex;
+            PssTableItemPtr->TransLatency = (UINT32)(100 + PssState[TableIndex].TransitionLatency);
+            PssTableItemPtr->Control  = (UINT32)(SW_SMI_OS_REQUEST | (TableIndex << 8));
+          }
+
+          PssTableItemPtr->BMLatency    = (UINT32)(PssState[TableIndex].BusMasterLatency);
+
+          ++PssTableItemPtr;
+        }
+
+        if (PssTable->NameStr == SIGNATURE_32 ('N', 'P', 'S', 'S')) {
+          ++NpssFixes;
+        }
+
+        SsdtPointer = (UINT8 *) PssTable + PackageSize;
+        break;
+
+      case SIGNATURE_32 ('G', 'P', 'S', 'S'):
+
+        PssTable = ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer);
+        if (PssTable->StartByte != AML_NAME_OP) {
+          continue;
+        }
+
+        ASSERT (CpuMiscData != NULL);
+        PssState = CpuMiscData->GreaterFvidTable;
+
+        ASSERT (CpuMiscData->GreaterNumberOfPStates <= GPSS_FVID_MAX_STATES);
+        if (CpuMiscData->GreaterNumberOfPStates > GPSS_FVID_MAX_STATES) {
+          continue;
+        }
+
+        AdjustSize  = PssTable->NumEntries * sizeof (PSS_PACKAGE);
+        AdjustSize -= (UINT32)(CpuMiscData->GreaterNumberOfPStates * sizeof (PSS_PACKAGE));
+        PackageSize     = (PssTable->Size & 0xF) + ((PssTable->Size & 0xFF00) >> 4);
+        NewPackageSize  = PackageSize - AdjustSize;
+        PssTable->Size  = (UINT16) ((NewPackageSize & 0xF) + ((NewPackageSize & 0x0FF0) << 4));
+
+        //
+        // Set most significant two bits of byte zero to 01, meaning two bytes used
+        //
+        PssTable->Size |= 0x40;
+
+        //
+        // Set unused table to Noop Code
+        //
+        SetMem (
+          (UINT8 *) PssTable + NewPackageSize + AML_NAME_PREFIX_SIZE,
+          AdjustSize,
+          AML_NOOP_OP
+          );
+        PssTable->NumEntries  = (UINT8) CpuMiscData->GreaterNumberOfPStates;
+        PssTableItemPtr       = (PSS_PACKAGE *) ((UINT8 *) PssTable + sizeof (ACPI_NAME_COMMAND));
+
+        //
+        // Update the size
+        //
+        for (TableIndex = 0; TableIndex < CpuMiscData->GreaterNumberOfPStates; ++TableIndex) {
+          PssTableItemPtr->CoreFreq = (UINT32) (CpuMiscData->IntendedFsbFrequency * PssState[TableIndex].Ratio);
+          if (mSocketPowermanagementConfiguration.TurboMode && (TableIndex == 0) && IsTurboModeEnabled()) {
+            PssTableItemPtr->CoreFreq = (UINT32)((CpuMiscData->IntendedFsbFrequency * PssState[TableIndex + 1].Ratio) + 1);
+          }
+
+          //
+          // If Turbo mode is supported, add one to the Max Non-Turbo frequency
+          //
+          PssTableItemPtr->Power = (UINT32)(PssState[TableIndex].Power); // when calulate Tdp already make it mW;
+          if (PssTable->NameStr == SIGNATURE_32 ('G', 'P', 'S', 'S')) {
+            PssTableItemPtr->TransLatency = (UINT32)(PssState[TableIndex].TransitionLatency);
+            PssTableItemPtr->Control  = (UINT32)(PssState[TableIndex].Ratio << 8);
+            PssTableItemPtr->Status   = (UINT32)(PssState[TableIndex].Ratio << 8);
+          } else {
+            //
+            // This method should be supported by SMM PPM Handler
+            //
+            // Status is simply the state number.
+            // Use the state number w/ OS command value so that the
+            // legacy interface may be used.  Latency for SMM is 100 + BM latency.
+            //
+            PssTableItemPtr->Status   = (UINT32)TableIndex;
+            PssTableItemPtr->TransLatency = (UINT32)(100 + PssState[TableIndex].TransitionLatency);
+            PssTableItemPtr->Control  = (UINT32)(SW_SMI_OS_REQUEST | (TableIndex << 8));
+          }
+
+          PssTableItemPtr->BMLatency    = (UINT32)(PssState[TableIndex].BusMasterLatency);
+
+          ++PssTableItemPtr;
+        }
+
+        if (PssTable->NameStr == SIGNATURE_32 ('G', 'P', 'S', 'S')) {
+          ++GpssFixes;
+        }
+
+        SsdtPointer = (UINT8 *) PssTable + PackageSize;
+        break;
+
+      default:
+        break;
+    } // switch
+  } // for
+
+  //
+  // N fixes together currently
+  //
+  ASSERT (CpuFixes == (UINT32) MAX_CPU_NUM);
+
+  if (!mPStateEnable || !mSocketPowermanagementConfiguration.ProcessorEistEnable || (mSocketPowermanagementConfiguration.ProcessorHWPMEnable > HWP_MODE_NATIVE) ) {
+      Status = EFI_UNSUPPORTED;  //CPU EIST
+      return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PatchSsdtTable (
+  IN OUT EFI_ACPI_COMMON_HEADER     *Table,
+  IN OUT EFI_ACPI_TABLE_VERSION     *Version
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_ACPI_DESCRIPTION_HEADER   *TableHeader;
+
+  Status = EFI_SUCCESS;
+  TableHeader = (EFI_ACPI_DESCRIPTION_HEADER   *)Table;
+
+    //
+    // Do not load the xHCI table. It is handled by separate function.
+    //
+    TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
+    if (CompareMem (&TableHeader->OemTableId, "xh_", 3) == 0) {
+      DEBUG ((DEBUG_ERROR,"Xhci TableHeader->OemTableId = %x\n ", TableHeader->OemTableId));
+      *Version = EFI_ACPI_TABLE_VERSION_NONE;
+    }
+
+    if (TableHeader->OemTableId == SIGNATURE_64 ('S', 'S', 'D', 'T', ' ', ' ', 'P', 'M')) {
+      PatchCpuPmSsdtTable (Table);  //CPU PM
+    }
+
+  return Status;
+}
+
+/**
+  Update the OEM2 HWP SSDT table if needed
+
+  @param *TableHeader   - The table to be set
+
+  @retval EFI_SUCCESS -  Returns Success
+**/
+EFI_STATUS
+PatchOem2SsdtTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER  *Table
+  )
+{
+  EFI_STATUS    Status = EFI_SUCCESS;
+
+  if ((mSocketPowermanagementConfiguration.ProcessorHWPMEnable == 0) || (mSocketPowermanagementConfiguration.ProcessorHWPMEnable == HWP_MODE_OOB)) {
+    Status = EFI_UNSUPPORTED;
+  }
+
+  return Status;
+}
+
+/**
+  Update the OEM3 T-State SSDT table (TST)
+
+  @param *TableHeader   - The table to be set
+
+  @retval EFI_SUCCESS -  Returns Success
+**/
+EFI_STATUS
+PatchOem3SsdtTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER  *Table
+  )
+{
+  UINT8                       *CurrPtr;
+  UINT8                       *EndPtr;
+  UINT8                       *SsdtPointer;
+  UINT32                      Signature;
+  UINT32                      CpuFixes;
+  UINT32                      CpuSkt;
+  UINT32                      CpuIndex;
+  UINT32                      ThreadIndex;
+  UINT32                      AdjustSize;
+  UINT32                      DomnValue;
+  ACPI_NAME_COMMAND           *PsdPackage;
+  PSD_PACKAGE_LAYOUT          *PsdPackageItemPtr;
+
+  DEBUG ((DEBUG_INFO, "Patching SSDT PatchOem3SsdtTable\n"));
+
+  if (!mSocketPowermanagementConfiguration.TStateEnable || (mSocketPowermanagementConfiguration.ProcessorHWPMEnable > HWP_MODE_NATIVE) ) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Loop through the ASL looking for values that we must fix up.
+  //
+  DomnValue = 0;
+  CpuFixes  = 0;
+  CpuSkt    = 0;
+  ThreadIndex  = 0;
+  CurrPtr = (UINT8 *) Table;
+  EndPtr  = (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length);
+
+  //
+  // CurrPtr = beginning of table we want to search
+  //
+  CurrPtr = SkipExternalSbOpcodes(CurrPtr, EndPtr, (UINT32) MAX_CPU_NUM);
+
+  //
+  // Subtract 11 from EndPtr - this is the size of the larget data item we will read
+  //  so that we don't read beyond the end of the table
+  //
+  EndPtr -= 11;
+
+  for (SsdtPointer = CurrPtr; SsdtPointer <= EndPtr; ++SsdtPointer) {
+    Signature = *(UINT32 *) SsdtPointer;
+    CpuIndex  = 0;
+    AdjustSize  = 0;
+
+    switch (Signature) {
+
+    case SIGNATURE_32 ('_', 'S', 'B', '_'):
+      //
+      // SKTX
+      //
+      CpuSkt = *(SsdtPointer + 7);
+      CpuSkt -= '0';
+
+      if ((*(SsdtPointer + 8) != 'C')) {
+        continue;
+      }
+
+      if ((*(SsdtPointer + 11) > '0') && (*(SsdtPointer + 11) <= '9')) {
+        CpuIndex = (*(SsdtPointer + 11) -'0');
+      } else if ((*(SsdtPointer + 11) >= 'A') && (*(SsdtPointer + 11) <= 'F')) {
+        CpuIndex = (*(SsdtPointer + 11) -'A' + 10);
+      }
+
+      if ((*(SsdtPointer + 10) > '0') && ( *(SsdtPointer + 10) <= '9')) {
+        AdjustSize = (*(SsdtPointer + 10) -'0') * 0x10;
+      } else if ((*(SsdtPointer + 10) >= 'A') && (*(SsdtPointer + 10) <= 'F')) {
+        AdjustSize = (*(SsdtPointer + 10) -'A' + 10) * 0x10;
+      }
+
+      CpuIndex += AdjustSize;
+      AdjustSize  = 0;
+
+      if ((*(SsdtPointer + 9) > '0') && (*(SsdtPointer + 9) <= '9')) {
+        AdjustSize = (*(SsdtPointer + 9) -'0') * 0x100;
+      } else if ((*(SsdtPointer + 9) >= 'A') && (*(SsdtPointer + 9) <= 'F')) {
+        AdjustSize = (*(SsdtPointer + 9) -'A' + 10) * 0x100;
+      }
+
+      CpuIndex += AdjustSize;
+      ThreadIndex = CpuIndex;
+
+      //
+      // PCPS - Update DOMN
+      //
+      DomnValue = (UINT8) CpuSkt;
+
+      if ((mCpuPCPSInfo[CpuSkt] & B_PCPS_DISABLE) == 0) {
+        DomnValue = LocateApicIdInfo (CpuSkt, ThreadIndex);
+
+        if (mNcpuValue[CpuSkt] == 2) {
+          DomnValue = (DomnValue >> 1);
+        }
+      }
+
+      DEBUG ((
+        DEBUG_VERBOSE,
+        "PatchOem3SsdtTable(): CpuIndex: 0x%x ThreadIndex: 0x%x CpuFixes: 0x%x (%d)\n",
+        CpuIndex,
+        ThreadIndex,
+        CpuFixes,
+        CpuFixes
+        ));
+
+      DEBUG ((
+        DEBUG_INFO,
+        "PatchOem3SsdtTable(): CpuSkt: %d CpuIndex: 0x%x, NcpuValue = 0x%x, DomnValue = 0x%x\n",
+        CpuSkt,
+        CpuIndex,
+        mNcpuValue[CpuSkt],
+        DomnValue
+        ));
+      ++CpuFixes;
+      break;
+
+    case SIGNATURE_32 ('T', 'S', 'D', 'C'):
+    case SIGNATURE_32 ('T', 'S', 'D', 'D'):
+      PsdPackage = ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer);
+      if (PsdPackage->StartByte != AML_NAME_OP) {
+        continue;
+      }
+
+      PsdPackageItemPtr       = (PSD_PACKAGE_LAYOUT *) ((UINT8 *) PsdPackage);
+      DEBUG ((
+        DEBUG_VERBOSE,
+        "TSDC: PsdPackageItemPtr table: %x is detected...\n",
+        PsdPackage->NameStr
+        ));
+      DEBUG ((
+        DEBUG_VERBOSE,
+        "   Initial Values:     Domain = %x,    CoordType = %x,   NumProcessors = %x\n",
+        PsdPackageItemPtr->Domain,
+        PsdPackageItemPtr->CoordType,
+        PsdPackageItemPtr->NumProcessors
+        ));
+
+      PsdPackageItemPtr->Domain = DomnValue;
+      PsdPackageItemPtr->NumProcessors = mNcpuValue[CpuSkt];
+      DEBUG ((
+        DEBUG_VERBOSE,
+        "   PsdPackage = %x,    PsdPackageItemPtr = %x,   SsdtPointer = %x\n",
+        (UINT8 *)PsdPackage,
+        (UINT8 *)PsdPackageItemPtr,
+        (UINT8 *)SsdtPointer
+        ));
+      DEBUG ((
+        DEBUG_VERBOSE,
+        "   Updated TSD Domain = %x,    CoordType = %x,   NumProcessors = %x\n",
+        PsdPackageItemPtr->Domain,
+        PsdPackageItemPtr->CoordType,
+        PsdPackageItemPtr->NumProcessors
+        ));
+      break;
+
+    default:
+      break;
+    } // switch
+  } // for
+
+  //
+  // N fixes together currently
+  //
+  ASSERT (CpuFixes == (UINT32) MAX_CPU_NUM);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Update the OEM4 C State SSDT table (CST)
+
+  @param *TableHeader   - The table to be set
+
+  @retval EFI_SUCCESS -  Returns Success
+**/
+EFI_STATUS
+PatchOem4SsdtTable (
+  IN OUT   EFI_ACPI_COMMON_HEADER  *Table
+  )
+{
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec
index 4d416325ae..a80472e73c 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec
+++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec
@@ -398,6 +398,11 @@
   ##
   gPlatformModuleTokenSpaceGuid.PcdEnableHighSpeedUart|FALSE|BOOLEAN|0x0000002C
 
+  ## Platform Not support Acpi Table
+  #
+  gPlatformTokenSpaceGuid.PcdPlatformNotSupportAcpiTable|FALSE|BOOLEAN|0x40000012
+  gPlatformTokenSpaceGuid.PcdPlatformNotSupportAcpiBdatTable|FALSE|BOOLEAN|0x40000013
+
 [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamicEx]
   ## MemoryCheck value for checking memory before boot OS.
   #  To save the boot performance, the default MemoryCheck is set to 0.
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
index 39b93d9289..5dfee0eeb5 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
+++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
@@ -621,6 +621,7 @@
   CrcLib|WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
   PlatformSpecificAcpiTableLib|WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf
   BuildAcpiTablesLib|WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf
+  AcpiPlatformTableLib|WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.inf
 
 [LibraryClasses.Common.SEC, LibraryClasses.Common.PEI_CORE, LibraryClasses.Common.PEIM]
   FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
-- 
2.27.0.windows.1


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

* [edk2-devel][edk2-platforms][PATCH V1 8/9] WhitleyOpenBoardPkg/AcpiPlatform: Add driver for publishing ACPI tables
  2022-03-10 22:41 [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Oram, Isaac W
                   ` (6 preceding siblings ...)
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 7/9] WhitleyOpenBoardPkg/AcpiTablesLib: Add library for AcpiPlatform driver Oram, Isaac W
@ 2022-03-10 22:41 ` Oram, Isaac W
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 9/9] WhitleyOpenBoardPkg/Build: Remove confusing build options Oram, Isaac W
  2022-03-11  1:12 ` [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Nate DeSimone
  9 siblings, 0 replies; 14+ messages in thread
From: Oram, Isaac W @ 2022-03-10 22:41 UTC (permalink / raw)
  To: devel; +Cc: Nate DeSimone, Chasel Chiu

AcpiPlatform DXE driver loads and patches ACPI tables before publishing.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>
---
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.c         |  754 +++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.h         |  117 ++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.inf       |  107 ++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.c    |  384 +++++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.h    |   51 +
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.c    |  133 ++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.h    |   66 +
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformVTDHooks.c | 1762 ++++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec                                   |   11 +-
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc                                   |    3 +
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.fdf                                   |    3 +
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaMain/StaticSkuDataDxe/Readme.md            |    1 +
 Platform/Intel/WhitleyOpenBoardPkg/WilsonCityRvp/AmlOffsets/AmlOffsets.inf           |    2 +-
 13 files changed, 3388 insertions(+), 6 deletions(-)

diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.c b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.c
new file mode 100644
index 0000000000..1648029bd1
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.c
@@ -0,0 +1,754 @@
+/** @file
+  ACPI Platform Driver
+
+  @copyright
+  Copyright 1999 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "AcpiPlatform.h"
+#include "AcpiPlatformUtils.h"
+#include "AcpiPlatformHooks.h"
+#include <Library/PcdLib.h>
+#include <Protocol/PciEnumerationComplete.h>
+#include <IioSetupDefinitions.h>
+#include <ProcessorPpmSetup.h>
+
+
+#ifndef __GNUC__
+#pragma optimize("", off)
+#endif  //__GNUC__
+
+extern SOCKET_IIO_CONFIGURATION                       mSocketIioConfiguration;
+extern SOCKET_POWERMANAGEMENT_CONFIGURATION           mSocketPowermanagementConfiguration;
+extern SOCKET_PROCESSORCORE_CONFIGURATION             mSocketProcessorCoreConfiguration;
+extern EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE *mSpcrTable;
+extern EFI_GUID                                       gEfiGlobalVariableGuid;
+extern EFI_GUID                                       gEfiPmSsdtTableStorageGuid;
+
+BIOS_ACPI_PARAM       *mAcpiParameter = NULL;
+BOOLEAN               mFirstNotify;
+SYSTEM_CONFIGURATION  mSystemConfiguration;
+PCH_SETUP             mPchSetup;
+
+UINT8                       mKBPresent = 0;
+UINT8                       mMousePresent = 0;
+EFI_IIO_UDS_PROTOCOL        *mIioUds2 = NULL;
+extern CPU_CSR_ACCESS_VAR   *mCpuCsrAccessVarPtr;
+UINT8                       mPStateEnable = 0;
+
+
+VOID
+EFIAPI
+AcpiOnPciEnumCmplCallback (
+  IN EFI_EVENT  Event,
+  IN VOID      *Context
+  )
+{
+  EFI_STATUS    Status;
+
+  Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid, NULL, &Context);
+  if (EFI_ERROR (Status)) {
+    //
+    // Skip the first dummy event signal.
+    //
+    return;
+  }
+  gBS->CloseEvent (Event);
+
+  DEBUG ((DEBUG_INFO, "[ACPI] %a\n", __FUNCTION__));
+  AcpiVtdTablesInstall ();
+}
+
+
+VOID
+EFIAPI
+AcpiOnEndOfDxeCallback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  DEBUG ((DEBUG_INFO, "[ACPI] %a\n", __FUNCTION__));
+  //
+  // Installing ACPI Tables: NFIT, PCAT
+  //
+  InstallAndPatchAcpiTable (NVDIMM_FW_INTERFACE_TABLE_SIGNATURE);
+  InstallAndPatchAcpiTable (NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE_SIGNATURE);
+}
+
+
+//
+// Enable SCI for ACPI aware OS at ExitBootServices
+//
+VOID
+EFIAPI
+AcpiOnExitBootServicesCallback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  UINT16        Pm1Cnt;
+
+  gBS->CloseEvent (Event);
+
+  DEBUG ((DEBUG_INFO, "[ACPI] %a\n", __FUNCTION__));
+  //
+  // Enable SCI
+  //
+  Pm1Cnt = IoRead16 (mAcpiParameter->PmBase + R_ACPI_IO_PM1_CNT);
+  Pm1Cnt |= B_ACPI_IO_PM1_CNT_SCI_EN;
+  IoWrite16 (mAcpiParameter->PmBase + R_ACPI_IO_PM1_CNT, Pm1Cnt);
+}
+
+/**
+  Disables the SW SMI Timer.
+  ACPI events are disabled and ACPI event status is cleared.
+  SCI mode is then enabled.
+
+  Disable SW SMI Timer
+
+  Clear all ACPI event status and disable all ACPI events
+  Disable PM sources except power button
+  Clear status bits
+
+  Disable GPE0 sources
+  Clear status bits
+
+  Disable GPE1 sources
+  Clear status bits
+
+  Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
+
+  Enable SCI
+
+  @param Event   - not used
+  @param Context - not used
+
+  @retval None
+**/
+STATIC
+VOID
+AcpiEnableAtReadyToBoot (
+  VOID
+  )
+{
+  UINT32      SmiEn;
+  UINT8       Data8;
+  UINT16      Pm1En;
+
+  ASSERT (mAcpiParameter->PmBase != 0);
+
+  SmiEn = IoRead32 (mAcpiParameter->PmBase + R_ACPI_IO_SMI_EN);
+
+  //
+  // Disable SW SMI Timer and legacy USB
+  //
+  SmiEn &= ~(B_ACPI_IO_SMI_EN_SWSMI_TMR | B_ACPI_IO_SMI_EN_LEGACY_USB | B_ACPI_IO_SMI_EN_LEGACY_USB2);
+
+
+  //
+  // And enable SMI on write to B_ACPI_IO_PM1_CNT_SLP_EN when SLP_TYP is written
+  //
+  SmiEn |= B_ACPI_IO_SMI_EN_ON_SLP_EN;
+  IoWrite32(mAcpiParameter->PmBase + R_ACPI_IO_SMI_EN, SmiEn);
+
+  //
+  // Disable PM sources except power button
+  //
+
+  Pm1En = B_ACPI_IO_PM1_EN_PWRBTN;
+  IoWrite16(mAcpiParameter->PmBase + R_ACPI_IO_PM1_EN, Pm1En);
+
+  //
+  // Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
+  //
+  Data8 = RTC_ADDRESS_REGISTER_D;
+  IoWrite8(R_IOPORT_CMOS_STANDARD_INDEX, Data8);
+  Data8 = 0x0;
+  IoWrite8(R_IOPORT_CMOS_STANDARD_DATA, Data8);
+
+  //
+  // Do platform specific stuff for ACPI enable SMI
+  //
+
+
+}
+
+/**
+  Executes ACPI Platform actions related with ready to boot event
+
+  @param Event   - not used
+  @param Context - not used
+
+  @retval None
+**/
+STATIC
+VOID
+EFIAPI
+AcpiOnReadyToBootCallback (
+  IN     EFI_EVENT            Event,
+  IN     VOID                *Context
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_ACPI_DESCRIPTION_HEADER Table = {0};
+  EFI_ACPI_TABLE_VERSION      TableVersion;
+  UINTN                       TableHandle;
+  EFI_ACPI_TABLE_PROTOCOL     *AcpiTable;
+  EFI_CPUID_REGISTER          CpuidRegisters;
+  SETUP_DATA                  SetupData;
+  UINT8                       ARIForward;
+
+  DYNAMIC_SI_LIBARY_PROTOCOL  *DynamicSiLibraryProtocol = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &DynamicSiLibraryProtocol);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return;
+  }
+
+  if (mFirstNotify) {
+    return;
+  }
+  mFirstNotify = TRUE;
+  DEBUG ((DEBUG_INFO, "[ACPI] %a\n", __FUNCTION__));
+
+  Status = GetEntireConfig (&SetupData);
+  ASSERT_EFI_ERROR (Status);
+  CopyMem (&mSystemConfiguration, &(SetupData.SystemConfig), sizeof(SYSTEM_CONFIGURATION));
+  CopyMem (&mSocketIioConfiguration, &(SetupData.SocketConfig.IioConfig), sizeof(SOCKET_IIO_CONFIGURATION));
+  CopyMem (&mSocketPowermanagementConfiguration, &(SetupData.SocketConfig.PowerManagementConfig), sizeof(SOCKET_POWERMANAGEMENT_CONFIGURATION));
+  CopyMem (&mSocketProcessorCoreConfiguration, &(SetupData.SocketConfig.SocketProcessorCoreConfiguration), sizeof(SOCKET_PROCESSORCORE_CONFIGURATION));
+  CopyMem (&mPchSetup, &(SetupData.PchSetup), sizeof(PCH_SETUP));
+
+  mAcpiParameter->TpmEnable = mSystemConfiguration.TpmEnable;
+
+  //
+  // CpuPm.Asl: External (CSEN, FieldUnitObj)
+  //
+  mAcpiParameter->CStateEnable = TRUE;
+  //
+  // CpuPm.Asl: External (C3EN, FieldUnitObj)
+  //
+  mAcpiParameter->C3Enable     = mSocketPowermanagementConfiguration.C3Enable;
+  //
+  // CpuPm.Asl: External (C6EN, FieldUnitObj)
+  //
+  AsmCpuid (CPUID_MONITOR_MWAIT, &CpuidRegisters.RegEax, &CpuidRegisters.RegEbx, &CpuidRegisters.RegEcx, &CpuidRegisters.RegEdx);
+  //
+  // If C6 is not supported by CPU, disregard setup C6 knob value
+  //
+  if (((CpuidRegisters.RegEdx >> 12) & 0xF) > 0) {
+    if (mSocketPowermanagementConfiguration.C6Enable == PPM_AUTO) {
+      mAcpiParameter->C6Enable = 1;  // POR Default = Enabled
+    } else {
+      mAcpiParameter->C6Enable = mSocketPowermanagementConfiguration.C6Enable;
+    }
+  } else {
+    mAcpiParameter->C6Enable = 0;
+    DEBUG ((DEBUG_INFO, "Cpu does not support C6 state\n"));
+  }
+
+  if (mAcpiParameter->C6Enable && mAcpiParameter->C3Enable) {  //C3 and C6 enable are exclusive
+    mAcpiParameter->C6Enable = 1;
+    mAcpiParameter->C3Enable = 0;
+  }
+  //
+  // CpuPm.Asl: External (C7EN, FieldUnitObj)
+  //
+  mAcpiParameter->C7Enable     = 0;
+  //
+  // CpuPm.Asl: External (OSCX, FieldUnitObj)
+  //
+  mAcpiParameter->OSCX         = mSocketPowermanagementConfiguration.OSCx;
+  //
+  // CpuPm.Asl: External (MWOS, FieldUnitObj)
+  //
+  mAcpiParameter->MonitorMwaitEnable = 1;
+  //
+  // CpuPm.Asl: External (PSEN, FieldUnitObj)
+  //
+  mAcpiParameter->PStateEnable = mPStateEnable;
+  //
+  // CpuPm.Asl: External (HWAL, FieldUnitObj)
+  //
+  mAcpiParameter->HWAllEnable = mSocketPowermanagementConfiguration.ProcessorEistPsdFunc;
+
+  mAcpiParameter->KBPresent    = mKBPresent;
+  mAcpiParameter->MousePresent = mMousePresent;
+  mAcpiParameter->TStateEnable = mSocketPowermanagementConfiguration.TStateEnable;
+  //
+  // Debug mode indicator for Acpi use
+  //
+  mAcpiParameter->DebugModeIndicator = (UINT8)PcdGet8 (PcdDebugModeEnable);
+  DEBUG ((DEBUG_ERROR, "DebugModeIndicator = %x\n", mAcpiParameter->DebugModeIndicator));
+
+  //
+  // Fine grained T state
+  //
+  AsmCpuid (CPUID_THERMAL_POWER_MANAGEMENT,  &CpuidRegisters.RegEax, &CpuidRegisters.RegEbx, &CpuidRegisters.RegEcx, &CpuidRegisters.RegEdx);
+  if ((((CPUID_THERMAL_POWER_MANAGEMENT_EAX*)&CpuidRegisters.RegEax)->Bits.ECMD) && mSocketPowermanagementConfiguration.TStateEnable) {
+    mAcpiParameter->TStateFineGrained = 1;
+  }
+  if (((CPUID_THERMAL_POWER_MANAGEMENT_EAX*)&CpuidRegisters.RegEax)->Bits.HWP_Notification != 0) {
+    mAcpiParameter->HwpInterrupt = 1;
+  }
+  //
+  // CpuPm.Asl: External (HWEN, FieldUnitObj)
+  //
+  mAcpiParameter->HWPMEnable = DetectHwpFeature ();
+
+  mAcpiParameter->EmcaEn    = mSystemConfiguration.EmcaEn;
+  mAcpiParameter->WheaSupportEn  = mSystemConfiguration.WheaSupportEn;
+
+  mAcpiParameter->PcieAcpiHotPlugEnable = (UINT8) (BOOLEAN) (mSocketIioConfiguration.PcieAcpiHotPlugEnable != 0);
+  //
+  // Initialize USB3 mode from setup data
+  //
+  // If mode != manual control
+  //  just copy mode from setup
+  //
+  if (mPchSetup.PchUsbManualMode != 1) {
+    mAcpiParameter->XhciMode = mPchSetup.PchUsbManualMode;
+  }
+
+  //
+  // Get ACPI IO Base Address
+  //
+  mAcpiParameter->PmBase = DynamicSiLibraryProtocol->PmcGetAcpiBase ();
+  DEBUG ((DEBUG_INFO, "ACPI IO Base Address = %x\n", mAcpiParameter->PmBase));
+
+  //
+  // When X2APIC enabled and VTD support enabled, Enable ApicIdOverrided parameter to update ACPI table.
+  //
+  if (mSocketIioConfiguration.VTdSupport && mSocketProcessorCoreConfiguration.ProcessorX2apic) {
+    mAcpiParameter->ApicIdOverrided = 1;
+  }
+
+  //
+  // Find the AcpiTable protocol
+  //
+  Status = LocateSupportProtocol (
+            &gEfiAcpiTableProtocolGuid,
+            gEfiAcpiTableStorageGuid,
+            &AcpiTable,
+            FALSE
+            );
+
+  ASSERT_EFI_ERROR (Status);
+
+  TableVersion    = EFI_ACPI_TABLE_VERSION_2_0;
+  Table.Signature = EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE;
+  Status = PlatformUpdateTables ((EFI_ACPI_COMMON_HEADER *)&Table, &TableVersion);
+  if (!EFI_ERROR (Status)) {
+    //
+    // Add SPCR table
+    //
+    if (mSpcrTable != NULL) {
+      DEBUG ((DEBUG_INFO, "mSpcrTable->Header.Length=%d\n", mSpcrTable->Header.Length));
+      DEBUG ((DEBUG_INFO, "install=%x\n", &(AcpiTable->InstallAcpiTable)));
+      DEBUG ((DEBUG_INFO, "acpit=%x\n",   AcpiTable));
+      DEBUG ((DEBUG_INFO, "mSpcr=%x\n",   mSpcrTable));
+      DEBUG ((DEBUG_INFO, "len   =%d\n",  mSpcrTable->Header.Length));
+
+      TableHandle = 0;
+      Status = AcpiTable->InstallAcpiTable (
+        AcpiTable,
+        mSpcrTable,
+        mSpcrTable->Header.Length,
+        &TableHandle
+        );
+      ASSERT_EFI_ERROR (Status);
+    } else {
+      DEBUG ((DEBUG_INFO, "Warning: mSpcrTable is NULL\n"));
+    }
+  }
+  if (mSpcrTable != NULL) {
+    gBS->FreePool (mSpcrTable);
+  }
+
+  AcpiEnableAtReadyToBoot();
+
+  Status = GetOptionData (&gEfiSetupVariableGuid,  OFFSET_OF(SYSTEM_CONFIGURATION, ARIForward), &ARIForward, sizeof(UINT8));
+  ASSERT_EFI_ERROR (Status);
+  if (!ARIForward) {
+    DisableAriForwarding ();
+  }
+
+}
+
+
+/**
+  Installs ACPI Platform tables
+
+  @param None
+
+  @retval EFI_SUCCESS -  Operation completed successfully.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AcpiPlatformEarlyAcpiTablesInstall (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_STATUS                    AcpiStatus;
+  BOOLEAN                       Installed;
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL  *FwVol;
+  INTN                          Instance = 0;
+  EFI_ACPI_COMMON_HEADER        *CurrentTable;
+  EFI_ACPI_TABLE_VERSION        TableVersion;
+  UINTN                         TableHandle;
+  UINT32                        FvStatus;
+  UINT32                        Size;
+
+  //
+  // Find the AcpiTable protocol
+  //
+  Status = LocateSupportProtocol (
+            &gEfiAcpiTableProtocolGuid,
+            gEfiAcpiTableStorageGuid,
+            &AcpiTable,
+            FALSE
+            );
+
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Locate the firmware volume protocol
+  //
+  Status = LocateSupportProtocol (
+            &gEfiFirmwareVolume2ProtocolGuid,
+            gEfiAcpiTableStorageGuid,
+            &FwVol,
+            TRUE
+            );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Read tables from the storage file.
+  //
+  while (!EFI_ERROR (Status)) {
+    CurrentTable = NULL;
+    TableVersion = EFI_ACPI_TABLE_VERSION_NONE;
+    TableHandle = 0;
+    Installed = FALSE;
+
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      &gEfiAcpiTableStorageGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      &CurrentTable,
+                      (UINTN *) &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR (Status)) {
+
+      DEBUG ((DEBUG_INFO, "[ACPI] Table '%c%c%c%c' found in FwVol\n",
+              ((CHAR8*)&CurrentTable->Signature)[0], ((CHAR8*)&CurrentTable->Signature)[1],
+              ((CHAR8*)&CurrentTable->Signature)[2], ((CHAR8*)&CurrentTable->Signature)[3]));
+
+      //
+      // Check if table should be processed or will be updated later
+      //
+      if (CurrentTable->Signature != NVDIMM_FW_INTERFACE_TABLE_SIGNATURE
+          && CurrentTable->Signature != NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE_SIGNATURE
+          ) {
+        //
+        // Allow platform specific code to reject the table or update it
+        //
+        AcpiStatus = AcpiPlatformHooksIsActiveTable (CurrentTable); //SystemBoard);
+        if (!EFI_ERROR (AcpiStatus)) {
+          //
+          // Perform any table specific updates.
+          //
+          AcpiStatus = PlatformUpdateTables (CurrentTable, &TableVersion);
+          if (!EFI_ERROR (AcpiStatus)) {
+            //
+            // Add the table
+            //
+            if (TableVersion != EFI_ACPI_TABLE_VERSION_NONE) {
+              //
+              // Install the table
+              //
+              AcpiStatus = AcpiTable->InstallAcpiTable (AcpiTable, CurrentTable, CurrentTable->Length, &TableHandle);
+              if (!EFI_ERROR (AcpiStatus)) {
+                Installed = TRUE;
+              }
+              ASSERT_EFI_ERROR (AcpiStatus);
+            }
+          }
+        }
+      }
+      //
+      // Increment the instance
+      //
+      Instance++;
+    }
+  }
+
+  //
+  // Build any from-scratch ACPI tables. Halt on errors for debug builds, but
+  // for release builds it is safe to continue.
+  //
+  Status = PlatformBuildTables ();
+  ASSERT_EFI_ERROR (Status);
+  return EFI_SUCCESS;
+}
+
+/**
+  Installs ACPI Platform tables that wasn't installed in the early phase
+
+  @param None
+
+  @retval EFI_SUCCESS -  Operation completed successfully.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AcpiPlatformLateAcpiTablesInstall (
+  VOID
+  )
+{
+  //
+  // Install xHCI ACPI Table
+  //
+  InstallXhciAcpiTable ();
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Installs ACPI PmSsdt tables
+
+  @param None
+
+  @retval EFI_SUCCESS -  Operation completed successfully.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+PmSsdtEarlyAcpiTablesInstall (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_STATUS                    AcpiStatus;
+  BOOLEAN                       Installed;
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+  INTN                          Instance = 0;
+  EFI_ACPI_COMMON_HEADER        *CurrentTable;
+  EFI_ACPI_TABLE_VERSION        TableVersion;
+  UINTN                         TableHandle;
+  UINT32                        FvStatus;
+  UINT32                        Size;
+
+  //
+  // Find the AcpiTable protocol
+  //
+  Status = LocateSupportProtocol (
+            &gEfiAcpiTableProtocolGuid,
+            gEfiPmSsdtTableStorageGuid,
+            &AcpiTable,
+            FALSE
+            );
+
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Locate the firmware volume protocol
+  //
+  Status = LocateSupportProtocol (
+            &gEfiFirmwareVolume2ProtocolGuid,
+            gEfiPmSsdtTableStorageGuid,
+            &FwVol,
+            TRUE
+            );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Read tables from the storage file.
+  //
+  while (!EFI_ERROR (Status)) {
+    CurrentTable = NULL;
+    TableVersion = EFI_ACPI_TABLE_VERSION_NONE;
+    TableHandle = 0;
+    Installed = FALSE;
+
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      &gEfiPmSsdtTableStorageGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      &CurrentTable,
+                      (UINTN *) &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR (Status)) {
+      //
+      // Check if table should be processed or will be updated later
+      //
+      if (CurrentTable->Signature != NVDIMM_FW_INTERFACE_TABLE_SIGNATURE) {
+        //
+        // Allow platform specific code to reject the table or update it
+        //
+        AcpiStatus = AcpiPlatformHooksIsActiveTable (CurrentTable);
+        if (!EFI_ERROR (AcpiStatus)) {
+          //
+          // Perform any table specific updates.
+          //
+          AcpiStatus = PlatformUpdateTables (CurrentTable, &TableVersion);
+          if (!EFI_ERROR (AcpiStatus)) {
+            //
+            // Add the table
+            //
+            if (TableVersion != EFI_ACPI_TABLE_VERSION_NONE) {
+              //
+              // Install the table
+              //
+              AcpiStatus = AcpiTable->InstallAcpiTable (AcpiTable, CurrentTable, CurrentTable->Length, &TableHandle);
+              if (!EFI_ERROR (AcpiStatus)) {
+                Installed = TRUE;
+              }
+              ASSERT_EFI_ERROR (AcpiStatus);
+            }
+          }
+        }
+      }
+      //
+      // Increment the instance
+      //
+      Instance++;
+    }
+  }
+  return EFI_SUCCESS;
+} // PmSsdtEarlyAcpiTablesInstall()
+
+
+/**
+  Entry point for Acpi platform driver.
+
+  @param ImageHandle  -  A handle for the image that is initializing this driver.
+  @param SystemTable  -  A pointer to the EFI system table.
+
+  @retval EFI_SUCCESS           -  Driver initialized successfully.
+  @retval EFI_LOAD_ERROR        -  Failed to Initialize or has been loaded.
+  @retval EFI_OUT_OF_RESOURCES  -  Could not allocate needed resources.
+**/
+EFI_STATUS
+EFIAPI
+AcpiPlatformEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  EFI_EVENT   Event;
+  VOID        *HobList;
+  VOID        *RgstPtr;
+
+  DYNAMIC_SI_LIBARY_PROTOCOL  *DynamicSiLibraryProtocol = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &DynamicSiLibraryProtocol);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  mFirstNotify = FALSE;
+  //
+  // Report Status Code to indicate Acpi Init
+  //
+  REPORT_STATUS_CODE (
+    EFI_PROGRESS_CODE,
+    (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_BS_ACPI_INIT)
+    );
+
+  Status = gBS->LocateProtocol (&gEfiIioUdsProtocolGuid, NULL, &mIioUds2);
+  if (EFI_ERROR (Status)) {
+
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  mCpuCsrAccessVarPtr = DynamicSiLibraryProtocol->GetSysCpuCsrAccessVar ();
+  //
+  // Update HOB variable for PCI resource information
+  // Get the HOB list.  If it is not present, then ASSERT.
+  //
+  Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize Platform Hooks
+  //
+  PlatformHookInit ();
+
+  //
+  // Install ACPI PLatform Tables
+  //
+  Status = AcpiPlatformEarlyAcpiTablesInstall ();
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install ACPI PMSsdt Tables
+  //
+  Status = PmSsdtEarlyAcpiTablesInstall ();
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install ACPI PLatform Tables that wasn't installed yet (NFIT/xHCI)
+  //
+  Status = AcpiPlatformLateAcpiTablesInstall ();
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Register ready to boot event handler
+  //
+  Status = EfiCreateEventReadyToBootEx (TPL_NOTIFY, AcpiOnReadyToBootCallback, NULL, &Event);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Create PCI Enumeration Completed callback.
+  //
+  Event = EfiCreateProtocolNotifyEvent (&gEfiPciEnumerationCompleteProtocolGuid, TPL_CALLBACK,
+                                        AcpiOnPciEnumCmplCallback, NULL, &RgstPtr);
+  ASSERT (Event != NULL);
+
+  //
+  // Register EndOfDxe handler
+  //
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  AcpiOnEndOfDxeCallback,
+                  NULL,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &Event
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Register ExitBootServicesEvent handler
+  //
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  AcpiOnExitBootServicesCallback,
+                  NULL,
+                  &gEfiEventExitBootServicesGuid,
+                  &Event
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+} // AcpiPlatformEntryPoint()
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.h b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.h
new file mode 100644
index 0000000000..162c162df8
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.h
@@ -0,0 +1,117 @@
+/** @file
+
+  @copyright
+  Copyright 1999 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_PLATFORM_H_
+#define _ACPI_PLATFORM_H_
+
+//
+// Statements that include other header files
+//
+#include <PiDxe.h>
+#include <PchAccess.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
+#include <IndustryStandard/DmaRemappingReportingTable.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/AcpiPlatformLib.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Protocol/IioUds.h>
+#include <Protocol/DmaRemap.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/SerialIo.h>
+  #include <Protocol/MpService.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Guid/PlatformInfo.h>
+#include <Guid/SetupVariable.h>
+#include <PchSetupVariable.h>
+#include <Guid/SocketVariable.h>
+#include <Guid/HobList.h>
+#include <Guid/MemoryMapData.h>
+#include <Protocol/PlatformType.h>
+#include <Protocol/CpuCsrAccess.h>
+#include <PpmPolicyPeiDxeCommon.h>
+#include <Acpi/Mcfg.h>
+#include <Acpi/Hpet.h>
+#include <Acpi/Srat.h>
+#include <Acpi/Slit.h>
+#include <Acpi/Migt.h>
+#include <Acpi/Msct.h>
+#include <Acpi/Bdat.h>
+#include <Acpi/Nfit.h>
+#include <Acpi/Pcat.h>
+#include "Platform.h"
+#include <AcpiVtd.h>
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/PchInfoLib.h>
+#include <Library/ReportStatusCodeLib.h>
+
+#include <SystemBoard.h>
+#include <PchAccess.h>
+#include <UncoreCommonIncludes.h>
+
+#include <SystemInfoVar.h>
+#include <Register/Cpuid.h>
+#include <Library/PlatformStatusCodes.h>
+#include <Protocol/DynamicSiLibraryProtocol.h>
+#include <Protocol/DynamicSiLibraryProtocol2.h>
+#include <Protocol/DmaRemap.h>
+
+#define RTC_ADDRESS_REGISTER_D                      13
+
+
+/**
+  Entry point for Acpi platform driver.
+
+  @param ImageHandle  -  A handle for the image that is initializing this driver.
+  @param SystemTable  -  A pointer to the EFI system table.
+
+  @retval EFI_SUCCESS           -  Driver initialized successfully.
+  @retval EFI_LOAD_ERROR        -  Failed to Initialize or has been loaded.
+  @retval EFI_OUT_OF_RESOURCES  -  Could not allocate needed resources.
+**/
+EFI_STATUS
+EFIAPI
+AcpiPlatformEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+EFI_STATUS
+LocateSupportProtocol (
+  IN   EFI_GUID       *Protocol,
+  IN   EFI_GUID       gEfiAcpiMultiTableStorageGuid,
+  OUT  VOID           **Instance,
+  IN   UINT32         Type
+  );
+
+VOID
+AcpiVtdIntRemappingEnable (
+  VOID
+  );
+
+EFI_STATUS
+AcpiVtdTablesInstall (
+  VOID
+  );
+
+#endif // _ACPI_PLATFORM_H_
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.inf b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.inf
new file mode 100644
index 0000000000..f4980ede74
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.inf
@@ -0,0 +1,107 @@
+## @file
+#
+# @copyright
+# Copyright 2009 - 2020 Intel Corporation. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                   = 0x00010005
+  BASE_NAME                     = AcpiPlatform
+  FILE_GUID                     = 87AB821C-79B8-4ef6-A913-21D22063F55F
+  MODULE_TYPE                   = DXE_DRIVER
+  VERSION_STRING                = 1.0
+  ENTRY_POINT                   = AcpiPlatformEntryPoint
+
+[Sources]
+  AcpiPlatform.c
+  AcpiPlatform.h
+  AcpiPlatformUtils.c
+  AcpiPlatformUtils.h
+  AcpiPlatformHooks.c
+  AcpiPlatformHooks.h
+  AcpiPlatformVTDHooks.c
+
+[Packages]
+  WhitleyOpenBoardPkg/PlatformPkg.dec
+  WhitleySiliconPkg/SiliconPkg.dec
+  WhitleySiliconPkg/Cpu/CpuRcPkg.dec
+  WhitleySiliconPkg/CpRcPkg.dec
+  WhitleySiliconPkg/WhitleySiliconPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  BaseMemoryLib
+  DebugLib
+  UefiLib
+  UefiRuntimeServicesTableLib
+  HobLib
+  SetupLib
+  AcpiPlatformTableLib
+  ReportStatusCodeLib
+  PcdLib
+  LocalApicLib
+
+[Protocols]
+  gEfiMpServiceProtocolGuid
+  gEfiIioUdsProtocolGuid
+  gEfiGlobalNvsAreaProtocolGuid
+  gEfiPciEnumerationCompleteProtocolGuid
+  gEfiPciIoProtocolGuid
+  gEfiFirmwareVolume2ProtocolGuid
+  gEfiAcpiTableProtocolGuid             # ALWAYS_CONSUMED; before was gEfiAcpiSupportProtocolGuid
+  gEfiSerialIoProtocolGuid
+  gDxeEnhancedSpeedstepProtocolGuid
+  gEfiPlatformTypeProtocolGuid
+  gDmaRemapProtocolGuid
+  gEfiCrystalRidgeGuid
+  gEfiSmbiosProtocolGuid
+  gEfiPciRootBridgeIoProtocolGuid
+  gAcpiPlatformProtocolGuid
+  gDynamicSiLibraryProtocolGuid                 ## CONSUMES
+  gDynamicSiLibraryProtocol2Guid                ## CONSUMES
+
+[Guids]
+  gEfiGlobalVariableGuid
+  gEfiAcpiTableStorageGuid
+  gEfiPmSsdtTableStorageGuid
+  gEfiPcAnsiGuid
+  gEfiVT100PlusGuid
+  gEfiVT100Guid
+  gEfiVTUTF8Guid
+  gEfiHobListGuid
+  gEfiPlatformInfoGuid
+  gEfiSetupVariableGuid
+  gEfiEndOfDxeEventGroupGuid
+  gEfiEventExitBootServicesGuid
+  gEfiSocketIioVariableGuid
+  gEfiSocketMemoryVariableGuid
+  gEfiSocketCommonRcVariableGuid
+  gEfiSocketMpLinkVariableGuid
+  gEfiSocketPowermanagementVarGuid
+  gEfiSocketProcessorCoreVarGuid
+  gPchInfoHobGuid             ## CONSUMES
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+  gOemSkuTokenSpaceGuid.PcdOemTableIdXhci
+  gPlatformTokenSpaceGuid.PcdDebugModeEnable  ## CONSUMES
+
+[FixedPcd]
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuCoreCount
+
+[Depex]
+  gDynamicSiLibraryProtocolGuid AND
+  gDynamicSiLibraryProtocol2Guid AND
+  gDmaRemapProtocolGuid AND
+  gEfiAcpiTableProtocolGuid AND
+  gEfiMpServiceProtocolGuid AND
+  gEfiIioSystemProtocolGuid AND
+  gSmbiosMemInfoProtocolGuid
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.c b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.c
new file mode 100644
index 0000000000..93f312a178
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.c
@@ -0,0 +1,384 @@
+/** @file
+  ACPI Platform Driver Hooks
+
+  @copyright
+  Copyright 1996 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "AcpiPlatform.h"
+#include "AcpiPlatformUtils.h"
+#include "AcpiPlatformHooks.h"
+
+#ifndef __GNUC__
+#pragma optimize("",off)
+#endif  //__GNUC__
+
+extern BOOLEAN                        mX2ApicEnabled;
+extern UINT32                         mNumOfBitShift;
+extern EFI_PLATFORM_INFO              *mPlatformInfo;
+extern BIOS_ACPI_PARAM                *mAcpiParameter;
+extern EFI_IIO_UDS_PROTOCOL           *mIioUds2;
+extern CPU_CSR_ACCESS_VAR             *mCpuCsrAccessVarPtr;
+
+extern SOCKET_MEMORY_CONFIGURATION    mSocketMemoryConfiguration;
+extern SOCKET_MP_LINK_CONFIGURATION   mSocketMpLinkConfiguration;
+extern SOCKET_COMMONRC_CONFIGURATION  mSocketCommonRcConfiguration;
+extern SOCKET_IIO_CONFIGURATION       mSocketIioConfiguration;
+
+extern SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanagementConfiguration;
+extern SOCKET_PROCESSORCORE_CONFIGURATION   mSocketProcessorCoreConfiguration;
+
+extern SYSTEM_CONFIGURATION           mSystemConfiguration;
+extern PCH_SETUP                      mPchSetup;
+extern BOOLEAN                        Is14nmCpu;
+
+EFI_GLOBAL_NVS_AREA_PROTOCOL        mGlobalNvsArea;
+
+
+EFI_STATUS
+PlatformHookInit (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_HANDLE                    Handle;
+  EFI_PHYSICAL_ADDRESS          AcpiParameterAddr;
+  EFI_CPUID_REGISTER            CpuidRegisters;
+  SETUP_DATA                    SetupData;
+
+  ASSERT (mIioUds2);
+
+  Status = EFI_SUCCESS;
+
+  Status = GetEntireConfig (&SetupData);
+
+  CopyMem (&mSocketMemoryConfiguration, &(SetupData.SocketConfig.MemoryConfig), sizeof(SOCKET_MEMORY_CONFIGURATION));
+  CopyMem (&mSocketMpLinkConfiguration, &(SetupData.SocketConfig.UpiConfig), sizeof(SOCKET_MP_LINK_CONFIGURATION));
+  CopyMem (&mSocketCommonRcConfiguration, &(SetupData.SocketConfig.CommonRcConfig), sizeof(SOCKET_COMMONRC_CONFIGURATION));
+  CopyMem (&mSocketPowermanagementConfiguration, &(SetupData.SocketConfig.PowerManagementConfig), sizeof(SOCKET_POWERMANAGEMENT_CONFIGURATION));
+  CopyMem (&mSocketProcessorCoreConfiguration, &(SetupData.SocketConfig.SocketProcessorCoreConfiguration), sizeof(SOCKET_PROCESSORCORE_CONFIGURATION));
+  CopyMem (&mSystemConfiguration, &(SetupData.SystemConfig), sizeof(SYSTEM_CONFIGURATION));
+  CopyMem (&mSocketIioConfiguration, &(SetupData.SocketConfig.IioConfig), sizeof(SOCKET_IIO_CONFIGURATION));
+  CopyMem (&mPchSetup, &(SetupData.PchSetup), sizeof(PCH_SETUP));
+
+  if (EFI_ERROR (Status)) {
+    mSocketPowermanagementConfiguration.ProcessorEistEnable = 0;
+    mSocketPowermanagementConfiguration.TurboMode           = 0;
+    mSocketPowermanagementConfiguration.PackageCState       = 0;
+    mSocketPowermanagementConfiguration.PwrPerfTuning       = PWR_PERF_TUNING_BIOS_CONTROL;
+    mSocketProcessorCoreConfiguration.ProcessorX2apic         = 0;
+    mSocketProcessorCoreConfiguration.ForcePhysicalModeEnable = 0;
+  }
+  //
+  // If Emulation flag set by InitializeDefaultData in ProcMemInit.c
+  //  force X2APIC
+  // Else read setup data
+  //
+  mX2ApicEnabled = mSocketProcessorCoreConfiguration.ProcessorX2apic;
+
+  //
+  // Force x2APIC if the system is configured as X2APIC; or CPU hotplug is enabled.
+  //
+  if ((GetApicMode () == LOCAL_APIC_MODE_X2APIC) || (mIioUds2->IioUdsPtr->SystemStatus.OutKtiCpuSktHotPlugEn)) {
+    mX2ApicEnabled = TRUE;
+  }
+
+  //
+  // Allocate 256 runtime memory to pass ACPI parameter
+  // This Address must be < 4G because we only have 32bit in the dsdt
+  //
+  AcpiParameterAddr = 0xffffffff;
+  Status = gBS->AllocatePages (
+                  AllocateMaxAddress,
+                  EfiACPIMemoryNVS,
+                  EFI_SIZE_TO_PAGES (sizeof(BIOS_ACPI_PARAM)),
+                  &AcpiParameterAddr
+                  );
+  ASSERT_EFI_ERROR (Status);
+  mAcpiParameter = (BIOS_ACPI_PARAM *)AcpiParameterAddr;
+
+  DEBUG ((DEBUG_INFO, "ACPI Parameter Block Address: 0x%X\n", mAcpiParameter));
+
+  ZeroMem (mAcpiParameter, sizeof (BIOS_ACPI_PARAM));
+  mAcpiParameter->PlatformId    = (UINT32)mPlatformInfo->BoardId;
+  mAcpiParameter->IoApicEnable  = mPlatformInfo->SysData.SysIoApicEnable;
+  mAcpiParameter->PchIoApic_24_119 = mPchSetup.PchIoApic24119Entries;
+
+  Handle = NULL;
+  mGlobalNvsArea.Area = mAcpiParameter;
+  gBS->InstallProtocolInterface (
+         &Handle,
+         &gEfiGlobalNvsAreaProtocolGuid,
+         EFI_NATIVE_INTERFACE,
+         &mGlobalNvsArea
+         );
+  ASSERT_EFI_ERROR (Status);
+
+  AsmCpuid (CPUID_VERSION_INFO,  &CpuidRegisters.RegEax, &CpuidRegisters.RegEbx, &CpuidRegisters.RegEcx, &CpuidRegisters.RegEdx);
+  mAcpiParameter->ProcessorId = (CpuidRegisters.RegEax & 0xFFFF0);
+
+  //
+  // support up to 64 threads/socket
+  //
+  AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 1, &mNumOfBitShift, NULL, NULL, NULL);
+  mNumOfBitShift &= 0x1F;
+
+  //
+  // Set the bit shift value for CPU SKU
+  //
+  mAcpiParameter->CpuSkuNumOfBitShift = (UINT8) mNumOfBitShift;
+
+  mAcpiParameter->ProcessorApicIdBase[0] = (UINT32) (0 << mNumOfBitShift);
+  mAcpiParameter->ProcessorApicIdBase[1] = (UINT32) (1 << mNumOfBitShift);
+  mAcpiParameter->ProcessorApicIdBase[2] = (UINT32) (2 << mNumOfBitShift);
+  mAcpiParameter->ProcessorApicIdBase[3] = (UINT32) (3 << mNumOfBitShift);
+  mAcpiParameter->ProcessorApicIdBase[4] = (UINT32) (4 << mNumOfBitShift);
+  mAcpiParameter->ProcessorApicIdBase[5] = (UINT32) (5 << mNumOfBitShift);
+  mAcpiParameter->ProcessorApicIdBase[6] = (UINT32) (6 << mNumOfBitShift);
+  mAcpiParameter->ProcessorApicIdBase[7] = (UINT32) (7 << mNumOfBitShift);
+
+  //
+  // If SNC is enabled, and NumOfCluster is 2, set the ACPI variable for PXM value
+  //
+  if (mIioUds2->IioUdsPtr->SystemStatus.OutSncEn) {
+    mAcpiParameter->SncAnd2Cluster = mIioUds2->IioUdsPtr->SystemStatus.OutNumOfCluster;
+  }
+
+   mAcpiParameter->MmCfg = (UINT32)mIioUds2->IioUdsPtr->PlatformData.PciExpressBase;
+   mAcpiParameter->TsegSize = (UINT32)(mIioUds2->IioUdsPtr->PlatformData.MemTsegSize >> 20);
+
+  Status = PlatformHookAfterAcpiParamInit ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "PlatformHookAfterAcpiParamInit() failed with Status: %r\n", Status));
+  }
+
+  return Status;
+}
+
+
+/**
+  Install and patch specific ACPI Table
+
+  @param AcpiTableSignature
+
+  @retval None
+**/
+VOID
+InstallAndPatchAcpiTable (
+  UINT32 AcpiTableSignature
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
+  EFI_ACPI_TABLE_VERSION        TableVersion;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+  EFI_ACPI_COMMON_HEADER        *CurrentTable = NULL;
+  UINT32                        FvStatus;
+  UINTN                         Size;
+  UINTN                         TableHandle = 0;
+  INTN                          Instance = 0;
+
+  DEBUG ((DEBUG_INFO, "InstallAndPatchAcpiTable '%c%c%c%c'\n",
+          ((CHAR8*)&AcpiTableSignature)[0], ((CHAR8*)&AcpiTableSignature)[1],
+          ((CHAR8*)&AcpiTableSignature)[2], ((CHAR8*)&AcpiTableSignature)[3]));
+
+  Status = LocateSupportProtocol (
+            &gEfiAcpiTableProtocolGuid,
+            gEfiAcpiTableStorageGuid,
+            &AcpiTable,
+            FALSE
+            );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = LocateSupportProtocol (
+            &gEfiFirmwareVolume2ProtocolGuid,
+            gEfiAcpiTableStorageGuid,
+            &FwVol,
+            TRUE
+            );
+  ASSERT_EFI_ERROR (Status);
+
+  while (!EFI_ERROR (Status)) {
+
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      &gEfiAcpiTableStorageGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      &CurrentTable,
+                      (UINTN *) &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR (Status)) {
+      if (CurrentTable->Signature == AcpiTableSignature) {
+
+        Status = AcpiPlatformHooksIsActiveTable (CurrentTable);
+        if (!EFI_ERROR (Status)) {
+
+          Status = PlatformUpdateTables (CurrentTable, &TableVersion);
+          if (!EFI_ERROR (Status)) {
+
+            if (TableVersion != EFI_ACPI_TABLE_VERSION_NONE) {
+              Status = AcpiTable->InstallAcpiTable (
+                                        AcpiTable,
+                                        CurrentTable,
+                                        CurrentTable->Length,
+                                        &TableHandle
+                                        );
+            }
+          }
+          ASSERT_EFI_ERROR (Status);
+        } else {
+          DEBUG ((DEBUG_ERROR, "No Table for current platform\n"));
+        }
+      }
+
+      CurrentTable = NULL;
+      Instance++;
+    }
+  }
+}
+
+
+/**
+  Install Xhci ACPI Table
+
+**/
+VOID
+InstallXhciAcpiTable (
+  VOID
+  )
+{
+  EFI_HANDLE                    *HandleBuffer;
+  EFI_STATUS                    Status;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+  EFI_ACPI_COMMON_HEADER        *CurrentTable;
+  UINT32                        FvStatus;
+  UINTN                         Size;
+  UINTN                         TableHandle;
+  INTN                          Instance;
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
+  EFI_ACPI_DESCRIPTION_HEADER   *TableHeader;
+  UINT64                        XhciAcpiTable;
+  UINT64                        *XhciAcpiTablePtr;
+  UINT64                        TempOemTableId;
+
+  HandleBuffer  = 0;
+  Instance      = 0;
+  TableHandle   = 0;
+  CurrentTable  = NULL;
+  FwVol         = NULL;
+  XhciAcpiTable = 0;
+
+  DEBUG ((DEBUG_INFO, "InstallXhciAcpiTable\n"));
+
+
+  XhciAcpiTablePtr = (UINT64*)PcdGetPtr (PcdOemTableIdXhci);
+  if (XhciAcpiTablePtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "XhciAcpiTablePtr is NULL\n"));
+    ASSERT (XhciAcpiTablePtr != NULL);
+    return;
+  }
+
+  XhciAcpiTable = *XhciAcpiTablePtr;
+
+  //
+  // Find the AcpiSupport protocol
+  //
+  Status = LocateSupportProtocol (
+            &gEfiAcpiTableProtocolGuid,
+            gEfiAcpiTableStorageGuid,
+            &AcpiTable,
+            FALSE
+            );
+
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Locate the firmware volume protocol
+  //
+  Status = LocateSupportProtocol (
+            &gEfiFirmwareVolume2ProtocolGuid,
+            gEfiAcpiTableStorageGuid,
+            &FwVol,
+            TRUE
+            );
+
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Read tables from the storage file.
+  //
+  while (Status == EFI_SUCCESS) {
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      &gEfiAcpiTableStorageGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      &CurrentTable,
+                      &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR (Status)) {
+
+      TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
+
+      if (TableHeader->OemTableId == XhciAcpiTable) {
+        DEBUG ((DEBUG_INFO, "Install xhci table: %x\n", TableHeader->OemTableId));
+
+        TempOemTableId  = PcdGet64 (PcdAcpiDefaultOemTableId);
+
+        CopyMem (TableHeader->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof(TableHeader->OemId));
+        CopyMem (&TableHeader->OemTableId, &TempOemTableId, sizeof(TableHeader->OemTableId));
+
+        TableHeader->CreatorId = EFI_ACPI_CREATOR_ID;
+        TableHeader->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
+
+        //
+        // Add the table
+        //
+        TableHandle = 0;
+
+        Status = AcpiTable->InstallAcpiTable (
+                                    AcpiTable,
+                                    CurrentTable,
+                                    CurrentTable->Length,
+                                    &TableHandle
+                                    );
+        break;
+      }
+
+      //
+      // Increment the instance
+      //
+
+      Instance++;
+      CurrentTable = NULL;
+    }
+  }
+}
+
+UINT8
+EFIAPI
+DetectHwpFeature (
+   VOID
+  )
+{
+  EFI_STATUS                       Status;
+  DYNAMIC_SI_LIBARY_PROTOCOL2      *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return FALSE;
+  }
+
+  return DynamicSiLibraryProtocol2->DetectHwpFeature ();
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.h b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.h
new file mode 100644
index 0000000000..2201dd5316
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.h
@@ -0,0 +1,51 @@
+/** @file
+
+  @copyright
+  Copyright 1996 - 2020 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_PLATFORM_HOOKS_H_
+#define _ACPI_PLATFORM_HOOKS_H_
+
+//
+// Statements that include other header files
+//
+#include <PiDxe.h>
+#include <Library/CpuConfigLib.h>
+#include <Library/SetupLib.h>
+#include <Library/LocalApicLib.h>
+
+EFI_STATUS
+PlatformHookInit (
+  VOID
+  );
+
+VOID
+DisableAriForwarding (
+  VOID
+  );
+
+EFI_STATUS
+AllocateRasfSharedMemory (
+  VOID
+  );
+
+UINT8
+EFIAPI
+DetectHwpFeature (
+  VOID
+  );
+
+VOID
+InstallAndPatchAcpiTable (
+  UINT32
+  );
+
+VOID
+InstallXhciAcpiTable (
+  VOID
+  );
+
+#endif
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.c b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.c
new file mode 100644
index 0000000000..27a9803fcc
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.c
@@ -0,0 +1,133 @@
+/** @file
+  ACPI Platform Utilities
+
+  @copyright
+  Copyright 2017 - 2018 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "AcpiPlatformUtils.h"
+#include <IndustryStandard/Acpi.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+
+#include <Protocol/FirmwareVolume2.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Acpi/Mcfg.h>
+#include <Acpi/Hpet.h>
+#include <Acpi/Srat.h>
+#include <Acpi/Slit.h>
+#include <Acpi/Migt.h>
+#include <Acpi/Msct.h>
+#include <Acpi/Bdat.h>
+
+/**
+  Locate the first instance of a protocol.  If the protocol requested is an
+  FV protocol, then it will return the first FV that contains the ACPI table
+  storage file.
+
+  @param[in]  Protocol            - The protocol to find.
+  @param[in]  EfiAcpiStorageGuid  - EFI ACPI tables storage guid
+  @param[out] Instance            -  Return pointer to the first instance of the protocol.
+  @param[in]  Type                -  The type of protocol to locate.
+
+  @retval EFI_SUCCESS           -  The function completed successfully.
+  @retval EFI_NOT_FOUND         -  The protocol could not be located.
+  @retval EFI_OUT_OF_RESOURCES  -  There are not enough resources to find the protocol.
+**/
+EFI_STATUS
+LocateSupportProtocol (
+  IN   EFI_GUID       *Protocol,
+  IN   EFI_GUID       EfiAcpiStorageGuid,
+  OUT  VOID           **Instance,
+  IN   UINT32         Type
+  )
+{
+  EFI_STATUS              Status;
+  EFI_HANDLE              *HandleBuffer;
+  UINTN                   NumberOfHandles;
+  EFI_FV_FILETYPE         FileType;
+  UINT32                  FvStatus;
+  EFI_FV_FILE_ATTRIBUTES  Attributes;
+  UINTN                   Size;
+  UINTN                   Index;
+
+  FvStatus = 0;
+  //
+  // Locate protocol.
+  //
+  Status = gBS->LocateHandleBuffer (
+                                    ByProtocol,
+                                    Protocol,
+                                    NULL,
+                                    &NumberOfHandles,
+                                    &HandleBuffer
+                                    );
+  if (EFI_ERROR (Status)) {
+    //
+    // Defined errors at this time are not found and out of resources.
+    //
+    return Status;
+  }
+  //
+  // Looking for FV with ACPI storage file
+  //
+  for (Index = 0; Index < NumberOfHandles; Index++) {
+    //
+    // Get the protocol on this handle
+    // This should not fail because of LocateHandleBuffer
+    //
+    Status = gBS->HandleProtocol (
+                                  HandleBuffer[Index],
+                                  Protocol,
+                                  Instance
+                                  );
+    ASSERT (!EFI_ERROR (Status));
+
+    if (!Type) {
+      //
+      // Not looking for the FV protocol, so find the first instance of the
+      // protocol.  There should not be any errors because our handle buffer
+      // should always contain at least one or LocateHandleBuffer would have
+      // returned not found.
+      //
+      break;
+    }
+    //
+    // See if it has the ACPI storage file
+    //
+    Status = ((EFI_FIRMWARE_VOLUME2_PROTOCOL *) (*Instance))->ReadFile (
+                                                                        *Instance,
+                                                                        &EfiAcpiStorageGuid,
+                                                                        NULL,
+                                                                        &Size,
+                                                                        &FileType,
+                                                                        &Attributes,
+                                                                        &FvStatus
+                                                                        );
+
+    //
+    // If we found it, then we are done
+    //
+    if (!EFI_ERROR (Status)) {
+      break;
+    }
+  }
+  //
+  // Our exit status is determined by the success of the previous operations
+  // If the protocol was found, Instance already points to it.
+  //
+  //
+  // Free any allocated buffers
+  //
+  gBS->FreePool (HandleBuffer);
+
+  return Status;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.h b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.h
new file mode 100644
index 0000000000..50a5f0471e
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.h
@@ -0,0 +1,66 @@
+/** @file
+
+  @copyright
+  Copyright 2017 - 2018 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_PLATFORM_UTILS_H_
+#define _ACPI_PLATFORM_UTILS_H_
+
+extern EFI_GUID gEfiAcpiTableStorageGuid;
+
+
+/**
+  Function checks if ACPI Platform Protocol is ready to install
+
+  @param None
+
+  @retval TRUE  ACPI Platform Protocol can be installed,
+          FALSE ACPI Platform Protocol not ready yet
+
+**/
+BOOLEAN
+IsAcpiPlatformProtocolReadyForInstall (
+  VOID
+  );
+
+/**
+  Function checks if ACPI Platform Protocol is already installed
+
+  @param None
+
+  @retval TRUE  ACPI Platform Protocol is installed,
+          FALSE ACPI Platform Protocol not installed yet
+
+**/
+BOOLEAN
+IsAcpiPlatformProtocolInstalled (
+  VOID
+  );
+
+/**
+  Locate the first instance of a protocol.  If the protocol requested is an
+  FV protocol, then it will return the first FV that contains the ACPI table
+  storage file.
+
+  @param[in]  Protocol            - The protocol to find.
+  @param[in]  EfiAcpiStorageGuid  - EFI ACPI tables storage guid
+  @param[out] Instance            - Return pointer to the first instance of the protocol.
+  @param[in]  Type                - The type of protocol to locate.
+
+  @retval EFI_SUCCESS           -  The function completed successfully.
+  @retval EFI_NOT_FOUND         -  The protocol could not be located.
+  @retval EFI_OUT_OF_RESOURCES  -  There are not enough resources to find the protocol.
+
+**/
+EFI_STATUS
+LocateSupportProtocol (
+  IN   EFI_GUID       *Protocol,
+  IN   EFI_GUID       EfiAcpiStorageGuid,
+  OUT  VOID           **Instance,
+  IN   UINT32         Type
+  );
+
+#endif // _ACPI_PLATFORM_UTILS_H_
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformVTDHooks.c b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformVTDHooks.c
new file mode 100644
index 0000000000..a517a9adce
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformVTDHooks.c
@@ -0,0 +1,1762 @@
+/** @file
+  ACPI Platform Driver VT-D Hooks
+
+  @copyright
+  Copyright 2012 - 2021 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "AcpiPlatform.h"
+#include "AcpiPlatformHooks.h"
+#include <Protocol/PciRootBridgeIo.h>
+#include <UncoreCommonIncludes.h>
+#include <IioSetupDefinitions.h>
+#include <PchInfoHob.h>
+
+extern EFI_PLATFORM_INFO                    *mPlatformInfo;
+extern BIOS_ACPI_PARAM                      *mAcpiParameter;
+extern EFI_IIO_UDS_PROTOCOL                 *mIioUds2;
+extern CPU_CSR_ACCESS_VAR                   *mCpuCsrAccessVarPtr;
+extern SYSTEM_CONFIGURATION                 mSystemConfiguration;
+extern SOCKET_IIO_CONFIGURATION             mSocketIioConfiguration;
+extern SOCKET_PROCESSORCORE_CONFIGURATION   mSocketProcessorCoreConfiguration;
+extern EFI_GUID                             mSystemConfigurationGuid;
+extern BOOLEAN                              mX2ApicEnabled;
+
+
+#define EFI_PCI_CAPABILITY_PTR              0x34
+#define EFI_PCIE_CAPABILITY_BASE_OFFSET     0x100
+#define EFI_PCIE_CAPABILITY_ID_ACS          0x000D
+#define EFI_PCI_CAPABILITY_ID_PCIEXP        0x10
+#define EFI_PCI_EXPRESS_CAPABILITY_REGISTER 0x02
+
+#define ACS_CAPABILITY_REGISTER             0x04
+#define ACS_SOURCE_VALIDATION               BIT0
+#define ACS_P2P_REQUEST_REDIRECT            BIT2
+#define ACS_P2P_COMPLETION_REDIRECT         BIT3
+#define ACS_UPSTREAM_FORWARDING             BIT4
+
+#define ACS_CONTROL_REGISTER                0x06
+#define ACS_SOURCE_VALIDATION_ENABLE        BIT0
+#define ACS_P2P_REQUEST_REDIRECT_ENABLE     BIT2
+#define ACS_P2P_COMPLETION_REDIRECT_ENABLE  BIT3
+#define ACS_UPSTREAM_FORWARDING_ENABLE      BIT4
+
+#define R_VTD_GCMD_REG                      0x18
+#define R_VTD_GSTS_REG                      0x1C
+#define R_VTD_IQT_REG                       0x88
+#define R_VTD_IQA_REG                       0x90
+#define R_VTD_IRTA_REG                      0xB8
+
+#define VTD_ISOCH_ENGINE_OFFSET             0x1000
+
+//
+// a flag to indicate if we should disable Vt-d for ACS WA
+//
+BOOLEAN                                     mDisableVtd = FALSE;
+
+DMA_REMAP_PROTOCOL                          DmaRemapProt;
+#define  VTD_SUPPORT_INSTANCE_FROM_THIS(a)  CR(a, VTD_SUPPORT_INSTANCE, DmaRemapProt, EFI_ACPI_6_2_DMA_REMAPPING_TABLE_SIGNATURE)
+#define  EFI_PCI_CAPABILITY_ID_ATS          0x0F
+
+#define SEGMENT0                            0x00
+#define MEM_BLK_COUNT                       0x140
+#define INTRREMAP                           BIT3
+#define MEMORY_SIZE                         (MaxIIO * NUMBER_PORTS_PER_SOCKET)
+#define R_VTD_EXT_CAP_LOW                   0x10
+#define R_VTD_EXT_CAP_HIGH                  0x14
+#define IIO_STACK0                          0
+#define IOAT_DEVICE_NUM_10NM                0x01
+
+
+PCI_NODE  mPciPath0_1[]   = {
+  {PCI_DEVICE_NUMBER_PCH_HDA, PCI_FUNCTION_NUMBER_PCH_HDA},
+  {(UINT8) -1,  (UINT8) -1},
+};
+
+//
+// IOAPIC2  - IIO IoApic
+//
+PCI_NODE  mPciPath2_0_10nm[] = {
+    { PCIE_PORT_0_DEV_0, PCIE_PORT_0_FUNC_0 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_1_10nm[] = {
+    { PCIE_PORT_1A_DEV_1, PCIE_PORT_1A_FUNC_1 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_2_10nm[] = {
+    { PCIE_PORT_1B_DEV_1, PCIE_PORT_1B_FUNC_1 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_3_10nm[] = {
+    { PCIE_PORT_1C_DEV_1, PCIE_PORT_1C_FUNC_1 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_4_10nm[] = {
+    { PCIE_PORT_1D_DEV_1, PCIE_PORT_1D_FUNC_1 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_5_10nm[] = {
+    { PCIE_PORT_2A_DEV_2, PCIE_PORT_2A_FUNC_2 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_6_10nm[] = {
+    { PCIE_PORT_2B_DEV_2, PCIE_PORT_2B_FUNC_2 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_7_10nm[] = {
+    { PCIE_PORT_2C_DEV_2, PCIE_PORT_2C_FUNC_2 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_8_10nm[] = {
+    { PCIE_PORT_2D_DEV_2, PCIE_PORT_2D_FUNC_2 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_9_10nm[] = {
+    { PCIE_PORT_3A_DEV_3, PCIE_PORT_3A_FUNC_3 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_10_10nm[] = {
+    { PCIE_PORT_3B_DEV_3, PCIE_PORT_3B_FUNC_3 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_11_10nm[] = {
+    { PCIE_PORT_3C_DEV_3, PCIE_PORT_3C_FUNC_3 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_12_10nm[] = {
+    { PCIE_PORT_3D_DEV_3, PCIE_PORT_3D_FUNC_3 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_13_10nm[] = {
+    { PCIE_PORT_4A_DEV_4, PCIE_PORT_4A_FUNC_4 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_14_10nm[] = {
+    { PCIE_PORT_4B_DEV_4, PCIE_PORT_4B_FUNC_4 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_15_10nm[] = {
+    { PCIE_PORT_4C_DEV_4, PCIE_PORT_4C_FUNC_4 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_16_10nm[] = {
+    { PCIE_PORT_4D_DEV_4, PCIE_PORT_4D_FUNC_4 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_17_10nm[] = {
+    { PCIE_PORT_5A_DEV_5, PCIE_PORT_5A_FUNC_5 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_18_10nm[] = {
+    { PCIE_PORT_5B_DEV_5, PCIE_PORT_5B_FUNC_5 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_19_10nm[] = {
+    { PCIE_PORT_5C_DEV_5, PCIE_PORT_5C_FUNC_5 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+PCI_NODE  mPciPath2_20_10nm[] = {
+    { PCIE_PORT_5D_DEV_5, PCIE_PORT_5D_FUNC_5 },
+    { (UINT8)-1, (UINT8)-1 },
+};
+
+DEVICE_SCOPE              mDevScopeDRHD[] = {
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT,    // Device type - HD Audio
+    00,                                               // Enumeration ID
+    DEFAULT_PCI_BUS_NUMBER_PCH,                       // Start Bus Number
+    &mPciPath0_1[0]
+  },
+};
+
+DEVICE_SCOPE              mDevScopeATSR10nm[] = {
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port1
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_0_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port2
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_1_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port3
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_2_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port4
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_3_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port5
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_4_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port6
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_5_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port7
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_6_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port8
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_7_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port9
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_8_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port10
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_9_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port11
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_10_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port12
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_11_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port13
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_12_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port14
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_13_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port15
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+        &mPciPath2_14_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port16
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_15_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port17
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_16_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port18
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_17_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port19
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_18_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port20
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_19_10nm[0]
+  },
+  {
+    EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE,  // Pcie Port21
+    00,                                           // Enumeration ID
+    DMI_BUS_NUM,
+    &mPciPath2_20_10nm[0]
+  }
+};
+
+DMAR_DRHD                 mDrhd = {
+  DRHD_SIGNATURE,
+  00,                                             // Flags
+  SEGMENT0,                                       // Segment number
+  00,                                             // Base Address
+  00,                                             // Number of dev scope structures
+  &mDevScopeDRHD[0]
+};
+
+DMAR_DRHD                 mDrhdIsoc = {
+  DRHD_SIGNATURE,
+  00,                                             // Flags
+  SEGMENT0,                                       // Segment number
+  00,                                             // Base Address
+  00,                                             // Number of dev scope structures
+  &mDevScopeDRHD[0]
+};
+
+DMAR_ATSR                 mAtsr10nm = {
+    ATSR_SIGNATURE,
+    SEGMENT0,                                       // Segment number
+    00,
+    NUMBER_PORTS_PER_SOCKET - 1,
+    00,
+    &mDevScopeATSR10nm[0]
+};
+
+PCI_NODE     mPciPath[] = {
+  { 00,      00},
+  { (UINT8)-1,   (UINT8)-1},
+};
+
+UINT8  IoApicID[] = { PCH_IOAPIC_ID,   //PCH
+   PC00_IOAPIC_ID, PC01_IOAPIC_ID, PC02_IOAPIC_ID, PC03_IOAPIC_ID, PC04_IOAPIC_ID, PC05_IOAPIC_ID,  //Socket0
+   PC06_IOAPIC_ID, PC07_IOAPIC_ID, PC08_IOAPIC_ID, PC09_IOAPIC_ID, PC10_IOAPIC_ID, PC11_IOAPIC_ID,  //Socket1
+   PC12_IOAPIC_ID, PC13_IOAPIC_ID, PC14_IOAPIC_ID, PC15_IOAPIC_ID, PC16_IOAPIC_ID, PC17_IOAPIC_ID,  //Socket2
+   PC18_IOAPIC_ID, PC19_IOAPIC_ID, PC20_IOAPIC_ID, PC21_IOAPIC_ID, PC22_IOAPIC_ID, PC23_IOAPIC_ID,  //Socket3
+   PC24_IOAPIC_ID, PC25_IOAPIC_ID, PC26_IOAPIC_ID, PC27_IOAPIC_ID, PC28_IOAPIC_ID, PC29_IOAPIC_ID,  //Socket4
+   PC30_IOAPIC_ID, PC31_IOAPIC_ID, PC32_IOAPIC_ID, PC33_IOAPIC_ID, PC34_IOAPIC_ID, PC35_IOAPIC_ID,  //Socket5
+   PC36_IOAPIC_ID, PC37_IOAPIC_ID, PC38_IOAPIC_ID, PC39_IOAPIC_ID, PC40_IOAPIC_ID, PC41_IOAPIC_ID,  //Socket6
+   PC42_IOAPIC_ID, PC43_IOAPIC_ID, PC44_IOAPIC_ID, PC45_IOAPIC_ID, PC46_IOAPIC_ID, PC47_IOAPIC_ID,  //Socket7
+};
+
+PCI_NODE     mPciPath7[] = {
+  { PCI_DEVICE_NUMBER_PCH_XHCI,      PCI_FUNCTION_NUMBER_PCH_XHCI  },
+  { (UINT8)-1,   (UINT8)-1},
+};
+DEVICE_SCOPE DevScopeRmrr[] = {
+  {
+    1,                                  // RMRR dev Scope - XHCI
+    0,                                  // Enumeration ID
+    0,                                  // Start Bus Number
+    &mPciPath7[0]
+  },
+};
+
+DMAR_RMRR    mRmrr = {
+  RMRR_SIGNATURE,                       // Signature
+  SEGMENT0,                             // Segment number
+  ' ',                                  // Reserved Memory RegionBase Address
+  ' ',                                  // Reserved Memory RegionLimit Address
+  ' ',                                  // Number of Dev Scope structures
+  &DevScopeRmrr[0]
+};
+
+typedef struct {
+    UINT8   aBuf[32];
+} MEM_BLK;
+
+DMAR_RHSA                 mRhsa;
+
+typedef struct {
+    UINT8   Bus;
+    UINT8   Dev;
+    UINT8   Func;
+} DMAR_DEVICE;
+
+EFI_STATUS
+LocateCapRegBlock(
+  IN     EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN     UINT8                CapID,
+  OUT    UINT8                *PciExpressOffset,
+  OUT    UINT8                *NextRegBlock
+  );
+
+EFI_STATUS
+LocatePciExpressCapRegBlock (
+  IN     EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN     UINT16               CapID,
+  OUT    UINT32               *Offset,
+  OUT    UINT32               *NextRegBlock
+);
+
+DMAR_DRHD                 mDrhd;
+DMAR_RHSA                 mRhsa;
+
+DMAR_ATSR* GetDmarAtsrTablePointer (
+  VOID
+  )
+{
+  DMAR_ATSR* pAtsr = NULL;
+
+  pAtsr = &mAtsr10nm;
+
+  return pAtsr;
+}
+
+
+/**
+  Enable VT-d interrupt remapping.
+
+  This function should be called late at ReadyToBoot event. If called in AcpiVtdTablesInstall()
+  would hang in CpuDeadLoop() because of timeout when waiting for invalidation commands complete.
+**/
+VOID
+AcpiVtdIntRemappingEnable (
+  VOID
+  )
+{
+  EFI_STATUS                  Status;
+  UINT64                      *xApicAddr;
+  UINT64                      *IRTA;
+  UINT64                      *Addr;
+  UINT64                      Value=0;
+  UINT16                      IRTECount;
+  UINT16                      Count;
+  UINT64                      IRTEValue;
+  UINT8                       RemapEng;
+  UINT8                       RemapEngCount;
+  EFI_CPUID_REGISTER          CpuidRegisters;
+  UINT32                      VtdBarAddress;
+  UINT8                       Stack;
+  VTD_SUPPORT_INSTANCE        *DmarPrivateData;
+  DMA_REMAP_PROTOCOL          *DmaRemap = NULL;
+
+  static volatile UINT64      TempQWord[MaxIIO] = {0};
+
+  DYNAMIC_SI_LIBARY_PROTOCOL2  *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return;
+  }
+
+  Status = gBS->LocateProtocol (&gDmaRemapProtocolGuid, NULL, &DmaRemap);
+  if (EFI_ERROR (Status) || !DmaRemap->VTdSupport || !DmaRemap->InterruptRemap) {
+
+    DEBUG ((DEBUG_INFO, "[VTD] %a disabled\n",
+            (DmaRemap != NULL && DmaRemap->VTdSupport) ? "Interrupt remapping" : "Virtualization Technology for Directed I/O"));
+    return;
+  }
+  ASSERT (mIioUds2);
+
+  IRTEValue = 00;
+  RemapEng = 0;
+  RemapEngCount = mIioUds2->IioUdsPtr->PlatformData.numofIIO;
+  DmarPrivateData = VTD_SUPPORT_INSTANCE_FROM_THIS (DmaRemap);
+
+  if (RemapEngCount > NELEMENTS (TempQWord)) {
+    DEBUG ((DEBUG_ERROR, "[ACPI](DMAR) ERROR: Number of IIO exceed internal table (%d > %d)\n", RemapEngCount, NELEMENTS (TempQWord)));
+    RemapEngCount = NELEMENTS (TempQWord);
+  }
+
+  //
+  // Xapic tables update
+  //
+  IRTECount = 16 * 24;    // Total 24 IRTE entries with 128 bits each.
+  //
+  // Allocate 4K alligned space for IRTE entries  Added extra space of 500 bytes.
+  //
+  Status = gBS->AllocatePool (EfiACPIReclaimMemory, IRTECount + 0x1500, &xApicAddr);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Allocate IRT - Allocate zero-initialized, 4KB aligned, 4KB memory for interrupt-remap-table and mark this memory as "ACPI Reclaim Memory"
+  //
+  xApicAddr = (UINT64 *)((UINT64)xApicAddr & (~0xFFF));
+  ZeroMem (xApicAddr, IRTECount +0x1500);
+
+  //
+  // 1. Program IRTE - Initialize the interrupt-remap-table as follows: (this table will be shared by all VT-d units)
+  //
+  for (Count = 0; Count < 24; Count++)  {
+
+    IRTEValue = 00;
+    if (Count == 0) {
+      IRTEValue = (7 << 05) + 03;    // Preset flag set, Ext int enabled, FPD set
+    }
+
+    AsmCpuid (
+      CPUID_EXTENDED_TOPOLOGY,
+      &CpuidRegisters.RegEax,
+      &CpuidRegisters.RegEbx,
+      &CpuidRegisters.RegEcx,
+      &CpuidRegisters.RegEdx
+      );
+    IRTEValue |= (UINT64)CpuidRegisters.RegEdx << 32;    // Destination Processor Apic ID
+
+    *(volatile UINT64 *)((UINT64)xApicAddr + (Count * 16))= IRTEValue;
+
+    //
+    // Perform a CLFLUSH instruction for each cachline in this 4KB memory to ensure that updates to the interrupt-remap-table are visible in memory
+    //
+    AsmFlushCacheLine ((VOID *)((UINT64)xApicAddr + (Count * 16)));
+  }
+  //
+  // 3. Program the VT-D remap engines
+  //
+  for (RemapEng = 0; RemapEng < RemapEngCount; RemapEng++) {
+    for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
+      //
+      // Check for valid stack
+      //
+      if (!(mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[RemapEng].stackPresentBitmap & (1 << Stack))) {
+        continue;
+      }
+      VtdBarAddress = DynamicSiLibraryProtocol2->GetVtdBar (RemapEng, Stack);
+      if (VtdBarAddress) {
+        //
+        // 2. For each VT-d unit in the platform, allocate and initialize the invalidation queue/commands as follows
+        //
+
+        //
+        // Allocate memory for the queued invalidation.
+        //
+        Status = gBS->AllocatePool (EfiACPIReclaimMemory, 0x1000 + 0x1000, &Addr);
+        if (EFI_ERROR (Status)) {
+          ASSERT (FALSE);
+          return;
+        }
+        ZeroMem (Addr, 0x1000 + 0x1000);
+        Addr = (UINT64 *)((UINT64)Addr & (~0xFFF));
+
+        //
+        // Submit two descriptors to the respective VT-d unit's invalidation queue as follows:
+        // Program 1st descriptor in invalidation-queue as Interrupt-Entry-Cache Invalidation Descriptor
+        // with G (Granularity) field Clear
+        //
+        Addr[0] = 0x04;     // Interrupt Entry Cache Invalidate Descriptor
+        Addr[1] = 0x00;
+
+        //
+        // Program 2nd descriptor in invalidation-queue as Invalidation-Wait-Descriptor as follows:          +Status-Data=1
+        // +Status-Address=address of variable tmp[unit +SW=1 +FN=1 +IF=0
+        //
+
+        Addr[2] = ((UINT64)1 << 32) + (06 << 04) + 05;      // Invalidation Wait Descriptor
+
+        TempQWord[RemapEng] = 00;
+        Addr[3] = (UINTN)&TempQWord[RemapEng];    // Status Address [63:2] bits[127:65]
+
+        //
+        // 3. Program the IRTA register to point to the IRT table.
+        // For each VT-d unit in the platform, program interrupt-remap-table address and enable extended-interrupt-mode as follows
+        //
+        IRTA  = (UINT64 *)((UINT64)VtdBarAddress + R_VTD_IRTA_REG);
+        Value = *(volatile UINT32 *)((UINT64)VtdBarAddress+ R_VTD_GSTS_REG);
+        //
+        // *(volatile UINT64*)IRTA = 04  + 0x800 + (UINT64)xApicAddr ;   // [0:3] size = 2 Power (X+1). Bit11 =1 Xapic mode Bit[12:63] address
+        //
+        if (DmarPrivateData->Dmar->Flags && EFI_ACPI_DMAR_FLAGS_X2APIC_OPT_OUT) {
+          *(volatile UINT64*)IRTA = 07 + (UINT64)xApicAddr ;   // [0:3] size = 2 Power (X+1). Bit11 =1 Xapic mode Bit[12:63] address
+          *(volatile UINT32 *)((UINT64)VtdBarAddress+ R_VTD_GCMD_REG) = (UINT32)(Value | BIT23);
+        } else {
+          *(volatile UINT64*)IRTA = 07  + 0x800 + (UINT64)xApicAddr ;   // [0:3] size = 2 Power (X+1). Bit11 =1 Xapic mode Bit[12:63] addrerss
+        }
+        //
+        // b. Set SIRTP in the command register.
+        //
+        Count = 0x1000;
+        *(volatile UINT32 *)((UINT64)VtdBarAddress+ R_VTD_GCMD_REG) = (UINT32)(Value | BIT24);
+
+        //
+        // Wait till the status bit is set indicating the completion of the SIRTP.
+        //
+        while (Count)  {
+          Count--;
+          Value = *(volatile UINT32 *)((UINT64)VtdBarAddress + R_VTD_GSTS_REG);
+          if (Value & BIT24) {
+            break;
+          }
+        }
+        if (Count == 0) {
+          ASSERT(FALSE);
+          CpuDeadLoop ();
+        }
+        *(volatile UINT64 *)((UINT64)VtdBarAddress+ R_VTD_IQA_REG) = (UINT64)Addr;
+      } // End of if (VtdBarAddress)
+    } // End of for (Stack = 0; Stack < MAX_IIO_STACK; Stack++)
+  }
+
+  for (RemapEng = 0; RemapEng < RemapEngCount; RemapEng++) {
+
+    for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
+
+      //
+      // Check for valid stack
+      //
+      if (!(mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[RemapEng].stackPresentBitmap & (1 << Stack))) {
+        continue;
+      }
+      VtdBarAddress = DynamicSiLibraryProtocol2->GetVtdBar (RemapEng, Stack);
+      if (VtdBarAddress) {
+
+        //
+        // 4. For each VT-d unit in the platform, setup invalidation-queue base registers and enable invalidation as follows
+        // Initialize a single descriptor which invalidates all the interrupt entries.
+        // IQA register write (zeros IQH and IQT)
+        //
+
+        //
+        // Enable queued invalidation in the command register.
+        //
+        Count = 0x1000;
+        Value = *(volatile UINT32 *)((UINT64)VtdBarAddress+ R_VTD_GSTS_REG);
+        *(volatile UINT32 *)((UINT64)VtdBarAddress + R_VTD_GCMD_REG) = (UINT32)(Value | BIT26);
+
+        while (Count)  {
+          Count--;
+          Value = *(volatile UINT32 *)((UINT64)VtdBarAddress+ R_VTD_GSTS_REG);
+          if( Value & BIT26) {
+            break;
+          }
+        }
+        if (Count == 0) {
+          ASSERT(FALSE);
+          CpuDeadLoop ();
+        }
+
+        //
+        // Start invalidations, program the IQT register
+        // Write the invalidation queue tail (IQT_REG) register as follows to indicate to hardware two descriptors are submitted:
+        // +Bits 63:19 are 0 +Bits 18:4 gets value of 2h +Bits 3:0 are 0
+        //
+
+        *(volatile UINT64 *)((UINT64)VtdBarAddress + R_VTD_IQT_REG) = (02 << 04); // Set tail to 02
+      } // End of if (VtdAddress)
+    } //End of for (Stack = 0; Stack < MAX_IIO_STACK; Stack++)
+  }
+
+  for (RemapEng = 0; RemapEng < RemapEngCount; RemapEng++) {
+
+    for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
+
+      if (!(mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[RemapEng].stackPresentBitmap & (1 << Stack))) {
+        continue;  // Skip invalid stacks
+      }
+      VtdBarAddress = DynamicSiLibraryProtocol2->GetVtdBar (RemapEng, Stack);
+      if (VtdBarAddress) {
+        //
+        // 5. For each VT-d unit in the platform, wait for invalidation completion, and enable interrupt remapping as follows
+        // Wait till the previously submitted invalidation commands are completed as follows
+        // Poll on the variable tmp[unit] in memory, until its value is 1h.
+        //
+        Count = 0x1000;
+        while (Count)  {
+          Count--;
+          Value = TempQWord[RemapEng];
+          if (Value & 01) {
+            break;
+          }
+        }
+        if (Count == 0) {
+          ASSERT(FALSE);
+          CpuDeadLoop ();
+        }
+      } // End of if VtdBarAddress
+    } //End of for (Stack = 0; Stack < MAX_IIO_STACK; Stack++)
+  }
+
+  //
+  // 5. Enable external interrupts in the IOAPIC RTE entry 0
+  //
+  *(volatile UINT32 *)((UINT64)PCH_IOAPIC_ADDRESS)        = 0x10;
+  *(volatile UINT32 *)((UINT64)PCH_IOAPIC_ADDRESS + 0x10) = 0x00; // Set index to the IRTE0
+
+  *(volatile UINT32 *)((UINT64)PCH_IOAPIC_ADDRESS)        = 0x10+1;
+  *(volatile UINT32 *)((UINT64)PCH_IOAPIC_ADDRESS + 0x10) = 0x10000;// Set Remap enable bit
+}
+
+
+/**
+  Build DRHD entry into ACPI DMAR table for specific stack.
+  Include IOxAPIC, PCIExpress ports, and CBDMA if C-STACK.
+
+  @param DmaRemap        - pointer to DMA remapping protocol
+  @param IioIndex        - IIO index to be processed
+  @param Stack           - stack index to be processed
+  @param DevScope        - buffer for device scope data structure
+  @param PciNode         - buffer for PCI node data structure
+  @param PciRootBridgePtr- pointer to PciRootBridgeIo protocol for PCI access
+
+  @retval EFI_SUCCESS - DRHD entry built successfully
+**/
+EFI_STATUS
+BuildDRHDForStack (
+  DMA_REMAP_PROTOCOL              *DmaRemap,
+  UINT8                           IioIndex,
+  UINT8                           Stack,
+  DEVICE_SCOPE                    *DevScope,
+  PCI_NODE                        *PciNode,
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgePtr,
+  UINT8                            ApicIndex
+  )
+{
+  EFI_STATUS                  Status = EFI_SUCCESS;
+  UINT8                       Bus;
+  UINT8                       Dev;
+  UINT8                       Func;
+  UINT8                       DevIndex;
+  UINT8                       PciNodeIndex;
+  UINT8                       PortIndex;
+  UINT8                       MaxPortNumberPerSocket;
+  UINT8                       CBIndex;
+  UINT64                      VtdMmioExtCap;
+  UINT32                      VtdBase;
+  UINT32                      VidDid;
+  DMAR_ATSR                   *pAtsr = NULL;
+  DYNAMIC_SI_LIBARY_PROTOCOL2  *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return EFI_NOT_FOUND;
+  }
+
+  ASSERT (mIioUds2);
+  if (Stack > MAX_IIO_STACK){
+    return EFI_UNSUPPORTED;
+  }
+  if (PciRootBridgePtr == NULL) {
+    ASSERT (!(PciRootBridgePtr == NULL));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  mDrhd.Flags = 0;  // all non-legacy stack has INCLUDE_ALL flag cleared
+
+  VtdBase = DynamicSiLibraryProtocol2->GetVtdBar (IioIndex, Stack);
+
+  if (VtdBase == 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  VtdMmioExtCap = *(volatile UINT64*)((UINTN)VtdBase + R_VTD_EXT_CAP_LOW);
+  mDrhd.RegisterBase = VtdBase;
+
+  DevIndex                      = 00;
+  PciNodeIndex                  = 00;
+  mDrhd.DeviceScopeNumber       = 00;
+  ZeroMem (DevScope, MEMORY_SIZE * sizeof (DEVICE_SCOPE));
+  ZeroMem (PciNode, MEMORY_SIZE * sizeof (PCI_NODE));
+
+  //
+  // DRHD - CBDMA entry
+  //
+  if (Stack == IIO_STACK0) {
+
+    for (CBIndex = 0; CBIndex <= 7; CBIndex++) {
+
+      DevScope[DevIndex].DeviceType         = EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT;
+      DevScope[DevIndex].EnumerationID      = 00;
+      DevScope[DevIndex].StartBusNumber     = mCpuCsrAccessVarPtr ->StackBus[IioIndex][IIO_STACK0];
+      DevScope[DevIndex].PciNode            = &PciNode[PciNodeIndex];
+
+      PciNode[PciNodeIndex].Device = IOAT_DEVICE_NUM_10NM;
+      PciNode[PciNodeIndex].Function        = CBIndex;
+      DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d] Build DRHD CBDMA: Type %d, EnumId %d, StartBus 0x%x, PciNode %02X.%X\n",
+              IioIndex, Stack,
+              DevScope[DevIndex].DeviceType, DevScope[DevIndex].EnumerationID, DevScope[DevIndex].StartBusNumber,
+              DevScope[DevIndex].PciNode->Device, DevScope[DevIndex].PciNode->Function));
+      DevIndex++;
+      PciNodeIndex++;
+      PciNode[PciNodeIndex].Device    = (UINT8) -1;
+      PciNode[PciNodeIndex].Function  = (UINT8) -1;
+      PciNodeIndex++;
+
+      mDrhd.DeviceScopeNumber++;
+    } // End of for for(CBIndex = 0; CBIndex <= 07; CBIndex++)
+  }
+
+  //
+  // DRHD - PCI-Ex ports
+  //
+  pAtsr = GetDmarAtsrTablePointer ();
+  MaxPortNumberPerSocket = DynamicSiLibraryProtocol2->GetMaxPortPerSocket (IioIndex);
+  for (PortIndex = 1; PortIndex < MaxPortNumberPerSocket; PortIndex++) {
+
+    if (DynamicSiLibraryProtocol2->GetStackPerPort (IioIndex, PortIndex) != Stack) {
+      continue;
+    }
+    Bus = DynamicSiLibraryProtocol2->GetSocketPortBusNum (IioIndex, PortIndex);
+    Dev = 0;
+    Func = 0;
+    if (pAtsr != NULL) {
+      Dev = pAtsr->DeviceScope[PortIndex].PciNode->Device;
+      Func = pAtsr->DeviceScope[PortIndex].PciNode->Function;
+    }
+    if (DynamicSiLibraryProtocol2->IioNtbIsEnabled (IioIndex, PortIndex, &Dev, &Func)) {
+
+      DevScope[DevIndex].DeviceType = EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT;
+    } else {
+      DevScope[DevIndex].DeviceType = EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE;
+    }
+    //
+    // Skip root ports which do not respond to PCI configuration cycles.
+    //
+    VidDid = 0;
+    Status = PciRootBridgePtr->Pci.Read (
+                PciRootBridgePtr,
+                EfiPciWidthUint32,
+                EFI_PCI_ADDRESS (Bus, Dev, Func, 0),
+                1,
+                &VidDid);
+    if (EFI_ERROR (Status) || VidDid == 0xffffffff) {
+
+      DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d p%d] %02X:%02X:%02X.%d Hidden (%X) - skip\n",
+              IioIndex, Stack, PortIndex,
+              mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[IioIndex].PcieSegment,
+              Bus, Dev, Func, VidDid));
+      continue;
+    }
+    if (DynamicSiLibraryProtocol2->IioVmdPortIsEnabled (IioIndex, PortIndex) || DynamicSiLibraryProtocol2->GetCurrentPXPMap (IioIndex, PortIndex) == 0) {
+
+      DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d p%d] %a - skip\n", IioIndex, Stack, PortIndex,
+              (DynamicSiLibraryProtocol2->GetCurrentPXPMap (IioIndex, PortIndex) == 0) ? "Link width not set" : "Dummy VMD function"));
+      continue;
+    }
+    DevScope[DevIndex].EnumerationID      = 00;
+    DevScope[DevIndex].StartBusNumber     = Bus;
+    DevScope[DevIndex].PciNode            = &PciNode[PciNodeIndex];
+    PciNode[PciNodeIndex].Device          = Dev;
+    PciNode[PciNodeIndex].Function        = Func;
+    DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d p%d] Build DRHD PCI: Type %d, EnumId %d, StartBus 0x%x, PciNode %02X.%X\n",
+            IioIndex, Stack, PortIndex,
+            DevScope[DevIndex].DeviceType, DevScope[DevIndex].EnumerationID, DevScope[DevIndex].StartBusNumber,
+            DevScope[DevIndex].PciNode->Device, DevScope[DevIndex].PciNode->Function));
+    DevIndex++;
+    PciNodeIndex++;
+    PciNode[PciNodeIndex].Device    = (UINT8) -1;
+    PciNode[PciNodeIndex].Function  = (UINT8) -1;
+    PciNodeIndex++;
+
+    mDrhd.DeviceScopeNumber++;
+  } // for (PortIndex...)
+
+  Status = DynamicSiLibraryProtocol2->IioVmdGetPciLocation (IioIndex, Stack,
+                                 &PciNode[PciNodeIndex].Device, &PciNode[PciNodeIndex].Function);
+  if (!EFI_ERROR (Status)) {
+    //
+    // VMD is enabled in this stack, expose VMD PCI device in DMAR for DMA remapping.
+    //
+    DevScope[DevIndex].DeviceType         = EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT;
+    DevScope[DevIndex].EnumerationID      = 00;
+    DevScope[DevIndex].StartBusNumber     = mCpuCsrAccessVarPtr->StackBus[IioIndex][Stack];
+    DevScope[DevIndex].PciNode            = &PciNode[PciNodeIndex];
+    DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d] Build DRHD VMD: Type %d, EnumId %d, StartBus 0x%x, PciNode %02X.%X\n",
+            IioIndex, Stack,
+            DevScope[DevIndex].DeviceType, DevScope[DevIndex].EnumerationID, DevScope[DevIndex].StartBusNumber,
+            DevScope[DevIndex].PciNode->Device, DevScope[DevIndex].PciNode->Function));
+    DevIndex++;
+    PciNodeIndex++;
+    PciNode[PciNodeIndex].Device = (UINT8)-1;
+    PciNode[PciNodeIndex].Function = (UINT8)-1;
+    PciNodeIndex++;
+
+    mDrhd.DeviceScopeNumber++;
+  }
+
+  DmaRemap->InsertDmaRemap (DmaRemap, DrhdType, &mDrhd);
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+ReportDmar (
+  IN DMA_REMAP_PROTOCOL           *DmaRemap
+  )
+{
+  EFI_STATUS                      Status = EFI_SUCCESS;
+  UINT8                           SocketIndex, IioBusBase, Bus;
+  UINT8                           Dev, Func;
+  UINT8                           DevIndex;
+  UINT8                           PciNodeIndex;
+  UINT8                           PciPortIndex;
+  UINT8                           MaxPortNumberPerSocket;
+  UINT64                          VtdMmioExtCap;
+  UINT32                          VtdBase;
+  VTD_SUPPORT_INSTANCE            *DmarPrivateData;
+  UINT16                          NumberOfHpets;
+  UINT16                          HpetCapIdValue;
+  DEVICE_SCOPE                    *DevScope;
+  PCI_NODE                        *PciNode;
+  EFI_PHYSICAL_ADDRESS            Pointer;
+  UINT32                          AlignedSize;
+  UINT32                          NumberofPages;
+  BOOLEAN                         IntrRemapSupport;
+  EFI_CPUID_REGISTER              CpuidRegisters;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgePtr;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeTab[MAX_SOCKET];
+  UINT32                          VidDid;
+  UINT8                           Index;
+  UINT8                           Stack = 0;
+  UINT8                           FirstRun = 0;
+  VOID                            *HobPtr;
+  PCH_INFO_HOB                    *PchInfoHob;
+  DMAR_ATSR                       *pAtsr = NULL;
+  UINT8                           ApicIndex = 1;
+  UINTN                           HandleCount;
+  EFI_HANDLE                      *HandleBuffer;
+  DYNAMIC_SI_LIBARY_PROTOCOL2     *DynamicSiLibraryProtocol2 = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &DynamicSiLibraryProtocol2);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return FALSE;
+  }
+
+  HobPtr = GetFirstGuidHob (&gPchInfoHobGuid);
+  if (HobPtr == NULL) {
+    ASSERT (HobPtr != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PchInfoHob = (PCH_INFO_HOB*) GET_GUID_HOB_DATA (HobPtr);
+  if (PchInfoHob == NULL) {
+    ASSERT (PchInfoHob != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ASSERT (mIioUds2);
+
+  DmarPrivateData = VTD_SUPPORT_INSTANCE_FROM_THIS (DmaRemap);
+  //
+  // Get DMAR_HOST_ADDRESS_WIDTH from CPUID.(EAX=80000008h) return the Phyical Address
+  // Size in the EAX register. EAX[7:0]
+  // Sync with Brickland code  DMAR_HOST_ADDRESS_WIDTH 45 = 46 - 1
+  //
+  AsmCpuid (
+    CPUID_VIR_PHY_ADDRESS_SIZE,
+    &CpuidRegisters.RegEax,
+    &CpuidRegisters.RegEbx,
+    &CpuidRegisters.RegEcx,
+    &CpuidRegisters.RegEdx
+  );
+
+  DmarPrivateData->Dmar->HostAddressWidth = (UINT8)((CpuidRegisters.RegEax & 0xFF)-1);
+  DmarPrivateData->Dmar->Flags = 0; // INTR_REMAP
+
+  //
+  // Locate PCI root bridge I/O protocol, for confirming PCI functions respond
+  // to PCI configuration cycles.
+  //
+  ZeroMem (&PciRootBridgeTab[0], sizeof(PciRootBridgeTab));
+
+  Status = gBS->LocateHandleBuffer (
+                ByProtocol,
+                &gEfiPciRootBridgeIoProtocolGuid,
+                NULL,
+                &HandleCount,
+                &HandleBuffer
+                );
+
+  ASSERT_EFI_ERROR (Status);
+
+  for (Index = 0; Index < HandleCount; Index ++) {
+    Status = gBS->HandleProtocol (
+                  HandleBuffer[Index],
+                  &gEfiPciRootBridgeIoProtocolGuid,
+                  &PciRootBridgePtr
+                  );
+
+    ASSERT_EFI_ERROR (Status);
+
+    PciRootBridgeTab[PciRootBridgePtr->SegmentNumber] = PciRootBridgePtr;
+  }
+  FreePool (HandleBuffer);
+
+  //
+  // Allocate memory to DevScope structures
+  //
+  Status = gBS->AllocatePool (EfiACPIMemoryNVS, MEMORY_SIZE * sizeof (DEVICE_SCOPE), &DevScope);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->AllocatePool (EfiACPIMemoryNVS, MEMORY_SIZE * sizeof (PCI_NODE), &PciNode);
+  ASSERT_EFI_ERROR (Status);
+
+  for (Index = 1; Index <= MAX_SOCKET; Index++) {
+    //
+    // VT-d specification request that DHRD entry 0 should be the latest entry of the DMAR table.
+    // To accomplish this, the following check will ensure that latest entry will be the one related to Socket 0.
+    //
+    if (Index == MAX_SOCKET) {
+      SocketIndex = 0;
+    } else {
+      SocketIndex = Index;
+    }
+
+    if (SocketIndex >= MAX_SOCKET) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if (!DynamicSiLibraryProtocol2->SocketPresent (SocketIndex)) {
+      continue;
+    }
+
+    if (mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[SocketIndex].PcieSegment >= MAX_SOCKET) {
+      return EFI_INVALID_PARAMETER;
+    }
+    PciRootBridgePtr = PciRootBridgeTab[mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[SocketIndex].PcieSegment];
+
+    Stack = IIO_STACK0;
+    VtdBase = DynamicSiLibraryProtocol2->GetVtdBar (SocketIndex, Stack);
+
+    DevIndex                      = 00;
+    PciNodeIndex                  = 00;
+
+    mDrhd.Signature               = DRHD_SIGNATURE;
+    mDrhd.SegmentNumber           = mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[SocketIndex].PcieSegment;
+    mDrhd.DeviceScopeNumber       = 00;
+    mDrhd.DeviceScope             = DevScope;
+    mDrhd.RegisterBase            = VtdBase;
+    ZeroMem (DevScope, MEMORY_SIZE * sizeof (DEVICE_SCOPE));
+    ZeroMem (PciNode, MEMORY_SIZE * sizeof (PCI_NODE));
+
+    VtdMmioExtCap = *(volatile UINT64*)((UINTN)VtdBase + R_VTD_EXT_CAP_LOW);
+
+    //
+    // Check Interrupt Remap support.
+    //
+    IntrRemapSupport = FALSE;
+    if (VtdMmioExtCap & INTRREMAP) {
+      IntrRemapSupport = TRUE;
+    }
+    DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d] VT-d base 0x%X, ExtCap=0x%X\n",
+            SocketIndex, Stack, VtdBase, VtdMmioExtCap));
+
+    if (SocketIndex == 0) {
+      ApicIndex = 1;
+      //
+      // DRHD - Legacy IOH
+      //
+      // Build DRHD on IIO0 - Stack1 to Stack5, not include C-STACK
+      //
+      for (Stack = 1; Stack < MAX_IIO_STACK; Stack++) {
+
+        if (!DynamicSiLibraryProtocol2->IfStackPresent (SocketIndex, Stack)) {  // Skip invalid stack
+          continue;
+        }
+        BuildDRHDForStack (DmaRemap, SocketIndex, Stack, DevScope, PciNode, PciRootBridgePtr, ApicIndex);
+        ApicIndex++;
+      }
+
+      Stack = IIO_STACK0;
+
+      //
+      // Re-initialize DRHD template for DRHD entry in legacy socket C-STACK
+      //
+      DevIndex                      = 00;
+      PciNodeIndex                  = 00;
+      mDrhd.DeviceScopeNumber       = 00;
+      mDrhd.RegisterBase            = DynamicSiLibraryProtocol2->GetVtdBar (SocketIndex, Stack);
+      ZeroMem (DevScope, MEMORY_SIZE * sizeof (DEVICE_SCOPE));
+      ZeroMem (PciNode, MEMORY_SIZE * sizeof (PCI_NODE));
+
+      IioBusBase = mCpuCsrAccessVarPtr ->StackBus[SocketIndex][Stack]; // Stack 0
+      mDrhd.Flags = 1;
+
+      DEBUG ((DEBUG_INFO, "[ACPI](DMAR) InterruptRemap is %aabled (%d & %d)\n",
+              (DmaRemap->InterruptRemap && IntrRemapSupport) ? "en" : "dis", DmaRemap->InterruptRemap, IntrRemapSupport));
+      if (DmaRemap->InterruptRemap && IntrRemapSupport) {
+
+        DmarPrivateData->Dmar->Flags = 0x01; // INTR_REMAP
+
+        if (DmaRemap->X2ApicOptOut) {
+          DmarPrivateData->Dmar->Flags |= 0x02; // X2APIC_OPT_OUT
+        }
+        //
+        // PCH - IOAPIC
+        // This information will be provided by PCH side
+        // Currently is a hard-coded temporal solution to set:
+        // Bus = 0; Device and Function (together) = 0xF7;
+        // This is the value that is stored in IBDF register:
+        //#define V_P2SB_CFG_IBDF_BUS                        0
+        //#define V_P2SB_CFG_IBDF_DEV                        30
+        //#define V_P2SB_CFG_IBDF_FUNC                       7
+        //
+        DevScope[DevIndex].DeviceType = EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC;
+        DevScope[DevIndex].EnumerationID = PCH_IOAPIC_ID; // PCH team needs confirm this value. (This value affects VTd functionality?)
+        DevScope[DevIndex].StartBusNumber = (UINT8)PchInfoHob->IoApicBusNum;
+        DevScope[DevIndex].PciNode = &PciNode[PciNodeIndex];
+
+        PciNode[PciNodeIndex].Device = (UINT8)PchInfoHob->IoApicDevNum;
+        PciNode[PciNodeIndex].Function = (UINT8)PchInfoHob->IoApicFuncNum;
+        DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d] Build DRHD PCH IOAPIC: Type %d, EnumId %d, StartBus 0x%x, PciNode %02X.%X\n",
+                SocketIndex, Stack,
+                DevScope[DevIndex].DeviceType, DevScope[DevIndex].EnumerationID, DevScope[DevIndex].StartBusNumber,
+                DevScope[DevIndex].PciNode->Device, DevScope[DevIndex].PciNode->Function));
+        DevIndex++;
+        PciNodeIndex++;
+        PciNode[PciNodeIndex].Device = (UINT8)-1;
+        PciNode[PciNodeIndex].Function = (UINT8)-1;
+        PciNodeIndex++;
+
+        mDrhd.DeviceScopeNumber++;
+
+        HpetCapIdValue = *(UINT16 *)(UINTN)(HPET_BLOCK_ADDRESS);
+        NumberOfHpets = (HpetCapIdValue >> 0x08) & 0x1F;  // Bits [8:12] contains the number of Hpets
+
+        if (NumberOfHpets && (NumberOfHpets != 0x1f) &&
+            (*((volatile UINT32 *)(UINTN)(HPET_BLOCK_ADDRESS + 0x100)) & BIT15)) {
+
+            DevScope[DevIndex].DeviceType = EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET;
+            DevScope[DevIndex].EnumerationID = 00; //Hard-coded
+            DevScope[DevIndex].StartBusNumber = (UINT8)PchInfoHob->HpetBusNum;
+            DevScope[DevIndex].PciNode = &PciNode[PciNodeIndex];
+            PciNode[PciNodeIndex].Device = (UINT8)PchInfoHob->HpetDevNum;
+            PciNode[PciNodeIndex].Function = (UINT8)PchInfoHob->HpetFuncNum;
+            DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d] Build DRHD HPET: Type %d, EnumId %d, StartBus 0x%x, PciNode %02X.%X\n",
+                    SocketIndex, Stack,
+                    DevScope[DevIndex].DeviceType, DevScope[DevIndex].EnumerationID, DevScope[DevIndex].StartBusNumber,
+                    DevScope[DevIndex].PciNode->Device, DevScope[DevIndex].PciNode->Function));
+            DevIndex++;
+            PciNodeIndex++;
+            PciNode[PciNodeIndex].Device = (UINT8)-1;
+            PciNode[PciNodeIndex].Function = (UINT8)-1;
+            PciNodeIndex++;
+
+          mDrhd.DeviceScopeNumber++;
+        }
+      } // DmaRemap->InterruptRemap
+
+      DEBUG ((DEBUG_INFO, "[ACPI](DMAR) DMA_CTRL_PLATFORM_OPT_IN_FLAG is %aabled\n", (DmaRemap->DmaCtrlOptIn) ? "En" : "Dis"));
+      if (DmaRemap->DmaCtrlOptIn) {
+
+        DmarPrivateData->Dmar->Flags |= 0x04; // DMA_CTRL_PLATFORM_OPT_IN_FLAG
+      }
+      DmaRemap->InsertDmaRemap (DmaRemap, DrhdType, &mDrhd);
+
+    } else { // End of if (IioSocketId == 0)
+
+      if (FirstRun == 0) {
+        ApicIndex = 0;
+        for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
+          //
+          // Skip not valid stack
+          //
+          if (!DynamicSiLibraryProtocol2->IfStackPresent (0 ,Stack)) {
+            continue;
+          }
+          ApicIndex++;
+        }
+        FirstRun = 1;
+      }
+      //
+      // Build DRHD on IIO1 - Stack0 to Stack5
+      //
+      for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
+        //
+        // Skip not valid stack
+        //
+        if (!DynamicSiLibraryProtocol2->IfStackPresent (SocketIndex,Stack)) {
+          continue;
+        }
+        BuildDRHDForStack (DmaRemap, SocketIndex, Stack, DevScope, PciNode, PciRootBridgePtr, ApicIndex);
+        ApicIndex++;
+      } //for( StackIndex=0; StackIndex<MAX_IIO_STACK ; StackIndex++) {
+    } // End of if (IioSocketId == 0)
+
+  } // End of for ( Index = 1; Index <= MAX_SOCKET; Index++)
+
+  //
+  // ATSR
+  //
+  pAtsr = GetDmarAtsrTablePointer ();
+  if (DmaRemap->ATS) {
+    for (SocketIndex = 0; SocketIndex < MAX_SOCKET; SocketIndex++) {
+
+      DEBUG((DEBUG_ERROR, "T_TEST: Build ATSR SocketIndex=%d.\n", SocketIndex));
+      DEBUG((DEBUG_ERROR, "        IIO_resource.valid=%d.\n", mIioUds2->IioUdsPtr->PlatformData.IIO_resource[SocketIndex].Valid));
+
+      if (SocketIndex >= MAX_SOCKET) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      if (!DynamicSiLibraryProtocol2->SocketPresent (SocketIndex)) {
+        continue;
+      }
+
+      IioBusBase = mIioUds2->IioUdsPtr->PlatformData.IIO_resource[SocketIndex].BusBase;
+
+      if (mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[SocketIndex].PcieSegment >= MAX_SOCKET) {
+        return EFI_INVALID_PARAMETER;
+      }
+      PciRootBridgePtr = PciRootBridgeTab[mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[SocketIndex].PcieSegment];
+
+      PciNodeIndex            = 00;
+      DevIndex                = 00;
+
+      ZeroMem (DevScope, MEMORY_SIZE * sizeof (DEVICE_SCOPE));
+      ZeroMem (PciNode, MEMORY_SIZE * sizeof (PCI_NODE));
+
+      if (pAtsr != NULL) {
+        pAtsr->Signature = ATSR_SIGNATURE;
+        pAtsr->Flags = 00;
+        pAtsr->SegmentNumber = mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[SocketIndex].PcieSegment;
+        pAtsr->DeviceScopeNumber = 00;
+        pAtsr->DeviceScope = DevScope;
+        pAtsr->ATSRPresentBit = (UINT32)-1;   // Not useful really Backwards project compatability (remove it later)
+      }
+
+      //
+      // Loop From Port 1 to 15 for Legacy IOH and 0 to 15 for Non-Legacy IOH
+      //
+      MaxPortNumberPerSocket = DynamicSiLibraryProtocol2->GetMaxPortPerSocket (SocketIndex);
+      for (PciPortIndex = 1; PciPortIndex < MaxPortNumberPerSocket; PciPortIndex++)  {
+        //
+        // Check device IOTLBs supported or not in VT-d Extended capability register
+        //
+        Stack = DynamicSiLibraryProtocol2->GetStackPerPort (SocketIndex, PciPortIndex);
+        //
+        // Check for a valid stack
+        //
+        if (!(DynamicSiLibraryProtocol2->IfStackPresent (SocketIndex, Stack))) {
+          DEBUG ((DEBUG_WARN, "[ACPI](DMAR) [%d.%d p%d] Stack not present\n", SocketIndex, Stack, PciPortIndex));
+          continue;
+        }
+
+        VtdBase = DynamicSiLibraryProtocol2->GetVtdBar (SocketIndex, Stack);
+        if (VtdBase != 0) {
+
+          VtdMmioExtCap = *(volatile UINT64*)((UINTN)VtdBase + R_VTD_EXT_CAP_LOW);
+          //
+          // ATSR is applicable only for platform supporting device IOTLBs through the VT-d extended capability register
+          //
+          if ((VtdMmioExtCap & BIT2) != 0) {
+
+            Bus = DynamicSiLibraryProtocol2->GetSocketPortBusNum (SocketIndex,PciPortIndex);
+            Dev = 0;
+            Func = 0;
+            Dev = mDevScopeATSR10nm[PciPortIndex].PciNode->Device;
+            Func = mDevScopeATSR10nm[PciPortIndex].PciNode->Function;
+            if (DynamicSiLibraryProtocol2->IioNtbIsEnabled (SocketIndex, PciPortIndex, &Dev, &Func)) {
+              DevScope[DevIndex].DeviceType = EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT;
+            } else {
+              DevScope[DevIndex].DeviceType = EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE;
+            }
+            //
+            // Skip root ports which do not respond to PCI configuration cycles.
+            //
+            VidDid = 0;
+            Status = PciRootBridgePtr->Pci.Read (
+                      PciRootBridgePtr,
+                      EfiPciWidthUint32,
+                      EFI_PCI_ADDRESS (Bus, Dev, Func, 0),
+                      1,
+                      &VidDid);
+            if (EFI_ERROR (Status) || VidDid == 0xffffffff) {
+
+              DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d p%d] %02X:%02X:%02X.%d Hidden (%X) - skip\n",
+                      SocketIndex, Stack, PciPortIndex,
+                      mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[SocketIndex].PcieSegment,
+                      Bus, Dev, Func, VidDid));
+              continue;
+            }
+            if (DynamicSiLibraryProtocol2->IioVmdPortIsEnabled (SocketIndex, PciPortIndex) || DynamicSiLibraryProtocol2->GetCurrentPXPMap (SocketIndex, PciPortIndex) == 0) {
+
+              DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d p%d] %a - skip\n", SocketIndex, Stack, PciPortIndex,
+                      (DynamicSiLibraryProtocol2->GetCurrentPXPMap (SocketIndex, PciPortIndex) == 0) ? "Link width not set" : "Dummy VMD function"));
+              continue;
+            }
+            DevScope[DevIndex].EnumerationID      = 00;
+            DevScope[DevIndex].StartBusNumber     = Bus;
+            DevScope[DevIndex].PciNode            = &PciNode[PciNodeIndex];
+            PciNode[PciNodeIndex].Device   = Dev;
+            PciNode[PciNodeIndex].Function = Func;
+            DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d p%d] Build DRHD PCI: Type %d, EnumId %d, StartBus 0x%x, PciNode %02X.%X\n",
+                    SocketIndex, Stack, PciPortIndex,
+                    DevScope[DevIndex].DeviceType, DevScope[DevIndex].EnumerationID, DevScope[DevIndex].StartBusNumber,
+                    DevScope[DevIndex].PciNode->Device, DevScope[DevIndex].PciNode->Function));
+            DevIndex++;
+            PciNodeIndex++;
+            PciNode[PciNodeIndex].Device    = (UINT8) -1;
+            PciNode[PciNodeIndex].Function  = (UINT8) -1;
+            PciNodeIndex++;
+            if(pAtsr != NULL){
+              pAtsr->DeviceScopeNumber++;
+            }
+          } // End of if ((VtdMmioExtCap & BIT2) != 0)
+        } // End of if VtdBase
+      } // for (PciPortIndex...)
+
+      if (pAtsr != NULL){
+        if (pAtsr->DeviceScopeNumber) {
+          DmaRemap->InsertDmaRemap(DmaRemap, AtsrType, pAtsr);
+        }
+      }
+    } // End of for (RootBridgeLoop = 0; RootBridgeLoop < mIioUds2->IioUdsPtr->PlatformData.numofIIO; RootBridgeLoop++)
+  } // End of if (ATS) {
+
+  //
+  // RMRR
+  //
+  AlignedSize  = (MEM_BLK_COUNT * sizeof(MEM_BLK));
+  if (AlignedSize % 0x1000) {
+    AlignedSize  = ( (MEM_BLK_COUNT * sizeof(MEM_BLK)) & (~0xfff) ) + 0x1000;
+  } // aligend to 4k Boundary
+  NumberofPages = AlignedSize/0x1000;
+  //
+  // Allocate memory (below 4GB)
+  //
+  Pointer = 0xffffffff;
+  Status = gBS->AllocatePages (
+                   AllocateMaxAddress,
+                   EfiReservedMemoryType,
+                   NumberofPages,
+                   &Pointer // Base address need to be 4K aligned for VT-d RMRR
+                   );
+  ASSERT_EFI_ERROR (Status);
+
+  if (DmaRemap->VTdSupport) {
+    //
+    // RMRR
+    //
+    mRmrr.DeviceScope       = &DevScopeRmrr[0];
+    //
+    // Calculate the right size of DevScope for mRmrr entry
+    //
+    mRmrr.DeviceScopeNumber = sizeof(DevScopeRmrr) / sizeof(DEVICE_SCOPE);
+    mRmrr.RsvdMemBase       = (UINT64)Pointer;
+    mRmrr.RsvdMemLimit      = mRmrr.RsvdMemBase + AlignedSize - 1;
+    DEBUG ((DEBUG_INFO, "[ACPI](DMAR) RMRR Base 0x%llX, Limit 0x%llX\n", mRmrr.RsvdMemBase, mRmrr.RsvdMemLimit));
+    DmaRemap->InsertDmaRemap (DmaRemap, RmrrType, &mRmrr);
+  }
+  gBS->FreePool (PciNode);
+  gBS->FreePool (DevScope);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Install ACPI DMAR table for VT-d.
+
+  This function needs gEfiPciIoProtocolGuid so it can run only after PCI Enumeraion is complete.
+
+  @retval EFI_SUCCESS          DMAR installed successfuly.
+  @retval EFI_NOT_FOUND        gEfiPciIoProtocolGuid or gDmaRemapProtocolGuid not found.
+  @retval EFI_OUT_OF_RESOURCES Could not allocate resources.
+**/
+EFI_STATUS
+AcpiVtdTablesInstall (
+  VOID
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_ACPI_TABLE_VERSION      TableVersion;
+  DMA_REMAP_PROTOCOL          *DmaRemap;
+  UINTN                       TableHandle;
+  EFI_ACPI_COMMON_HEADER      *CurrentTable;
+  EFI_ACPI_TABLE_PROTOCOL     *AcpiTable;
+
+  UINTN                       HandleCount;
+  EFI_HANDLE                  *HandleBuffer;
+  UINTN                       Index;
+  EFI_PCI_IO_PROTOCOL         *PciIo;
+  PCI_TYPE01                  PciConfigHeader;
+  UINTN                       Segment;
+  UINTN                       Bus;
+  UINTN                       Device;
+  UINTN                       Function;
+  UINT8                       PciExpressOffset;
+  UINT32                      AcsOffset;
+  UINT16                      PciExpressCapabilityReg;
+  UINT8                       AcsCapCount;
+  UINT16                      RequiredAcsCap;
+  UINT32                      AcsCapRegValue;
+  UINT16                      AcsConRegValue;
+  USRA_PCIE_ADDR_TYPE         *AcsDevArray;
+  USRA_ADDRESS                Address;
+
+  DYNAMIC_SI_LIBARY_PROTOCOL  *DynamicSiLibraryProtocol = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &DynamicSiLibraryProtocol);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return EFI_NOT_FOUND;
+  }
+
+  PciExpressOffset = 0;
+  AcsOffset        = 0;
+  AcsCapCount      = 0;
+  AcsCapRegValue   = 0;
+  AcsConRegValue   = 0;
+  RequiredAcsCap   =  ACS_SOURCE_VALIDATION | ACS_P2P_REQUEST_REDIRECT | ACS_P2P_COMPLETION_REDIRECT | ACS_UPSTREAM_FORWARDING;
+
+  //
+  // Locate all PciIo protocols
+  //
+  Status = gBS->LocateHandleBuffer (
+               ByProtocol,
+               &gEfiPciIoProtocolGuid,
+               NULL,
+               &HandleCount,
+               &HandleBuffer
+               );
+  if (EFI_ERROR (Status)) {
+
+    DEBUG((DEBUG_ERROR, "[ACPI](DMAR) ERROR: Cannot locate gEfiPciIoProtocolGuid (%r)\n", Status));
+    ASSERT (FALSE);
+    return Status;
+  }
+  AcsDevArray = AllocateZeroPool (sizeof (USRA_PCIE_ADDR_TYPE) * HandleCount);
+  if (AcsDevArray == NULL) {
+    ASSERT (AcsDevArray != NULL);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  for (Index = 0; Index < HandleCount; Index ++) {
+
+    gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, &PciIo);
+    PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, sizeof(PciConfigHeader) / sizeof(UINT32), &PciConfigHeader);
+    if ((PciConfigHeader.Hdr.ClassCode[0] == 0x00 || PciConfigHeader.Hdr.ClassCode[0] == 0x01) && PciConfigHeader.Hdr.ClassCode[1] == 0x04 && PciConfigHeader.Hdr.ClassCode[2] == 0x06) {
+      //
+      // 060400h or 060401h indicates it's PCI-PCI bridge, get its bus number, device number and function number
+      //
+
+      PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
+
+      USRA_PCIE_SEG_ADDRESS(Address, UsraWidth16, Segment, Bus, Device, Function, 0);
+
+      if (PciConfigHeader.Hdr.Status == EFI_PCI_STATUS_CAPABILITY) {
+        //
+        // the bridge support Capability list and offset 0x34 is the pointer to the data structure
+        //
+        // Detect if PCI Express Device
+        //
+        Status = LocateCapRegBlock (PciIo, EFI_PCI_CAPABILITY_ID_PCIEXP, &PciExpressOffset, NULL);
+
+        if (Status == EFI_SUCCESS) {
+          //
+          // this bridge device is a PCI Express bridge
+          // Check if it is downstream port of PCIE switch
+          //
+          Address.Pcie.Offset = PciExpressOffset + EFI_PCI_EXPRESS_CAPABILITY_REGISTER;
+          DynamicSiLibraryProtocol->RegisterRead(&Address, &PciExpressCapabilityReg);
+
+          //
+          // BIT 7:4 indicate Device/port type, 0110b indicates downstream port of PCI express switch
+          //
+          if ((PciExpressCapabilityReg & 0x00F0) == 0x60) {
+            //
+            // it is downstream port of PCI Express switch
+            // Look for ACS capability register in PCI express configuration space
+            //
+            Status = LocatePciExpressCapRegBlock (PciIo, EFI_PCIE_CAPABILITY_ID_ACS, &AcsOffset, NULL);
+            DEBUG((DEBUG_ERROR, "ACS capable port is B%x.D%x.F%x - ACS Cap offset - 0x%x\n", Bus, Device, Function, AcsOffset));
+
+            if (Status == EFI_SUCCESS) {
+              //
+              // Read ACS capability register
+              //
+              Address.Pcie.Offset = AcsOffset + ACS_CAPABILITY_REGISTER;
+              Address.Attribute.AccessWidth = UsraWidth32;
+              DynamicSiLibraryProtocol->RegisterRead(&Address, &AcsCapRegValue);
+              DEBUG((DEBUG_INFO, "Bus =%x, Device=%x, Function=%x, AcsCapRegValue = %x \n", Bus, Device, Function, AcsCapRegValue));
+
+              if ((AcsCapRegValue & RequiredAcsCap) == RequiredAcsCap) {
+                //
+                // The PCI express downstream port support ACS, record this port
+                //
+                AcsDevArray[AcsCapCount].Bus = (UINT32)Bus;
+                AcsDevArray[AcsCapCount].Dev = (UINT32)Device;
+                AcsDevArray[AcsCapCount].Func = (UINT32)Function;
+                AcsDevArray[AcsCapCount].Offset = AcsOffset;
+                AcsDevArray[AcsCapCount].Seg = (UINT32)Segment;
+                AcsCapCount++;
+              }
+            }
+          }
+        }
+      }
+    }
+  }  /// End for
+
+  //
+  // Free the Handle buffer
+  //
+  if (HandleBuffer != NULL) {
+    gBS->FreePool (HandleBuffer);
+  }
+
+  ASSERT (AcsCapCount <= HandleCount);
+
+  //
+  // all PCI express switch downstream ports support ACS and meet the required ACS capabilities
+  // for each downstream ports, enable the required Capabilities in ACS control register
+  //
+  Address.Attribute.AccessWidth = UsraWidth16;
+  for (Index = 0; Index < AcsCapCount; Index ++) {
+    //
+    // Program the corresponding bits in ACS control register
+    //
+    Address.Pcie = AcsDevArray[Index];
+    Address.Pcie.Offset += ACS_CONTROL_REGISTER;
+    DynamicSiLibraryProtocol->RegisterRead (&Address, &AcsConRegValue);
+    DEBUG ((DEBUG_ERROR, "AcsConRegValue is 0x%x\n", AcsConRegValue));
+    AcsConRegValue |= (ACS_SOURCE_VALIDATION_ENABLE | ACS_P2P_REQUEST_REDIRECT_ENABLE | ACS_P2P_COMPLETION_REDIRECT_ENABLE | ACS_UPSTREAM_FORWARDING_ENABLE);
+    DEBUG ((DEBUG_ERROR, "After Enable BITs AcsConRegValue is 0x%x\n", AcsConRegValue));
+    DynamicSiLibraryProtocol->RegisterWrite (&Address, &AcsConRegValue);
+    //
+    // report VT-d and other features to OS/VMM, report DMAR and remapping engine to OS/VMM
+    //
+  }
+
+  //
+  // Find the AcpiSupport protocol
+  //
+  Status = LocateSupportProtocol (&gEfiAcpiTableProtocolGuid, gEfiAcpiTableStorageGuid, &AcpiTable, FALSE);
+  ASSERT_EFI_ERROR (Status);
+
+  TableVersion = EFI_ACPI_TABLE_VERSION_2_0;
+
+  Status = gBS->LocateProtocol (&gDmaRemapProtocolGuid, NULL, &DmaRemap);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "[ACPI](DMAR) ERROR: Cannot locate gDmaRemapProtocolGuid (%r)\n", Status));
+  } else {
+    if (DmaRemap->VTdSupport) {
+      ReportDmar (DmaRemap);
+      Status = DmaRemap->GetDmarTable (DmaRemap, &CurrentTable);
+
+      if (EFI_ERROR (Status)) {
+        ASSERT_EFI_ERROR (Status);
+      } else {
+        //
+        // Perform any table specific updates.
+        //
+        Status = PlatformUpdateTables (CurrentTable, &TableVersion);
+        ASSERT_EFI_ERROR (Status);
+
+        TableHandle = 0;
+        Status = AcpiTable->InstallAcpiTable (
+                            AcpiTable,
+                            CurrentTable,
+                            CurrentTable->Length,
+                            &TableHandle
+                            );
+        ASSERT_EFI_ERROR (Status);
+      }
+    }
+  }
+  FreePool (AcsDevArray);
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+LocateCapRegBlock (
+  IN     EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN     UINT8                CapID,
+  OUT    UINT8                *PciExpressOffset,
+  OUT    UINT8                *NextRegBlock
+  )
+{
+  UINT16  CapabilityID;
+  UINT32  Temp;
+  UINT8   CapabilityPtr;
+  UINT16  CapabilityEntry;
+
+  PciIo->Pci.Read (
+            PciIo,
+            EfiPciIoWidthUint32,
+            PCI_CAPBILITY_POINTER_OFFSET,
+            1,
+            &Temp
+            );
+
+  CapabilityPtr = (UINT8)Temp;
+  //
+  // According to the PCI spec a value of 0x00
+  // is the end of the list
+  //
+  while (CapabilityPtr >= 0x40) {
+    //
+    // Mask it to DWORD alignment per PCI spec
+    //
+    CapabilityPtr &= 0xFC;
+    PciIo->Pci.Read (
+               PciIo,
+               EfiPciIoWidthUint16,
+               CapabilityPtr,
+               1,
+               &CapabilityEntry
+               );
+
+    CapabilityID = (UINT8) CapabilityEntry;
+
+    if (CapabilityID == CapID) {
+      *PciExpressOffset = CapabilityPtr;
+      if (NextRegBlock != NULL) {
+        *NextRegBlock = (UINT8) ((CapabilityEntry >> 8) & 0xFC);
+      }
+
+      return EFI_SUCCESS;
+    }
+
+    CapabilityPtr = (UINT8) ((CapabilityEntry >> 8) & 0xFC);
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS
+LocatePciExpressCapRegBlock (
+  IN     EFI_PCI_IO_PROTOCOL  *PciIo,
+  IN     UINT16               CapID,
+  OUT    UINT32               *Offset,
+  OUT    UINT32               *NextRegBlock
+)
+{
+  UINT32  CapabilityPtr;
+  UINT32  CapabilityEntry;
+  UINT16  CapabilityID;
+
+  CapabilityPtr = EFI_PCIE_CAPABILITY_BASE_OFFSET;
+
+  while ((CapabilityPtr != 0) && (CapabilityPtr < 0x1000)) {
+    //
+    // Mask it to DWORD alignment per PCI spec
+    //
+    CapabilityPtr &= 0xFFC;
+    PciIo->Pci.Read (
+               PciIo,
+               EfiPciIoWidthUint32,
+               CapabilityPtr,
+               1,
+               &CapabilityEntry
+               );
+
+    CapabilityID = (UINT16) CapabilityEntry;
+
+    if (CapabilityID == CapID) {
+      *Offset = CapabilityPtr;
+      if (NextRegBlock != NULL) {
+        *NextRegBlock = (CapabilityEntry >> 20) & 0xFFF;
+      }
+
+      return EFI_SUCCESS;
+    }
+
+    CapabilityPtr = (CapabilityEntry >> 20) & 0xFFF;
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+
+VOID
+DisableAriForwarding (
+  VOID
+  )
+{
+  EFI_STATUS                  Status;
+  UINTN                       HandleCount;
+  EFI_HANDLE                  *HandleBuffer;
+  UINTN                       Index;
+  EFI_PCI_IO_PROTOCOL         *PciIo;
+  PCI_TYPE01                  PciConfigHeader;
+  UINTN                       Segment;
+  UINTN                       Bus;
+  UINTN                       Device;
+  UINTN                       Function;
+  UINT8                       PciExpressOffset;
+  PCI_REG_PCIE_DEVICE_CONTROL2 DevCtl2;
+
+  //
+  // Disable ARI forwarding before handoff to OS, as it may not be ARI-aware
+  //
+  //
+  // ARI forwarding exist in bridge
+  //
+
+  //
+  // Locate all PciIo protocol
+  //
+  Status = gBS->LocateHandleBuffer (
+               ByProtocol,
+               &gEfiPciIoProtocolGuid,
+               NULL,
+               &HandleCount,
+               &HandleBuffer
+               );
+  for (Index = 0; Index < HandleCount; Index ++) {
+    gBS->HandleProtocol (
+          HandleBuffer[Index],
+          &gEfiPciIoProtocolGuid,
+          &PciIo
+          );
+    PciIo->Pci.Read (
+                PciIo,
+                EfiPciIoWidthUint32,
+                0,
+                sizeof (PciConfigHeader) / sizeof (UINT32),
+                &PciConfigHeader
+                );
+    if ((PciConfigHeader.Hdr.ClassCode[0] == 0x00 || PciConfigHeader.Hdr.ClassCode[0] == 0x01) && PciConfigHeader.Hdr.ClassCode[1] == 0x04 && PciConfigHeader.Hdr.ClassCode[2] == 0x06) {
+      //
+      // 060400h or 060401h indicates it's PCI-PCI bridge, get its bus number, device number and function number
+      //
+      PciIo->GetLocation (
+              PciIo,
+              &Segment,
+              &Bus,
+              &Device,
+              &Function
+              );
+      if (PciConfigHeader.Hdr.Status == EFI_PCI_STATUS_CAPABILITY) {
+        //
+        // the bridge support Capability list and offset 0x34 is the pointer to the data structure
+        //
+        //
+        // Detect if PCI Express Device
+        //
+        Status = LocateCapRegBlock (PciIo, EFI_PCI_CAPABILITY_ID_PCIEXP, &PciExpressOffset, NULL);
+        if (Status == EFI_SUCCESS) {
+          //
+          // this bridge device is a PCI Express bridge, Check ARI forwarding bit in Device Control 2 register
+          //
+          PciIo->Pci.Read (
+                  PciIo,
+                  EfiPciIoWidthUint16,
+                  PciExpressOffset + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2),
+                  1,
+                  &DevCtl2
+                  );
+          if (DevCtl2.Bits.AriForwarding) {
+            //
+            // ARI forwarding enable bit is set, we need to clear this bit before handing off control to OS
+            // because OS may not ARI aware
+            //
+            DEBUG((DEBUG_INFO, "[VTD] %02X:%02X:%02X.%X: ARI forwarding disable before booting OS, DevCtl2 0x%02X -> 0x%02X\n",
+                   Segment, Bus, Device, Function, DevCtl2.Uint16, DevCtl2.Uint16 & ~BIT5));
+            DevCtl2.Bits.AriForwarding = 0;
+            PciIo->Pci.Write (
+                  PciIo,
+                  EfiPciIoWidthUint16,
+                  PciExpressOffset + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2),
+                  1,
+                  &DevCtl2
+                  );
+          }
+        }
+      }
+    }
+  }
+} // DisableAriForwarding()
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec
index a80472e73c..27253b1a58 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec
+++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec
@@ -24,6 +24,7 @@
 
 [Guids]
   gBiosInfoGuid                                       = { 0x1b453c67, 0xcb1a, 0x46ec, { 0x86, 0x4b, 0xe2, 0x24, 0xa6, 0xb7, 0xfe, 0xe8 } }
+  gEfiAcpiTableStorageGuid                            = { 0x7e374e25, 0x8e01, 0x4fee, { 0x87, 0xf2, 0x39, 0x0c, 0x23, 0xc6, 0x06, 0xcd } }
   gClvBootTimeTestExecution                           = { 0x3ff7d152, 0xef86, 0x47c3, { 0x97, 0xb0, 0xce, 0xd9, 0xbb, 0x80, 0x9a, 0x67 } }
   gUbaCurrentConfigHobGuid                            = { 0xe4b2025b, 0xc7db, 0x4e5d, { 0xa6, 0x5e, 0x2b, 0x25, 0x7e, 0xb1, 0x5,  0x8e } }
 
@@ -181,6 +182,11 @@
   gPlatformTokenSpaceGuid.PcdSupportLegacyStack|TRUE|BOOLEAN|0x30000030
   gPlatformTokenSpaceGuid.PcdMaxOptionRomNumber|0x4|UINT8|0x30000031
 
+  #
+  # Debug Mode indicator
+  #
+  gPlatformTokenSpaceGuid.PcdDebugModeEnable|0x01|UINT8|0xE0000040
+
   gPlatformTokenSpaceGuid.PcdCmosDebugPrintLevelReg|0x4C|UINT8|0x30000032
 
   # Choose the default serial debug message level when CMOS is bad; in the later BIOS phase, the setup default is applied
@@ -238,11 +244,6 @@
   gPlatformModuleTokenSpaceGuid.PcdPcIoApicInterruptBase|24|UINT32|0x90000018
 
 
-  gPlatformModuleTokenSpaceGuid.PcdMaxCpuThreadCount|2|UINT32|0x90000021
-  gPlatformModuleTokenSpaceGuid.PcdMaxCpuCoreCount|8|UINT32|0x90000022
-  gPlatformModuleTokenSpaceGuid.PcdMaxCpuSocketCount|4|UINT32|0x90000023
-  gPlatformModuleTokenSpaceGuid.PcdHpetTimerBlockId|0x8086A201|UINT32|0x90000024
-
   gPlatformModuleTokenSpaceGuid.PcdFadtPreferredPmProfile|0x02|UINT8|0x90000025
   gPlatformModuleTokenSpaceGuid.PcdFadtIaPcBootArch|0x0001|UINT16|0x90000026
   gPlatformModuleTokenSpaceGuid.PcdFadtFlags|0x000086A5|UINT32|0x90000027
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
index 5dfee0eeb5..042c27c709 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
+++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
@@ -809,7 +809,10 @@
 
   $(RP_PKG)/Features/Pci/Dxe/PciPlatform/PciPlatform.inf
 
+!if $(CPUTARGET) == "ICX"
+  $(RP_PKG)/Features/Acpi/AcpiPlatform/AcpiPlatform.inf
   $(RP_PKG)/Features/Acpi/AcpiTables/AcpiTables10nm.inf
+!endif
   $(RP_PKG)/Features/AcpiVtd/AcpiVtd.inf
 
   $(PLATFORM_PKG)/Acpi/AcpiSmm/AcpiSmm.inf
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.fdf b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.fdf
index ca3514b8ba..ab594ff409 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.fdf
+++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.fdf
@@ -671,7 +671,10 @@ SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize         = 0x01000000
   INF  BoardModulePkg/LegacySioDxe/LegacySioDxe.inf
   INF  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
 
+!if $(CPUTARGET) == "ICX"
   INF  RuleOverride = ACPITABLE WhitleyOpenBoardPkg/Features/Acpi/AcpiTables/AcpiTables10nm.inf
+  INF  WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.inf
+!endif
   INF  WhitleyOpenBoardPkg/Features/AcpiVtd/AcpiVtd.inf
   INF  MinPlatformPkg/Acpi/AcpiSmm/AcpiSmm.inf
 
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaMain/StaticSkuDataDxe/Readme.md b/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaMain/StaticSkuDataDxe/Readme.md
index 08fd02f922..58f9b88dae 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaMain/StaticSkuDataDxe/Readme.md
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaMain/StaticSkuDataDxe/Readme.md
@@ -16,4 +16,5 @@ The AmlOffsetTable.c file is generated in two key steps:
 
 Common Issues:
 * The same iasl compiler version must be used to build the AML offset table and to build the DSDT.
+* The same iasl compiler version must be used to build the AML offset table and to build the DSDT.  With the addition of -so for building the AML offset table.
 * The Board/*AmlOffsets*.dsc file name, Board/*AmlOffsets* directory name, Board/AmlOffsets/*AmlOffsets*.inf file name, and the BASE_NAME in *AmlOffsets*.inf must all match exactly.
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/WilsonCityRvp/AmlOffsets/AmlOffsets.inf b/Platform/Intel/WhitleyOpenBoardPkg/WilsonCityRvp/AmlOffsets/AmlOffsets.inf
index 8945f372e3..859875ab5b 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/WilsonCityRvp/AmlOffsets/AmlOffsets.inf
+++ b/Platform/Intel/WhitleyOpenBoardPkg/WilsonCityRvp/AmlOffsets/AmlOffsets.inf
@@ -23,4 +23,4 @@
 
 [BuildOptions]
   # add -vr and -so to generate offset.h
-  *_*_*_ASL_FLAGS = -oi -vr -so
+  *_*_*_ASL_FLAGS = -so
-- 
2.27.0.windows.1


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

* [edk2-devel][edk2-platforms][PATCH V1 9/9] WhitleyOpenBoardPkg/Build: Remove confusing build options
  2022-03-10 22:41 [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Oram, Isaac W
                   ` (7 preceding siblings ...)
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 8/9] WhitleyOpenBoardPkg/AcpiPlatform: Add driver for publishing ACPI tables Oram, Isaac W
@ 2022-03-10 22:41 ` Oram, Isaac W
  2022-03-11  1:12 ` [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Nate DeSimone
  9 siblings, 0 replies; 14+ messages in thread
From: Oram, Isaac W @ 2022-03-10 22:41 UTC (permalink / raw)
  To: devel; +Cc: Nate DeSimone, Chasel Chiu

There is an unnecessary inheritance of a SKX build option that has
confused the build settings.

Removed unused IE_ENABLE, PCH_PKG_OPTIONS, and SECURITY_OPTIONS

Fix a bug where changes in PlatformPkgConfig.dsc were not
taking effect because of missing [Defines] context.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>
---
 Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc        | 12 ++++--------
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc                     |  8 ++++----
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkgConfig.dsc               |  7 +------
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaDxeRpBoards.fdf              |  6 ++++--
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaRpBoards.dsc                 |  6 ++++--
 Silicon/Intel/WhitleySiliconPkg/Product/Whitley/SiliconPkg10nmPcds.dsc |  4 ++--
 6 files changed, 19 insertions(+), 24 deletions(-)

diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc b/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc
index 1a85a26e25..068ca195bf 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc
@@ -55,20 +55,16 @@ DEFINE NVDIMM_OPTIONS =
 
 !if $(CPUTARGET) == "ICX"
   DEFINE CPU_TYPE_OPTIONS  = -D ICX_HOST -D A0_HOST -D B0_HOST
+  DEFINE MAX_IMC_CH_OPTIONS = -D MAX_IMC=4 -D MAX_MC_CH=2
 !elseif $(CPUTARGET) == "CPX"
   DEFINE CPU_TYPE_OPTIONS  = -D SKX_HOST -D CLX_HOST -D CPX_HOST -D A0_HOST -D B0_HOST
+  DEFINE MAX_IMC_CH_OPTIONS = -D MAX_IMC=2 -D MAX_MC_CH=3
 !endif
 
 DEFINE MAX_SOCKET_CORE_THREAD_OPTIONS = -D MAX_SOCKET=$(MAX_SOCKET) -D MAX_CORE=$(MAX_CORE) -D MAX_THREAD=$(MAX_THREAD)
 
 DEFINE MRC_OPTIONS = -D LRDIMM_SUPPORT -D DDRT_SUPPORT
 
-!if $(CPU_SKX_ONLY_SUPPORT) == FALSE
-  DEFINE MAX_IMC_CH_OPTIONS = -D MAX_IMC=4 -D MAX_MC_CH=2
-!else
-  DEFINE MAX_IMC_CH_OPTIONS = -D MAX_IMC=2 -D MAX_MC_CH=3
-!endif
-
 DEFINE MAX_SAD_RULE_OPTION = -D MAX_SAD_RULES=24 -D MAX_DRAM_CLUSTERS=1
 
 DEFINE LT_BUILD_OPTIONS = -D LT_FLAG
@@ -88,9 +84,9 @@ DEFINE IIO_STACK_OPTIONS = -D MAX_IIO_STACK=6 -D MAX_LOGIC_IIO_STACK=8
 
 DEFINE PCH_BIOS_BUILD_OPTIONS = $(PCH_BUILD_OPTION) $(SC_PATH) $(SERVER_BUILD_OPTION)
 
-DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS = $(CRB_EDKII_BUILD_OPTIONS) $(EDKII_DEBUG_BUILD_OPTIONS) $(PCH_BIOS_BUILD_OPTIONS) $(PCH_PKG_OPTIONS) $(MAX_SOCKET_CORE_THREAD_OPTIONS) $(MAX_IMC_CH_OPTIONS) $(MAX_SAD_RULE_OPTION) $(KTI_OPTIONS) $(IIO_STACK_OPTIONS) $(LT_BUILD_OPTIONS) $(SECURITY_OPTIONS) $(SPARING_SCRATCHPAD_OPTION) $(SCRATCHPAD_DEBUG_OPTION) $(NVDIMM_OPTIONS) -D EFI_PCI_IOV_SUPPORT -D WHEA_SUPPORT $(CPU_TYPE_OPTIONS) -D MMCFG_BASE_ADDRESS=0x80000000 -D DISABLE_NEW_DEPRECATED_INTERFACES $(MRC_OPTIONS) $(FSP_BUILD_OPTIONS)
+DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS = $(CRB_EDKII_BUILD_OPTIONS) $(EDKII_DEBUG_BUILD_OPTIONS) $(PCH_BIOS_BUILD_OPTIONS) $(MAX_SOCKET_CORE_THREAD_OPTIONS) $(MAX_IMC_CH_OPTIONS) $(MAX_SAD_RULE_OPTION) $(KTI_OPTIONS) $(IIO_STACK_OPTIONS) $(LT_BUILD_OPTIONS) $(SPARING_SCRATCHPAD_OPTION) $(SCRATCHPAD_DEBUG_OPTION) $(NVDIMM_OPTIONS) -D EFI_PCI_IOV_SUPPORT -D WHEA_SUPPORT $(CPU_TYPE_OPTIONS) -D MMCFG_BASE_ADDRESS=0x80000000 -D DISABLE_NEW_DEPRECATED_INTERFACES $(MRC_OPTIONS) $(FSP_BUILD_OPTIONS)
 
-DEFINE IE_OPTIONS = $(IE_PATH) -DIE_SUPPORT=0
+DEFINE IE_OPTIONS = $(IE_PATH)
 
 !if $(LINUX_GCC_BUILD) == TRUE
   DEFINE EDK2_LINUX_BUILD_OPTIONS = -D EDK2_CTE_BUILD
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
index 042c27c709..8c4b9cf6ce 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
+++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
@@ -169,7 +169,7 @@
   ## This PCD specifies whether FPGA routine will be active
   gSocketPkgFpgaGuid.PcdSktFpgaActive|TRUE
 
-!if $(CPU_SKX_ONLY_SUPPORT) == TRUE
+!if $(CPUTARGET) == "CPX"
   gEfiCpRcPkgTokenSpaceGuid.PerBitMargin|FALSE
   gEfiCpRcPkgTokenSpaceGuid.PcdSeparateCwlAdj|TRUE
 !endif
@@ -343,7 +343,7 @@
   # Disable Fast Warm Boot for Whitley Openboard Package
   gEfiCpRcPkgTokenSpaceGuid.PcdMrcFastBootDefault|FALSE
 
-!if $(CPU_SKX_ONLY_SUPPORT) == FALSE
+!if $(CPUTARGET) == "ICX"
   gCpuUncoreTokenSpaceGuid.PcdWaSerializationEn|FALSE
   gEfiCpRcPkgTokenSpaceGuid.PcdMrcCmdVrefCenteringTrainingEnable|FALSE
 !endif
@@ -426,7 +426,7 @@
   #
 
   gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07         # Enable status codes for debug, progress, and errors
-  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000042           # Displayed messages:  Error, Info, warn
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000047           # Displayed messages:  Error, Info, warn
 
   gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x80000000
   gUefiCpuPkgTokenSpaceGuid.PcdCpuNumberOfReservedVariableMtrrs|0
@@ -856,7 +856,7 @@
   DEFINE CPU_CPX_SUPPORT                     = FALSE
 !endif
 [PcdsFixedAtBuild]
-!if ($(CPU_SKX_ONLY_SUPPORT) == TRUE)
+!if $(CPUTARGET) == "CPX"
   gSiPkgTokenSpaceGuid.PcdPostedCsrAccessSupported         |FALSE
 !endif
 [LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION]
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkgConfig.dsc b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkgConfig.dsc
index ecfdb895ba..a4ac8b6935 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkgConfig.dsc
+++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkgConfig.dsc
@@ -11,6 +11,7 @@
 # TRUE is ENABLE. FALSE is DISABLE.
 #
 
+[Defines]
 DEFINE CRB_FLAG_ENABLE                       = TRUE
 DEFINE DEBUG_FLAGS_ENABLE                    = FALSE
 
@@ -19,12 +20,6 @@ DEFINE PERFORMANCE_ENABLE                    = TRUE
 DEFINE SERVER_BIOS_ENABLE                    = TRUE
 DEFINE PCH_SERVER_BIOS_ENABLE                = TRUE
 
-!if $(CPUTARGET) == "CPX"
-  DEFINE CPU_SKX_ONLY_SUPPORT                = TRUE
-!else
-  DEFINE CPU_SKX_ONLY_SUPPORT                 = FALSE
-!endif
-
 !if $(CPUTARGET) == "CPX"
   DEFINE CPU_CPX_SUPPORT                     = TRUE
 !else
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaDxeRpBoards.fdf b/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaDxeRpBoards.fdf
index 7c182db5df..6010637a73 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaDxeRpBoards.fdf
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaDxeRpBoards.fdf
@@ -8,9 +8,11 @@
 ##
 
 #
-# Currently shared by all platforms
+# Currently shared by all ICX platforms
 #
-INF  $(RP_PKG)/Uba/UbaMain/StaticSkuDataDxe/StaticSkuDataDxe.inf
+!if $(CPUTARGET) == "ICX"
+  INF  $(RP_PKG)/Uba/UbaMain/StaticSkuDataDxe/StaticSkuDataDxe.inf
+!endif
 
 #
 # Platform TypeWilsonCityRP
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaRpBoards.dsc b/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaRpBoards.dsc
index 48b26de427..477745df07 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaRpBoards.dsc
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaRpBoards.dsc
@@ -31,9 +31,11 @@ $(RP_PKG)/Uba/BoardInit/Pei/BoardInitPei.inf {
 
 [Components.X64]
 #
-# Currently shared by all platforms
+# Currently shared by all ICX platforms
 #
-$(RP_PKG)/Uba/UbaMain/StaticSkuDataDxe/StaticSkuDataDxe.inf
+!if $(CPUTARGET) == "ICX"
+  $(RP_PKG)/Uba/UbaMain/StaticSkuDataDxe/StaticSkuDataDxe.inf
+!endif
 
 #
 # Platform TypeWilsonCityRP
diff --git a/Silicon/Intel/WhitleySiliconPkg/Product/Whitley/SiliconPkg10nmPcds.dsc b/Silicon/Intel/WhitleySiliconPkg/Product/Whitley/SiliconPkg10nmPcds.dsc
index 4402540f91..f9c588b61c 100644
--- a/Silicon/Intel/WhitleySiliconPkg/Product/Whitley/SiliconPkg10nmPcds.dsc
+++ b/Silicon/Intel/WhitleySiliconPkg/Product/Whitley/SiliconPkg10nmPcds.dsc
@@ -52,7 +52,7 @@
   # for 10nm
   #
 
-!if $(CPU_SKX_ONLY_SUPPORT) == TRUE
+!if $(CPUTARGET) == "CPX"
 
   gEfiCpRcPkgTokenSpaceGuid.PcdMrcBdatDefault|FALSE
   gEfiCpRcPkgTokenSpaceGuid.PcdMrcWritePreambleTclkDefault|0x0
@@ -96,4 +96,4 @@
   #
   # enable NVDIMM support
   #
-  gEfiCpRcPkgTokenSpaceGuid.PcdNvDimmEn|TRUE
\ No newline at end of file
+  gEfiCpRcPkgTokenSpaceGuid.PcdNvDimmEn|TRUE
-- 
2.27.0.windows.1


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

* Re: [edk2-devel][edk2-platforms][PATCH V1 3/9] WhitleyOpenBoardPkg/BaseCrcLib: Add library for CRC16
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 3/9] WhitleyOpenBoardPkg/BaseCrcLib: Add library for CRC16 Oram, Isaac W
@ 2022-03-10 23:18   ` Pedro Falcato
  2022-03-10 23:34     ` Oram, Isaac W
  0 siblings, 1 reply; 14+ messages in thread
From: Pedro Falcato @ 2022-03-10 23:18 UTC (permalink / raw)
  To: edk2-devel-groups-io, isaac.w.oram; +Cc: Nate DeSimone, Chasel Chiu

[-- Attachment #1: Type: text/plain, Size: 7200 bytes --]

Hi,

I've just noticed this patch adds CRC16, which I've already added to my
Ext4Pkg (
https://github.com/tianocore/edk2-platforms/blob/master/Features/Ext4Pkg/Ext4Dxe/Crc16.c
).
I suggest we add CRC16 (and possibly CRC32C, which I already have in my
package as well) to MdePkg, as to de-duplicate code which might be useful
in other places.
What do you think? If it sounds good to you, I'll open a bugzilla and work
on that.

Best regards,
Pedro

On Thu, Mar 10, 2022 at 10:41 PM Oram, Isaac W <isaac.w.oram@intel.com>
wrote:

> Core only supports CRC32, this library adds CRC16 support.
>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>
> ---
>  Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h          | 42
> ++++++++++++
>  Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c   | 71
> ++++++++++++++++++++
>  Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf | 23
> +++++++
>  Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc                   |  1
> +
>  4 files changed, 137 insertions(+)
>
> diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h
> b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h
> new file mode 100644
> index 0000000000..7ca3b7cabb
> --- /dev/null
> +++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h
> @@ -0,0 +1,42 @@
> +/** @file
> +  Interface header file for the CRC library class.
> +
> +  @copyright
> +  Copyright 2016 - 2018 Intel Corporation. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CRC_LIB_H_
> +#define _CRC_LIB_H_
> +
> +#include <Uefi.h>
> +
> +/**
> +  Calculate a 16-bit CRC.
> +
> +  The algorithm used is MSB-first form of the ITU-T Recommendation V.41,
> which
> +  uses an initial value of 0x0000 and a polynomial of 0x1021. It is the
> same
> +  algorithm used by XMODEM.
> +
> +  The output CRC location is not updated until the calculation is
> finished, so
> +  it is possible to pass a structure as the data, and the CRC field of
> the same
> +  structure as the output location for the calculated CRC. The CRC field
> should
> +  be set to zero before calling this function. Once the CRC field is
> updated by
> +  this function, running it again over the structure produces a CRC of
> zero.
> +
> +  @param[in]  Data              A pointer to the target data.
> +  @param[in]  DataSize          The target data size.
> +  @param[out] CrcOut            A pointer to the return location of the
> CRC.
> +
> +  @retval EFI_SUCCESS           The CRC was calculated successfully.
> +  @retval EFI_INVALID_PARAMETER A null pointer was provided.
> +**/
> +EFI_STATUS
> +CalculateCrc16 (
> +  IN  VOID    *Data,
> +  IN  UINTN   DataSize,
> +  OUT UINT16  *CrcOut
> +  );
> +
> +#endif  // _CRC_LIB_H_
> diff --git
> a/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c
> b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c
> new file mode 100644
> index 0000000000..3e8fa402ad
> --- /dev/null
> +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c
> @@ -0,0 +1,71 @@
> +/** @file
> +  Base implementation of the CRC library class.
> +
> +  @copyright
> +  Copyright 2016 - 2018 Intel Corporation. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Library/CrcLib.h>
> +
> +/**
> +  Calculate a 16-bit CRC.
> +
> +  The algorithm used is MSB-first form of the ITU-T Recommendation V.41,
> which
> +  uses an initial value of 0x0000 and a polynomial of 0x1021. It is the
> same
> +  algorithm used by XMODEM.
> +
> +  The output CRC location is not updated until the calculation is
> finished, so
> +  it is possible to pass a structure as the data, and the CRC field of
> the same
> +  structure as the output location for the calculated CRC. The CRC field
> should
> +  be set to zero before calling this function. Once the CRC field is
> updated by
> +  this function, running it again over the structure produces a CRC of
> zero.
> +
> +  @param[in]  Data              A pointer to the target data.
> +  @param[in]  DataSize          The target data size.
> +  @param[out] CrcOut            A pointer to the return location of the
> CRC.
> +
> +  @retval EFI_SUCCESS           The CRC was calculated successfully.
> +  @retval EFI_INVALID_PARAMETER A null pointer was provided.
> +**/
> +EFI_STATUS
> +CalculateCrc16 (
> +  IN  VOID    *Data,
> +  IN  UINTN   DataSize,
> +  OUT UINT16  *CrcOut
> +  )
> +{
> +  UINT32  Crc;
> +  UINTN   Index;
> +  UINT8   *Byte;
> +
> +  if (Data == NULL || CrcOut == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Crc = 0x0000;
> +  for (Byte = (UINT8 *) Data; Byte < (UINT8 *) Data + DataSize; Byte++) {
> +    //
> +    // XOR the next data byte into the CRC.
> +    //
> +    Crc ^= (UINT16) *Byte << 8;
> +    //
> +    // Shift out eight bits, feeding back based on the polynomial
> whenever a
> +    // 1 is shifted out of bit 15.
> +    //
> +    for (Index = 0; Index < 8; Index++) {
> +      Crc <<= 1;
> +      if (Crc & BIT16) {
> +        Crc ^= 0x1021;
> +      }
> +    }
> +  }
> +
> +  //
> +  // Mask and return the 16-bit CRC.
> +  //
> +  *CrcOut = (UINT16) (Crc & 0xFFFF);
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
> b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
> new file mode 100644
> index 0000000000..6b404e1259
> --- /dev/null
> +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
> @@ -0,0 +1,23 @@
> +## @file
> +# Base implementation of the CRC library class.
> +#
> +# @copyright
> +# Copyright 2016 Intel Corporation. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> +  INF_VERSION                   = 0x00010019
> +  BASE_NAME                     = BaseCrcLib
> +  FILE_GUID                     = F3BE9A28-78A2-4B02-AB26-D27EE85D9256
> +  MODULE_TYPE                   = BASE
> +  VERSION_STRING                = 1.0
> +  LIBRARY_CLASS                 = CrcLib
> +
> +[Sources]
> +  BaseCrcLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  WhitleyOpenBoardPkg/PlatformPkg.dec
> diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
> b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
> index e78a104004..9cdb5bc2f6 100644
> --- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
> +++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
> @@ -618,6 +618,7 @@
>
>  PciSegmentInfoLib|$(PLATFORM_PKG)/Pci/Library/PciSegmentInfoLibSimple/PciSegmentInfoLibSimple.inf
>
>  PlatformOpromPolicyLib|$(RP_PKG)/Library/PlatformOpromPolicyLibNull/PlatformOpromPolicyLibNull.inf
>    VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> +  CrcLib|WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
>
>  [LibraryClasses.Common.SEC, LibraryClasses.Common.PEI_CORE,
> LibraryClasses.Common.PEIM]
>
>  FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
> --
> 2.27.0.windows.1
>
>
>
> 
>
>
>

-- 
Pedro Falcato

[-- Attachment #2: Type: text/html, Size: 8816 bytes --]

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

* Re: [edk2-devel][edk2-platforms][PATCH V1 3/9] WhitleyOpenBoardPkg/BaseCrcLib: Add library for CRC16
  2022-03-10 23:18   ` Pedro Falcato
@ 2022-03-10 23:34     ` Oram, Isaac W
  0 siblings, 0 replies; 14+ messages in thread
From: Oram, Isaac W @ 2022-03-10 23:34 UTC (permalink / raw)
  To: Pedro Falcato, edk2-devel-groups-io; +Cc: Desimone, Nathaniel L, Chiu, Chasel

[-- Attachment #1: Type: text/plain, Size: 7685 bytes --]

Pedro,

It sounds good to me.  I am exposing our formerly proprietary code without much refactoring.  But I see no reason to have CRC related code in multiple libraries.

Regards,
Isaac

From: Pedro Falcato <pedro.falcato@gmail.com>
Sent: Thursday, March 10, 2022 3:19 PM
To: edk2-devel-groups-io <devel@edk2.groups.io>; Oram, Isaac W <isaac.w.oram@intel.com>
Cc: Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>
Subject: Re: [edk2-devel][edk2-platforms][PATCH V1 3/9] WhitleyOpenBoardPkg/BaseCrcLib: Add library for CRC16

Hi,

I've just noticed this patch adds CRC16, which I've already added to my Ext4Pkg (https://github.com/tianocore/edk2-platforms/blob/master/Features/Ext4Pkg/Ext4Dxe/Crc16.c).
I suggest we add CRC16 (and possibly CRC32C, which I already have in my package as well) to MdePkg, as to de-duplicate code which might be useful in other places.
What do you think? If it sounds good to you, I'll open a bugzilla and work on that.

Best regards,
Pedro

On Thu, Mar 10, 2022 at 10:41 PM Oram, Isaac W <isaac.w.oram@intel.com<mailto:isaac.w.oram@intel.com>> wrote:
Core only supports CRC32, this library adds CRC16 support.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com<mailto:nathaniel.l.desimone@intel.com>>
Cc: Chasel Chiu <chasel.chiu@intel.com<mailto:chasel.chiu@intel.com>>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com<mailto:isaac.w.oram@intel.com>>
---
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h          | 42 ++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c   | 71 ++++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf | 23 +++++++
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc                   |  1 +
 4 files changed, 137 insertions(+)

diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h
new file mode 100644
index 0000000000..7ca3b7cabb
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h
@@ -0,0 +1,42 @@
+/** @file
+  Interface header file for the CRC library class.
+
+  @copyright
+  Copyright 2016 - 2018 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CRC_LIB_H_
+#define _CRC_LIB_H_
+
+#include <Uefi.h>
+
+/**
+  Calculate a 16-bit CRC.
+
+  The algorithm used is MSB-first form of the ITU-T Recommendation V.41, which
+  uses an initial value of 0x0000 and a polynomial of 0x1021. It is the same
+  algorithm used by XMODEM.
+
+  The output CRC location is not updated until the calculation is finished, so
+  it is possible to pass a structure as the data, and the CRC field of the same
+  structure as the output location for the calculated CRC. The CRC field should
+  be set to zero before calling this function. Once the CRC field is updated by
+  this function, running it again over the structure produces a CRC of zero.
+
+  @param[in]  Data              A pointer to the target data.
+  @param[in]  DataSize          The target data size.
+  @param[out] CrcOut            A pointer to the return location of the CRC.
+
+  @retval EFI_SUCCESS           The CRC was calculated successfully.
+  @retval EFI_INVALID_PARAMETER A null pointer was provided.
+**/
+EFI_STATUS
+CalculateCrc16 (
+  IN  VOID    *Data,
+  IN  UINTN   DataSize,
+  OUT UINT16  *CrcOut
+  );
+
+#endif  // _CRC_LIB_H_
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c
new file mode 100644
index 0000000000..3e8fa402ad
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c
@@ -0,0 +1,71 @@
+/** @file
+  Base implementation of the CRC library class.
+
+  @copyright
+  Copyright 2016 - 2018 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/CrcLib.h>
+
+/**
+  Calculate a 16-bit CRC.
+
+  The algorithm used is MSB-first form of the ITU-T Recommendation V.41, which
+  uses an initial value of 0x0000 and a polynomial of 0x1021. It is the same
+  algorithm used by XMODEM.
+
+  The output CRC location is not updated until the calculation is finished, so
+  it is possible to pass a structure as the data, and the CRC field of the same
+  structure as the output location for the calculated CRC. The CRC field should
+  be set to zero before calling this function. Once the CRC field is updated by
+  this function, running it again over the structure produces a CRC of zero.
+
+  @param[in]  Data              A pointer to the target data.
+  @param[in]  DataSize          The target data size.
+  @param[out] CrcOut            A pointer to the return location of the CRC.
+
+  @retval EFI_SUCCESS           The CRC was calculated successfully.
+  @retval EFI_INVALID_PARAMETER A null pointer was provided.
+**/
+EFI_STATUS
+CalculateCrc16 (
+  IN  VOID    *Data,
+  IN  UINTN   DataSize,
+  OUT UINT16  *CrcOut
+  )
+{
+  UINT32  Crc;
+  UINTN   Index;
+  UINT8   *Byte;
+
+  if (Data == NULL || CrcOut == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Crc = 0x0000;
+  for (Byte = (UINT8 *) Data; Byte < (UINT8 *) Data + DataSize; Byte++) {
+    //
+    // XOR the next data byte into the CRC.
+    //
+    Crc ^= (UINT16) *Byte << 8;
+    //
+    // Shift out eight bits, feeding back based on the polynomial whenever a
+    // 1 is shifted out of bit 15.
+    //
+    for (Index = 0; Index < 8; Index++) {
+      Crc <<= 1;
+      if (Crc & BIT16) {
+        Crc ^= 0x1021;
+      }
+    }
+  }
+
+  //
+  // Mask and return the 16-bit CRC.
+  //
+  *CrcOut = (UINT16) (Crc & 0xFFFF);
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
new file mode 100644
index 0000000000..6b404e1259
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
@@ -0,0 +1,23 @@
+## @file
+# Base implementation of the CRC library class.
+#
+# @copyright
+# Copyright 2016 Intel Corporation. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                   = 0x00010019
+  BASE_NAME                     = BaseCrcLib
+  FILE_GUID                     = F3BE9A28-78A2-4B02-AB26-D27EE85D9256
+  MODULE_TYPE                   = BASE
+  VERSION_STRING                = 1.0
+  LIBRARY_CLASS                 = CrcLib
+
+[Sources]
+  BaseCrcLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
index e78a104004..9cdb5bc2f6 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
+++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
@@ -618,6 +618,7 @@
   PciSegmentInfoLib|$(PLATFORM_PKG)/Pci/Library/PciSegmentInfoLibSimple/PciSegmentInfoLibSimple.inf
   PlatformOpromPolicyLib|$(RP_PKG)/Library/PlatformOpromPolicyLibNull/PlatformOpromPolicyLibNull.inf
   VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
+  CrcLib|WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf

 [LibraryClasses.Common.SEC, LibraryClasses.Common.PEI_CORE, LibraryClasses.Common.PEIM]
   FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
--
2.27.0.windows.1







--
Pedro Falcato

[-- Attachment #2: Type: text/html, Size: 12967 bytes --]

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

* Re: [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver
  2022-03-10 22:41 [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Oram, Isaac W
                   ` (8 preceding siblings ...)
  2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 9/9] WhitleyOpenBoardPkg/Build: Remove confusing build options Oram, Isaac W
@ 2022-03-11  1:12 ` Nate DeSimone
  2022-03-11 18:49   ` Oram, Isaac W
  9 siblings, 1 reply; 14+ messages in thread
From: Nate DeSimone @ 2022-03-11  1:12 UTC (permalink / raw)
  To: Oram, Isaac W, devel@edk2.groups.io; +Cc: Chiu, Chasel

For the series...

Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>

-----Original Message-----
From: Oram, Isaac W <isaac.w.oram@intel.com> 
Sent: Thursday, March 10, 2022 2:41 PM
To: devel@edk2.groups.io
Cc: Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>
Subject: [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver

This series converts the AcpiPlatform driver for Whitley ICX to open source.
The driver requires libraries providing:
16-bit CRC service
A library to update the tables based on boot time data.
A board hook library to control publishing individual tables and to modify tables.
A library to build MADT and SRAT tables during boot.
A Universal Board Abstraction library to translate UBA data.

The driver consumes the AcpiTables data file and the AML opcode patching table From StaticSkuDataDxe driver.

This code does not support the CooperCity hardware at present.
The code depends on additional DynamicSiLibraryProtocol2 and updated WhitleyFspBinPkg content.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>

Isaac Oram (9):
  WhitleyOpenBoardPkg: Add definitions needed for AcpiPlatform driver
  WhitleySiliconPkg: Add definitions used in ACPI subsystem
  WhitleyOpenBoardPkg/BaseCrcLib: Add library for CRC16
  WhitleyOpenBoardPkg: Add UbaPlatLib Library
  WhitleyOpenBoardPkg/PlatformSpecificAcpiTableLib: Add library
  WhitleyOpenBoardPkg/BuildAcpiTablesLib: Add lib for building MADT and
    SRAT
  WhitleyOpenBoardPkg/AcpiTablesLib: Add library for AcpiPlatform driver
  WhitleyOpenBoardPkg/AcpiPlatform: Add driver for publishing ACPI
    tables
  WhitleyOpenBoardPkg/Build: Remove confusing build options

 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.c                                     |  754 +++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.h                                     |  117 ++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.inf                                   |  107 ++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.c                                |  384 +++++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.h                                |   51 +
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.c                                |  133 ++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.h                                |   66 +
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformVTDHooks.c                             | 1762 ++++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciHostBridge/PciHostBridge.inf                              |    1 +
 Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciPlatform/PciPlatform.inf                                  |    1 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Madt.h                                                           |  118 ++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Slit.h                                                           |   75 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Srat.h                                                           |   53 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/amlresrc.h                                                       |  542 ++++++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc                                                  |   18 +-
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/AcpiPlatformLib.h                                             |  107 ++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h                                          |  111 ++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h                                                      |   42 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSpecificAcpiTableLib.h                                |  129 ++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformStatusCodes.h                                         |  364 ++++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaFpkConfigLib.h                                             |   55 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaSmbiosUpdateLib.h                                          |  275 +++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.c                                |  534 ++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.inf                              |  127 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibApic.c                            |  735 ++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibBdat.c                            | 1574 +++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibDsdt.c                            |  673 ++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibFadt.c                            |   75 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibHmat.c                            | 1710 +++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibLocal.h                           |  441 +++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMcfg.c                            |  134 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMigt.c                            |   69 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMsct.c                            |  101 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibNfit.c                            |   45 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPcat.c                            |   42 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPmtt.c                            |  267 +++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSlit.c                            | 1153 +++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSrat.c                            |  952 +++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSsdt.c                            | 1004 +++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c                                               |   71 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf                                             |   23 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/BoardInitLib/BoardInitDxeLib.inf                                      |    1 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.c                            |  470 ++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf                          |   40 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/AcpiPlatformLibSpcrNull.c            |   23 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.c   |   50 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf |   27 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaGpioPlatformConfigLib.c                              |  388 +++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemBoardInfoLib.c                                 |   62 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemConfigUpdateLib.c                              |   60 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaUsbOcUpdateLib.c                                     |   61 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaAcpiUpdateLib.c                                         |   59 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaFpkConfigLib.c                                          |   57 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaIioConfigLib.c                                          |  132 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaOpromUpdateLib.c                                        |  221 +++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaPlatLib.inf                                             |   62 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSlotUpdateLib.c                                         |  114 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSmbiosUpdateLib.c                                       |  663 ++++++++
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec                                                               |   16 +-
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc                                                               |   15 +-
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.fdf                                                               |    3 +
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkgConfig.dsc                                                         |    7 +-
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaCommon.dsc                                                             |    3 +
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaDxeRpBoards.fdf                                                        |    6 +-
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaMain/StaticSkuDataDxe/Readme.md                                        |    1 +
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaRpBoards.dsc                                                           |    6 +-
 Platform/Intel/WhitleyOpenBoardPkg/WilsonCityRvp/AmlOffsets/AmlOffsets.inf                                       |    2 +-
 Silicon/Intel/WhitleySiliconPkg/CpRcPkg.dec                                                                      |    3 +
 Silicon/Intel/WhitleySiliconPkg/Cpu/Include/CpuDataStruct.h                                                      |    7 +
 Silicon/Intel/WhitleySiliconPkg/Cpu/Include/Library/CpuConfigLib.h                                               |   82 +
 Silicon/Intel/WhitleySiliconPkg/Include/BackCompatible.h                                                         |    3 +
 Silicon/Intel/WhitleySiliconPkg/Include/BdatSchema.h                                                             |  301 ++++
 Silicon/Intel/WhitleySiliconPkg/Include/Guid/MemoryMapData.h                                                     |    2 +
 Silicon/Intel/WhitleySiliconPkg/Include/IioRegs.h                                                                |   74 +-
 Silicon/Intel/WhitleySiliconPkg/Include/Library/EnhancedWarningLogLib.h                                          |  494 ++++++
 Silicon/Intel/WhitleySiliconPkg/Include/Library/SpdAccessLib.h                                                   |   32 +
 Silicon/Intel/WhitleySiliconPkg/Include/MemCommon.h                                                              |    7 +
 Silicon/Intel/WhitleySiliconPkg/Include/Platform.h                                                               |    7 +
 Silicon/Intel/WhitleySiliconPkg/Include/Ppi/MemoryPolicyPpi.h                                                    |    2 +-
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/AcpiPlatformProtocol.h                                          |   51 +
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/CpuCsrAccess.h                                                  |  254 +++
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol.h                                      |   43 +-
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol2.h                                     |  255 +++
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/NfitTableUpdateProtocol.h                                       |   27 +
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/SmbiosMemInfo.h                                                 |   87 +
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MemRegs.h                                 |    2 +
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MrcCommonTypes.h                          |   25 +
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/SysHost.h                                 |   34 +-
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Platform/MemDefaults.h                                 |    7 +
 Silicon/Intel/WhitleySiliconPkg/Pch/SouthClusterLbg/Include/PchInfoHob.h                                         |   50 +
 Silicon/Intel/WhitleySiliconPkg/Product/Whitley/SiliconPkg10nmPcds.dsc                                           |    4 +-
 Silicon/Intel/WhitleySiliconPkg/WhitleySiliconPkg.dec                                                            |    1 +
 92 files changed, 19300 insertions(+), 98 deletions(-)  create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformVTDHooks.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Madt.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Slit.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Srat.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/amlresrc.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/AcpiPlatformLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSpecificAcpiTableLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformStatusCodes.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaFpkConfigLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaSmbiosUpdateLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibApic.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibBdat.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibDsdt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibFadt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibHmat.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibLocal.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMcfg.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMigt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMsct.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibNfit.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPcat.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPmtt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSlit.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSrat.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSsdt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/AcpiPlatformLibSpcrNull.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaGpioPlatformConfigLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemBoardInfoLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemConfigUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaUsbOcUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaAcpiUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaFpkConfigLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaIioConfigLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaOpromUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaPlatLib.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSlotUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSmbiosUpdateLib.c
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/BdatSchema.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Library/EnhancedWarningLogLib.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Library/SpdAccessLib.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/AcpiPlatformProtocol.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/CpuCsrAccess.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol2.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/NfitTableUpdateProtocol.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/SmbiosMemInfo.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Pch/SouthClusterLbg/Include/PchInfoHob.h

--
2.27.0.windows.1

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

* Re: [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver
  2022-03-11  1:12 ` [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Nate DeSimone
@ 2022-03-11 18:49   ` Oram, Isaac W
  0 siblings, 0 replies; 14+ messages in thread
From: Oram, Isaac W @ 2022-03-11 18:49 UTC (permalink / raw)
  To: Desimone, Nathaniel L, devel@edk2.groups.io; +Cc: Chiu, Chasel

Pushed as: 3c40bddded..7cd51aa3c1

-----Original Message-----
From: Desimone, Nathaniel L <nathaniel.l.desimone@intel.com> 
Sent: Thursday, March 10, 2022 5:13 PM
To: Oram, Isaac W <isaac.w.oram@intel.com>; devel@edk2.groups.io
Cc: Chiu, Chasel <chasel.chiu@intel.com>
Subject: RE: [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver

For the series...

Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>

-----Original Message-----
From: Oram, Isaac W <isaac.w.oram@intel.com> 
Sent: Thursday, March 10, 2022 2:41 PM
To: devel@edk2.groups.io
Cc: Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>
Subject: [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver

This series converts the AcpiPlatform driver for Whitley ICX to open source.
The driver requires libraries providing:
16-bit CRC service
A library to update the tables based on boot time data.
A board hook library to control publishing individual tables and to modify tables.
A library to build MADT and SRAT tables during boot.
A Universal Board Abstraction library to translate UBA data.

The driver consumes the AcpiTables data file and the AML opcode patching table From StaticSkuDataDxe driver.

This code does not support the CooperCity hardware at present.
The code depends on additional DynamicSiLibraryProtocol2 and updated WhitleyFspBinPkg content.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>

Isaac Oram (9):
  WhitleyOpenBoardPkg: Add definitions needed for AcpiPlatform driver
  WhitleySiliconPkg: Add definitions used in ACPI subsystem
  WhitleyOpenBoardPkg/BaseCrcLib: Add library for CRC16
  WhitleyOpenBoardPkg: Add UbaPlatLib Library
  WhitleyOpenBoardPkg/PlatformSpecificAcpiTableLib: Add library
  WhitleyOpenBoardPkg/BuildAcpiTablesLib: Add lib for building MADT and
    SRAT
  WhitleyOpenBoardPkg/AcpiTablesLib: Add library for AcpiPlatform driver
  WhitleyOpenBoardPkg/AcpiPlatform: Add driver for publishing ACPI
    tables
  WhitleyOpenBoardPkg/Build: Remove confusing build options

 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.c                                     |  754 +++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.h                                     |  117 ++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.inf                                   |  107 ++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.c                                |  384 +++++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.h                                |   51 +
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.c                                |  133 ++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.h                                |   66 +
 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformVTDHooks.c                             | 1762 ++++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciHostBridge/PciHostBridge.inf                              |    1 +
 Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciPlatform/PciPlatform.inf                                  |    1 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Madt.h                                                           |  118 ++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Slit.h                                                           |   75 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Srat.h                                                           |   53 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/amlresrc.h                                                       |  542 ++++++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc                                                  |   18 +-
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/AcpiPlatformLib.h                                             |  107 ++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h                                          |  111 ++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h                                                      |   42 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSpecificAcpiTableLib.h                                |  129 ++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformStatusCodes.h                                         |  364 ++++
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaFpkConfigLib.h                                             |   55 +
 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaSmbiosUpdateLib.h                                          |  275 +++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.c                                |  534 ++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.inf                              |  127 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibApic.c                            |  735 ++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibBdat.c                            | 1574 +++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibDsdt.c                            |  673 ++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibFadt.c                            |   75 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibHmat.c                            | 1710 +++++++++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibLocal.h                           |  441 +++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMcfg.c                            |  134 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMigt.c                            |   69 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMsct.c                            |  101 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibNfit.c                            |   45 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPcat.c                            |   42 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPmtt.c                            |  267 +++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSlit.c                            | 1153 +++++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSrat.c                            |  952 +++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSsdt.c                            | 1004 +++++++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c                                               |   71 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf                                             |   23 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/BoardInitLib/BoardInitDxeLib.inf                                      |    1 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.c                            |  470 ++++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf                          |   40 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/AcpiPlatformLibSpcrNull.c            |   23 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.c   |   50 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf |   27 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaGpioPlatformConfigLib.c                              |  388 +++++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemBoardInfoLib.c                                 |   62 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemConfigUpdateLib.c                              |   60 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaUsbOcUpdateLib.c                                     |   61 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaAcpiUpdateLib.c                                         |   59 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaFpkConfigLib.c                                          |   57 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaIioConfigLib.c                                          |  132 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaOpromUpdateLib.c                                        |  221 +++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaPlatLib.inf                                             |   62 +
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSlotUpdateLib.c                                         |  114 ++
 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSmbiosUpdateLib.c                                       |  663 ++++++++
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec                                                               |   16 +-
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc                                                               |   15 +-
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.fdf                                                               |    3 +
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkgConfig.dsc                                                         |    7 +-
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaCommon.dsc                                                             |    3 +
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaDxeRpBoards.fdf                                                        |    6 +-
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaMain/StaticSkuDataDxe/Readme.md                                        |    1 +
 Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaRpBoards.dsc                                                           |    6 +-
 Platform/Intel/WhitleyOpenBoardPkg/WilsonCityRvp/AmlOffsets/AmlOffsets.inf                                       |    2 +-
 Silicon/Intel/WhitleySiliconPkg/CpRcPkg.dec                                                                      |    3 +
 Silicon/Intel/WhitleySiliconPkg/Cpu/Include/CpuDataStruct.h                                                      |    7 +
 Silicon/Intel/WhitleySiliconPkg/Cpu/Include/Library/CpuConfigLib.h                                               |   82 +
 Silicon/Intel/WhitleySiliconPkg/Include/BackCompatible.h                                                         |    3 +
 Silicon/Intel/WhitleySiliconPkg/Include/BdatSchema.h                                                             |  301 ++++
 Silicon/Intel/WhitleySiliconPkg/Include/Guid/MemoryMapData.h                                                     |    2 +
 Silicon/Intel/WhitleySiliconPkg/Include/IioRegs.h                                                                |   74 +-
 Silicon/Intel/WhitleySiliconPkg/Include/Library/EnhancedWarningLogLib.h                                          |  494 ++++++
 Silicon/Intel/WhitleySiliconPkg/Include/Library/SpdAccessLib.h                                                   |   32 +
 Silicon/Intel/WhitleySiliconPkg/Include/MemCommon.h                                                              |    7 +
 Silicon/Intel/WhitleySiliconPkg/Include/Platform.h                                                               |    7 +
 Silicon/Intel/WhitleySiliconPkg/Include/Ppi/MemoryPolicyPpi.h                                                    |    2 +-
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/AcpiPlatformProtocol.h                                          |   51 +
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/CpuCsrAccess.h                                                  |  254 +++
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol.h                                      |   43 +-
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol2.h                                     |  255 +++
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/NfitTableUpdateProtocol.h                                       |   27 +
 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/SmbiosMemInfo.h                                                 |   87 +
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MemRegs.h                                 |    2 +
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/MrcCommonTypes.h                          |   25 +
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/SysHost.h                                 |   34 +-
 Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Platform/MemDefaults.h                                 |    7 +
 Silicon/Intel/WhitleySiliconPkg/Pch/SouthClusterLbg/Include/PchInfoHob.h                                         |   50 +
 Silicon/Intel/WhitleySiliconPkg/Product/Whitley/SiliconPkg10nmPcds.dsc                                           |    4 +-
 Silicon/Intel/WhitleySiliconPkg/WhitleySiliconPkg.dec                                                            |    1 +
 92 files changed, 19300 insertions(+), 98 deletions(-)  create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformHooks.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformUtils.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatformVTDHooks.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Madt.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Slit.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Srat.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/amlresrc.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/AcpiPlatformLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSpecificAcpiTableLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformStatusCodes.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaFpkConfigLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaSmbiosUpdateLib.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLib.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibApic.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibBdat.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibDsdt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibFadt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibHmat.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibLocal.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMcfg.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMigt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibMsct.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibNfit.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPcat.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibPmtt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSlit.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSrat.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatformLibSsdt.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/AcpiPlatformLibSpcrNull.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaGpioPlatformConfigLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemBoardInfoLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemConfigUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaUsbOcUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaAcpiUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaFpkConfigLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaIioConfigLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaOpromUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaPlatLib.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSlotUpdateLib.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSmbiosUpdateLib.c
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/BdatSchema.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Library/EnhancedWarningLogLib.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Library/SpdAccessLib.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/AcpiPlatformProtocol.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/CpuCsrAccess.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol2.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/NfitTableUpdateProtocol.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Include/Protocol/SmbiosMemInfo.h
 create mode 100644 Silicon/Intel/WhitleySiliconPkg/Pch/SouthClusterLbg/Include/PchInfoHob.h

--
2.27.0.windows.1

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

end of thread, other threads:[~2022-03-11 18:49 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-10 22:41 [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 1/9] WhitleyOpenBoardPkg: Add definitions needed for " Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 2/9] WhitleySiliconPkg: Add definitions used in ACPI subsystem Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 3/9] WhitleyOpenBoardPkg/BaseCrcLib: Add library for CRC16 Oram, Isaac W
2022-03-10 23:18   ` Pedro Falcato
2022-03-10 23:34     ` Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 4/9] WhitleyOpenBoardPkg: Add UbaPlatLib Library Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 5/9] WhitleyOpenBoardPkg/PlatformSpecificAcpiTableLib: Add library Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 6/9] WhitleyOpenBoardPkg/BuildAcpiTablesLib: Add lib for building MADT and SRAT Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 7/9] WhitleyOpenBoardPkg/AcpiTablesLib: Add library for AcpiPlatform driver Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 8/9] WhitleyOpenBoardPkg/AcpiPlatform: Add driver for publishing ACPI tables Oram, Isaac W
2022-03-10 22:41 ` [edk2-devel][edk2-platforms][PATCH V1 9/9] WhitleyOpenBoardPkg/Build: Remove confusing build options Oram, Isaac W
2022-03-11  1:12 ` [edk2-devel][edk2-platforms][PATCH V1 0/9] Add Whitley AcpiPlatform driver Nate DeSimone
2022-03-11 18:49   ` Oram, Isaac W

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