public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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


  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