public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Sheng Wei" <w.sheng@intel.com>
To: "Ni, Ray" <ray.ni@intel.com>,
	"Huang, Jenny" <jenny.huang@intel.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Chaganty, Rangasai V" <rangasai.v.chaganty@intel.com>,
	"Kowalewski, Robert" <robert.kowalewski@intel.com>
Subject: Re: [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once.
Date: Mon, 24 Jan 2022 02:44:22 +0000	[thread overview]
Message-ID: <PH0PR11MB4870E878BB06BAAC0CFE7621E15E9@PH0PR11MB4870.namprd11.prod.outlook.com> (raw)
In-Reply-To: <DM6PR11MB4627D610871592516C0F2ABBE25B9@DM6PR11MB4627.namprd11.prod.outlook.com>

As the review comment form Ray, I will use a fixed MAX VTdUnit number in function VTdInfoNotify().
After that, it will no need to allocate memory at every function call of VTdInfoNotify().
I set the MAX VTd unit number to 42. The total memory usage will just smaller than 4k (1 page). And this number is enough for client and server projects.
I update to patch V6
@Ni, Ray Could you help review and merge the patch ?
Thank you
BR
Sheng Wei


> -----Original Message-----
> From: Huang, Jenny <jenny.huang@intel.com>
> Sent: 2022年1月21日 16:36
> To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Kowalewski, Robert
> <robert.kowalewski@intel.com>
> Subject: RE: [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA
> buffer once.
> 
> Reviewed-by: Jenny Huang <jenny.huang@intel.com>
> 
> -----Original Message-----
> From: Sheng, W <w.sheng@intel.com>
> Sent: Tuesday, January 18, 2022 4:15 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Huang, Jenny <jenny.huang@intel.com>;
> Kowalewski, Robert <robert.kowalewski@intel.com>
> Subject: [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer
> once.
> 
> VTdInfoNotify may be called manay times, PEI DMA buffer should be
>  generated only once.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3667
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Jenny Huang <jenny.huang@intel.com>
> Cc: Robert Kowalewski <robert.kowalewski@intel.com>
> Reviewed-by: Jenny Huang <jenny.huang@intel.com>
> Signed-off-by: Sheng Wei <w.sheng@intel.com>
> ---
>  .../Feature/VTd/IntelVTdDmarPei/DmarTable.c        | 545 +--------------------
>  .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c     | 433 +++++++---------
>  .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.c  | 474 ++++++++++----
> ----
>  .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h  | 119 ++---
>  .../Feature/VTd/IntelVTdDmarPei/TranslationTable.c | 196 ++------
>  5 files changed, 533 insertions(+), 1234 deletions(-)
> 
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
> index e9c99d0a..acfbc4a8 100644
> ---
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
> @@ -1,6 +1,7 @@
>  /** @file
> 
> -  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
> +
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
>  **/
> @@ -104,74 +105,6 @@ DumpDmarDeviceScopeEntry (
>    return;
>  }
> 
> -/**
> -  Dump DMAR RMRR table.
> -
> -  @param[in]  Rmrr              DMAR RMRR table
> -**/
> -VOID
> -DumpDmarRmrr (
> -  IN EFI_ACPI_DMAR_RMRR_HEADER  *Rmrr
> -  )
> -{
> -  EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> *DmarDeviceScopeEntry;
> -  INTN                                            RmrrLen;
> -
> -  if (Rmrr == NULL) {
> -    return;
> -  }
> -
> -  DEBUG ((DEBUG_INFO,
> -    "
> **********************************************************
> *****************\n"
> -    ));
> -  DEBUG ((DEBUG_INFO,
> -    "  *       Reserved Memory Region Reporting Structure                        *\n"
> -    ));
> -  DEBUG ((DEBUG_INFO,
> -    "
> **********************************************************
> *****************\n"
> -    ));
> -  DEBUG ((DEBUG_INFO,
> -    (sizeof (UINTN) == sizeof (UINT64)) ?
> -    "  RMRR address ........................................... 0x%016lx\n" :
> -    "  RMRR address ........................................... 0x%08x\n",
> -    Rmrr
> -    ));
> -  DEBUG ((DEBUG_INFO,
> -    "    Type ................................................. 0x%04x\n",
> -    Rmrr->Header.Type
> -    ));
> -  DEBUG ((DEBUG_INFO,
> -    "    Length ............................................... 0x%04x\n",
> -    Rmrr->Header.Length
> -    ));
> -  DEBUG ((DEBUG_INFO,
> -    "    Segment Number ....................................... 0x%04x\n",
> -    Rmrr->SegmentNumber
> -    ));
> -  DEBUG ((DEBUG_INFO,
> -    "    Reserved Memory Region Base Address .................. 0x%016lx\n",
> -    Rmrr->ReservedMemoryRegionBaseAddress
> -    ));
> -  DEBUG ((DEBUG_INFO,
> -    "    Reserved Memory Region Limit Address ................. 0x%016lx\n",
> -    Rmrr->ReservedMemoryRegionLimitAddress
> -    ));
> -
> -  RmrrLen  = Rmrr->Header.Length -
> sizeof(EFI_ACPI_DMAR_RMRR_HEADER);
> -  DmarDeviceScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) (Rmrr + 1);
> -  while (RmrrLen > 0) {
> -    DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry);
> -    RmrrLen -= DmarDeviceScopeEntry->Length;
> -    DmarDeviceScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN)
> DmarDeviceScopeEntry + DmarDeviceScopeEntry->Length);
> -  }
> -
> -  DEBUG ((DEBUG_INFO,
> -    "
> **********************************************************
> *****************\n\n"
> -    ));
> -
> -  return;
> -}
> -
>  /**
>    Dump DMAR DRHD table.
> 
> @@ -312,9 +245,6 @@ DumpAcpiDMAR (
>      case EFI_ACPI_DMAR_TYPE_DRHD:
>        DumpDmarDrhd ((EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader);
>        break;
> -    case EFI_ACPI_DMAR_TYPE_RMRR:
> -      DumpDmarRmrr ((EFI_ACPI_DMAR_RMRR_HEADER *) DmarHeader);
> -      break;
>      default:
>        break;
>      }
> @@ -329,492 +259,43 @@ DumpAcpiDMAR (
>    return;
>  }
> 
> -/**
> -  Get VTd engine number.
> -
> -  @param[in]  AcpiDmarTable     DMAR ACPI table
> -
> -  @return the VTd engine number.
> -**/
> -UINTN
> -GetVtdEngineNumber (
> -  IN EFI_ACPI_DMAR_HEADER       *AcpiDmarTable
> -  )
> -{
> -  EFI_ACPI_DMAR_STRUCTURE_HEADER        *DmarHeader;
> -  UINTN                                 VtdIndex;
> -
> -  VtdIndex = 0;
> -  DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN)
> (AcpiDmarTable + 1));
> -  while ((UINTN) DmarHeader < (UINTN) AcpiDmarTable + AcpiDmarTable-
> >Header.Length) {
> -    switch (DmarHeader->Type) {
> -    case EFI_ACPI_DMAR_TYPE_DRHD:
> -      VtdIndex++;
> -      break;
> -    default:
> -      break;
> -    }
> -    DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN)
> DmarHeader + DmarHeader->Length);
> -  }
> -  return VtdIndex ;
> -}
> -
> -/**
> -  Get PCI device information from DMAR DevScopeEntry.
> -
> -  @param[in]  Segment           The segment number.
> -  @param[in]  DmarDevScopeEntry DMAR DevScopeEntry
> -  @param[out] Bus               The bus number.
> -  @param[out] Device            The device number.
> -  @param[out] Function          The function number.
> -
> -  @retval EFI_SUCCESS  The PCI device information is returned.
> -**/
> -EFI_STATUS
> -GetPciBusDeviceFunction (
> -  IN  UINT16                                      Segment,
> -  IN  EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> *DmarDevScopeEntry,
> -  OUT UINT8                                       *Bus,
> -  OUT UINT8                                       *Device,
> -  OUT UINT8                                       *Function
> -  )
> -{
> -  EFI_ACPI_DMAR_PCI_PATH                          *DmarPciPath;
> -  UINT8                                           MyBus;
> -  UINT8                                           MyDevice;
> -  UINT8                                           MyFunction;
> -
> -  DmarPciPath = (EFI_ACPI_DMAR_PCI_PATH *) ((UINTN)
> (DmarDevScopeEntry + 1));
> -  MyBus = DmarDevScopeEntry->StartBusNumber;
> -  MyDevice = DmarPciPath->Device;
> -  MyFunction = DmarPciPath->Function;
> -
> -  switch (DmarDevScopeEntry->Type) {
> -  case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:
> -  case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE:
> -    while ((UINTN) DmarPciPath + sizeof (EFI_ACPI_DMAR_PCI_PATH) <
> (UINTN) DmarDevScopeEntry + DmarDevScopeEntry->Length) {
> -      MyBus = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (Segment,
> MyBus, MyDevice, MyFunction,
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
> -      DmarPciPath ++;
> -      MyDevice = DmarPciPath->Device;
> -      MyFunction = DmarPciPath->Function;
> -    }
> -    break;
> -  case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC:
> -  case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET:
> -  case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE:
> -    break;
> -  }
> -
> -  *Bus = MyBus;
> -  *Device = MyDevice;
> -  *Function = MyFunction;
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Return the index of PCI data.
> -
> -  @param[in]  VTdUnitInfo       The VTd engine unit information.
> -  @param[in]  Segment           The Segment used to identify a VTd engine.
> -  @param[in]  SourceId          The SourceId used to identify a VTd engine and
> table entry.
> -
> -  @return The index of the PCI data.
> -  @retval (UINTN)-1  The PCI data is not found.
> -**/
> -UINTN
> -GetPciDataIndex (
> -  IN VTD_UNIT_INFO              *VTdUnitInfo,
> -  IN UINT16                     Segment,
> -  IN VTD_SOURCE_ID              SourceId
> -  )
> -{
> -  UINTN                         Index;
> -  VTD_SOURCE_ID                 *PciSourceId;
> -  PEI_PCI_DEVICE_DATA           *PciDeviceDataBase;
> -
> -  if (Segment != VTdUnitInfo->Segment) {
> -    return (UINTN)-1;
> -  }
> -
> -  for (Index = 0; Index < VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber;
> Index++) {
> -    PciDeviceDataBase = (PEI_PCI_DEVICE_DATA*) (UINTN) VTdUnitInfo-
> >PciDeviceInfo.PciDeviceData;
> -    PciSourceId = &PciDeviceDataBase[Index].PciSourceId;
> -    if ((PciSourceId->Bits.Bus == SourceId.Bits.Bus) &&
> -        (PciSourceId->Bits.Device == SourceId.Bits.Device) &&
> -        (PciSourceId->Bits.Function == SourceId.Bits.Function) ) {
> -      return Index;
> -    }
> -  }
> -
> -  return (UINTN)-1;
> -}
> -
> -
> -/**
> -  Register PCI device to VTd engine.
> -
> -  @param[in]  VTdUnitInfo       The VTd engine unit information.
> -  @param[in]  Segment           The segment of the source.
> -  @param[in]  SourceId          The SourceId of the source.
> -  @param[in]  DeviceType        The DMAR device scope type.
> -  @param[in]  CheckExist        TRUE: ERROR will be returned if the PCI device
> is already registered.
> -                                FALSE: SUCCESS will be returned if the PCI device is
> registered.
> -
> -  @retval EFI_SUCCESS           The PCI device is registered.
> -  @retval EFI_OUT_OF_RESOURCES  No enough resource to register a new
> PCI device.
> -  @retval EFI_ALREADY_STARTED   The device is already registered.
> -
> -**/
> -EFI_STATUS
> -RegisterPciDevice (
> -  IN VTD_UNIT_INFO              *VTdUnitInfo,
> -  IN UINT16                     Segment,
> -  IN VTD_SOURCE_ID              SourceId,
> -  IN UINT8                      DeviceType,
> -  IN BOOLEAN                    CheckExist
> -  )
> -{
> -  PEI_PCI_DEVICE_INFORMATION    *PciDeviceInfo;
> -  VTD_SOURCE_ID                 *PciSourceId;
> -  UINTN                         PciDataIndex;
> -  UINTN                         PciDeviceDataSize;
> -  PEI_PCI_DEVICE_DATA           *NewPciDeviceData;
> -  PEI_PCI_DEVICE_DATA           *PciDeviceDataBase;
> -
> -  PciDeviceInfo = &VTdUnitInfo->PciDeviceInfo;
> -
> -  PciDataIndex = GetPciDataIndex (VTdUnitInfo, Segment, SourceId);
> -  if (PciDataIndex == (UINTN)-1) {
> -    //
> -    // Register new
> -    //
> -
> -    if (PciDeviceInfo->PciDeviceDataNumber >= PciDeviceInfo-
> >PciDeviceDataMaxNumber) {
> -      //
> -      // Reallocate
> -      //
> -      PciDeviceDataSize = sizeof(*NewPciDeviceData) * (PciDeviceInfo-
> >PciDeviceDataMaxNumber + MAX_VTD_PCI_DATA_NUMBER);
> -      DEBUG ((DEBUG_INFO, "New PciDeviceDataSize:%d Page:%d\n",
> PciDeviceDataSize, EFI_SIZE_TO_PAGES (PciDeviceDataSize)));
> -      NewPciDeviceData = AllocateZeroPages
> (EFI_SIZE_TO_PAGES(PciDeviceDataSize));
> -      if (NewPciDeviceData == NULL) {
> -        return EFI_OUT_OF_RESOURCES;
> -      }
> -      PciDeviceInfo->PciDeviceDataMaxNumber +=
> MAX_VTD_PCI_DATA_NUMBER;
> -      if (PciDeviceInfo->PciDeviceData != 0) {
> -        CopyMem (NewPciDeviceData, (VOID *) (UINTN) PciDeviceInfo-
> >PciDeviceData, sizeof (*NewPciDeviceData) * PciDeviceInfo-
> >PciDeviceDataNumber);
> -        FreePages((VOID *) (UINTN) PciDeviceInfo->PciDeviceData,
> PciDeviceInfo->PciDeviceDataPageSize);
> -      }
> -      PciDeviceInfo->PciDeviceData = (UINT32) (UINTN) NewPciDeviceData;
> -      PciDeviceInfo->PciDeviceDataPageSize = (UINT32) EFI_SIZE_TO_PAGES
> (PciDeviceDataSize);
> -    }
> -
> -    ASSERT (PciDeviceInfo->PciDeviceDataNumber < PciDeviceInfo-
> >PciDeviceDataMaxNumber);
> -
> -    PciDeviceDataBase = (PEI_PCI_DEVICE_DATA *) (UINTN) PciDeviceInfo-
> >PciDeviceData;
> -    PciSourceId = &PciDeviceDataBase[PciDeviceInfo-
> >PciDeviceDataNumber].PciSourceId;
> -    PciSourceId->Bits.Bus = SourceId.Bits.Bus;
> -    PciSourceId->Bits.Device = SourceId.Bits.Device;
> -    PciSourceId->Bits.Function = SourceId.Bits.Function;
> -
> -    DEBUG ((DEBUG_INFO, "  RegisterPciDevice: PCI S%04x B%02x D%02x
> F%02x", Segment, SourceId.Bits.Bus, SourceId.Bits.Device,
> SourceId.Bits.Function));
> -
> -    PciDeviceDataBase[PciDeviceInfo->PciDeviceDataNumber].DeviceType =
> DeviceType;
> -
> -    if ((DeviceType != EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT)
> &&
> -        (DeviceType != EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE)) {
> -      DEBUG ((DEBUG_INFO, " (*)"));
> -    }
> -    DEBUG ((DEBUG_INFO, "\n"));
> -
> -    PciDeviceInfo->PciDeviceDataNumber++;
> -  } else {
> -    if (CheckExist) {
> -      DEBUG ((DEBUG_INFO, "  RegisterPciDevice: PCI S%04x B%02x D%02x
> F%02x already registered\n", Segment, SourceId.Bits.Bus,
> SourceId.Bits.Device, SourceId.Bits.Function));
> -      return EFI_ALREADY_STARTED;
> -    }
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Process DMAR DRHD table.
> -
> -  @param[in]  VTdUnitInfo       The VTd engine unit information.
> -  @param[in]  DmarDrhd          The DRHD table.
> -
> -**/
> -VOID
> -ProcessDrhd (
> -  IN VTD_UNIT_INFO              *VTdUnitInfo,
> -  IN EFI_ACPI_DMAR_DRHD_HEADER  *DmarDrhd
> -  )
> -{
> -  EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> *DmarDevScopeEntry;
> -  UINT8                                           Bus;
> -  UINT8                                           Device;
> -  UINT8                                           Function;
> -  EFI_STATUS                                      Status;
> -  VTD_SOURCE_ID                                   SourceId;
> -
> -  DEBUG ((DEBUG_INFO,"  VTD BaseAddress -  0x%016lx\n", DmarDrhd-
> >RegisterBaseAddress));
> -  VTdUnitInfo->VtdUnitBaseAddress = (UINT32) DmarDrhd-
> >RegisterBaseAddress;
> -
> -  VTdUnitInfo->EnableQueuedInvalidation = 0;
> -
> -  DEBUG ((DEBUG_INFO,"  VTD Segment - %d\n", DmarDrhd-
> >SegmentNumber));
> -  VTdUnitInfo->Segment = DmarDrhd->SegmentNumber;
> -
> -  VTdUnitInfo->FixedSecondLevelPagingEntry = 0;
> -  VTdUnitInfo->RmrrSecondLevelPagingEntry = 0;
> -  VTdUnitInfo->RootEntryTable = 0;
> -  VTdUnitInfo->ExtRootEntryTable = 0;
> -  VTdUnitInfo->RootEntryTablePageSize = 0;
> -  VTdUnitInfo->ExtRootEntryTablePageSize = 0;
> -
> -  VTdUnitInfo->PciDeviceInfo.IncludeAllFlag = 0;
> -  VTdUnitInfo->PciDeviceInfo.PciDeviceDataMaxNumber = 0;
> -  VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber = 0;
> -  VTdUnitInfo->PciDeviceInfo.PciDeviceDataPageSize = 0;
> -  VTdUnitInfo->PciDeviceInfo.PciDeviceData = 0;
> -
> -  if ((DmarDrhd->Flags &
> EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL) != 0) {
> -    VTdUnitInfo->PciDeviceInfo.IncludeAllFlag = TRUE;
> -    DEBUG ((DEBUG_INFO,"  ProcessDrhd: with INCLUDE ALL\n"));
> -  } else {
> -    VTdUnitInfo->PciDeviceInfo.IncludeAllFlag = FALSE;
> -    DEBUG ((DEBUG_INFO,"  ProcessDrhd: without INCLUDE ALL\n"));
> -  }
> -
> -  VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber = 0;
> -  VTdUnitInfo->PciDeviceInfo.PciDeviceDataMaxNumber = 0;
> -  VTdUnitInfo->PciDeviceInfo.PciDeviceDataPageSize = 0;
> -  VTdUnitInfo->PciDeviceInfo.PciDeviceData = 0;
> -
> -  DmarDevScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN)
> (DmarDrhd + 1));
> -  while ((UINTN)DmarDevScopeEntry < (UINTN) DmarDrhd + DmarDrhd-
> >Header.Length) {
> -
> -    Status = GetPciBusDeviceFunction (DmarDrhd->SegmentNumber,
> DmarDevScopeEntry, &Bus, &Device, &Function);
> -    if (EFI_ERROR (Status)) {
> -      return;
> -    }
> -
> -    DEBUG ((DEBUG_INFO,"  ProcessDrhd: "));
> -    switch (DmarDevScopeEntry->Type) {
> -      case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:
> -      DEBUG ((DEBUG_INFO,"PCI Endpoint"));
> -      break;
> -    case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE:
> -      DEBUG ((DEBUG_INFO,"PCI-PCI bridge"));
> -      break;
> -    case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC:
> -      DEBUG ((DEBUG_INFO,"IOAPIC"));
> -      break;
> -    case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET:
> -      DEBUG ((DEBUG_INFO,"MSI Capable HPET"));
> -      break;
> -    case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE:
> -      DEBUG ((DEBUG_INFO,"ACPI Namespace Device"));
> -      break;
> -    }
> -    DEBUG ((DEBUG_INFO," S%04x B%02x D%02x F%02x\n", DmarDrhd-
> >SegmentNumber, Bus, Device, Function));
> -
> -    SourceId.Bits.Bus = Bus;
> -    SourceId.Bits.Device = Device;
> -    SourceId.Bits.Function = Function;
> -
> -    Status = RegisterPciDevice (VTdUnitInfo, DmarDrhd->SegmentNumber,
> SourceId, DmarDevScopeEntry->Type, TRUE);
> -    if (EFI_ERROR (Status)) {
> -      DEBUG ((DEBUG_ERROR,"RegisterPciDevice Failed !\n"));
> -    }
> -
> -    DmarDevScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN)
> DmarDevScopeEntry + DmarDevScopeEntry->Length);
> -  }
> -}
> -
> -/**
> -  Dump the PCI device information managed by this VTd engine.
> -
> -  @param[in]  VTdInfo           The VTd engine context information.
> -  @param[in]  VtdIndex          The index of VTd engine.
> -
> -**/
> -VOID
> -DumpPciDeviceInfo (
> -  IN VTD_INFO                   *VTdInfo,
> -  IN UINTN                      VtdIndex
> -  )
> -{
> -  UINTN                         Index;
> -  PEI_PCI_DEVICE_DATA           *PciDeviceDataBase;
> -
> -  DEBUG ((DEBUG_INFO,"PCI Device Information (Number 0x%x, IncludeAll -
>  %d):\n",
> -    VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.PciDeviceDataNumber,
> -    VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.IncludeAllFlag
> -    ));
> -
> -  PciDeviceDataBase = (PEI_PCI_DEVICE_DATA *) (UINTN) VTdInfo-
> >VtdUnitInfo[VtdIndex].PciDeviceInfo.PciDeviceData;
> -
> -  for (Index = 0; Index < VTdInfo-
> >VtdUnitInfo[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {
> -    DEBUG ((DEBUG_INFO,"  S%04x B%02x D%02x F%02x\n",
> -      VTdInfo->VtdUnitInfo[VtdIndex].Segment,
> -      PciDeviceDataBase[Index].PciSourceId.Bits.Bus,
> -      PciDeviceDataBase[Index].PciSourceId.Bits.Device,
> -      PciDeviceDataBase[Index].PciSourceId.Bits.Function
> -      ));
> -  }
> -}
> -
>  /**
>    Parse DMAR DRHD table.
> 
>    @param[in]  AcpiDmarTable     DMAR ACPI table
> +  @param[in]  Callback          Callback function for handle DRHD
> +  @param[in]  Context           Callback function Context
> 
>    @return EFI_SUCCESS  The DMAR DRHD table is parsed.
> 
>  **/
>  EFI_STATUS
>  ParseDmarAcpiTableDrhd (
> -  IN EFI_ACPI_DMAR_HEADER               *AcpiDmarTable
> +  IN EFI_ACPI_DMAR_HEADER               *AcpiDmarTable,
> +  IN PROCESS_DRHD_CALLBACK_FUNC         Callback,
> +  IN VOID                               *Context
>    )
>  {
>    EFI_ACPI_DMAR_STRUCTURE_HEADER        *DmarHeader;
> -  UINTN                                 VtdUnitNumber;
> -  UINTN                                 VtdIndex;
> -  VTD_INFO                              *VTdInfo;
> -
> -  VtdUnitNumber = GetVtdEngineNumber (AcpiDmarTable);
> -  if (VtdUnitNumber == 0) {
> -    return EFI_UNSUPPORTED;
> -  }
> -
> -  VTdInfo = BuildGuidHob (&mVTdInfoGuid, sizeof (VTD_INFO) +
> (VtdUnitNumber - 1) * sizeof (VTD_UNIT_INFO));
> -  ASSERT(VTdInfo != NULL);
> -  if (VTdInfo == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  //
> -  // Initialize the engine mask to all.
> -  //
> -  VTdInfo->AcpiDmarTable    = (UINT32) (UINTN) AcpiDmarTable;
> -  VTdInfo->HostAddressWidth = AcpiDmarTable->HostAddressWidth;
> -  VTdInfo->VTdEngineCount   = (UINT32) VtdUnitNumber;
> +  UINT32                                VtdIndex;
> 
>    VtdIndex = 0;
>    DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN)
> (AcpiDmarTable + 1));
> +
>    while ((UINTN) DmarHeader < (UINTN) AcpiDmarTable + AcpiDmarTable-
> >Header.Length) {
>      switch (DmarHeader->Type) {
>      case EFI_ACPI_DMAR_TYPE_DRHD:
> -      ASSERT (VtdIndex < VtdUnitNumber);
> -      ProcessDrhd (&VTdInfo->VtdUnitInfo[VtdIndex],
> (EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader);
> +      if (Callback != NULL) {
> +        Callback (Context, VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)
> DmarHeader);
> +      }
>        VtdIndex++;
> -
>        break;
> -
>      default:
>        break;
>      }
>      DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN)
> DmarHeader + DmarHeader->Length);
>    }
> -  ASSERT (VtdIndex == VtdUnitNumber);
> -
> -  for (VtdIndex = 0; VtdIndex < VtdUnitNumber; VtdIndex++) {
> -    DumpPciDeviceInfo (VTdInfo, VtdIndex);
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -
> -/**
> -  Process DMAR RMRR table.
> -
> -  @param[in]  VTdInfo           The VTd engine context information.
> -  @param[in]  DmarRmrr          The RMRR table.
> -
> -**/
> -VOID
> -ProcessRmrr (
> -  IN VTD_INFO                                     *VTdInfo,
> -  IN EFI_ACPI_DMAR_RMRR_HEADER                    *DmarRmrr
> -  )
> -{
> -  EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> *DmarDevScopeEntry;
> -  UINT8                                           Bus;
> -  UINT8                                           Device;
> -  UINT8                                           Function;
> -  EFI_STATUS                                      Status;
> -  VTD_SOURCE_ID                                   SourceId;
> -
> -  DEBUG ((DEBUG_INFO,"  PEI RMRR (Base 0x%016lx, Limit 0x%016lx)\n",
> DmarRmrr->ReservedMemoryRegionBaseAddress, DmarRmrr-
> >ReservedMemoryRegionLimitAddress));
> -
> -  if ((DmarRmrr->ReservedMemoryRegionBaseAddress == 0) ||
> -      (DmarRmrr->ReservedMemoryRegionLimitAddress == 0)) {
> -    return ;
> -  }
> -
> -  DmarDevScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN)
> (DmarRmrr + 1));
> -  while ((UINTN) DmarDevScopeEntry < (UINTN) DmarRmrr + DmarRmrr-
> >Header.Length) {
> -    if (DmarDevScopeEntry->Type !=
> EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT) {
> -      DEBUG ((DEBUG_INFO,"RMRR DevScopeEntryType is not endpoint,
> type[0x%x] \n", DmarDevScopeEntry->Type));
> -      return;
> -    }
> -
> -    Status = GetPciBusDeviceFunction (DmarRmrr->SegmentNumber,
> DmarDevScopeEntry, &Bus, &Device, &Function);
> -    if (EFI_ERROR (Status)) {
> -      continue;
> -    }
> -
> -    DEBUG ((DEBUG_INFO,"RMRR S%04x B%02x D%02x F%02x\n", DmarRmrr-
> >SegmentNumber, Bus, Device, Function));
> -
> -    SourceId.Bits.Bus = Bus;
> -    SourceId.Bits.Device = Device;
> -    SourceId.Bits.Function = Function;
> -
> -    Status = EnableRmrrPageAttribute (
> -               VTdInfo,
> -               DmarRmrr->SegmentNumber,
> -               SourceId,
> -               DmarRmrr->ReservedMemoryRegionBaseAddress,
> -               DmarRmrr->ReservedMemoryRegionLimitAddress,
> -               EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE
> -               );
> -    if (EFI_ERROR (Status)) {
> -      DEBUG ((DEBUG_INFO, "EnableRmrrPageAttribute : %r\n", Status));
> -    }
> -
> -    DmarDevScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN)
> DmarDevScopeEntry + DmarDevScopeEntry->Length);
> -  }
> -}
> -
> -/**
> -  Parse DMAR DRHD table.
> -
> -  @param[in]  VTdInfo           The VTd engine context information.
> -
> -**/
> -VOID
> -ParseDmarAcpiTableRmrr (
> -  IN VTD_INFO                           *VTdInfo
> -  )
> -{
> -  EFI_ACPI_DMAR_HEADER                  *AcpiDmarTable;
> -  EFI_ACPI_DMAR_STRUCTURE_HEADER        *DmarHeader;
> 
> -  AcpiDmarTable = (EFI_ACPI_DMAR_HEADER *) (UINTN) VTdInfo-
> >AcpiDmarTable;
> -
> -  DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN)
> (AcpiDmarTable + 1));
> -  while ((UINTN) DmarHeader < (UINTN) AcpiDmarTable + AcpiDmarTable-
> >Header.Length) {
> -    switch (DmarHeader->Type) {
> -    case EFI_ACPI_DMAR_TYPE_RMRR:
> -      ProcessRmrr (VTdInfo, (EFI_ACPI_DMAR_RMRR_HEADER *)
> DmarHeader);
> -      break;
> -    default:
> -      break;
> -    }
> -    DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN)
> DmarHeader + DmarHeader->Length);
> -  }
> +  return VtdIndex;
>  }
> 
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.
> c
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.
> c
> index 63397a1a..0ed216bb 100644
> ---
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.
> c
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.
> c
> @@ -1,6 +1,6 @@
>  /** @file
> 
> -  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
> 
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -79,77 +79,73 @@ PerpareCacheInvalidationInterface (
>    IN VTD_UNIT_INFO *VTdUnitInfo
>    )
>  {
> -  UINT16         QueueSize;
> +  UINT16         QiDescLength;
>    UINT64         Reg64;
>    UINT32         Reg32;
>    VTD_ECAP_REG   ECapReg;
> +  UINTN          VtdUnitBaseAddress;
> 
> +  VtdUnitBaseAddress = VTdUnitInfo->VtdUnitBaseAddress;
> 
> -  if (VTdUnitInfo->VerReg.Bits.Major <= 6) {
> +  if (VTdUnitInfo->VerReg.Bits.Major <= 5) {
>      VTdUnitInfo->EnableQueuedInvalidation = 0;
> -    DEBUG ((DEBUG_INFO, "Use Register-based Invalidation Interface for
> engine [0x%x]\n", VTdUnitInfo->VtdUnitBaseAddress));
> +    DEBUG ((DEBUG_INFO, "Use Register-based Invalidation Interface for
> engine [0x%x]\n", VtdUnitBaseAddress));
>      return EFI_SUCCESS;
>    }
> 
> -  ECapReg.Uint64 = MmioRead64 ((UINTN)VTdUnitInfo-
> >VtdUnitBaseAddress + R_ECAP_REG);
> +  ECapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_ECAP_REG);
>    if (ECapReg.Bits.QI == 0) {
> -    DEBUG ((DEBUG_ERROR, "Hardware does not support queued
> invalidations interface for engine [0x%x]\n", VTdUnitInfo-
> >VtdUnitBaseAddress));
> +    DEBUG ((DEBUG_ERROR, "Hardware does not support queued
> invalidations interface for engine [0x%x]\n", VtdUnitBaseAddress));
>      return EFI_UNSUPPORTED;
>    }
> 
>    VTdUnitInfo->EnableQueuedInvalidation = 1;
> -  DEBUG ((DEBUG_INFO, "Use Queued Invalidation Interface for engine
> [0x%x]\n", VTdUnitInfo->VtdUnitBaseAddress));
> +  DEBUG ((DEBUG_INFO, "Use Queued Invalidation Interface for engine
> [0x%x]\n", VtdUnitBaseAddress));
> 
> -  Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> +  Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
>    if ((Reg32 & B_GSTS_REG_QIES) != 0) {
>      DEBUG ((DEBUG_INFO,"Queued Invalidation Interface was enabled.\n"));
>      Reg32 &= (~B_GSTS_REG_QIES);
> -    MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GCMD_REG, Reg32);
> +    MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32);
>      do {
> -      Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> +      Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
>      } while ((Reg32 & B_GSTS_REG_QIES) != 0);
> -    MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQA_REG,
> 0);
> -
> -    if (VTdUnitInfo->QiDesc != NULL) {
> -      FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES(sizeof(QI_DESC) *
> VTdUnitInfo->QiDescLength));
> -      VTdUnitInfo->QiDesc = NULL;
> -      VTdUnitInfo->QiDescLength = 0;
> -    }
> +    MmioWrite64 (VtdUnitBaseAddress + R_IQA_REG, 0);
>    }
> 
>    //
>    // Initialize the Invalidation Queue Tail Register to zero.
>    //
> -  MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQT_REG,
> 0);
> +  MmioWrite64 (VtdUnitBaseAddress + R_IQT_REG, 0);
> 
>    //
>    // Setup the IQ address, size and descriptor width through the Invalidation
> Queue Address Register
>    //
> -  QueueSize = 0;
> -  VTdUnitInfo->QiDescLength = 1 << (QueueSize + 8);
> -  VTdUnitInfo->QiDesc = (QI_DESC *) AllocatePages
> (EFI_SIZE_TO_PAGES(sizeof(QI_DESC) * VTdUnitInfo->QiDescLength));
> -
>    if (VTdUnitInfo->QiDesc == NULL) {
> -    VTdUnitInfo->QiDescLength = 0;
> -    DEBUG ((DEBUG_ERROR,"Could not Alloc Invalidation Queue Buffer.\n"));
> -    return EFI_OUT_OF_RESOURCES;
> +    VTdUnitInfo->QueueSize = 0;
> +    QiDescLength = 1 << (VTdUnitInfo->QueueSize + 8);
> +    VTdUnitInfo->QiDesc = (QI_DESC *) AllocatePages
> (EFI_SIZE_TO_PAGES(sizeof(QI_DESC) * QiDescLength));
> +    if (VTdUnitInfo->QiDesc == NULL) {
> +      DEBUG ((DEBUG_ERROR,"Could not Alloc Invalidation Queue
> Buffer.\n"));
> +      return EFI_OUT_OF_RESOURCES;
> +    }
>    }
> 
> -  DEBUG ((DEBUG_INFO, "Invalidation Queue Length : %d\n", VTdUnitInfo-
> >QiDescLength));
> -  Reg64 = (UINT64)(UINTN)VTdUnitInfo->QiDesc;
> -  Reg64 |= QueueSize;
> -  MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQA_REG,
> Reg64);
> +  DEBUG ((DEBUG_INFO, "Invalidation Queue Length : %d\n",
> QiDescLength));
> +  Reg64 = (UINT64) (UINTN) VTdUnitInfo->QiDesc;
> +  Reg64 |= VTdUnitInfo->QueueSize;
> +  MmioWrite64 (VtdUnitBaseAddress + R_IQA_REG, Reg64);
> 
>    //
>    // Enable the queued invalidation interface through the Global Command
> Register.
>    // When enabled, hardware sets the QIES field in the Global Status Register.
>    //
> -  Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> +  Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
>    Reg32 |= B_GMCD_REG_QIE;
> -  MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GCMD_REG, Reg32);
> +  MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32);
>    DEBUG ((DEBUG_INFO, "Enable Queued Invalidation Interface. GCMD_REG
> = 0x%x\n", Reg32));
>    do {
> -    Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> +    Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
>    } while ((Reg32 & B_GSTS_REG_QIES) == 0);
> 
>    VTdUnitInfo->QiFreeHead = 0;
> @@ -167,21 +163,23 @@ DisableQueuedInvalidationInterface (
>    IN VTD_UNIT_INFO *VTdUnitInfo
>    )
>  {
> -  UINT32  Reg32;
> +  UINT32         Reg32;
> +  UINT16         QiDescLength;
> 
>    if (VTdUnitInfo->EnableQueuedInvalidation != 0) {
> -    Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> +    Reg32 = MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
>      Reg32 &= (~B_GMCD_REG_QIE);
> -    MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GCMD_REG, Reg32);
> +    MmioWrite32 (VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG,
> Reg32);
>      DEBUG ((DEBUG_INFO, "Disable Queued Invalidation Interface.
> GCMD_REG = 0x%x\n", Reg32));
>      do {
> -      Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> +      Reg32 = MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
>      } while ((Reg32 & B_GSTS_REG_QIES) != 0);
> 
>      if (VTdUnitInfo->QiDesc != NULL) {
> -      FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES(sizeof(QI_DESC) *
> VTdUnitInfo->QiDescLength));
> +      QiDescLength = 1 << (VTdUnitInfo->QueueSize + 8);
> +      FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES(sizeof(QI_DESC)
> * QiDescLength));
>        VTdUnitInfo->QiDesc = NULL;
> -      VTdUnitInfo->QiDescLength = 0;
> +      VTdUnitInfo->QueueSize = 0;
>      }
> 
>      VTdUnitInfo->EnableQueuedInvalidation = 0;
> @@ -203,26 +201,11 @@ QueuedInvalidationCheckFault (
>  {
>    UINT32     FaultReg;
> 
> -  FaultReg = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_FSTS_REG);
> -
> -  if (FaultReg & B_FSTS_REG_IQE) {
> -    DEBUG((DEBUG_ERROR, "Detect Invalidation Queue Error [0x%08x]\n",
> FaultReg));
> -    FaultReg |= B_FSTS_REG_IQE;
> -    MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG,
> FaultReg);
> -    return RETURN_DEVICE_ERROR;
> -  }
> -
> -  if (FaultReg & B_FSTS_REG_ITE) {
> -    DEBUG((DEBUG_ERROR, "Detect Invalidation Time-out Error [0x%08x]\n",
> FaultReg));
> -    FaultReg |= B_FSTS_REG_ITE;
> -    MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG,
> FaultReg);
> -    return RETURN_DEVICE_ERROR;
> -  }
> -
> -  if (FaultReg & B_FSTS_REG_ICE) {
> -    DEBUG((DEBUG_ERROR, "Detect Invalidation Completion Error
> [0x%08x]\n", FaultReg));
> -    FaultReg |= B_FSTS_REG_ICE;
> -    MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG,
> FaultReg);
> +  FaultReg = MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress +
> R_FSTS_REG);
> +  if (FaultReg & (B_FSTS_REG_IQE | B_FSTS_REG_ITE | B_FSTS_REG_ICE)) {
> +    DEBUG((DEBUG_ERROR, "Detect Queue Invalidation Error [0x%08x]\n",
> FaultReg));
> +    FaultReg |= (B_FSTS_REG_IQE | B_FSTS_REG_ITE | B_FSTS_REG_ICE);
> +    MmioWrite32 (VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG,
> FaultReg);
>      return RETURN_DEVICE_ERROR;
>    }
> 
> @@ -256,7 +239,7 @@ SubmitQueuedInvalidationDescriptor (
>      return EFI_INVALID_PARAMETER;
>    }
> 
> -  QiDescLength = VTdUnitInfo->QiDescLength;
> +  QiDescLength = 1 << (VTdUnitInfo->QueueSize + 8);
>    BaseDesc = VTdUnitInfo->QiDesc;
> 
>    DEBUG((DEBUG_INFO, "[0x%x] Submit QI Descriptor [0x%08x, 0x%08x]\n",
> VTdUnitInfo->VtdUnitBaseAddress, Desc->Low, Desc->High));
> @@ -268,12 +251,12 @@ SubmitQueuedInvalidationDescriptor (
>    DEBUG((DEBUG_INFO,"QI Free Head=0x%x\n", VTdUnitInfo-
> >QiFreeHead));
>    VTdUnitInfo->QiFreeHead = (VTdUnitInfo->QiFreeHead + 1) %
> QiDescLength;
> 
> -  Reg64Iqh = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_IQH_REG);
> +  Reg64Iqh = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> R_IQH_REG);
>    //
>    // Update the HW tail register indicating the presence of new descriptors.
>    //
>    Reg64Iqt = VTdUnitInfo->QiFreeHead << DMAR_IQ_SHIFT;
> -  MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQT_REG,
> Reg64Iqt);
> +  MmioWrite64 (VTdUnitInfo->VtdUnitBaseAddress + R_IQT_REG,
> Reg64Iqt);
> 
>    Status = EFI_SUCCESS;
>    do {
> @@ -283,7 +266,7 @@ SubmitQueuedInvalidationDescriptor (
>        break;
>      }
> 
> -    Reg64Iqh = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_IQH_REG);
> +    Reg64Iqh = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> R_IQH_REG);
>    } while (Reg64Iqt != Reg64Iqh);
> 
>    DEBUG((DEBUG_ERROR,"SubmitQueuedInvalidationDescriptor end\n"));
> @@ -307,18 +290,18 @@ InvalidateContextCache (
>      //
>      // Register-based Invalidation
>      //
> -    Reg64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_CCMD_REG);
> +    Reg64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> R_CCMD_REG);
>      if ((Reg64 & B_CCMD_REG_ICC) != 0) {
> -      DEBUG ((DEBUG_ERROR,"ERROR: InvalidateContextCache:
> B_CCMD_REG_ICC is set for VTD(%x)\n", (UINTN)VTdUnitInfo-
> >VtdUnitBaseAddress));
> +      DEBUG ((DEBUG_ERROR,"ERROR: InvalidateContextCache:
> B_CCMD_REG_ICC is set for VTD(%x)\n", VTdUnitInfo-
> >VtdUnitBaseAddress));
>        return EFI_DEVICE_ERROR;
>      }
> 
>      Reg64 &= ((~B_CCMD_REG_ICC) & (~B_CCMD_REG_CIRG_MASK));
>      Reg64 |= (B_CCMD_REG_ICC | V_CCMD_REG_CIRG_GLOBAL);
> -    MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_CCMD_REG, Reg64);
> +    MmioWrite64 (VTdUnitInfo->VtdUnitBaseAddress + R_CCMD_REG,
> Reg64);
> 
>      do {
> -      Reg64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_CCMD_REG);
> +      Reg64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> R_CCMD_REG);
>      } while ((Reg64 & B_CCMD_REG_ICC) != 0);
>    } else {
>      //
> @@ -351,26 +334,26 @@ InvalidateIOTLB (
>      //
>      // Register-based Invalidation
>      //
> -    ECapReg.Uint64 = MmioRead64 ((UINTN)VTdUnitInfo-
> >VtdUnitBaseAddress + R_ECAP_REG);
> +    ECapReg.Uint64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> R_ECAP_REG);
> 
> -    Reg64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> (ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
> +    Reg64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> (ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
>       if ((Reg64 & B_IOTLB_REG_IVT) != 0) {
> -       DEBUG ((DEBUG_ERROR, "ERROR: InvalidateIOTLB: B_IOTLB_REG_IVT is
> set for VTD(%x)\n", (UINTN)VTdUnitInfo->VtdUnitBaseAddress));
> +       DEBUG ((DEBUG_ERROR, "ERROR: InvalidateIOTLB: B_IOTLB_REG_IVT is
> set for VTD(%x)\n", VTdUnitInfo->VtdUnitBaseAddress));
>         return EFI_DEVICE_ERROR;
>      }
> 
>      Reg64 &= ((~B_IOTLB_REG_IVT) & (~B_IOTLB_REG_IIRG_MASK));
>      Reg64 |= (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_GLOBAL);
> -    MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> (ECapReg.Bits.IRO * 16) + R_IOTLB_REG, Reg64);
> +    MmioWrite64 (VTdUnitInfo->VtdUnitBaseAddress + (ECapReg.Bits.IRO *
> 16) + R_IOTLB_REG, Reg64);
> 
>      do {
> -      Reg64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> (ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
> +      Reg64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> (ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
>      } while ((Reg64 & B_IOTLB_REG_IVT) != 0);
>    } else {
>      //
>      // Queued Invalidation
>      //
> -    ECapReg.Uint64 = MmioRead64 ((UINTN)VTdUnitInfo-
> >VtdUnitBaseAddress + R_ECAP_REG);
> +    ECapReg.Uint64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> R_ECAP_REG);
>      QiDesc.Low = QI_IOTLB_DID(0) |
> QI_IOTLB_DR(CAP_READ_DRAIN(ECapReg.Uint64)) |
> QI_IOTLB_DW(CAP_WRITE_DRAIN(ECapReg.Uint64)) | QI_IOTLB_GRAN(1) |
> QI_IOTLB_TYPE;
>      QiDesc.High = QI_IOTLB_ADDR(0) | QI_IOTLB_IH(0) | QI_IOTLB_AM(0);
> 
> @@ -392,14 +375,14 @@ InvalidateIOTLB (
>  EFI_STATUS
>  EnableDmarPreMem (
>    IN UINTN                        VtdUnitBaseAddress,
> -  IN UINTN                        RtaddrRegValue
> +  IN UINT64                       RtaddrRegValue
>    )
>  {
>    UINT32                          Reg32;
> 
>    DEBUG ((DEBUG_INFO, ">>>>>>EnableDmarPreMem() for engine [%x] \n",
> VtdUnitBaseAddress));
> 
> -  DEBUG ((DEBUG_INFO, "RTADDR_REG : 0x%x \n", RtaddrRegValue));
> +  DEBUG ((DEBUG_INFO, "RTADDR_REG : 0x%016lx \n", RtaddrRegValue));
>    MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64)
> RtaddrRegValue);
> 
>    Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> @@ -452,30 +435,33 @@ EnableDmar (
>    )
>  {
>    UINT32                        Reg32;
> +  UINTN                         VtdUnitBaseAddress;
> 
> -  DEBUG ((DEBUG_INFO, ">>>>>>EnableDmar() for engine [%x] \n",
> VTdUnitInfo->VtdUnitBaseAddress));
> +  VtdUnitBaseAddress = VTdUnitInfo->VtdUnitBaseAddress;
> +
> +  DEBUG ((DEBUG_INFO, ">>>>>>EnableDmar() for engine [%x] \n",
> VtdUnitBaseAddress));
> 
>    DEBUG ((DEBUG_INFO, "RootEntryTable 0x%x \n", RootEntryTable));
> -  MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_RTADDR_REG, (UINT64) (UINTN) RootEntryTable);
> +  MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64)
> RootEntryTable);
> 
> -  Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> -  MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GCMD_REG, Reg32 | B_GMCD_REG_SRTP);
> +  Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> +  MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32 |
> B_GMCD_REG_SRTP);
> 
>    DEBUG ((DEBUG_INFO, "EnableDmar: waiting for RTPS bit to be set... \n"));
>    do {
> -    Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> +    Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
>    } while((Reg32 & B_GSTS_REG_RTPS) == 0);
>    DEBUG ((DEBUG_INFO, "EnableDmar: R_GSTS_REG = 0x%x \n", Reg32));
> 
>    //
>    // Init DMAr Fault Event and Data registers
>    //
> -  Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_FEDATA_REG);
> +  Reg32 = MmioRead32 (VtdUnitBaseAddress + R_FEDATA_REG);
> 
>    //
>    // Write Buffer Flush before invalidation
>    //
> -  FlushWriteBuffer ((UINTN)VTdUnitInfo->VtdUnitBaseAddress);
> +  FlushWriteBuffer (VtdUnitBaseAddress);
> 
>    //
>    // Invalidate the context cache
> @@ -490,11 +476,11 @@ EnableDmar (
>    //
>    // Enable VTd
>    //
> -  Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> -  MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GCMD_REG, Reg32 | B_GMCD_REG_TE);
> +  Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> +  MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32 |
> B_GMCD_REG_TE);
>    DEBUG ((DEBUG_INFO, "EnableDmar: Waiting B_GSTS_REG_TE ...\n"));
>    do {
> -    Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> +    Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
>    } while ((Reg32 & B_GSTS_REG_TE) == 0);
> 
>    DEBUG ((DEBUG_INFO, "VTD () enabled!<<<<<<\n"));
> @@ -566,139 +552,52 @@ DisableDmar (
>  }
> 
>  /**
> -  Dump VTd version registers.
> +  Enable VTd translation table protection for block DMA
> 
> -  @param[in]  VerReg            The version register.
> -**/
> -VOID
> -DumpVtdVerRegs (
> -  IN VTD_VER_REG                *VerReg
> -  )
> -{
> -  DEBUG ((DEBUG_INFO, "  VerReg:\n", VerReg->Uint32));
> -  DEBUG ((DEBUG_INFO, "    Major    - 0x%x\n", VerReg->Bits.Major));
> -  DEBUG ((DEBUG_INFO, "    Minor    - 0x%x\n", VerReg->Bits.Minor));
> -}
> -
> -/**
> -  Dump VTd capability registers.
> -
> -  @param[in]  CapReg            The capability register.
> -**/
> -VOID
> -DumpVtdCapRegs (
> -  IN VTD_CAP_REG                *CapReg
> -  )
> -{
> -  DEBUG ((DEBUG_INFO, "  CapReg:\n", CapReg->Uint64));
> -  DEBUG ((DEBUG_INFO, "    ND     - 0x%x\n", CapReg->Bits.ND));
> -  DEBUG ((DEBUG_INFO, "    AFL    - 0x%x\n", CapReg->Bits.AFL));
> -  DEBUG ((DEBUG_INFO, "    RWBF   - 0x%x\n", CapReg->Bits.RWBF));
> -  DEBUG ((DEBUG_INFO, "    PLMR   - 0x%x\n", CapReg->Bits.PLMR));
> -  DEBUG ((DEBUG_INFO, "    PHMR   - 0x%x\n", CapReg->Bits.PHMR));
> -  DEBUG ((DEBUG_INFO, "    CM     - 0x%x\n", CapReg->Bits.CM));
> -  DEBUG ((DEBUG_INFO, "    SAGAW  - 0x%x\n", CapReg->Bits.SAGAW));
> -  DEBUG ((DEBUG_INFO, "    MGAW   - 0x%x\n", CapReg->Bits.MGAW));
> -  DEBUG ((DEBUG_INFO, "    ZLR    - 0x%x\n", CapReg->Bits.ZLR));
> -  DEBUG ((DEBUG_INFO, "    FRO    - 0x%x\n", CapReg->Bits.FRO));
> -  DEBUG ((DEBUG_INFO, "    SLLPS  - 0x%x\n", CapReg->Bits.SLLPS));
> -  DEBUG ((DEBUG_INFO, "    PSI    - 0x%x\n", CapReg->Bits.PSI));
> -  DEBUG ((DEBUG_INFO, "    NFR    - 0x%x\n", CapReg->Bits.NFR));
> -  DEBUG ((DEBUG_INFO, "    MAMV   - 0x%x\n", CapReg->Bits.MAMV));
> -  DEBUG ((DEBUG_INFO, "    DWD    - 0x%x\n", CapReg->Bits.DWD));
> -  DEBUG ((DEBUG_INFO, "    DRD    - 0x%x\n", CapReg->Bits.DRD));
> -  DEBUG ((DEBUG_INFO, "    FL1GP  - 0x%x\n", CapReg->Bits.FL1GP));
> -  DEBUG ((DEBUG_INFO, "    PI     - 0x%x\n", CapReg->Bits.PI));
> -}
> +  @param[in] VtdUnitBaseAddress The base address of the VTd engine.
> 
> -/**
> -  Dump VTd extended capability registers.
> -
> -  @param[in]  ECapReg           The extended capability register.
> +  @retval EFI_SUCCESS         DMAR translation is enabled.
> +  @retval EFI_DEVICE_ERROR    DMAR translation is not enabled.
>  **/
> -VOID
> -DumpVtdECapRegs (
> -  IN VTD_ECAP_REG               *ECapReg
> -  )
> -{
> -  DEBUG ((DEBUG_INFO, "  ECapReg:\n", ECapReg->Uint64));
> -  DEBUG ((DEBUG_INFO, "    C      - 0x%x\n", ECapReg->Bits.C));
> -  DEBUG ((DEBUG_INFO, "    QI     - 0x%x\n", ECapReg->Bits.QI));
> -  DEBUG ((DEBUG_INFO, "    DT     - 0x%x\n", ECapReg->Bits.DT));
> -  DEBUG ((DEBUG_INFO, "    IR     - 0x%x\n", ECapReg->Bits.IR));
> -  DEBUG ((DEBUG_INFO, "    EIM    - 0x%x\n", ECapReg->Bits.EIM));
> -  DEBUG ((DEBUG_INFO, "    PT     - 0x%x\n", ECapReg->Bits.PT));
> -  DEBUG ((DEBUG_INFO, "    SC     - 0x%x\n", ECapReg->Bits.SC));
> -  DEBUG ((DEBUG_INFO, "    IRO    - 0x%x\n", ECapReg->Bits.IRO));
> -  DEBUG ((DEBUG_INFO, "    MHMV   - 0x%x\n", ECapReg->Bits.MHMV));
> -  DEBUG ((DEBUG_INFO, "    MTS    - 0x%x\n", ECapReg->Bits.MTS));
> -  DEBUG ((DEBUG_INFO, "    NEST   - 0x%x\n", ECapReg->Bits.NEST));
> -  DEBUG ((DEBUG_INFO, "    PASID  - 0x%x\n", ECapReg->Bits.PASID));
> -  DEBUG ((DEBUG_INFO, "    PRS    - 0x%x\n", ECapReg->Bits.PRS));
> -  DEBUG ((DEBUG_INFO, "    ERS    - 0x%x\n", ECapReg->Bits.ERS));
> -  DEBUG ((DEBUG_INFO, "    SRS    - 0x%x\n", ECapReg->Bits.SRS));
> -  DEBUG ((DEBUG_INFO, "    NWFS   - 0x%x\n", ECapReg->Bits.NWFS));
> -  DEBUG ((DEBUG_INFO, "    EAFS   - 0x%x\n", ECapReg->Bits.EAFS));
> -  DEBUG ((DEBUG_INFO, "    PSS    - 0x%x\n", ECapReg->Bits.PSS));
> -  DEBUG ((DEBUG_INFO, "    ADMS   - 0x%x\n", ECapReg->Bits.ADMS));
> -}
> -
> -
> -/**
> -  Enable VTd translation table protection for all.
> -
> -  @param[in]  VTdInfo           The VTd engine context information.
> -  @param[in]  EngineMask        The mask of the VTd engine to be accessed.
> -**/
> -VOID
> -EnableVTdTranslationProtectionAll (
> -  IN VTD_INFO                   *VTdInfo,
> -  IN UINT64                     EngineMask
> +EFI_STATUS
> +EnableVTdTranslationProtectionBlockDma (
> +  IN UINTN                      VtdUnitBaseAddress
>    )
>  {
> -  EFI_STATUS                                Status;
> -  EDKII_VTD_NULL_ROOT_ENTRY_TABLE_PPI       *RootEntryTable;
> -  UINTN                                     Index;
> +  EFI_STATUS                            Status;
> +  VTD_ECAP_REG                          ECapReg;
> +  EDKII_VTD_NULL_ROOT_ENTRY_TABLE_PPI   *RootEntryTable;
> 
> -  DEBUG ((DEBUG_INFO, "EnableVTdTranslationProtectionAll - 0x%lx\n",
> EngineMask));
> +  DEBUG ((DEBUG_INFO, "EnableVTdTranslationProtectionBlockDma -
> 0x%08x\n", VtdUnitBaseAddress));
> 
> -  for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
> -    if ((EngineMask & LShiftU64(1, Index)) == 0) {
> -      continue;
> -    }
> +  ECapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_ECAP_REG);
> +  DEBUG ((DEBUG_INFO, "ECapReg : 0%016lx\n", ECapReg.Uint64));
> 
> -    VTdInfo->VtdUnitInfo[Index].VerReg.Uint32 = MmioRead32 (VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress + R_VER_REG);
> -    DumpVtdVerRegs (&VTdInfo->VtdUnitInfo[Index].VerReg);
> -    VTdInfo->VtdUnitInfo[Index].CapReg.Uint64 = MmioRead64 (VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress + R_CAP_REG);
> -    DumpVtdCapRegs (&VTdInfo->VtdUnitInfo[Index].CapReg);
> -    VTdInfo->VtdUnitInfo[Index].ECapReg.Uint64 = MmioRead64 (VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress + R_ECAP_REG);
> -    DumpVtdECapRegs (&VTdInfo->VtdUnitInfo[Index].ECapReg);
> -
> -    if (VTdInfo->VtdUnitInfo[Index].ECapReg.Bits.ADMS == 1) {
> -      //
> -      // Use Abort DMA Mode
> -      //
> -      Status = EnableDmarPreMem (VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress, V_RTADDR_REG_TTM_ADM);
> -    } else {
> -      //
> -      // Use Null Root Entry Table
> -      //
> -      Status = PeiServicesLocatePpi (
> -                 &gEdkiiVTdNullRootEntryTableGuid,
> -                 0,
> -                 NULL,
> -                 (VOID **)&RootEntryTable
> -                 );
> -      if (EFI_ERROR(Status)) {
> -        DEBUG ((DEBUG_ERROR, "Locate Null Root Entry Table Ppi Failed : %r\n",
> Status));
> -        ASSERT (FALSE);
> -        return;
> -      }
> -      EnableDmarPreMem (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress,
> (UINTN) *RootEntryTable);
> +  if (ECapReg.Bits.ADMS == 1) {
> +    //
> +    // Use Abort DMA Mode
> +    //
> +    DEBUG ((DEBUG_INFO, "Enable abort DMA mode.\n"));
> +    Status = EnableDmarPreMem (VtdUnitBaseAddress,
> V_RTADDR_REG_TTM_ADM);
> +  } else {
> +    //
> +    // Use Null Root Entry Table
> +    //
> +    Status = PeiServicesLocatePpi (
> +               &gEdkiiVTdNullRootEntryTableGuid,
> +               0,
> +               NULL,
> +               (VOID **)&RootEntryTable
> +               );
> +    if (EFI_ERROR(Status)) {
> +      DEBUG ((DEBUG_ERROR, "Locate Null Root Entry Table Ppi Failed : %r\n",
> Status));
> +      ASSERT (FALSE);
> +      return EFI_DEVICE_ERROR;
>      }
> +    Status = EnableDmarPreMem (VtdUnitBaseAddress, (UINT64)
> (*RootEntryTable));
>    }
> 
> -  return;
> +  return Status;
>  }
> 
>  /**
> @@ -715,18 +614,25 @@ EnableVTdTranslationProtection (
>    )
>  {
>    EFI_STATUS                    Status;
> -  UINTN                         VtdIndex;
> +  UINTN                         Index;
> +  VTD_UNIT_INFO                 *VtdUnitInfo;
> 
> -  for (VtdIndex = 0; VtdIndex < VTdInfo->VTdEngineCount; VtdIndex++) {
> -    if (VTdInfo->VtdUnitInfo[VtdIndex].ExtRootEntryTable != 0) {
> -      DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) ExtRootEntryTable
> 0x%x\n", VtdIndex, VTdInfo->VtdUnitInfo[VtdIndex].ExtRootEntryTable));
> -      Status = EnableDmar (&VTdInfo->VtdUnitInfo[VtdIndex], VTdInfo-
> >VtdUnitInfo[VtdIndex].ExtRootEntryTable);
> +  for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
> +    VtdUnitInfo = &VTdInfo->VtdUnitInfo[Index];
> +    if (VtdUnitInfo->Done) {
> +      DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) was enabled\n", Index));
> +      continue;
> +    }
> +
> +    if (VtdUnitInfo->ExtRootEntryTable != 0) {
> +      DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) ExtRootEntryTable
> 0x%x\n", Index, VtdUnitInfo->ExtRootEntryTable));
> +      Status = EnableDmar (VtdUnitInfo, VtdUnitInfo->ExtRootEntryTable);
>      } else {
> -      DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) RootEntryTable 0x%x\n",
> VtdIndex, VTdInfo->VtdUnitInfo[VtdIndex].RootEntryTable));
> -      Status = EnableDmar (&VTdInfo->VtdUnitInfo[VtdIndex], VTdInfo-
> >VtdUnitInfo[VtdIndex].RootEntryTable);
> +      DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) RootEntryTable 0x%x\n",
> Index, VtdUnitInfo->RootEntryTable));
> +      Status = EnableDmar (VtdUnitInfo, VtdUnitInfo->RootEntryTable);
>      }
>      if (EFI_ERROR (Status)) {
> -      DEBUG ((DEBUG_ERROR, "EnableVtdDmar (%d) Failed !\n", VtdIndex));
> +      DEBUG ((DEBUG_ERROR, "EnableVtdDmar (%d) Failed !\n", Index));
>        return Status;
>      }
>    }
> @@ -737,23 +643,22 @@ EnableVTdTranslationProtection (
>    Disable VTd translation table protection.
> 
>    @param[in]  VTdInfo           The VTd engine context information.
> -  @param[in]  EngineMask        The mask of the VTd engine to be accessed.
>  **/
>  VOID
>  DisableVTdTranslationProtection (
> -  IN VTD_INFO                   *VTdInfo,
> -  IN UINT64                     EngineMask
> +  IN VTD_INFO                   *VTdInfo
>    )
>  {
>    UINTN                         Index;
> 
> -  DEBUG ((DEBUG_INFO, "DisableVTdTranslationProtection - 0x%lx\n",
> EngineMask));
> +  if (VTdInfo == NULL) {
> +    return;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "DisableVTdTranslationProtection - %d Vtd
> Engine\n", VTdInfo->VTdEngineCount));
> 
>    for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
> -    if ((EngineMask & LShiftU64(1, Index)) == 0) {
> -      continue;
> -    }
> -    DisableDmar ((UINTN) VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress);
> +    DisableDmar (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress);
> 
>      DisableQueuedInvalidationInterface(&VTdInfo->VtdUnitInfo[Index]);
>    }
> @@ -786,6 +691,36 @@ PrepareVtdCacheInvalidationConfig (
>    return EFI_SUCCESS;
>  }
> 
> +/**
> +
> +**/
> +EFI_STATUS
> +VtdCheckUsing5LevelPaging (
> +  IN  UINT8                            HostAddressWidth,
> +  IN  VTD_UNIT_INFO                    *VtdUnitInfo,
> +  OUT BOOLEAN                          *Is5LevelPaging
> +  )
> +{
> +  DEBUG((DEBUG_INFO, "  CapReg SAGAW bits : 0x%02x\n", VtdUnitInfo-
> >CapReg.Bits.SAGAW));
> +
> +  *Is5LevelPaging = FALSE;
> +  if ((VtdUnitInfo->CapReg.Bits.SAGAW & BIT3) != 0) {
> +    *Is5LevelPaging = TRUE;
> +    if ((HostAddressWidth <= 48) &&
> +         ((VtdUnitInfo->CapReg.Bits.SAGAW & BIT2) != 0)) {
> +      *Is5LevelPaging = FALSE;
> +    } else {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +  if ((VtdUnitInfo->CapReg.Bits.SAGAW & (BIT3 | BIT2)) == 0) {
> +    return EFI_UNSUPPORTED;
> +  }
> +  DEBUG((DEBUG_INFO, "  Using %d Level Paging\n", *Is5LevelPaging ? 5 :
> 4));
> +  return EFI_SUCCESS;
> +}
> +
> +
>  /**
>    Prepare VTD configuration.
> 
> @@ -798,43 +733,37 @@ PrepareVtdConfig (
>    IN VTD_INFO                   *VTdInfo
>    )
>  {
> +  EFI_STATUS                    Status;
>    UINTN                         Index;
> -  UINTN                         DomainNumber;
> +  VTD_UNIT_INFO                 *VtdUnitInfo;
> +  UINTN                         VtdUnitBaseAddress;
> 
>    for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
> -    DEBUG ((DEBUG_ERROR, "Dump VTd Capability (%d)\n", Index));
> -    VTdInfo->VtdUnitInfo[Index].VerReg.Uint32 = MmioRead32 (VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress + R_VER_REG);
> -    DumpVtdVerRegs (&VTdInfo->VtdUnitInfo[Index].VerReg);
> -    VTdInfo->VtdUnitInfo[Index].CapReg.Uint64 = MmioRead64 (VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress + R_CAP_REG);
> -    DumpVtdCapRegs (&VTdInfo->VtdUnitInfo[Index].CapReg);
> -    VTdInfo->VtdUnitInfo[Index].ECapReg.Uint64 = MmioRead64 (VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress + R_ECAP_REG);
> -    DumpVtdECapRegs (&VTdInfo->VtdUnitInfo[Index].ECapReg);
> -
> -    VTdInfo->VtdUnitInfo[Index].Is5LevelPaging = FALSE;
> -    if ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & BIT2) != 0) {
> -      DEBUG ((DEBUG_INFO, "Support 4-level page-table on VTD %d\n",
> Index));
> -    }
> -    if ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & BIT3) != 0) {
> -      DEBUG((DEBUG_INFO, "Support 5-level page-table on VTD %d\n",
> Index));
> -      VTdInfo->VtdUnitInfo[Index].Is5LevelPaging = TRUE;
> -
> -      if ((VTdInfo->HostAddressWidth <= 48) &&
> -          ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & BIT2) != 0)) {
> -        DEBUG ((DEBUG_INFO, "Rollback to 4-level page-table on VTD %d\n",
> Index));
> -        VTdInfo->VtdUnitInfo[Index].Is5LevelPaging = FALSE;
> -      }
> +    VtdUnitInfo = &VTdInfo->VtdUnitInfo[Index];
> +    if (VtdUnitInfo->Done) {
> +      continue;
>      }
> -    if ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & (BIT3 | BIT2)) ==
> 0) {
> -      DEBUG ((DEBUG_ERROR, "!!!! Page-table type 0x%X is not supported on
> VTD %d !!!!\n", Index, VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW));
> -      return EFI_UNSUPPORTED;
> +    VtdUnitBaseAddress = VtdUnitInfo->VtdUnitBaseAddress;
> +    DEBUG((DEBUG_INFO, "VTd Engine: 0x%08X\n", VtdUnitBaseAddress));
> +
> +    VtdUnitInfo->VerReg.Uint32 = MmioRead32 (VtdUnitBaseAddress +
> R_VER_REG);
> +    VtdUnitInfo->CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress +
> R_CAP_REG);
> +    VtdUnitInfo->ECapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress +
> R_ECAP_REG);
> +    DEBUG((DEBUG_INFO, "  VerReg  : 0x%08X\n", VtdUnitInfo-
> >VerReg.Uint32));
> +    DEBUG((DEBUG_INFO, "  CapReg  : 0x%016lX\n", VtdUnitInfo-
> >CapReg.Uint64));
> +    DEBUG((DEBUG_INFO, "  ECapReg : 0x%016lX\n", VtdUnitInfo-
> >ECapReg.Uint64));
> +
> +    Status = VtdCheckUsing5LevelPaging (VTdInfo->HostAddressWidth,
> VtdUnitInfo, &(VtdUnitInfo->Is5LevelPaging));
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "!!!! Page-table type 0x%X is not
> supported!!!!\n", VtdUnitInfo->CapReg.Bits.SAGAW));
> +      return Status;
>      }
> 
> -    DomainNumber = (UINTN)1 << (UINT8) ((UINTN) VTdInfo-
> >VtdUnitInfo[Index].CapReg.Bits.ND * 2 + 4);
> -    if (VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataNumber >=
> DomainNumber) {
> -      DEBUG ((DEBUG_ERROR, "!!!! Pci device Number(0x%x) >=
> DomainNumber(0x%x) !!!!\n", VTdInfo-
> >VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataNumber, DomainNumber));
> -      return EFI_UNSUPPORTED;
> +    Status = PerpareCacheInvalidationInterface(VtdUnitInfo);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
>      }
>    }
> +
>    return EFI_SUCCESS;
>  }
> -
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.c
> index a8f7bfee..ac91eac3 100644
> ---
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.c
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.c
> @@ -1,6 +1,6 @@
>  /** @file
> 
> -  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
> 
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -50,20 +50,20 @@ typedef struct {
>    the device driver need use SetAttribute() to update the IOMMU
>    attribute to request DMA access (read and/or write).
> 
> -  @param[in]  This              The PPI instance pointer.
> -  @param[in]  DeviceHandle      The device who initiates the DMA access
> request.
> -  @param[in]  Mapping           The mapping value returned from Map().
> -  @param[in]  IoMmuAccess       The IOMMU access.
> -
> -  @retval EFI_SUCCESS           The IoMmuAccess is set for the memory range
> specified by DeviceAddress and Length.
> -  @retval EFI_INVALID_PARAMETER Mapping is not a value that was
> returned by Map().
> -  @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal
> combination of access.
> -  @retval EFI_UNSUPPORTED       The bit mask of IoMmuAccess is not
> supported by the IOMMU.
> -  @retval EFI_UNSUPPORTED       The IOMMU does not support the memory
> range specified by Mapping.
> -  @retval EFI_OUT_OF_RESOURCES  There are not enough resources
> available to modify the IOMMU access.
> -  @retval EFI_DEVICE_ERROR      The IOMMU device reported an error while
> attempting the operation.
> -  @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but
> DMA buffer are
> -                                not available to be allocated yet.
> +  @param[in]  This                  The PPI instance pointer.
> +  @param[in]  DeviceHandle          The device who initiates the DMA access
> request.
> +  @param[in]  Mapping               The mapping value returned from Map().
> +  @param[in]  IoMmuAccess           The IOMMU access.
> +
> +  @retval EFI_SUCCESS               The IoMmuAccess is set for the memory
> range specified by DeviceAddress and Length.
> +  @retval EFI_INVALID_PARAMETER     Mapping is not a value that was
> returned by Map().
> +  @retval EFI_INVALID_PARAMETER     IoMmuAccess specified an illegal
> combination of access.
> +  @retval EFI_UNSUPPORTED           The bit mask of IoMmuAccess is not
> supported by the IOMMU.
> +  @retval EFI_UNSUPPORTED           The IOMMU does not support the
> memory range specified by Mapping.
> +  @retval EFI_OUT_OF_RESOURCES      There are not enough resources
> available to modify the IOMMU access.
> +  @retval EFI_DEVICE_ERROR          The IOMMU device reported an error
> while attempting the operation.
> +  @retval EFI_NOT_AVAILABLE_YET     DMA protection has been enabled,
> but DMA buffer are
> +                                    not available to be allocated yet.
>  **/
>  EFI_STATUS
>  EFIAPI
> @@ -93,22 +93,22 @@ PeiIoMmuSetAttribute (
>    Provides the controller-specific addresses required to access system
> memory from a
>    DMA bus master.
> 
> -  @param  This                  The PPI instance pointer.
> -  @param  Operation             Indicates if the bus master is going to read or
> write to system memory.
> -  @param  HostAddress           The system memory address to map to the PCI
> controller.
> -  @param  NumberOfBytes         On input the number of bytes to map. On
> output the number of bytes
> -                                that were mapped.
> -  @param  DeviceAddress         The resulting map address for the bus master
> PCI controller to use to
> -                                access the hosts HostAddress.
> -  @param  Mapping               A resulting value to pass to Unmap().
> -
> -  @retval EFI_SUCCESS           The range was mapped for the returned
> NumberOfBytes.
> -  @retval EFI_UNSUPPORTED       The HostAddress cannot be mapped as a
> common buffer.
> -  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
> -  @retval EFI_OUT_OF_RESOURCES  The request could not be completed
> due to a lack of resources.
> -  @retval EFI_DEVICE_ERROR      The system hardware could not map the
> requested address.
> -  @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but
> DMA buffer are
> -                                not available to be allocated yet.
> +  @param [in]       This            The PPI instance pointer.
> +  @param [in]       Operation       Indicates if the bus master is going to read or
> write to system memory.
> +  @param [in]       HostAddress     The system memory address to map to the
> PCI controller.
> +  @param [in] [out] NumberOfBytes   On input the number of bytes to map.
> On output the number of bytes
> +                                    that were mapped.
> +  @param [out]      DeviceAddress   The resulting map address for the bus
> master PCI controller to use to
> +                                    access the hosts HostAddress.
> +  @param [out]      Mapping         A resulting value to pass to Unmap().
> +
> +  @retval EFI_SUCCESS               The range was mapped for the returned
> NumberOfBytes.
> +  @retval EFI_UNSUPPORTED           The HostAddress cannot be mapped as a
> common buffer.
> +  @retval EFI_INVALID_PARAMETER     One or more parameters are invalid.
> +  @retval EFI_OUT_OF_RESOURCES      The request could not be completed
> due to a lack of resources.
> +  @retval EFI_DEVICE_ERROR          The system hardware could not map the
> requested address.
> +  @retval EFI_NOT_AVAILABLE_YET     DMA protection has been enabled,
> but DMA buffer are
> +                                    not available to be allocated yet.
>  **/
>  EFI_STATUS
>  EFIAPI
> @@ -140,7 +140,7 @@ PeiIoMmuMap (
> 
>    if (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer ||
>        Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) {
> -    *DeviceAddress = (UINTN)HostAddress;
> +    *DeviceAddress = (UINTN) HostAddress;
>      *Mapping = NULL;
>      return EFI_SUCCESS;
>    }
> @@ -184,14 +184,14 @@ PeiIoMmuMap (
>  /**
>    Completes the Map() operation and releases any corresponding resources.
> 
> -  @param  This                  The PPI instance pointer.
> -  @param  Mapping               The mapping value returned from Map().
> +  @param [in] This                  The PPI instance pointer.
> +  @param [in] Mapping               The mapping value returned from Map().
> 
> -  @retval EFI_SUCCESS           The range was unmapped.
> -  @retval EFI_INVALID_PARAMETER Mapping is not a value that was
> returned by Map().
> -  @retval EFI_DEVICE_ERROR      The data was not committed to the target
> system memory.
> -  @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but
> DMA buffer are
> -                                not available to be allocated yet.
> +  @retval EFI_SUCCESS               The range was unmapped.
> +  @retval EFI_INVALID_PARAMETER     Mapping is not a value that was
> returned by Map().
> +  @retval EFI_DEVICE_ERROR          The data was not committed to the target
> system memory.
> +  @retval EFI_NOT_AVAILABLE_YET     DMA protection has been enabled,
> but DMA buffer are
> +                                    not available to be allocated yet.
>  **/
>  EFI_STATUS
>  EFIAPI
> @@ -250,21 +250,21 @@ PeiIoMmuUnmap (
>    Allocates pages that are suitable for an OperationBusMasterCommonBuffer
> or
>    OperationBusMasterCommonBuffer64 mapping.
> 
> -  @param  This                  The PPI instance pointer.
> -  @param  MemoryType            The type of memory to allocate,
> EfiBootServicesData or
> -                                EfiRuntimeServicesData.
> -  @param  Pages                 The number of pages to allocate.
> -  @param  HostAddress           A pointer to store the base system memory
> address of the
> -                                allocated range.
> -  @param  Attributes            The requested bit mask of attributes for the
> allocated range.
> -
> -  @retval EFI_SUCCESS           The requested memory pages were allocated.
> -  @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal
> attribute bits are
> -                                MEMORY_WRITE_COMBINE, MEMORY_CACHED and
> DUAL_ADDRESS_CYCLE.
> -  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
> -  @retval EFI_OUT_OF_RESOURCES  The memory pages could not be
> allocated.
> -  @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but
> DMA buffer are
> -                                not available to be allocated yet.
> +  @param [in]       This            The PPI instance pointer.
> +  @param [in]       MemoryType      The type of memory to allocate,
> EfiBootServicesData or
> +                                    EfiRuntimeServicesData.
> +  @param [in]       Pages           The number of pages to allocate.
> +  @param [in] [out] HostAddress     A pointer to store the base system
> memory address of the
> +                                    allocated range.
> +  @param [in]       Attributes      The requested bit mask of attributes for the
> allocated range.
> +
> +  @retval EFI_SUCCESS               The requested memory pages were allocated.
> +  @retval EFI_UNSUPPORTED           Attributes is unsupported. The only legal
> attribute bits are
> +                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED and
> DUAL_ADDRESS_CYCLE.
> +  @retval EFI_INVALID_PARAMETER     One or more parameters are invalid.
> +  @retval EFI_OUT_OF_RESOURCES      The memory pages could not be
> allocated.
> +  @retval EFI_NOT_AVAILABLE_YET     DMA protection has been enabled,
> but DMA buffer are
> +                                    not available to be allocated yet.
>  **/
>  EFI_STATUS
>  EFIAPI
> @@ -307,15 +307,15 @@ PeiIoMmuAllocateBuffer (
>  /**
>    Frees memory that was allocated with AllocateBuffer().
> 
> -  @param  This                  The PPI instance pointer.
> -  @param  Pages                 The number of pages to free.
> -  @param  HostAddress           The base system memory address of the
> allocated range.
> +  @param [in] This                  The PPI instance pointer.
> +  @param [in] Pages                 The number of pages to free.
> +  @param [in] HostAddress           The base system memory address of the
> allocated range.
> 
> -  @retval EFI_SUCCESS           The requested memory pages were freed.
> -  @retval EFI_INVALID_PARAMETER The memory range specified by
> HostAddress and Pages
> -                                was not allocated with AllocateBuffer().
> -  @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but
> DMA buffer are
> -                                not available to be allocated yet.
> +  @retval EFI_SUCCESS               The requested memory pages were freed.
> +  @retval EFI_INVALID_PARAMETER     The memory range specified by
> HostAddress and Pages
> +                                    was not allocated with AllocateBuffer().
> +  @retval EFI_NOT_AVAILABLE_YET     DMA protection has been enabled,
> but DMA buffer are
> +                                    not available to be allocated yet.
>  **/
>  EFI_STATUS
>  EFIAPI
> @@ -364,52 +364,114 @@ CONST EFI_PEI_PPI_DESCRIPTOR mIoMmuPpiList
> = {
>  };
> 
>  /**
> -  Release the momery in the Intel VTd Info
> +  Get ACPI DMAT Table from EdkiiVTdInfo PPI
> 
> -  @param[in]  VTdInfo           The VTd engine context information.
> +  @retval Address              ACPI DMAT Table address
> +  @retval NULL                 Failed to get ACPI DMAT Table
>  **/
> -VOID
> -ReleaseVTdInfo (
> -  IN VTD_INFO                   *VTdInfo
> +EFI_ACPI_DMAR_HEADER * GetAcpiDmarTable (
> +  VOID
>    )
>  {
> -  UINTN                         Index;
> +  EFI_STATUS                  Status;
> +  EFI_ACPI_DMAR_HEADER        *AcpiDmarTable;
> 
> -  for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
> -    DEBUG ((DEBUG_INFO, "Release momery in VTdInfo[%d]\n", Index));
> +  //
> +  // Get the DMAR table
> +  //
> +  Status = PeiServicesLocatePpi (
> +             &gEdkiiVTdInfoPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **)&AcpiDmarTable
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Fail to get ACPI DMAR Table : %r\n", Status));
> +    AcpiDmarTable = NULL;
> +  } else {
> +    DumpAcpiDMAR (AcpiDmarTable);
> +  }
> 
> -    if (VTdInfo->VtdUnitInfo[Index].FixedSecondLevelPagingEntry) {
> -      FreePages ((VOID *) (UINTN) VTdInfo-
> >VtdUnitInfo[Index].FixedSecondLevelPagingEntry, 1);
> -      VTdInfo->VtdUnitInfo[Index].FixedSecondLevelPagingEntry = 0;
> -    }
> +  return AcpiDmarTable;
> +}
> 
> -    if (VTdInfo->VtdUnitInfo[Index].RmrrSecondLevelPagingEntry) {
> -      FreePages ((VOID *) (UINTN) VTdInfo-
> >VtdUnitInfo[Index].RmrrSecondLevelPagingEntry, 1);
> -      VTdInfo->VtdUnitInfo[Index].RmrrSecondLevelPagingEntry = 0;
> -    }
> +/**
> +  Get the VTd engine context information hob.
> 
> -    if (VTdInfo->VtdUnitInfo[Index].RootEntryTable) {
> -      FreePages ((VOID *) (UINTN) VTdInfo-
> >VtdUnitInfo[Index].RootEntryTable, VTdInfo-
> >VtdUnitInfo[Index].RootEntryTablePageSize);
> -      VTdInfo->VtdUnitInfo[Index].RootEntryTable = 0;
> -    }
> +  @retval The VTd engine context information.
> 
> -    if (VTdInfo->VtdUnitInfo[Index].ExtRootEntryTable) {
> -      FreePages ((VOID *) (UINTN) VTdInfo-
> >VtdUnitInfo[Index].ExtRootEntryTable, VTdInfo-
> >VtdUnitInfo[Index].ExtRootEntryTablePageSize);
> -      VTdInfo->VtdUnitInfo[Index].RootEntryTable = 0;
> -    }
> +**/
> +VTD_INFO *
> +GetVTdInfoHob (
> +  VOID
> +  )
> +{
> +  VOID                          *Hob;
> +  VTD_INFO                      *VTdInfo;
> 
> -    if (VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceData) {
> -      FreePages ((VOID *) (UINTN) VTdInfo-
> >VtdUnitInfo[Index].PciDeviceInfo.PciDeviceData, VTdInfo-
> >VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataPageSize);
> -      VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataPageSize = 0;
> -      VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceData = 0;
> -      VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataNumber = 0;
> -      VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataMaxNumber =
> 0;
> +  Hob = GetFirstGuidHob (&mVTdInfoGuid);
> +  if (Hob == NULL) {
> +    VTdInfo = BuildGuidHob (&mVTdInfoGuid, sizeof (VTD_INFO));
> +    if (VTdInfo != NULL) {
> +      ZeroMem (VTdInfo, sizeof (VTD_INFO));
>      }
> +  } else {
> +    VTdInfo = GET_GUID_HOB_DATA(Hob);
>    }
> +  return VTdInfo;
> +}
> +
> +/**
> +  Callback function of parse DMAR DRHD table in pre-memory phase.
> +
> +  @param [in] [out] Context          Callback function context.
> +  @param [in]       VTdIndex         The VTd engine index.
> +  @param [in]       DmarDrhd         The DRHD table.
> +
> +**/
> +VOID
> +ProcessDhrdPreMemory (
> +  IN OUT VOID                       *Context,
> +  IN     UINT32                     VTdIndex,
> +  IN     EFI_ACPI_DMAR_DRHD_HEADER  *DmarDrhd
> +  )
> +{
> +  DEBUG ((DEBUG_INFO,"VTD (%d) BaseAddress -  0x%016lx\n", VTdIndex,
> DmarDrhd->RegisterBaseAddress));
> +
> +  EnableVTdTranslationProtectionBlockDma ((UINTN) DmarDrhd-
> >RegisterBaseAddress);
>  }
> 
>  /**
> -  Initializes the Intel VTd Info.
> +  Callback function of parse DMAR DRHD table in post memory phase.
> +
> +  @param [in] [out] Context          Callback function context.
> +  @param [in]       VTdIndex         The VTd engine index.
> +  @param [in]       DmarDrhd         The DRHD table.
> +
> +**/
> +VOID
> +ProcessDrhdPostMemory (
> +  IN OUT VOID                       *Context,
> +  IN     UINT32                     VTdIndex,
> +  IN     EFI_ACPI_DMAR_DRHD_HEADER  *DmarDrhd
> +  )
> +{
> +  VTD_UNIT_INFO                 *VtdUnitInfo;
> +
> +  VtdUnitInfo = (VTD_UNIT_INFO *) Context;
> +  VtdUnitInfo += VTdIndex;
> +
> +  VtdUnitInfo->Done = FALSE;
> +  VtdUnitInfo->VtdUnitBaseAddress = (UINTN) DmarDrhd-
> >RegisterBaseAddress;
> +  VtdUnitInfo->Segment = DmarDrhd->SegmentNumber;
> +  VtdUnitInfo->Flags = DmarDrhd->Flags;
> +
> +  DEBUG ((DEBUG_INFO,"VTD (%d) BaseAddress -  0x%016lx\n", VTdIndex,
> DmarDrhd->RegisterBaseAddress));
> +  DEBUG ((DEBUG_INFO,"  Segment - %d, Flags   - 0x%x\n", DmarDrhd-
> >SegmentNumber, DmarDrhd->Flags));
> +}
> +
> +/**
> +  Initializes the Intel VTd Info in post memory phase.
> 
>    @retval EFI_SUCCESS           Usb bot driver is successfully initialized.
>    @retval EFI_OUT_OF_RESOURCES  Can't initialize the driver.
> @@ -419,89 +481,103 @@ InitVTdInfo (
>    VOID
>    )
>  {
> -  EFI_STATUS                    Status;
> -  EFI_ACPI_DMAR_HEADER          *AcpiDmarTable;
> -  VOID                          *Hob;
>    VTD_INFO                      *VTdInfo;
> -  UINT64                        EngineMask;
> +  EFI_ACPI_DMAR_HEADER          *AcpiDmarTable;
> +  UINTN                         VtdUnitNumber;
> +  VTD_UNIT_INFO                 *VtdUnitInfo;
> +  EFI_STATUS                    Status;
> +  UINTN                         NewUnitIndex;
> +  UINTN                         PreviousUnitIndex;
> 
> -  Status = PeiServicesLocatePpi (
> -             &gEdkiiVTdInfoPpiGuid,
> -             0,
> -             NULL,
> -             (VOID **)&AcpiDmarTable
> -             );
> -  ASSERT_EFI_ERROR (Status);
> +  VTdInfo = GetVTdInfoHob ();
> +  ASSERT (VTdInfo != NULL);
> 
> -  DumpAcpiDMAR (AcpiDmarTable);
> +  AcpiDmarTable = GetAcpiDmarTable ();
> +  ASSERT (AcpiDmarTable != NULL);
> 
>    //
> -  // Clear old VTdInfo Hob.
> +  // Get VTd Unit Number
>    //
> -  Hob = GetFirstGuidHob (&mVTdInfoGuid);
> -  if (Hob != NULL) {
> -    DEBUG ((DEBUG_INFO, " Find Hob : mVTdInfoGuid - 0x%x\n", Hob));
> -
> -    VTdInfo = GET_GUID_HOB_DATA(Hob);
> -    EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1;
> -    EnableVTdTranslationProtectionAll (VTdInfo, EngineMask);
> -
> -    ReleaseVTdInfo (VTdInfo);
> -    VTdInfo->VTdEngineCount = 0;
> +  VtdUnitNumber = ParseDmarAcpiTableDrhd (AcpiDmarTable, NULL, NULL);
> +  if (VtdUnitNumber == 0) {
> +    return EFI_UNSUPPORTED;
> +  }
> 
> -    ZeroMem (&((EFI_HOB_GUID_TYPE *) Hob)->Name, sizeof (EFI_GUID));
> +  //
> +  // Genrate a new Vtd Unit Info Table
> +  //
> +  VtdUnitInfo = AllocateZeroPages (EFI_SIZE_TO_PAGES (sizeof
> (VTD_UNIT_INFO) * VtdUnitNumber));
> +  if (VtdUnitInfo == NULL) {
> +    DEBUG ((DEBUG_ERROR, "InitVTdInfo - OUT_OF_RESOURCE\n"));
> +    ASSERT (FALSE);
> +    return EFI_OUT_OF_RESOURCES;
>    }
> 
>    //
> -  // Get DMAR information to local VTdInfo
> +  // Parse the DMAR ACPI Table to the new Vtd Unit Info Table
>    //
> -  Status = ParseDmarAcpiTableDrhd (AcpiDmarTable);
> -  if (EFI_ERROR(Status)) {
> -    DEBUG ((DEBUG_ERROR, " ParseDmarAcpiTableDrhd : %r\n", Status));
> +  Status = ParseDmarAcpiTableDrhd (AcpiDmarTable,
> ProcessDrhdPostMemory, VtdUnitInfo);
> +  if (EFI_ERROR (Status)) {
> +    ASSERT_EFI_ERROR (Status);
>      return Status;
>    }
> 
>    //
> -  // NOTE: Do not parse RMRR here, because RMRR may cause DMAR
> programming.
> +  // Check Host Address Width
>    //
> +  if (AcpiDmarTable->HostAddressWidth == VTdInfo->HostAddressWidth) {
> +    //
> +    // New Vtd Unit Info Table Loop
> +    //
> +    for (NewUnitIndex = 0; NewUnitIndex < VtdUnitNumber;
> NewUnitIndex++) {
> +      //
> +      // Previous Vtd Unit Info Table Loop
> +      //
> +      for (PreviousUnitIndex = 0; PreviousUnitIndex < VTdInfo-
> >VTdEngineCount; PreviousUnitIndex++) {
> +        //
> +        // Compare the new Vtd Unit with the previous VTd Unit
> +        //
> +        if (VtdUnitInfo[NewUnitIndex].VtdUnitBaseAddress == VTdInfo-
> >VtdUnitInfo[PreviousUnitIndex].VtdUnitBaseAddress) {
> +          DEBUG ((DEBUG_INFO,"Find VTD [0x%08x] Exist\n",
> VtdUnitInfo[NewUnitIndex].VtdUnitBaseAddress));
> +          CopyMem (&VtdUnitInfo[NewUnitIndex], &VTdInfo-
> >VtdUnitInfo[PreviousUnitIndex], sizeof (VTD_UNIT_INFO));
> +          VtdUnitInfo[NewUnitIndex].Done = TRUE;
> +
> +          break;
> +        }
> +      }
> +    }
> +  }
> +  VTdInfo->AcpiDmarTable = AcpiDmarTable;
> +  VTdInfo->HostAddressWidth = AcpiDmarTable->HostAddressWidth;
> +  VTdInfo->VTdEngineCount = VtdUnitNumber;
> +  VTdInfo->VtdUnitInfo = VtdUnitInfo;
> 
>    return EFI_SUCCESS;
>  }
> 
>  /**
> -  Initializes the Intel VTd DMAR for all memory.
> +  Initializes the Intel VTd DMAR for block all DMA.
> 
>    @retval EFI_SUCCESS           Driver is successfully initialized.
>    @retval RETURN_NOT_READY      Fail to get VTdInfo Hob .
>  **/
>  EFI_STATUS
> -InitVTdDmarForAll (
> +InitVTdDmarBlockAll (
>    VOID
>    )
>  {
> -  VOID                          *Hob;
> -  VTD_INFO                      *VTdInfo;
> -  UINT64                        EngineMask;
> -  EFI_STATUS                    Status;
> +  EFI_ACPI_DMAR_HEADER      *AcpiDmarTable;
> 
> -  Hob = GetFirstGuidHob (&mVTdInfoGuid);
> -  if (Hob == NULL) {
> -    DEBUG ((DEBUG_ERROR, "Fail to get VTdInfo Hob.\n"));
> -    return RETURN_NOT_READY;
> -  }
> -  VTdInfo = GET_GUID_HOB_DATA (Hob);
> -  EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1;
> -
> -  DEBUG ((DEBUG_INFO, "PrepareVtdConfig\n"));
> -  Status = PrepareVtdConfig (VTdInfo);
> -  if (EFI_ERROR (Status)) {
> -    ASSERT_EFI_ERROR (Status);
> -    return Status;
> -  }
> -
> -  EnableVTdTranslationProtectionAll (VTdInfo, EngineMask);
> +  //
> +  // Get the DMAR table
> +  //
> +  AcpiDmarTable = GetAcpiDmarTable ();
> +  ASSERT (AcpiDmarTable != NULL);
> 
> -  return EFI_SUCCESS;
> +  //
> +  // Parse the DMAR table and block all DMA
> +  //
> +  return ParseDmarAcpiTableDrhd (AcpiDmarTable, ProcessDhrdPreMemory,
> NULL);
>  }
> 
>  /**
> @@ -524,8 +600,8 @@ InitDmaBuffer(
>    DEBUG ((DEBUG_INFO, "InitDmaBuffer :\n"));
> 
>    Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
> +  ASSERT(Hob != NULL);
>    DmaBufferInfo = GET_GUID_HOB_DATA (Hob);
> -  VtdPmrHobPtr = GetFirstGuidHob (&gVtdPmrInfoDataHobGuid);
> 
>    /**
>    When gVtdPmrInfoDataHobGuid exists, it means:
> @@ -535,7 +611,7 @@ InitDmaBuffer(
>      4. Protection regions will be conveyed through VTD_PMR_INFO_HOB
> 
>    When gVtdPmrInfoDataHobGuid dosen't exist, it means:
> -    1. IntelVTdDmar driver will calcuate the PMR memory alignment
> +    1. IntelVTdDmarPei driver will calcuate the protected memory alignment
>      2. Dma buffer is reserved by AllocateAlignedPages()
>    **/
> 
> @@ -545,33 +621,40 @@ InitDmaBuffer(
>      return EFI_INVALID_PARAMETER;
>    }
> 
> -  if (VtdPmrHobPtr == NULL) {
> -    //
> -    // Allocate memory for DMA buffer
> -    //
> -    DmaBufferInfo->DmaBufferBase = (UINT64) (UINTN)
> AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) DmaBufferInfo-
> >DmaBufferSize), 0);
> -    if (DmaBufferInfo->DmaBufferBase == 0) {
> -      DEBUG ((DEBUG_ERROR, " InitDmaBuffer : OutOfResource\n"));
> -      return EFI_OUT_OF_RESOURCES;
> +  if (DmaBufferInfo->DmaBufferBase == 0) {
> +    VtdPmrHobPtr = GetFirstGuidHob (&gVtdPmrInfoDataHobGuid);
> +    if (VtdPmrHobPtr != NULL) {
> +      //
> +      // Get the protected memory ranges information from the VTd PMR hob
> +      //
> +      VtdPmrHob = GET_GUID_HOB_DATA (VtdPmrHobPtr);
> +
> +      if ((VtdPmrHob->ProtectedHighBase - VtdPmrHob->ProtectedLowLimit)
> < DmaBufferInfo->DmaBufferSize) {
> +        DEBUG ((DEBUG_ERROR, " DmaBufferSize not enough\n"));
> +        return EFI_INVALID_PARAMETER;
> +      }
> +      DmaBufferInfo->DmaBufferBase = VtdPmrHob->ProtectedLowLimit;
> +    } else {
> +      //
> +      // Allocate memory for DMA buffer
> +      //
> +      DmaBufferInfo->DmaBufferBase = (UINTN) AllocateAlignedPages
> (EFI_SIZE_TO_PAGES (DmaBufferInfo->DmaBufferSize), 0);
> +      if (DmaBufferInfo->DmaBufferBase == 0) {
> +        DEBUG ((DEBUG_ERROR, " InitDmaBuffer : OutOfResource\n"));
> +        return EFI_OUT_OF_RESOURCES;
> +      }
> +      DEBUG ((DEBUG_INFO, "Alloc DMA buffer success.\n"));
>      }
> -    DmaBufferInfo->DmaBufferLimit = DmaBufferInfo->DmaBufferBase +
> DmaBufferInfo->DmaBufferSize;
> -    DEBUG ((DEBUG_INFO, "Alloc DMA buffer success.\n"));
> -  } else {
> -    //
> -    // Get the PMR ranges information for the VTd PMR hob
> -    //
> -    VtdPmrHob = GET_GUID_HOB_DATA (VtdPmrHobPtr);
> -    DmaBufferInfo->DmaBufferBase = VtdPmrHob->ProtectedLowLimit;
> -    DmaBufferInfo->DmaBufferLimit = VtdPmrHob->ProtectedHighBase;
> +
> +    DmaBufferInfo->DmaBufferCurrentTop = DmaBufferInfo-
> >DmaBufferBase + DmaBufferInfo->DmaBufferSize;
> +    DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo-
> >DmaBufferBase;
> +
> +    DEBUG ((DEBUG_INFO, " DmaBufferSize          : 0x%x\n", DmaBufferInfo-
> >DmaBufferSize));
> +    DEBUG ((DEBUG_INFO, " DmaBufferBase          : 0x%x\n", DmaBufferInfo-
> >DmaBufferBase));
>    }
> -  DmaBufferInfo->DmaBufferCurrentTop = DmaBufferInfo->DmaBufferBase
> + DmaBufferInfo->DmaBufferSize;
> -  DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo-
> >DmaBufferBase;
> 
> -  DEBUG ((DEBUG_INFO, " DmaBufferSize          : 0x%lx\n", DmaBufferInfo-
> >DmaBufferSize));
> -  DEBUG ((DEBUG_INFO, " DmaBufferBase          : 0x%lx\n", DmaBufferInfo-
> >DmaBufferBase));
> -  DEBUG ((DEBUG_INFO, " DmaBufferLimit         : 0x%lx\n", DmaBufferInfo-
> >DmaBufferLimit));
> -  DEBUG ((DEBUG_INFO, " DmaBufferCurrentTop    : 0x%lx\n",
> DmaBufferInfo->DmaBufferCurrentTop));
> -  DEBUG ((DEBUG_INFO, " DmaBufferCurrentBottom : 0x%lx\n",
> DmaBufferInfo->DmaBufferCurrentBottom));
> +  DEBUG ((DEBUG_INFO, " DmaBufferCurrentTop    : 0x%x\n",
> DmaBufferInfo->DmaBufferCurrentTop));
> +  DEBUG ((DEBUG_INFO, " DmaBufferCurrentBottom : 0x%x\n",
> DmaBufferInfo->DmaBufferCurrentBottom));
> 
>    return EFI_SUCCESS;
>  }
> @@ -588,14 +671,14 @@ InitVTdDmarForDma (
>    VOID
>    )
>  {
> -  VOID                          *Hob;
>    VTD_INFO                      *VTdInfo;
> +
>    EFI_STATUS                    Status;
>    EFI_PEI_PPI_DESCRIPTOR        *OldDescriptor;
>    EDKII_IOMMU_PPI               *OldIoMmuPpi;
> 
> -  Hob = GetFirstGuidHob (&mVTdInfoGuid);
> -  VTdInfo = GET_GUID_HOB_DATA (Hob);
> +  VTdInfo = GetVTdInfoHob ();
> +  ASSERT (VTdInfo != NULL);
> 
>    DEBUG ((DEBUG_INFO, "PrepareVtdConfig\n"));
>    Status = PrepareVtdConfig (VTdInfo);
> @@ -604,13 +687,6 @@ InitVTdDmarForDma (
>      return Status;
>    }
> 
> -  DEBUG ((DEBUG_INFO, "PrepareVtdCacheInvalidationConfig\n"));
> -  Status = PrepareVtdCacheInvalidationConfig (VTdInfo);
> -  if (EFI_ERROR (Status)) {
> -    ASSERT_EFI_ERROR (Status);
> -    return Status;
> -  }
> -
>    // create root entry table
>    DEBUG ((DEBUG_INFO, "SetupTranslationTable\n"));
>    Status = SetupTranslationTable (VTdInfo);
> @@ -619,10 +695,6 @@ InitVTdDmarForDma (
>      return Status;
>    }
> 
> -  // If there is RMRR memory, parse it here.
> -  DEBUG ((DEBUG_INFO, "PeiParseDmarAcpiTableRmrr\n"));
> -  ParseDmarAcpiTableRmrr (VTdInfo);
> -
>    DEBUG ((DEBUG_INFO, "EnableVtdDmar\n"));
>    Status = EnableVTdTranslationProtection(VTdInfo);
>    if (EFI_ERROR (Status)) {
> @@ -668,21 +740,10 @@ S3EndOfPeiNotify(
>    IN VOID                       *Ppi
>    )
>  {
> -  VOID                          *Hob;
> -  VTD_INFO                      *VTdInfo;
> -  UINT64                        EngineMask;
> -
>    DEBUG((DEBUG_INFO, "VTd DMAR PEI S3EndOfPeiNotify\n"));
> 
>    if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT1) == 0) {
> -    Hob = GetFirstGuidHob (&mVTdInfoGuid);
> -    if (Hob == NULL) {
> -      return EFI_SUCCESS;
> -    }
> -    VTdInfo = GET_GUID_HOB_DATA(Hob);
> -
> -    EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1;
> -    DisableVTdTranslationProtection (VTdInfo, EngineMask);
> +    DisableVTdTranslationProtection (GetVTdInfoHob ());
>    }
>    return EFI_SUCCESS;
>  }
> @@ -733,18 +794,13 @@ VTdInfoNotify (
> 
>    DEBUG ((DEBUG_INFO, "MemoryInitialized - %x\n", MemoryInitialized));
> 
> -  //
> -  // NOTE: We need reinit VTdInfo because previous information might be
> overriden.
> -  //
> -  InitVTdInfo ();
> -
>    if (!MemoryInitialized) {
>      //
>      // If the memory is not initialized,
>      // Protect all system memory
>      //
> 
> -    InitVTdDmarForAll ();
> +    InitVTdDmarBlockAll ();
> 
>      //
>      // Install PPI.
> @@ -758,9 +814,16 @@ VTdInfoNotify (
>      //
> 
>      Status = InitDmaBuffer ();
> -    ASSERT_EFI_ERROR(Status);
> +    ASSERT_EFI_ERROR (Status);
> +
> +    //
> +    // NOTE: We need reinit VTdInfo because previous information might be
> overriden.
> +    //
> +    Status = InitVTdInfo ();
> +    ASSERT_EFI_ERROR (Status);
> 
> -    InitVTdDmarForDma ();
> +    Status = InitVTdDmarForDma ();
> +    ASSERT_EFI_ERROR (Status);
>    }
> 
>    return EFI_SUCCESS;
> @@ -826,4 +889,3 @@ IntelVTdDmarInitialize (
> 
>    return EFI_SUCCESS;
>  }
> -
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.h
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.h
> index e23a6c8e..351a7810 100644
> ---
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.h
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.h
> @@ -9,68 +9,61 @@
>  #ifndef __DMA_ACCESS_LIB_H__
>  #define __DMA_ACCESS_LIB_H__
> 
> -#define MAX_VTD_PCI_DATA_NUMBER             0x100
> -
>  #define VTD_64BITS_ADDRESS(Lo, Hi) (LShiftU64 (Lo, 12) | LShiftU64 (Hi, 32))
> 
>  typedef struct {
> -  UINT8                            DeviceType;
> -  VTD_SOURCE_ID                    PciSourceId;
> -} PEI_PCI_DEVICE_DATA;
> -
> -typedef struct {
> -  BOOLEAN                          IncludeAllFlag;
> -  UINT32                           PciDeviceDataNumber;
> -  UINT32                           PciDeviceDataMaxNumber;
> -  UINT32                           PciDeviceDataPageSize;
> -  UINT32                           PciDeviceData;
> -} PEI_PCI_DEVICE_INFORMATION;
> -
> -typedef struct {
> -  UINT32                           VtdUnitBaseAddress;
> +  BOOLEAN                          Done;
> +  UINTN                            VtdUnitBaseAddress;
>    UINT16                           Segment;
> +  UINT8                            Flags;
>    VTD_VER_REG                      VerReg;
>    VTD_CAP_REG                      CapReg;
>    VTD_ECAP_REG                     ECapReg;
>    BOOLEAN                          Is5LevelPaging;
> -  UINT32                           FixedSecondLevelPagingEntry;
> -  UINT32                           RmrrSecondLevelPagingEntry;
> -  UINT32                           RootEntryTable;
> -  UINT32                           ExtRootEntryTable;
> -  UINT16                           RootEntryTablePageSize;
> -  UINT16                           ExtRootEntryTablePageSize;
> -  PEI_PCI_DEVICE_INFORMATION       PciDeviceInfo;
>    UINT8                            EnableQueuedInvalidation;
> -  UINT16                           QiDescLength;
> +  UINT16                           QueueSize;
>    QI_DESC                          *QiDesc;
>    UINT16                           QiFreeHead;
> +  UINTN                            FixedSecondLevelPagingEntry;
> +  UINTN                            RootEntryTable;
> +  UINTN                            ExtRootEntryTable;
> +  UINTN                            RootEntryTablePageSize;
> +  UINTN                            ExtRootEntryTablePageSize;
>  } VTD_UNIT_INFO;
> 
>  typedef struct {
> -  UINT32                           AcpiDmarTable;
> +  EFI_ACPI_DMAR_HEADER             *AcpiDmarTable;
>    UINT8                            HostAddressWidth;
> -  UINT32                           VTdEngineCount;
> -  VTD_UNIT_INFO                    VtdUnitInfo[1];
> +  UINTN                            VTdEngineCount;
> +  VTD_UNIT_INFO                    *VtdUnitInfo;
>  } VTD_INFO;
> 
>  typedef struct {
> -  UINT64                            DmaBufferBase;
> -  UINT64                            DmaBufferSize;
> -  UINT64                            DmaBufferLimit;
> -  UINT64                            DmaBufferCurrentTop;
> -  UINT64                            DmaBufferCurrentBottom;
> +  UINTN                            DmaBufferBase;
> +  UINTN                            DmaBufferSize;
> +  UINTN                            DmaBufferCurrentTop;
> +  UINTN                            DmaBufferCurrentBottom;
>  } DMA_BUFFER_INFO;
> 
> +typedef
> +VOID
> +(*PROCESS_DRHD_CALLBACK_FUNC) (
> +  IN OUT VOID                       *Context,
> +  IN     UINT32                     VTdIndex,
> +  IN     EFI_ACPI_DMAR_DRHD_HEADER  *DmarDrhd
> +  );
> +
>  /**
> -  Enable VTd translation table protection.
> +  Enable VTd translation table protection for block DMA
> 
> -  @param[in]  VTdInfo           The VTd engine context information.
> -  @param[in]  EngineMask        The mask of the VTd engine to be accessed.
> +  @param[in] VtdUnitBaseAddress The base address of the VTd engine.
> +
> +  @retval EFI_SUCCESS           DMAR translation is enabled.
> +  @retval EFI_DEVICE_ERROR      DMAR translation is not enabled.
>  **/
> -VOID
> -EnableVTdTranslationProtectionAll (
> -  IN VTD_INFO                   *VTdInfo,
> -  IN UINT64                     EngineMask
> +EFI_STATUS
> +EnableVTdTranslationProtectionBlockDma (
> +  IN UINTN                      VtdUnitBaseAddress
>    );
> 
>  /**
> @@ -90,34 +83,27 @@ EnableVTdTranslationProtection (
>    Disable VTd translation table protection.
> 
>    @param[in]  VTdInfo           The VTd engine context information.
> -  @param[in]  EngineMask        The mask of the VTd engine to be accessed.
>  **/
>  VOID
>  DisableVTdTranslationProtection (
> -  IN VTD_INFO                   *VTdInfo,
> -  IN UINT64                     EngineMask
> +  IN VTD_INFO                   *VTdInfo
>    );
> 
>  /**
>    Parse DMAR DRHD table.
> 
>    @param[in]  AcpiDmarTable     DMAR ACPI table
> +  @param[in]  Callback          Callback function for handle DRHD
> +  @param[in]  Context           Callback function Context
> 
> -  @return EFI_SUCCESS           The DMAR DRHD table is parsed.
> -**/
> -EFI_STATUS
> -ParseDmarAcpiTableDrhd (
> -  IN EFI_ACPI_DMAR_HEADER       *AcpiDmarTable
> -  );
> -
> -/**
> -  Parse DMAR DRHD table.
> +  @return the VTd engine number.
> 
> -  @param[in]  VTdInfo           The VTd engine context information.
>  **/
> -VOID
> -ParseDmarAcpiTableRmrr (
> -  IN VTD_INFO                   *VTdInfo
> +UINTN
> +ParseDmarAcpiTableDrhd (
> +  IN EFI_ACPI_DMAR_HEADER               *AcpiDmarTable,
> +  IN PROCESS_DRHD_CALLBACK_FUNC         Callback,
> +  IN VOID                               *Context
>    );
> 
>  /**
> @@ -214,30 +200,7 @@ GetPciDataIndex (
>    IN VTD_SOURCE_ID              SourceId
>    );
> 
> -/**
> -  Always enable the VTd page attribute for the device.
> -
> -  @param[in]  VTdInfo           The VTd engine context information.
> -  @param[in]  Segment           The Segment used to identify a VTd engine.
> -  @param[in]  SourceId          The SourceId used to identify a VTd engine and
> table entry.
> -  @param[in]  MemoryBase        The base of the memory.
> -  @param[in]  MemoryLimit       The limit of the memory.
> -  @param[in]  IoMmuAccess       The IOMMU access.
> -
> -  @retval EFI_SUCCESS           The VTd entry is updated to always enable all
> DMA access for the specific device.
> -**/
> -EFI_STATUS
> -EnableRmrrPageAttribute (
> -  IN VTD_INFO                   *VTdInfo,
> -  IN UINT16                     Segment,
> -  IN VTD_SOURCE_ID              SourceId,
> -  IN UINT64                     MemoryBase,
> -  IN UINT64                     MemoryLimit,
> -  IN UINT64                     IoMmuAccess
> -  );
> -
>  extern EFI_GUID mVTdInfoGuid;
>  extern EFI_GUID mDmaBufferInfoGuid;
> 
>  #endif
> -
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTab
> le.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTab
> le.c
> index a309d566..c94f4a85 100644
> ---
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTab
> le.c
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTab
> le.c
> @@ -1,6 +1,7 @@
>  /** @file
> 
>    Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
> +
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
>  **/
> @@ -129,12 +130,12 @@ CreateSecondLevelPagingEntryTable (
>      FlushPageTableMemory (VTdUnitInfo, (UINTN) SecondLevelPagingEntry,
> EFI_PAGES_TO_SIZE (1));
>    }
> 
> -  DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n",
> SecondLevelPagingEntry));
> +  DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", (UINT64)
> (UINTN) SecondLevelPagingEntry));
>    //
>    // If no access is needed, just create not present entry.
>    //
>    if (IoMmuAccess == 0) {
> -    DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", (UINTN)
> SecondLevelPagingEntry));
> +    DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx Access 0\n",
> (UINT64) (UINTN) SecondLevelPagingEntry));
>      return SecondLevelPagingEntry;
>    }
> 
> @@ -244,7 +245,7 @@ CreateSecondLevelPagingEntryTable (
>    }
>    FlushPageTableMemory (VTdUnitInfo, (UINTN) &Lvl5PtEntry[Lvl5Start],
> (UINTN) &Lvl5PtEntry[Lvl5End + 1] - (UINTN) &Lvl5PtEntry[Lvl5Start]);
> 
> -  DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n",
> (UINTN)SecondLevelPagingEntry));
> +  DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", (UINT64)
> (UINTN) SecondLevelPagingEntry));
>    return SecondLevelPagingEntry;
>  }
> 
> @@ -276,6 +277,10 @@ CreateContextEntry (
>    VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry;
>    UINT64                        Pt;
> 
> +  if (VTdUnitInfo->RootEntryTable != 0) {
> +    return EFI_SUCCESS;
> +  }
> +
>    RootPages = EFI_SIZE_TO_PAGES (sizeof (VTD_ROOT_ENTRY) *
> VTD_ROOT_ENTRY_NUMBER);
>    ContextPages = EFI_SIZE_TO_PAGES (sizeof (VTD_CONTEXT_ENTRY) *
> VTD_CONTEXT_ENTRY_NUMBER);
>    EntryTablePages = RootPages + ContextPages *
> (VTD_ROOT_ENTRY_NUMBER);
> @@ -286,8 +291,8 @@ CreateContextEntry (
>    }
> 
>    DEBUG ((DEBUG_ERROR, "RootEntryTable address - 0x%x\n", Buffer));
> -  VTdUnitInfo->RootEntryTable = (UINT32) (UINTN) Buffer;
> -  VTdUnitInfo->RootEntryTablePageSize = (UINT16) EntryTablePages;
> +  VTdUnitInfo->RootEntryTable = (UINTN) Buffer;
> +  VTdUnitInfo->RootEntryTablePageSize = EntryTablePages;
>    RootEntryBase = (VTD_ROOT_ENTRY *) Buffer;
>    Buffer = (UINT8 *) Buffer + EFI_PAGES_TO_SIZE (RootPages);
> 
> @@ -304,7 +309,7 @@ CreateContextEntry (
>      RootEntry->Bits.ContextTablePointerHi  = (UINT32) RShiftU64 ((UINT64)
> (UINTN) Buffer, 32);
>      RootEntry->Bits.Present = 1;
>      Buffer = (UINT8 *)Buffer + EFI_PAGES_TO_SIZE (ContextPages);
> -    ContextEntryTable = (VTD_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, RootEntry-
> >Bits.ContextTablePointerHi) ;
> +    ContextEntryTable = (VTD_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, RootEntry-
> >Bits.ContextTablePointerHi);
> 
>      for (ContextIndex = 0; ContextIndex < VTD_CONTEXT_ENTRY_NUMBER;
> ContextIndex++) {
>        SourceId.Index.ContextIndex = (UINT8) ContextIndex;
> @@ -317,7 +322,7 @@ CreateContextEntry (
>        ContextEntry->Bits.AddressWidth = VTdUnitInfo->Is5LevelPaging ? 0x3 :
> 0x2;
> 
>        if (VTdUnitInfo->FixedSecondLevelPagingEntry != 0) {
> -        SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)
> (UINTN) VTdUnitInfo->FixedSecondLevelPagingEntry;
> +        SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)
> VTdUnitInfo->FixedSecondLevelPagingEntry;
>          Pt = (UINT64)RShiftU64 ((UINT64) (UINTN) SecondLevelPagingEntry, 12);
>          ContextEntry->Bits.SecondLevelPageTranslationPointerLo = (UINT32) Pt;
>          ContextEntry->Bits.SecondLevelPageTranslationPointerHi = (UINT32)
> RShiftU64(Pt, 20);
> @@ -359,6 +364,10 @@ CreateExtContextEntry (
>    VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry;
>    UINT64                        Pt;
> 
> +  if (VTdUnitInfo->ExtRootEntryTable != 0) {
> +    return EFI_SUCCESS;
> +  }
> +
>    RootPages = EFI_SIZE_TO_PAGES (sizeof (VTD_EXT_ROOT_ENTRY) *
> VTD_ROOT_ENTRY_NUMBER);
>    ContextPages = EFI_SIZE_TO_PAGES (sizeof (VTD_EXT_CONTEXT_ENTRY) *
> VTD_CONTEXT_ENTRY_NUMBER);
>    EntryTablePages = RootPages + ContextPages *
> (VTD_ROOT_ENTRY_NUMBER);
> @@ -369,8 +378,8 @@ CreateExtContextEntry (
>    }
> 
>    DEBUG ((DEBUG_ERROR, "ExtRootEntryTable address - 0x%x\n", Buffer));
> -  VTdUnitInfo->ExtRootEntryTable = (UINT32) (UINTN) Buffer;
> -  VTdUnitInfo->ExtRootEntryTablePageSize = (UINT16) EntryTablePages;
> +  VTdUnitInfo->ExtRootEntryTable = (UINTN) Buffer;
> +  VTdUnitInfo->ExtRootEntryTablePageSize = EntryTablePages;
>    ExtRootEntryBase = (VTD_EXT_ROOT_ENTRY *) Buffer;
>    Buffer = (UINT8 *) Buffer + EFI_PAGES_TO_SIZE (RootPages);
> 
> @@ -390,7 +399,7 @@ CreateExtContextEntry (
>      ExtRootEntry->Bits.UpperContextTablePointerHi  = (UINT32) RShiftU64
> (RShiftU64 ((UINT64) (UINTN) Buffer, 12) + 1, 20);
>      ExtRootEntry->Bits.UpperPresent = 1;
>      Buffer = (UINT8 *) Buffer + EFI_PAGES_TO_SIZE (ContextPages);
> -    ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS (ExtRootEntry->Bits.LowerContextTablePointerLo,
> ExtRootEntry->Bits.LowerContextTablePointerHi) ;
> +    ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS (ExtRootEntry->Bits.LowerContextTablePointerLo,
> ExtRootEntry->Bits.LowerContextTablePointerHi);
> 
>      for (ContextIndex = 0; ContextIndex < VTD_CONTEXT_ENTRY_NUMBER;
> ContextIndex++) {
>        SourceId.Index.ContextIndex = (UINT8) ContextIndex;
> @@ -403,7 +412,7 @@ CreateExtContextEntry (
>        ExtContextEntry->Bits.AddressWidth = VTdUnitInfo->Is5LevelPaging ?
> 0x3 : 0x2;
> 
>        if (VTdUnitInfo->FixedSecondLevelPagingEntry != 0) {
> -        SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)
> (UINTN) VTdUnitInfo->FixedSecondLevelPagingEntry;
> +        SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)
> VTdUnitInfo->FixedSecondLevelPagingEntry;
>          Pt = (UINT64)RShiftU64 ((UINT64) (UINTN) SecondLevelPagingEntry, 12);
> 
>          ExtContextEntry->Bits.SecondLevelPageTranslationPointerLo = (UINT32)
> Pt;
> @@ -791,9 +800,6 @@ SetSecondLevelPagingAttribute (
>      SplitAttribute = NeedSplitPage (BaseAddress, Length, PageAttribute);
>      if (SplitAttribute == PageNone) {
>        ConvertSecondLevelPageEntryAttribute (VTdUnitInfo, PageEntry,
> IoMmuAccess, &IsEntryModified);
> -      if (IsEntryModified) {
> -        //mVtdUnitInformation[VtdIndex].HasDirtyPages = TRUE;
> -      }
>        //
>        // Convert success, move to next
>        //
> @@ -805,7 +811,6 @@ SetSecondLevelPagingAttribute (
>          DEBUG ((DEBUG_ERROR, "SplitSecondLevelPage - %r\n", Status));
>          return RETURN_UNSUPPORTED;
>        }
> -      //mVtdUnitInformation[VtdIndex].HasDirtyPages = TRUE;
>        //
>        // Just split current page
>        // Convert success in next around
> @@ -837,7 +842,11 @@ CreateFixedSecondLevelPagingEntry (
>    VOID                          *Hob;
>    DMA_BUFFER_INFO               *DmaBufferInfo;
> 
> -  VTdUnitInfo->FixedSecondLevelPagingEntry = (UINT32) (UINTN)
> CreateSecondLevelPagingEntryTable (VTdUnitInfo, NULL, 0, SIZE_4GB, 0);
> +  if (VTdUnitInfo->FixedSecondLevelPagingEntry != 0) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  VTdUnitInfo->FixedSecondLevelPagingEntry = (UINTN)
> CreateSecondLevelPagingEntryTable (VTdUnitInfo, NULL, 0, SIZE_4GB, 0);
>    if (VTdUnitInfo->FixedSecondLevelPagingEntry == 0) {
>      DEBUG ((DEBUG_ERROR, "FixedSecondLevelPagingEntry is empty\n"));
>      return EFI_OUT_OF_RESOURCES;
> @@ -846,14 +855,14 @@ CreateFixedSecondLevelPagingEntry (
>    Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
>    DmaBufferInfo = GET_GUID_HOB_DATA (Hob);
>    BaseAddress = DmaBufferInfo->DmaBufferBase;
> -  Length = DmaBufferInfo->DmaBufferLimit - DmaBufferInfo-
> >DmaBufferBase;
> +  Length = DmaBufferInfo->DmaBufferSize;
>    IoMmuAccess = EDKII_IOMMU_ACCESS_READ |
> EDKII_IOMMU_ACCESS_WRITE;
> 
>    DEBUG ((DEBUG_INFO, "  BaseAddress = 0x%lx\n", BaseAddress));
>    DEBUG ((DEBUG_INFO, "  Length = 0x%lx\n", Length));
>    DEBUG ((DEBUG_INFO, "  IoMmuAccess = 0x%lx\n", IoMmuAccess));
> 
> -  Status = SetSecondLevelPagingAttribute (VTdUnitInfo,
> (VTD_SECOND_LEVEL_PAGING_ENTRY*) (UINTN) VTdUnitInfo-
> >FixedSecondLevelPagingEntry, BaseAddress, Length, IoMmuAccess);
> +  Status = SetSecondLevelPagingAttribute (VTdUnitInfo,
> (VTD_SECOND_LEVEL_PAGING_ENTRY*) VTdUnitInfo-
> >FixedSecondLevelPagingEntry, BaseAddress, Length, IoMmuAccess);
> 
>    return Status;
>  }
> @@ -877,6 +886,9 @@ SetupTranslationTable (
> 
>    for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
>      VtdUnitInfo = &VTdInfo->VtdUnitInfo[Index];
> +    if (VtdUnitInfo->Done) {
> +      continue;
> +    }
> 
>      Status = CreateFixedSecondLevelPagingEntry (VtdUnitInfo);
>      if (EFI_ERROR (Status)) {
> @@ -911,151 +923,3 @@ SetupTranslationTable (
>    return EFI_SUCCESS;
>  }
> 
> -/**
> -  Find the VTd index by the Segment and SourceId.
> -
> -  @param[in]  VTdInfo           The VTd engine context information.
> -  @param[in]  Segment           The segment of the source.
> -  @param[in]  SourceId          The SourceId of the source.
> -  @param[out] ExtContextEntry   The ExtContextEntry of the source.
> -  @param[out] ContextEntry      The ContextEntry of the source.
> -
> -  @return The index of the VTd engine.
> -  @retval (UINTN)-1  The VTd engine is not found.
> -**/
> -UINTN
> -FindVtdIndexBySegmentSourceId (
> -  IN  VTD_INFO                  *VTdInfo,
> -  IN  UINT16                    Segment,
> -  IN  VTD_SOURCE_ID             SourceId,
> -  OUT VTD_EXT_CONTEXT_ENTRY     **ExtContextEntry,
> -  OUT VTD_CONTEXT_ENTRY         **ContextEntry
> -  )
> -{
> -  UINTN                         VtdIndex;
> -  VTD_ROOT_ENTRY                *RootEntryBase;
> -  VTD_ROOT_ENTRY                *RootEntry;
> -  VTD_CONTEXT_ENTRY             *ContextEntryTable;
> -  VTD_CONTEXT_ENTRY             *ThisContextEntry;
> -  VTD_EXT_ROOT_ENTRY            *ExtRootEntryBase;
> -  VTD_EXT_ROOT_ENTRY            *ExtRootEntry;
> -  VTD_EXT_CONTEXT_ENTRY         *ExtContextEntryTable;
> -  VTD_EXT_CONTEXT_ENTRY         *ThisExtContextEntry;
> -
> -  for (VtdIndex = 0; VtdIndex < VTdInfo->VTdEngineCount; VtdIndex++) {
> -    if (GetPciDataIndex (&VTdInfo->VtdUnitInfo[VtdIndex], Segment,
> SourceId) != (UINTN)-1) {
> -      DEBUG ((DEBUG_INFO, "Find VtdIndex(0x%x) for S%04x B%02x D%02x
> F%02x\n", VtdIndex, Segment, SourceId.Bits.Bus, SourceId.Bits.Device,
> SourceId.Bits.Function));
> -      break;
> -    }
> -  }
> -  if (VtdIndex >= VTdInfo->VTdEngineCount) {
> -    for (VtdIndex = 0; VtdIndex < VTdInfo->VTdEngineCount; VtdIndex++) {
> -      if (Segment != VTdInfo->VtdUnitInfo[VtdIndex].Segment) {
> -        continue;
> -      }
> -      if (VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.IncludeAllFlag) {
> -        DEBUG ((DEBUG_INFO, "Find IncludeAllFlag VtdIndex(0x%x) for S%04x
> B%02x D%02x F%02x\n", VtdIndex, Segment, SourceId.Bits.Bus,
> SourceId.Bits.Device, SourceId.Bits.Function));
> -        break;
> -      }
> -    }
> -  }
> -
> -  if (VtdIndex < VTdInfo->VTdEngineCount) {
> -    ExtRootEntryBase = (VTD_EXT_ROOT_ENTRY *) (UINTN) VTdInfo-
> >VtdUnitInfo[VtdIndex].ExtRootEntryTable;
> -    if (ExtRootEntryBase != 0) {
> -      ExtRootEntry = &ExtRootEntryBase[SourceId.Index.RootIndex];
> -      ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS(ExtRootEntry->Bits.LowerContextTablePointerLo,
> ExtRootEntry->Bits.LowerContextTablePointerHi) ;
> -      ThisExtContextEntry  =
> &ExtContextEntryTable[SourceId.Index.ContextIndex];
> -      if (ThisExtContextEntry->Bits.AddressWidth == 0) {
> -        DEBUG ((DEBUG_INFO, "ExtContextEntry AddressWidth : 0x%x\n",
> ThisExtContextEntry->Bits.AddressWidth));
> -        return (UINTN)-1;
> -      }
> -      *ExtContextEntry = ThisExtContextEntry;
> -      *ContextEntry    = NULL;
> -    } else {
> -      RootEntryBase = (VTD_ROOT_ENTRY*) (UINTN) VTdInfo-
> >VtdUnitInfo[VtdIndex].RootEntryTable;
> -      RootEntry = &RootEntryBase[SourceId.Index.RootIndex];
> -      ContextEntryTable = (VTD_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, RootEntry-
> >Bits.ContextTablePointerHi) ;
> -      ThisContextEntry  = &ContextEntryTable[SourceId.Index.ContextIndex];
> -      if (ThisContextEntry->Bits.AddressWidth == 0) {
> -        DEBUG ((DEBUG_INFO, "ContextEntry AddressWidth : 0x%x\n",
> ThisContextEntry->Bits.AddressWidth));
> -        return (UINTN)-1;
> -      }
> -      *ExtContextEntry = NULL;
> -      *ContextEntry    = ThisContextEntry;
> -    }
> -
> -    return VtdIndex;
> -  }
> -
> -  return (UINTN)-1;
> -}
> -
> -/**
> -  Always enable the VTd page attribute for the device.
> -
> -  @param[in]  VTdInfo           The VTd engine context information.
> -  @param[in]  Segment           The Segment used to identify a VTd engine.
> -  @param[in]  SourceId          The SourceId used to identify a VTd engine and
> table entry.
> -  @param[in]  MemoryBase        The base of the memory.
> -  @param[in]  MemoryLimit       The limit of the memory.
> -  @param[in]  IoMmuAccess       The IOMMU access.
> -
> -  @retval EFI_SUCCESS           The VTd entry is updated to always enable all
> DMA access for the specific device.
> -**/
> -EFI_STATUS
> -EnableRmrrPageAttribute (
> -  IN VTD_INFO                   *VTdInfo,
> -  IN UINT16                     Segment,
> -  IN VTD_SOURCE_ID              SourceId,
> -  IN UINT64                     MemoryBase,
> -  IN UINT64                     MemoryLimit,
> -  IN UINT64                     IoMmuAccess
> -  )
> -{
> -  EFI_STATUS Status;
> -  UINTN                         VtdIndex;
> -  VTD_EXT_CONTEXT_ENTRY         *ExtContextEntry;
> -  VTD_CONTEXT_ENTRY             *ContextEntry;
> -  VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry;
> -  UINT64                        Pt;
> -
> -  DEBUG ((DEBUG_INFO, "EnableRmrrPageAttribute (S%04x B%02x D%02x
> F%02x)\n", Segment, SourceId.Bits.Bus, SourceId.Bits.Device,
> SourceId.Bits.Function));
> -
> -  VtdIndex = FindVtdIndexBySegmentSourceId (VTdInfo, Segment, SourceId,
> &ExtContextEntry, &ContextEntry);
> -  if (VtdIndex == (UINTN)-1) {
> -    DEBUG ((DEBUG_ERROR, "EnableRmrrPageAttribute - Can not locate Pci
> device (S%04x B%02x D%02x F%02x) !\n", Segment, SourceId.Bits.Bus,
> SourceId.Bits.Device, SourceId.Bits.Function));
> -    return EFI_DEVICE_ERROR;
> -  }
> -
> -  if (VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry == 0) {
> -    DEBUG ((DEBUG_INFO, "CreateSecondLevelPagingEntry - %d\n",
> VtdIndex));
> -    VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry =
> (UINT32)(UINTN)CreateSecondLevelPagingEntryTable (&VTdInfo-
> >VtdUnitInfo[VtdIndex], NULL, 0, SIZE_4GB, 0);
> -    if (VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry == 0) {
> -      return EFI_OUT_OF_RESOURCES;
> -    }
> -
> -    Status =SetSecondLevelPagingAttribute (&VTdInfo-
> >VtdUnitInfo[VtdIndex],
> (VTD_SECOND_LEVEL_PAGING_ENTRY*)(UINTN)VTdInfo-
> >VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry, MemoryBase,
> MemoryLimit + 1 - MemoryBase, IoMmuAccess);
> -    if (EFI_ERROR (Status)) {
> -      return Status;
> -    }
> -  }
> -
> -  SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)
> (UINTN) VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry;
> -  Pt = (UINT64) RShiftU64 ((UINT64) (UINTN) SecondLevelPagingEntry, 12);
> -  if (ExtContextEntry != NULL) {
> -    ExtContextEntry->Bits.SecondLevelPageTranslationPointerLo = (UINT32)
> Pt;
> -    ExtContextEntry->Bits.SecondLevelPageTranslationPointerHi = (UINT32)
> RShiftU64(Pt, 20);
> -    ExtContextEntry->Bits.DomainIdentifier = ((1 << (UINT8) ((UINTN)
> VTdInfo->VtdUnitInfo[VtdIndex].CapReg.Bits.ND * 2 + 4)) - 1);
> -    ExtContextEntry->Bits.Present = 1;
> -    FlushPageTableMemory (&VTdInfo->VtdUnitInfo[VtdIndex], (UINTN)
> ExtContextEntry, sizeof(*ExtContextEntry));
> -  } else if (ContextEntry != NULL) {
> -    ContextEntry->Bits.SecondLevelPageTranslationPointerLo = (UINT32) Pt;
> -    ContextEntry->Bits.SecondLevelPageTranslationPointerHi = (UINT32)
> RShiftU64 (Pt, 20);
> -    ContextEntry->Bits.DomainIdentifier = ((1 << (UINT8) ((UINTN) VTdInfo-
> >VtdUnitInfo[VtdIndex].CapReg.Bits.ND * 2 + 4)) - 1);
> -    ContextEntry->Bits.Present = 1;
> -    FlushPageTableMemory (&VTdInfo->VtdUnitInfo[VtdIndex], (UINTN)
> ContextEntry, sizeof (*ContextEntry));
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> --
> 2.16.2.windows.1


  reply	other threads:[~2022-01-24  2:44 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-18  8:14 [PATCH v5 0/4] There are 4 patches for VTd drivers Sheng Wei
2022-01-18  8:14 ` [PATCH v5 1/4] IntelSiliconPkg/VTd: Fix typos Sheng Wei
2022-01-18  8:31   ` Huang, Jenny
2022-01-19  8:26   ` Kowalewski, Robert
2022-01-18  8:14 ` [PATCH v5 2/4] IntelSiliconPkg/VTd: Update VTd register structs Sheng Wei
2022-01-21  8:24   ` Huang, Jenny
2022-01-18  8:14 ` [PATCH v5 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode Sheng Wei
2022-01-21  8:51   ` Huang, Jenny
2022-01-18  8:14 ` [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once Sheng Wei
2022-01-21  8:35   ` Huang, Jenny
2022-01-24  2:44     ` Sheng Wei [this message]
2022-01-18  8:30 ` [PATCH v5 0/4] There are 4 patches for VTd drivers Huang, Jenny

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=PH0PR11MB4870E878BB06BAAC0CFE7621E15E9@PH0PR11MB4870.namprd11.prod.outlook.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