* [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