From: "Oram, Isaac W" <isaac.w.oram@intel.com>
To: devel@edk2.groups.io
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>,
Chasel Chiu <chasel.chiu@intel.com>
Subject: [edk2-devel][edk2-platforms][PATCH V1 8/9] WhitleyOpenBoardPkg/AcpiPlatform: Add driver for publishing ACPI tables
Date: Thu, 10 Mar 2022 14:41:13 -0800 [thread overview]
Message-ID: <ffbeafad7e1038609ba61ac12d3498c4beea6efa.1646951441.git.isaac.w.oram@intel.com> (raw)
In-Reply-To: <cover.1646951441.git.isaac.w.oram@intel.com>
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
next prev parent reply other threads:[~2022-03-10 22:41 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
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 ` Oram, Isaac W [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ffbeafad7e1038609ba61ac12d3498c4beea6efa.1646951441.git.isaac.w.oram@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox