[edk2-devel] [Patch V2 30/40] TigerlakeSiliconPkg/IpBlock: Add Vtd component

Heng Luo heng.luo at intel.com
Thu Feb 4 08:49:09 UTC 2021


REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/Vtd/IncludePrivate
  * IpBlock/Vtd/Library
  * IpBlock/Vtd/LibraryPrivate

Cc: Sai Chaganty <rangasai.v.chaganty at intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone at intel.com>
Signed-off-by: Heng Luo <heng.luo at intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdInitLib.h              |  62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdPolicyLib.h            |  67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/VtdDataHob.h                         |  32 ++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/PeiDxeSmmVtdInfoLib.inf |  45 +++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/VtdInfoLib.c            |  86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.c        | 684 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.inf      |  71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.c    |  90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.inf  |  35 +++++++++++++++++++++++++++++++++++
 9 files changed, 1172 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdInitLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdInitLib.h
new file mode 100644
index 0000000000..e439cfbac2
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdInitLib.h
@@ -0,0 +1,62 @@
+/** @file
+  Header file for DXE VTD Init Lib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DXE_VTD_INIT_LIB_H_
+#define _DXE_VTD_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/VtdInfoLib.h>
+#include <Library/SaPlatformLib.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/Pci.h>
+#include <VtdDataHob.h>
+#include <PchConfigHob.h>
+#include <PchInfoHob.h>
+#include <Register/P2sbRegs.h>
+#include <Register/IpuRegs.h>
+#include <Register/IgdRegs.h>
+#include <Register/VtdRegs.h>
+#include <DmaRemappingTable.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/SaPolicy.h>
+#include <Protocol/SaNvsArea.h>
+#include <Protocol/FirmwareVolume2.h>
+
+/**
+  Locate the VT-d ACPI tables data file and read ACPI SSDT tables.
+  Publish the appropriate SSDT based on current configuration and capabilities.
+
+  @param[in] SaPolicy            SA DXE Policy protocol
+
+  @retval EFI_SUCCESS - Vtd initialization complete
+  @retval Other       - No Vtd function initiated
+**/
+EFI_STATUS
+VtdInit (
+  IN  SA_POLICY_PROTOCOL    *SaPolicy
+  );
+
+/**
+  EndOfPcieEnum routine for update DMAR
+**/
+VOID
+UpdateDmarEndOfPcieEnum (
+  VOID
+  );
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdPolicyLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdPolicyLib.h
new file mode 100644
index 0000000000..d55cf6bc34
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdPolicyLib.h
@@ -0,0 +1,67 @@
+/** @file
+  Prototype of the DXE VTD Policy Init library.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DXE_VTD_POLICY_INIT_LIB_H_
+#define _DXE_VTD_POLICY_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/SaPolicy.h>
+#include <ConfigBlock.h>
+#include <VtdConfig.h>
+#include <Library/SiConfigBlockLib.h>
+
+extern EFI_GUID gVtdDxeConfigGuid;
+
+/**
+  This function Load default Vtd DXE policy.
+
+  @param[in] ConfigBlockPointer    The pointer to add VTD config block
+**/
+VOID
+VtdLoadDefaultDxe (
+  IN VOID    *ConfigBlockPointer
+  );
+
+/**
+  This function prints the DXE phase VTD policy.
+
+  @param[in] SaPolicy - Instance of SA_POLICY_PROTOCOL
+**/
+VOID
+VtdPrintPolicyDxe (
+  IN  SA_POLICY_PROTOCOL      *SaPolicy
+  );
+
+/**
+  This function is used to add VTD Config Block.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add VTD config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+VtdAddConfigBlocksDxe (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+/**
+  Get VTD DXE config block table total size.
+
+  @retval     Size of VTD DXE config block table
+**/
+UINT16
+EFIAPI
+VtdGetConfigBlockTotalSizeDxe (
+  VOID
+  );
+#endif // _DXE_VTD_POLICY_INIT_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/VtdDataHob.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/VtdDataHob.h
new file mode 100644
index 0000000000..0f9d500af9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/VtdDataHob.h
@@ -0,0 +1,32 @@
+/** @file
+  The GUID definition for Vtd Data Hob
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _VTD_DATA_HOB_H_
+#define _VTD_DATA_HOB_H_
+
+#include <Library/VtdInfoLib.h>
+#include <Base.h>
+
+extern EFI_GUID gVtdDataHobGuid;
+
+#pragma pack (push,1)
+
+///
+/// The data elements should be initialized by a Platform Module.
+/// The data structure is for VT-d driver initialization
+///
+typedef struct {
+  EFI_HOB_GUID_TYPE     EfiHobGuidType;                    ///< GUID Hob type structure for gVtdDataHobGuid
+  BOOLEAN               VtdDisable;                        ///< 1 = Avoids programming Vtd bars, Vtd overrides and DMAR table
+  UINT32                BaseAddress[VTD_ENGINE_NUMBER];    ///< This field is used to describe the base addresses for VT-d function
+  BOOLEAN               X2ApicOptOut;                      ///< This field is used to enable the X2APIC_OPT_OUT bit in the DMAR table. <b>1=Enable/Set</b> and 0=Disable/Clear
+  BOOLEAN               DmaControlGuarantee;               ///< This field is used to enable the DMA_CONTROL_GUARANTEE bit in the DMAR table. <b>1=Enable/Set</b> and 0=Disable/Clear
+  BOOLEAN               InterruptRemappingSupport;         ///< This field is used to indicate Interrupt Remapping supported or not
+  UINT32                DmaBufferBase;                     ///< Iommu PEI DMA buffer base in low memory region, in Mbytes units
+} VTD_DATA_HOB;
+
+#pragma pack (pop)
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/PeiDxeSmmVtdInfoLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/PeiDxeSmmVtdInfoLib.inf
new file mode 100644
index 0000000000..c7c5e56b84
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/PeiDxeSmmVtdInfoLib.inf
@@ -0,0 +1,45 @@
+## @file
+# VTD Common Library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmVtdInfoLib
+FILE_GUID = A1480873-3FDA-4E90-B450-743D8031F9DE
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = VtdInfoLib
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciSegmentLib
+HobLib
+VtdInfoLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+VtdInfoLib.c
+
+[Pcd]
+gSiPkgTokenSpaceGuid.VtdEngine1BaseAddeess
+gSiPkgTokenSpaceGuid.VtdEngine2BaseAddeess
+gSiPkgTokenSpaceGuid.VtdEngine3BaseAddeess
+gSiPkgTokenSpaceGuid.VtdEngine4BaseAddeess
+gSiPkgTokenSpaceGuid.VtdEngine5BaseAddeess
+gSiPkgTokenSpaceGuid.VtdEngine6BaseAddeess
+gSiPkgTokenSpaceGuid.VtdEngine7BaseAddeess
+
+[FixedPcd]
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/VtdInfoLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/VtdInfoLib.c
new file mode 100644
index 0000000000..e4f08592cc
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/VtdInfoLib.c
@@ -0,0 +1,86 @@
+/** @file
+  VTD Info library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Ppi/SiPolicy.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/VtdInfoLib.h>
+#include <Register/VtdRegs.h>
+
+/**
+  Get VTD Engine Base Address from PCD value
+
+  @param[in]  VtdEngineNumber        - Engine number for which VTD Base Adderess is required.
+
+  @retval   VTD Engine Base Address
+**/
+UINT32
+GetVtdBaseAddress (
+  IN UINT8        VtdEngineNumber
+  )
+{
+  switch (VtdEngineNumber) {
+    case 0:
+      return PcdGet32(VtdEngine1BaseAddeess);
+      break;
+    case 2:
+      return PcdGet32(VtdEngine3BaseAddeess);
+      break;
+    default:
+      return 0x0;
+      break;
+  }
+}
+
+
+/**
+  Read VTD Engine Base Address from VTD BAR Offsets.
+
+  @param[in]  VtdEngineNumber        - Engine number for which VTD Base Adderess is required.
+
+  @retval   VTD Engine Base Address
+**/
+UINT32
+ReadVtdBaseAddress (
+  IN UINT8        VtdEngineNumber
+  )
+{
+  UINT64              McD0BaseAddress;
+  UINTN               MchBar;
+
+  McD0BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, 0);
+  MchBar          = PciSegmentRead32 (McD0BaseAddress + R_SA_MCHBAR) & (~BIT0);
+
+  switch (VtdEngineNumber) {
+    case 0:
+      return (MmioRead32 (MchBar + R_MCHBAR_VTD1_OFFSET) & (~BIT0));
+      break;
+    case 2:
+      return (MmioRead32 (MchBar + R_MCHBAR_VTD3_OFFSET) & (~BIT0));
+      break;
+    default:
+      return 0x0;
+      break;
+  }
+}
+
+/**
+  GetMaxVtdEngineNumber: Get Maximum Vtd Engine Number
+
+  @retval Vtd Engine Number
+**/
+UINT8
+GetMaxVtdEngineNumber(
+  VOID
+)
+{
+  return (UINT8)VTD_ENGINE_NUMBER;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.c
new file mode 100644
index 0000000000..faac07c45d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.c
@@ -0,0 +1,684 @@
+/** @file
+  DXE Library for VTD ACPI table initialization.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/DxeVtdInitLib.h>
+#include <Library/DxeVtdPolicyLib.h>
+#include <Library/VtdInitFruLib.h>
+#include <Register/SaRegsHostBridge.h>
+
+///
+/// Global Variables
+///
+GLOBAL_REMOVE_IF_UNREFERENCED VTD_DATA_HOB     *mVtdDataHob;
+
+BOOLEAN mInterruptRemappingSupport;
+
+/**
+  Get the corresponding device Enable/Disable bit according DevNum and FunNum
+
+  @param[in] DevNum  - Device Number
+  @param[in] FunNum  - Function Number
+
+  @retval If the device is found, return disable/Enable bit in FD/Deven reigster
+  @retval If not found return 0xFF
+**/
+UINT16
+GetFunDisableBit (
+  UINT8 DevNum,
+  UINT8 FunNum
+  )
+{
+  UINTN Index;
+
+  for (Index = 0; Index < mDevEnMapSize; Index++) {
+    if (mDevEnMap[Index][0] == ((DevNum << 0x08) | FunNum)) {
+      return mDevEnMap[Index][1];
+    }
+  }
+
+  return 0xFF;
+}
+
+/**
+  Update the DRHD structure
+
+  @param[in, out] DrhdEnginePtr       - A pointer to DRHD structure
+**/
+VOID
+UpdateDrhd (
+  IN OUT VOID *DrhdEnginePtr
+  )
+{
+  UINT16                        Length;
+  UINT16                        DisableBit;
+  BOOLEAN                       NeedRemove;
+  EFI_ACPI_DRHD_ENGINE1_STRUCT  *DrhdEngine;
+
+  //
+  // Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE1_STRUCT Pointer
+  //
+  DrhdEngine      = (EFI_ACPI_DRHD_ENGINE1_STRUCT *) DrhdEnginePtr;
+  Length          = DrhdEngine->DrhdHeader.Header.Length;
+  DisableBit = GetFunDisableBit (
+                 DrhdEngine->DeviceScope[0].PciPath.Device,
+                 DrhdEngine->DeviceScope[0].PciPath.Function
+                 );
+  NeedRemove = FALSE;
+
+  if ((DisableBit == 0xFF) ||
+      (DrhdEngine->DrhdHeader.RegisterBaseAddress == 0) ||
+      ((DisableBit == 0x80) &&
+       (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, DrhdEngine->DeviceScope[0].PciPath.Device, DrhdEngine->DeviceScope[0].PciPath.Function, 0x00)) == 0xFFFFFFFF))
+      ) {
+    NeedRemove = TRUE;
+  }
+  if ((DrhdEngine->DeviceScope[0].PciPath.Device == IGD_DEV_NUM) && (DrhdEngine->DeviceScope[0].PciPath.Function == IGD_FUN_NUM) &&
+      (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, DrhdEngine->DeviceScope[0].PciPath.Device, DrhdEngine->DeviceScope[0].PciPath.Function, 0x00)) != 0xFFFFFFFF)) {
+    NeedRemove = FALSE;
+  }
+  if (NeedRemove) {
+    Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+  }
+  ///
+  /// If no devicescope is left, we set the structure length as 0x00
+  ///
+  if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) || (DrhdEngine->DrhdHeader.Flags == 0x01)) {
+    DrhdEngine->DrhdHeader.Header.Length = Length;
+  } else {
+    DrhdEngine->DrhdHeader.Header.Length = 0;
+  }
+}
+
+/**
+  Get IOAPIC ID from LPC
+
+  @retval APIC ID
+**/
+UINT8
+GetIoApicId (
+  VOID
+  )
+{
+  UINT32                IoApicAddress;
+  UINT32                IoApicId;
+
+  IoApicAddress = PcdGet32 (PcdSiIoApicBaseAddress);
+  ///
+  /// Get current IO APIC ID
+  ///
+  MmioWrite8 ((UINTN) (IoApicAddress + R_IO_APIC_MEM_INDEX_OFFSET), 0);
+  IoApicId = MmioRead32 ((UINTN) (IoApicAddress + R_IO_APIC_MEM_DATA_OFFSET)) >> 24;
+
+  return (UINT8) IoApicId;
+}
+
+/**
+  Update the second DRHD structure
+
+  @param[in, out] DrhdEnginePtr       - A pointer to DRHD structure
+**/
+VOID
+UpdateDrhd2 (
+  IN OUT VOID *DrhdEnginePtr
+  )
+{
+  UINT16                        Length;
+  UINTN                         DeviceScopeNum;
+  UINTN                         ValidDeviceScopeNum;
+  UINT16                        Index;
+  UINT8                         Bus;
+  UINT8                         Path[2];
+  BOOLEAN                       NeedRemove;
+  EFI_ACPI_DRHD_ENGINE3_STRUCT  *DrhdEngine;
+  VOID                          *HobPtr;
+  PCH_INFO_HOB                  *PchInfoHob;
+
+  ///
+  /// Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE3_STRUCT Pointer
+  ///
+  DrhdEngine      = (EFI_ACPI_DRHD_ENGINE3_STRUCT *) DrhdEnginePtr;
+
+  Length          = DrhdEngine->DrhdHeader.Header.Length;
+  DeviceScopeNum  = (DrhdEngine->DrhdHeader.Header.Length - EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) / sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+  Bus             = 0;
+  ValidDeviceScopeNum = 0;
+  Path[0]         = 0;
+  Path[1]         = 0;
+
+  HobPtr = GetFirstGuidHob (&gPchInfoHobGuid);
+  ASSERT (HobPtr != NULL);
+  if (HobPtr == NULL) {
+    return;
+  }
+  PchInfoHob = (PCH_INFO_HOB *) GET_GUID_HOB_DATA (HobPtr);
+  ASSERT (PchInfoHob != NULL);
+  if (PchInfoHob == NULL) {
+    return;
+  }
+
+  for (Index = 0; Index < DeviceScopeNum; Index++) {
+    NeedRemove = FALSE;
+    /**
+      For HPET and APIC, update device scope if Interrupt remapping is supported. remove device scope
+      if interrupt remapping is not supported.
+      - Index = 0 - IOAPIC
+      - Index = 1 - HPET
+    **/
+    if (mInterruptRemappingSupport) {
+      if (Index == 0) {
+        ///
+        /// Update source id for IoApic's device scope entry
+        ///
+        Bus = (UINT8) PchInfoHob->IoApicBusNum;
+        Path[0] = (UINT8) PchInfoHob->IoApicDevNum;
+        Path[1] = (UINT8) PchInfoHob->IoApicFuncNum;
+        DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBusNumber = Bus;
+        DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
+        DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
+        //
+        // Update APIC ID
+        //
+        DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.EnumerationId = GetIoApicId ();
+      }
+      if (Index == 1) {
+        ///
+        /// Update source id for HPET's device scope entry
+        ///
+        Bus     = (UINT8) PchInfoHob->HpetBusNum;
+        Path[0] = (UINT8) PchInfoHob->HpetDevNum;
+        Path[1] = (UINT8) PchInfoHob->HpetFuncNum;
+        DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBusNumber = Bus;
+        DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
+        DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
+      }
+    } else {
+      if ((Index == 0) || (Index == 1)) {
+        NeedRemove = TRUE;
+      }
+    }
+
+    CopyMem (
+      &DrhdEngine->DeviceScope[ValidDeviceScopeNum],
+      &DrhdEngine->DeviceScope[Index],
+      sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)
+      );
+    if (NeedRemove) {
+      Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+    } else {
+      ValidDeviceScopeNum++;
+    }
+  }
+  ///
+  /// If no devicescope is left, we set the structure length as 0x00
+  ///
+  if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) || (DrhdEngine->DrhdHeader.Flags == 0x01)) {
+    DrhdEngine->DrhdHeader.Header.Length = Length;
+  } else {
+    DrhdEngine->DrhdHeader.Header.Length = 0;
+  }
+}
+
+/**
+  Update the RMRR structure
+
+  @param[in, out] RmrrPtr             - A pointer to RMRR structure
+**/
+VOID
+UpdateRmrr (
+  IN OUT VOID *RmrrPtr
+  )
+{
+  UINT16                  Length;
+  UINT16                  DisableBit;
+  UINTN                   DeviceScopeNum;
+  UINTN                   ValidDeviceScopeNum;
+  UINTN                   Index;
+  BOOLEAN                 NeedRemove;
+  EFI_ACPI_RMRR_USB_STRUC *Rmrr;
+
+  ///
+  /// To make sure all devicescope can be checked,
+  /// we convert the RmrrPtr to EFI_ACPI_RMRR_USB_STRUC pointer
+  ///
+  Rmrr                = (EFI_ACPI_RMRR_USB_STRUC *) RmrrPtr;
+
+  Length              = Rmrr->RmrrHeader.Header.Length;
+  ValidDeviceScopeNum = 0;
+  DeviceScopeNum      = (Rmrr->RmrrHeader.Header.Length - EFI_ACPI_RMRR_HEADER_LENGTH) / sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+  for (Index = 0; Index < DeviceScopeNum; Index++) {
+    DisableBit = GetFunDisableBit (
+                   Rmrr->DeviceScope[Index].PciPath.Device,
+                   Rmrr->DeviceScope[Index].PciPath.Function
+                   );
+    NeedRemove = FALSE;
+    if ((DisableBit == 0xFF) ||
+        ((DisableBit == 0x80) &&
+         (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, Rmrr->DeviceScope[Index].PciPath.Device, Rmrr->DeviceScope[Index].PciPath.Function, 0x00)) == 0xFFFFFFFF))
+        ) {
+      NeedRemove = TRUE;
+    } else if (DisableBit == 0x8F) {
+      DEBUG ((DEBUG_ERROR, "Rmrr->RmrrHeader.ReservedMemoryRegionBaseAddress %x\n", Rmrr->RmrrHeader.ReservedMemoryRegionBaseAddress));
+
+      if (Rmrr->RmrrHeader.ReservedMemoryRegionBaseAddress != 0) {
+        DEBUG ((DEBUG_ERROR, "NeedRemove = FALSE\n"));
+        NeedRemove = FALSE;
+      } else {
+        DEBUG ((DEBUG_ERROR, "NeedRemove = TRUE\n"));
+        NeedRemove = TRUE;
+      }
+    }
+    CopyMem (
+      &Rmrr->DeviceScope[ValidDeviceScopeNum],
+      &Rmrr->DeviceScope[Index],
+      sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)
+      );
+
+    if (Rmrr->RmrrHeader.ReservedMemoryRegionLimitAddress == 0x0) {
+      NeedRemove = TRUE;
+    }
+
+    if (NeedRemove) {
+      Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+    } else {
+      ValidDeviceScopeNum++;
+    }
+  }
+  ///
+  /// If No deviceScope is left, set length as 0x00
+  ///
+  if (Length > EFI_ACPI_RMRR_HEADER_LENGTH) {
+    Rmrr->RmrrHeader.Header.Length = Length;
+  } else {
+    Rmrr->RmrrHeader.Header.Length = 0;
+  }
+}
+
+/**
+  Update the DMAR table
+
+  @param[in, out] TableHeader         - The table to be set
+  @param[in, out] Version             - Version to publish
+**/
+VOID
+DmarTableUpdate (
+  IN OUT   EFI_ACPI_DESCRIPTION_HEADER       *TableHeader,
+  IN OUT   EFI_ACPI_TABLE_VERSION            *Version
+  )
+{
+  EFI_ACPI_DMAR_TABLE *DmarTable;
+  EFI_ACPI_DMAR_TABLE TempDmarTable;
+  UINTN               Offset;
+  UINTN               StructureLen;
+  UINT64              McD0BaseAddress;
+  UINT32              GttMmAdr;
+  UINT64              McD2BaseAddress;
+  UINT16              IgdMode;
+  UINT16              GttMode;
+  UINT32              IgdMemSize;
+  UINT32              GttMemSize;
+  EFI_STATUS          Status;
+  VTD_DXE_CONFIG      *VtdDxeConfig;
+  SA_POLICY_PROTOCOL  *SaPolicy;
+
+
+  IgdMemSize  = 0;
+  GttMemSize  = 0;
+  DmarTable   = (EFI_ACPI_DMAR_TABLE *) TableHeader;
+
+  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **) &SaPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gVtdDxeConfigGuid, (VOID *)&VtdDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Set INTR_REMAP bit (BIT 0) if interrupt remapping is supported
+  ///
+  if (mInterruptRemappingSupport) {
+    DmarTable->DmarHeader.Flags |= BIT0;
+  }
+
+  if (mVtdDataHob->X2ApicOptOut == 1) {
+    DmarTable->DmarHeader.Flags |= BIT1;
+  } else {
+    DmarTable->DmarHeader.Flags &= 0xFD;
+  }
+
+  ///
+  /// Set DMA_CONTROL_GUARANTEE bit (BIT 2) if Dma Control Guarantee is supported
+  ///
+  if (mVtdDataHob->DmaControlGuarantee == 1) {
+    DmarTable->DmarHeader.Flags |= BIT2;
+  }
+  ///
+  /// Get OemId
+  ///
+  CopyMem (DmarTable->DmarHeader.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (DmarTable->DmarHeader.Header.OemId));
+  DmarTable->DmarHeader.Header.OemTableId      = PcdGet64 (PcdAcpiDefaultOemTableId);
+  DmarTable->DmarHeader.Header.OemRevision     = PcdGet32 (PcdAcpiDefaultOemRevision);
+  DmarTable->DmarHeader.Header.CreatorId       = PcdGet32 (PcdAcpiDefaultCreatorId);
+  DmarTable->DmarHeader.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
+
+  ///
+  /// Calculate IGD memsize
+  ///
+  McD0BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, 0);
+  IgdMode = ((PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) & B_SA_GGC_GMS_MASK) >> N_SA_GGC_GMS_OFFSET) & 0xFF;
+  if (IgdMode < 0xF0) {
+    IgdMemSize = IgdMode * 32 * (1024) * (1024);
+  } else {
+    IgdMemSize = 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024);
+  }
+  ///
+  /// Calculate GTT mem size
+  ///
+  GttMemSize = 0;
+  GttMode = (PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) & B_SA_GGC_GGMS_MASK) >> N_SA_GGC_GGMS_OFFSET;
+  if (GttMode <= V_SA_GGC_GGMS_8MB) {
+    GttMemSize = (1 << GttMode) * (1024) * (1024);
+  }
+
+  McD2BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, 0);
+  GttMmAdr = (PciSegmentRead32 (McD2BaseAddress + R_SA_IGD_GTTMMADR)) & 0xFFFFFFF0;
+
+  DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress   = (PciSegmentRead32 (McD0BaseAddress + R_SA_BGSM) & ~(0x01));
+  DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress  = DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress + IgdMemSize + GttMemSize - 1;
+  DEBUG ((DEBUG_INFO, "RMRR Base  address IGD %016lX\n", DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress));
+  DEBUG ((DEBUG_INFO, "RMRR Limit address IGD %016lX\n", DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress));
+
+  ///
+  /// Update DRHD structures of DmarTable
+  ///
+  DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress = ReadVtdBaseAddress(0);
+  DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress = ReadVtdBaseAddress (2);
+
+  DEBUG ((DEBUG_INFO, "VTD base address 1 = %x\n", DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress));
+  DEBUG ((DEBUG_INFO, "VTD base address 3 = %x\n", DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress));
+  ///
+  /// copy DmarTable to TempDmarTable to be processed
+  ///
+  CopyMem (&TempDmarTable, DmarTable, sizeof (EFI_ACPI_DMAR_TABLE));
+
+  ///
+  /// Update DRHD structures of temp DMAR table
+  ///
+  UpdateDrhd (&TempDmarTable.DrhdEngine1);
+  UpdateDrhd2 (&TempDmarTable.DrhdEngine3);
+
+  ///
+  /// Remove unused device scope or entire DRHD structures
+  ///
+  Offset = (UINTN) (&TempDmarTable.DrhdEngine1);
+  if (TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length != 0) {
+    Offset += TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length;
+  }
+  if (TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length != 0) {
+    StructureLen = TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length;
+    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.DrhdEngine3, TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length);
+    Offset += StructureLen;
+  }
+  ///
+  /// Remove unused device scope or entire RMRR structures
+  ///
+  if (TempDmarTable.RmrrIgd.RmrrHeader.Header.Length != 0) {
+    StructureLen = TempDmarTable.RmrrIgd.RmrrHeader.Header.Length;
+    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrIgd, TempDmarTable.RmrrIgd.RmrrHeader.Header.Length);
+    Offset += StructureLen;
+  }
+  Offset = Offset - (UINTN) &TempDmarTable;
+  ///
+  /// Re-calculate DMAR table check sum
+  ///
+  TempDmarTable.DmarHeader.Header.Checksum = (UINT8) (TempDmarTable.DmarHeader.Header.Checksum + TempDmarTable.DmarHeader.Header.Length - Offset);
+  ///
+  /// Set DMAR table length
+  ///
+  TempDmarTable.DmarHeader.Header.Length = (UINT32) Offset;
+  ///
+  /// Replace DMAR table with rebuilt table TempDmarTable
+  ///
+  CopyMem ((VOID *) DmarTable, (VOID *) &TempDmarTable, TempDmarTable.DmarHeader.Header.Length);
+}
+
+/**
+  EndOfPcieEnumration routine for update DMAR
+**/
+VOID
+UpdateDmarEndOfPcieEnum (
+  VOID
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_HANDLE                      *HandleBuffer;
+  UINTN                           NumberOfHandles;
+  EFI_FV_FILETYPE                 FileType;
+  UINT32                          FvStatus;
+  EFI_FV_FILE_ATTRIBUTES          Attributes;
+  UINTN                           Size;
+  UINTN                           i;
+  INTN                            Instance;
+  EFI_ACPI_TABLE_VERSION          Version;
+  EFI_ACPI_COMMON_HEADER          *CurrentTable;
+  UINTN                           AcpiTableHandle;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL   *FwVol;
+  EFI_ACPI_TABLE_PROTOCOL         *AcpiTable;
+  EFI_ACPI_DESCRIPTION_HEADER     *VtdAcpiTable;
+  STATIC BOOLEAN                  Triggered = FALSE;
+
+
+  if (Triggered) {
+    return;
+  }
+
+  Triggered     = TRUE;
+
+  FwVol         = NULL;
+  AcpiTable     = NULL;
+  VtdAcpiTable  = NULL;
+
+  DEBUG ((DEBUG_INFO, "UpdateDmarEndOfPcieEnum \n"));
+
+
+  ///
+  /// Fix DMAR Table always created, skip install when disabled
+  ///
+  if ((mVtdDataHob->VtdDisable == TRUE) || (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MC_CAPID0_A_OFFSET)) & BIT23)) {
+    DEBUG ((DEBUG_INFO, "Vtd Disabled, skip DMAR Table install\n"));
+    return;
+  }
+
+
+  ///
+  /// Locate ACPI support protocol
+  ///
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+
+  ///
+  /// Locate protocol.
+  /// There is little chance we can't find an FV protocol
+  ///
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  NULL,
+                  &NumberOfHandles,
+                  &HandleBuffer
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Looking for FV with ACPI storage file
+  ///
+  for (i = 0; i < NumberOfHandles; i++) {
+    ///
+    /// Get the protocol on this handle
+    /// This should not fail because of LocateHandleBuffer
+    ///
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[i],
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    (VOID **) &FwVol
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    ///
+    /// See if it has the ACPI storage file
+    ///
+    Size      = 0;
+    FvStatus  = 0;
+    Status = FwVol->ReadFile (
+                      FwVol,
+                      &gSaAcpiTableStorageGuid,
+                      NULL,
+                      &Size,
+                      &FileType,
+                      &Attributes,
+                      &FvStatus
+                      );
+
+    ///
+    /// If we found it, then we are done
+    ///
+    if (Status == EFI_SUCCESS) {
+      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
+  ///
+  FreePool (HandleBuffer);
+
+  ///
+  /// Sanity check that we found our data file
+  ///
+  ASSERT (FwVol);
+  if (FwVol == NULL) {
+    return;
+  }
+  ///
+  /// By default, a table belongs in all ACPI table versions published.
+  ///
+  Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
+
+  ///
+  /// Read tables from the storage file.
+  ///
+  Instance      = 0;
+  CurrentTable  = NULL;
+
+  while (Status == EFI_SUCCESS) {
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      &gSaAcpiTableStorageGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      (VOID **) &CurrentTable,
+                      &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR (Status)) {
+      ///
+      /// Check the Signature ID to modify the table
+      ///
+      if ((CurrentTable != NULL) && ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Signature == EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE) {
+        VtdAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
+        DmarTableUpdate (VtdAcpiTable, &Version);
+        break;
+      }
+      ///
+      /// Increment the instance
+      ///
+      Instance++;
+      if (CurrentTable != NULL) {
+        gBS->FreePool (CurrentTable);
+        CurrentTable = NULL;
+      }
+    }
+  }
+  ///
+  /// Update the VTD table in the ACPI tables.
+  ///
+  AcpiTableHandle = 0;
+  if (VtdAcpiTable != NULL) {
+    Status = AcpiTable->InstallAcpiTable (
+                          AcpiTable,
+                          VtdAcpiTable,
+                          VtdAcpiTable->Length,
+                          &AcpiTableHandle
+                          );
+    FreePool (VtdAcpiTable);
+  }
+}
+
+/**
+  Locate the VT-d ACPI tables data file and read ACPI SSDT tables.
+  Publish the appropriate SSDT based on current configuration and capabilities.
+
+  @param[in] SaPolicy     -  SA DXE Policy protocol
+
+  @retval EFI_SUCCESS     - Vtd initialization complete
+  @exception EFI_UNSUPPORTED - Vtd is not enabled by policy
+**/
+EFI_STATUS
+VtdInit (
+  IN  SA_POLICY_PROTOCOL    *SaPolicy
+  )
+{
+  EFI_STATUS                      Status;
+  UINT64                          McD0BaseAddress;
+  UINT64                          McD2BaseAddress;
+  SYSTEM_AGENT_NVS_AREA_PROTOCOL  *SaNvsAreaProtocol;
+  UINT8                           Index;
+
+  mInterruptRemappingSupport  = FALSE;
+  mVtdDataHob = NULL;
+  mVtdDataHob = GetFirstGuidHob(&gVtdDataHobGuid);
+  if (mVtdDataHob != NULL) {
+    mInterruptRemappingSupport = mVtdDataHob->InterruptRemappingSupport;
+  }
+
+  ///
+  ///  Locate the SA Global NVS Protocol.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaNvsAreaProtocolGuid,
+                  NULL,
+                  (VOID **) &SaNvsAreaProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  McD0BaseAddress  = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, 0);
+  McD2BaseAddress  = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, 0);
+
+  if (mVtdDataHob != NULL) {
+    SaNvsAreaProtocol->Area->VtdDisable = mVtdDataHob->VtdDisable;
+  }
+
+  for (Index = 0; Index < VTD_ENGINE_NUMBER; Index++) {
+    SaNvsAreaProtocol->Area->VtdBaseAddress[Index] = ReadVtdBaseAddress (Index);
+  }
+  SaNvsAreaProtocol->Area->VtdEngine1Vid = PciSegmentRead16(McD2BaseAddress + PCI_VENDOR_ID_OFFSET);
+
+  if (mVtdDataHob != NULL) {
+    if ((mVtdDataHob->VtdDisable) || (PciSegmentRead32 (McD0BaseAddress + R_SA_MC_CAPID0_A_OFFSET) & BIT23)) {
+      DEBUG ((DEBUG_WARN, "VTd disabled or no capability!\n"));
+      return EFI_UNSUPPORTED;
+    }
+  }
+  ///
+  /// Check SA supports VTD and VTD is enabled in setup menu
+  ///
+  DEBUG ((DEBUG_INFO, "VTd enabled\n"));
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.inf
new file mode 100644
index 0000000000..9797c31cc6
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.inf
@@ -0,0 +1,71 @@
+## @file
+# Component description file for the Dxe VTD Init library.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeVtdInitLib
+FILE_GUID = 9BD11E68-923C-424C-A278-716084B4C931
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+LIBRARY_CLASS = DxeVtdInitLib
+
+[LibraryClasses]
+UefiLib
+UefiRuntimeServicesTableLib
+UefiBootServicesTableLib
+DebugLib
+PostCodeLib
+ConfigBlockLib
+HobLib
+IoLib
+PciSegmentLib
+BaseMemoryLib
+MemoryAllocationLib
+MmPciLib
+VtdInfoLib
+PchInfoLib
+PchCycleDecodingLib
+SaPlatformLib
+DxeVtdInitFruLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxeVtdInitLib.c
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdSiIoApicBaseAddress
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+
+[FixedPcd]
+
+[Guids]
+gPchInfoHobGuid          ## CONSUMES
+gSaAcpiTableStorageGuid
+gVtdDataHobGuid
+gVtdDxeConfigGuid
+
+[Protocols]
+gSaPolicyProtocolGuid                  ## CONSUMES
+gSaNvsAreaProtocolGuid                 ## CONSUMES
+gEfiFirmwareVolume2ProtocolGuid
+gEfiAcpiTableProtocolGuid
+
+[Depex]
+gEfiAcpiTableProtocolGuid AND
+gEfiFirmwareVolume2ProtocolGuid AND
+gSaPolicyProtocolGuid AND
+gEfiPciRootBridgeIoProtocolGuid AND
+gEfiPciHostBridgeResourceAllocationProtocolGuid AND # This is to ensure that PCI MMIO resource has been prepared and available for this driver to allocate.
+gEfiHiiDatabaseProtocolGuid
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.c
new file mode 100644
index 0000000000..168de0c0a9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.c
@@ -0,0 +1,90 @@
+/** @file
+  This file provides services for DXE VTD policy default initialization
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DxeVtdPolicyLib.h>
+
+/**
+  This function prints the DXE phase VTD policy.
+
+  @param[in] SaPolicy - Instance of SA_POLICY_PROTOCOL
+**/
+VOID
+VtdPrintPolicyDxe (
+  IN  SA_POLICY_PROTOCOL      *SaPolicy
+  )
+{
+  EFI_STATUS                  Status;
+  VTD_DXE_CONFIG             *VtdDxeConfig;
+
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gVtdDxeConfigGuid, (VOID *)&VtdDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG_CODE_BEGIN ();
+  DEBUG ((DEBUG_INFO, "\n------------------------ Vtd Policy (DXE) print BEGIN -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", VtdDxeConfig->Header.Revision));
+  ASSERT (VtdDxeConfig->Header.Revision == VTD_DXE_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, "\n------------------------ Vtd Policy (DXE) print END -----------------\n"));
+  DEBUG_CODE_END ();
+  return;
+}
+
+/**
+  This function Load default Vtd DXE policy.
+
+  @param[in] ConfigBlockPointer    The pointer to add VTD config block
+**/
+VOID
+VtdLoadDefaultDxe (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  VTD_DXE_CONFIG        *VtdDxeConfig;
+
+  VtdDxeConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "VtdDxeConfig->Header.GuidHob.Name = %g\n", &VtdDxeConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "VtdDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", VtdDxeConfig->Header.GuidHob.Header.HobLength));
+}
+
+static COMPONENT_BLOCK_ENTRY  mVtdDxeIpBlock = {
+  &gVtdDxeConfigGuid, sizeof (VTD_DXE_CONFIG), VTD_DXE_CONFIG_REVISION, VtdLoadDefaultDxe
+};
+
+/**
+  Get VTD DXE config block table total size.
+
+  @retval     Size of VTD DXE config block table
+**/
+UINT16
+EFIAPI
+VtdGetConfigBlockTotalSizeDxe (
+  VOID
+  )
+{
+  return mVtdDxeIpBlock.Size;
+}
+
+/**
+  VtdAddConfigBlocks add VTD DXE config block.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add VTD config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+VtdAddConfigBlocksDxe (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  EFI_STATUS  Status;
+  Status = AddComponentConfigBlocks (ConfigBlockTableAddress, &mVtdDxeIpBlock, 1);
+  return Status;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.inf
new file mode 100644
index 0000000000..1fe288416a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.inf
@@ -0,0 +1,35 @@
+## @file
+# Component description file for the DxeVtdPolicy library.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeVtdPolicyLib
+FILE_GUID = 54754C6D-4883-4B67-BBBA-49D241539BE7
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = DxeVtdPolicyLib
+
+[LibraryClasses]
+BaseMemoryLib
+UefiRuntimeServicesTableLib
+UefiBootServicesTableLib
+DebugLib
+PostCodeLib
+ConfigBlockLib
+HobLib
+SiConfigBlockLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxeVtdPolicyLib.c
+
+[Guids]
+gVtdDxeConfigGuid
-- 
2.24.0.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#71227): https://edk2.groups.io/g/devel/message/71227
Mute This Topic: https://groups.io/mt/80375687/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-






More information about the edk2-devel-archive mailing list