[edk2] [PATCH 2/3] IntelSiliconPkg/IntelVTd: update PlatformVtdPolicy

Jiewen Yao posted 3 patches 7 years, 4 months ago
[edk2] [PATCH 2/3] IntelSiliconPkg/IntelVTd: update PlatformVtdPolicy
Posted by Jiewen Yao 7 years, 4 months ago
1. Handle flexible exception list format.
1.1 Handle DeviceScope based device info.
1.2 Handle PciDeviceId based device info.
2. Reorg the PCI_DEVICE_INFORMATION
2.1 Merge data pointer reduce allocation times
2.2 Add PCI device id to PCI_DEVICE_INFORMATION
2.3 Rename PciDescriptor to avoid confusing.
3. Fix the debug message too long issue.

Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
 IntelSiliconPkg/IntelVTdDxe/DmaProtection.c      | 143 ++++++++++++-
 IntelSiliconPkg/IntelVTdDxe/DmaProtection.h      | 119 ++++++++---
 IntelSiliconPkg/IntelVTdDxe/DmarAcpiTable.c      |  48 +++--
 IntelSiliconPkg/IntelVTdDxe/PciInfo.c            | 212 ++++++++++++--------
 IntelSiliconPkg/IntelVTdDxe/TranslationTable.c   |  28 +--
 IntelSiliconPkg/IntelVTdDxe/TranslationTableEx.c |  20 +-
 IntelSiliconPkg/IntelVTdDxe/VtdReg.c             |  14 +-
 7 files changed, 423 insertions(+), 161 deletions(-)

diff --git a/IntelSiliconPkg/IntelVTdDxe/DmaProtection.c b/IntelSiliconPkg/IntelVTdDxe/DmaProtection.c
index f0628b5..82ed4d2 100644
--- a/IntelSiliconPkg/IntelVTdDxe/DmaProtection.c
+++ b/IntelSiliconPkg/IntelVTdDxe/DmaProtection.c
@@ -152,6 +152,132 @@ ReturnUefiMemoryMap (
 }
 
 /**
+  The scan bus callback function to always enable page attribute.
+
+  @param[in]  Context               The context of the callback.
+  @param[in]  Segment               The segment of the source.
+  @param[in]  Bus                   The bus of the source.
+  @param[in]  Device                The device of the source.
+  @param[in]  Function              The function of the source.
+
+  @retval EFI_SUCCESS           The VTd entry is updated to always enable all DMA access for the specific device.
+**/
+EFI_STATUS
+EFIAPI
+ScanBusCallbackAlwaysEnablePageAttribute (
+  IN VOID           *Context,
+  IN UINT16         Segment,
+  IN UINT8          Bus,
+  IN UINT8          Device,
+  IN UINT8          Function
+  )
+{
+  VTD_SOURCE_ID           SourceId;
+  EFI_STATUS              Status;
+
+  SourceId.Bits.Bus = Bus;
+  SourceId.Bits.Device = Device;
+  SourceId.Bits.Function = Function;
+  Status = AlwaysEnablePageAttribute (Segment, SourceId);
+  return Status;
+}
+
+/**
+  Always enable the VTd page attribute for the device in the DeviceScope.
+
+  @param[in]  DeviceScope  the input device scope data structure
+
+  @retval EFI_SUCCESS           The VTd entry is updated to always enable all DMA access for the specific device in the device scope.
+**/
+EFI_STATUS
+AlwaysEnablePageAttributeDeviceScope (
+  IN  EDKII_PLATFORM_VTD_DEVICE_SCOPE   *DeviceScope
+  )
+{
+  UINT8                             Bus;
+  UINT8                             Device;
+  UINT8                             Function;
+  VTD_SOURCE_ID                     SourceId;
+  UINT8                             SecondaryBusNumber;
+  EFI_STATUS                        Status;
+
+  Status = GetPciBusDeviceFunction (DeviceScope->SegmentNumber, &DeviceScope->DeviceScope, &Bus, &Device, &Function);
+
+  if (DeviceScope->DeviceScope.Type == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE) {
+    //
+    // Need scan the bridge and add all devices.
+    //
+    SecondaryBusNumber = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(DeviceScope->SegmentNumber, Bus, Device, Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+    Status = ScanPciBus (NULL, DeviceScope->SegmentNumber, SecondaryBusNumber, ScanBusCallbackAlwaysEnablePageAttribute);
+    return Status;
+  } else {
+    SourceId.Bits.Bus      = Bus;
+    SourceId.Bits.Device   = Device;
+    SourceId.Bits.Function = Function;
+    Status = AlwaysEnablePageAttribute (DeviceScope->SegmentNumber, SourceId);
+    return Status;
+  }
+}
+
+/**
+  Always enable the VTd page attribute for the device matching DeviceId.
+
+  @param[in]  PciDeviceId  the input PCI device ID
+
+  @retval EFI_SUCCESS           The VTd entry is updated to always enable all DMA access for the specific device matching DeviceId.
+**/
+EFI_STATUS
+AlwaysEnablePageAttributePciDeviceId (
+  IN  EDKII_PLATFORM_VTD_PCI_DEVICE_ID   *PciDeviceId
+  )
+{
+  UINTN            VtdIndex;
+  UINTN            PciIndex;
+  PCI_DEVICE_DATA  *PciDeviceData;
+  EFI_STATUS       Status;
+
+  for (VtdIndex = 0; VtdIndex < mVtdUnitNumber; VtdIndex++) {
+    for (PciIndex = 0; PciIndex < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; PciIndex++) {
+      PciDeviceData = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[PciIndex];
+
+      if (((PciDeviceId->VendorId == 0xFFFF) || (PciDeviceId->VendorId == PciDeviceData->PciDeviceId.VendorId)) &&
+          ((PciDeviceId->DeviceId == 0xFFFF) || (PciDeviceId->DeviceId == PciDeviceData->PciDeviceId.DeviceId)) &&
+          ((PciDeviceId->RevisionId == 0xFF) || (PciDeviceId->RevisionId == PciDeviceData->PciDeviceId.RevisionId)) &&
+          ((PciDeviceId->SubsystemVendorId == 0xFFFF) || (PciDeviceId->SubsystemVendorId == PciDeviceData->PciDeviceId.SubsystemVendorId)) &&
+          ((PciDeviceId->SubsystemDeviceId == 0xFFFF) || (PciDeviceId->SubsystemDeviceId == PciDeviceData->PciDeviceId.SubsystemDeviceId)) ) {
+        Status = AlwaysEnablePageAttribute (mVtdUnitInformation[VtdIndex].Segment, PciDeviceData->PciSourceId);
+        if (EFI_ERROR(Status)) {
+          continue;
+        }
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Always enable the VTd page attribute for the device.
+
+  @param[in]  DeviceInfo  the exception device information
+
+  @retval EFI_SUCCESS           The VTd entry is updated to always enable all DMA access for the specific device in the device info.
+**/
+EFI_STATUS
+AlwaysEnablePageAttributeExceptionDeviceInfo (
+  IN  EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO   *DeviceInfo
+  )
+{
+  switch (DeviceInfo->Type) {
+  case EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_DEVICE_SCOPE:
+    return AlwaysEnablePageAttributeDeviceScope ((VOID *)(DeviceInfo + 1));
+  case EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_PCI_DEVICE_ID:
+    return AlwaysEnablePageAttributePciDeviceId ((VOID *)(DeviceInfo + 1));
+  default:
+    return EFI_UNSUPPORTED;
+  }
+}
+
+/**
   Initialize platform VTd policy.
 **/
 VOID
@@ -159,10 +285,11 @@ InitializePlatformVTdPolicy (
   VOID
   )
 {
-  EFI_STATUS                        Status;
-  UINTN                             DeviceInfoCount;
-  EDKII_PLATFORM_VTD_DEVICE_INFO    *DeviceInfo;
-  UINTN                             Index;
+  EFI_STATUS                               Status;
+  UINTN                                    DeviceInfoCount;
+  VOID                                     *DeviceInfo;
+  EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO *ThisDeviceInfo;
+  UINTN                                    Index;
 
   //
   // It is optional.
@@ -173,10 +300,16 @@ InitializePlatformVTdPolicy (
                   (VOID **)&mPlatformVTdPolicy
                   );
   if (!EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_INFO, "InitializePlatformVTdPolicy\n"));
     Status = mPlatformVTdPolicy->GetExceptionDeviceList (mPlatformVTdPolicy, &DeviceInfoCount, &DeviceInfo);
     if (!EFI_ERROR(Status)) {
+      ThisDeviceInfo = DeviceInfo;
       for (Index = 0; Index < DeviceInfoCount; Index++) {
-        AlwaysEnablePageAttribute (DeviceInfo[Index].Segment, DeviceInfo[Index].SourceId);
+        if (ThisDeviceInfo->Type == EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_END) {
+          break;
+        }
+        AlwaysEnablePageAttributeExceptionDeviceInfo (ThisDeviceInfo);
+        ThisDeviceInfo = (VOID *)((UINTN)ThisDeviceInfo + ThisDeviceInfo->Length);
       }
       FreePool (DeviceInfo);
     }
diff --git a/IntelSiliconPkg/IntelVTdDxe/DmaProtection.h b/IntelSiliconPkg/IntelVTdDxe/DmaProtection.h
index c311b29..f7b5292 100644
--- a/IntelSiliconPkg/IntelVTdDxe/DmaProtection.h
+++ b/IntelSiliconPkg/IntelVTdDxe/DmaProtection.h
@@ -50,19 +50,24 @@
 #define ALIGN_VALUE_LOW(Value, Alignment) ((Value) & (~((Alignment) - 1)))
 
 //
-// This is the initial max PCI descriptor.
+// This is the initial max PCI DATA number.
 // The number may be enlarged later.
 //
-#define MAX_PCI_DESCRIPTORS             0x100
+#define MAX_VTD_PCI_DATA_NUMBER             0x100
 
 typedef struct {
-  BOOLEAN                IncludeAllFlag;
-  UINTN                  PciDescriptorNumber;
-  UINTN                  PciDescriptorMaxNumber;
-  BOOLEAN                *IsRealPciDevice;
-  VTD_SOURCE_ID          *PciDescriptors;
+  UINT8                            DeviceType;
+  VTD_SOURCE_ID                    PciSourceId;
+  EDKII_PLATFORM_VTD_PCI_DEVICE_ID PciDeviceId;
   // for statistic analysis
-  UINTN                  *AccessCount;
+  UINTN                            AccessCount;
+} PCI_DEVICE_DATA;
+
+typedef struct {
+  BOOLEAN                          IncludeAllFlag;
+  UINTN                            PciDeviceDataNumber;
+  UINTN                            PciDeviceDataMaxNumber;
+  PCI_DEVICE_DATA                  *PciDeviceData;
 } PCI_DEVICE_INFORMATION;
 
 typedef struct {
@@ -78,6 +83,29 @@ typedef struct {
   PCI_DEVICE_INFORMATION           PciDeviceInfo;
 } VTD_UNIT_INFORMATION;
 
+/**
+  The scan bus callback function.
+
+  It is called in PCI bus scan for each PCI device under the bus.
+
+  @param[in]  Context               The context of the callback.
+  @param[in]  Segment               The segment of the source.
+  @param[in]  Bus                   The bus of the source.
+  @param[in]  Device                The device of the source.
+  @param[in]  Function              The function of the source.
+
+  @retval EFI_SUCCESS           The specific PCI device is processed in the callback.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *SCAN_BUS_FUNC_CALLBACK_FUNC) (
+  IN VOID           *Context,
+  IN UINT16         Segment,
+  IN UINT8          Bus,
+  IN UINT8          Device,
+  IN UINT8          Function
+  );
+
 extern EFI_ACPI_DMAR_HEADER  *mAcpiDmarTable;
 
 extern UINT64                           mVtdHostAddressWidthMask;
@@ -182,13 +210,12 @@ DumpVtdECapRegs (
   );
 
 /**
-  Register PCI device to VTd engine as PCI descriptor.
+  Register PCI device to VTd engine.
 
   @param[in]  VtdIndex              The index of VTd engine.
   @param[in]  Segment               The segment of the source.
   @param[in]  SourceId              The SourceId of the source.
-  @param[in]  IsRealPciDevice       TRUE: It is a real PCI device.
-                                    FALSE: It is not a real PCI device.
+  @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.
 
@@ -201,25 +228,47 @@ RegisterPciDevice (
   IN UINTN          VtdIndex,
   IN UINT16         Segment,
   IN VTD_SOURCE_ID  SourceId,
-  IN BOOLEAN        IsRealPciDevice,
+  IN UINT8          DeviceType,
   IN BOOLEAN        CheckExist
   );
 
 /**
-  Scan PCI bus and register PCI devices under the bus.
+  The scan bus callback function to always enable page attribute.
 
-  @param[in]  VtdIndex              The index of VTd engine.
+  @param[in]  Context               The context of the callback.
   @param[in]  Segment               The segment of the source.
   @param[in]  Bus                   The bus of the source.
+  @param[in]  Device                The device of the source.
+  @param[in]  Function              The function of the source.
 
-  @retval EFI_SUCCESS           The PCI devices under the bus are registered.
-  @retval EFI_OUT_OF_RESOURCES  No enough resource to register a new PCI device.
+  @retval EFI_SUCCESS           The VTd entry is updated to always enable all DMA access for the specific device.
 **/
 EFI_STATUS
-ScanPciBus (
-  IN UINTN          VtdIndex,
+EFIAPI
+ScanBusCallbackRegisterPciDevice (
+  IN VOID           *Context,
   IN UINT16         Segment,
-  IN UINT8          Bus
+  IN UINT8          Bus,
+  IN UINT8          Device,
+  IN UINT8          Function
+  );
+
+/**
+  Scan PCI bus and invoke callback function for each PCI devices under the bus.
+
+  @param[in]  Context               The context of the callback function.
+  @param[in]  Segment               The segment of the source.
+  @param[in]  Bus                   The bus of the source.
+  @param[in]  Callback              The callback function in PCI scan.
+
+  @retval EFI_SUCCESS           The PCI devices under the bus are scaned.
+**/
+EFI_STATUS
+ScanPciBus (
+  IN VOID                         *Context,
+  IN UINT16                       Segment,
+  IN UINT8                        Bus,
+  IN SCAN_BUS_FUNC_CALLBACK_FUNC  Callback
   );
 
 /**
@@ -240,8 +289,8 @@ DumpPciDeviceInfo (
   @param[out] ExtContextEntry       The ExtContextEntry of the source.
   @param[out] ContextEntry          The ContextEntry of the source.
 
-  @return The index of the PCI descriptor.
-  @retval (UINTN)-1  The PCI descriptor is not found.
+  @return The index of the VTd engine.
+  @retval (UINTN)-1  The VTd engine is not found.
 **/
 UINTN
 FindVtdIndexByPciDevice (
@@ -371,17 +420,17 @@ SetAccessAttribute (
   );
 
 /**
-  Return the index of PCI descriptor.
+  Return the index of PCI data.
 
   @param[in]  VtdIndex          The index used to identify a VTd engine.
   @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 descriptor.
-  @retval (UINTN)-1  The PCI descriptor is not found.
+  @return The index of the PCI data.
+  @retval (UINTN)-1  The PCI data is not found.
 **/
 UINTN
-GetPciDescriptor (
+GetPciDataIndex (
   IN UINTN          VtdIndex,
   IN UINT16         Segment,
   IN VTD_SOURCE_ID  SourceId
@@ -490,4 +539,24 @@ FlushPageTableMemory (
   IN UINTN  Size
   );
 
+/**
+  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
+  );
+
 #endif
diff --git a/IntelSiliconPkg/IntelVTdDxe/DmarAcpiTable.c b/IntelSiliconPkg/IntelVTdDxe/DmarAcpiTable.c
index 84b5485..2456b0c 100644
--- a/IntelSiliconPkg/IntelVTdDxe/DmarAcpiTable.c
+++ b/IntelSiliconPkg/IntelVTdDxe/DmarAcpiTable.c
@@ -49,7 +49,11 @@ DumpDmarDeviceScopeEntry (
 
   DEBUG ((DEBUG_INFO,
     "    *************************************************************************\n"
+    ));
+  DEBUG ((DEBUG_INFO,
     "    *       DMA-Remapping Device Scope Entry Structure                      *\n"
+    ));
+  DEBUG ((DEBUG_INFO,
     "    *************************************************************************\n"
     ));
   DEBUG ((DEBUG_INFO,
@@ -140,7 +144,11 @@ DumpDmarAndd (
 
   DEBUG ((DEBUG_INFO,
     "  ***************************************************************************\n"
+    ));
+  DEBUG ((DEBUG_INFO,
     "  *       ACPI Name-space Device Declaration Structure                      *\n"
+    ));
+  DEBUG ((DEBUG_INFO,
     "  ***************************************************************************\n"
     ));
   DEBUG ((DEBUG_INFO,
@@ -189,7 +197,11 @@ DumpDmarRhsa (
 
   DEBUG ((DEBUG_INFO,
     "  ***************************************************************************\n"
+    ));
+  DEBUG ((DEBUG_INFO,
     "  *       Remapping Hardware Status Affinity Structure                      *\n"
+    ));
+  DEBUG ((DEBUG_INFO,
     "  ***************************************************************************\n"
     ));
   DEBUG ((DEBUG_INFO,
@@ -241,7 +253,11 @@ DumpDmarAtsr (
 
   DEBUG ((DEBUG_INFO,
     "  ***************************************************************************\n"
+    ));
+  DEBUG ((DEBUG_INFO,
     "  *       Root Port ATS Capability Reporting Structure                      *\n"
+    ));
+  DEBUG ((DEBUG_INFO,
     "  ***************************************************************************\n"
     ));
   DEBUG ((DEBUG_INFO,
@@ -305,7 +321,11 @@ DumpDmarRmrr (
 
   DEBUG ((DEBUG_INFO,
     "  ***************************************************************************\n"
+    ));
+  DEBUG ((DEBUG_INFO,
     "  *       Reserved Memory Region Reporting Structure                        *\n"
+    ));
+  DEBUG ((DEBUG_INFO,
     "  ***************************************************************************\n"
     ));
   DEBUG ((DEBUG_INFO,
@@ -369,7 +389,11 @@ DumpDmarDrhd (
 
   DEBUG ((DEBUG_INFO,
     "  ***************************************************************************\n"
+    ));
+  DEBUG ((DEBUG_INFO,
     "  *       DMA-Remapping Hardware Definition Structure                       *\n"
+    ));
+  DEBUG ((DEBUG_INFO,
     "  ***************************************************************************\n"
     ));
   DEBUG ((DEBUG_INFO,
@@ -440,7 +464,11 @@ DumpAcpiDMAR (
   //
   DEBUG ((DEBUG_INFO,
     "*****************************************************************************\n"
+    ));
+  DEBUG ((DEBUG_INFO,
     "*         DMAR Table                                                        *\n"
+    ));
+  DEBUG ((DEBUG_INFO,
     "*****************************************************************************\n"
     ));
 
@@ -548,11 +576,11 @@ GetPciBusDeviceFunction (
   switch (DmarDevScopeEntry->Type) {
   case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:
   case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE:
-    while ((UINTN)DmarPciPath < (UINTN)DmarDevScopeEntry + DmarDevScopeEntry->Length) {
+    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;
-      DmarPciPath ++;
     }
     break;
   case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC:
@@ -589,7 +617,6 @@ ProcessDhrd (
   UINT8                                             SecondaryBusNumber;
   EFI_STATUS                                        Status;
   VTD_SOURCE_ID                                     SourceId;
-  BOOLEAN                                           IsRealPciDevice;
 
   mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress = (UINTN)DmarDrhd->RegisterBaseAddress;
   DEBUG ((DEBUG_INFO,"  VTD (%d) BaseAddress -  0x%016lx\n", VtdIndex, DmarDrhd->RegisterBaseAddress));
@@ -600,7 +627,7 @@ ProcessDhrd (
     mVtdUnitInformation[VtdIndex].PciDeviceInfo.IncludeAllFlag = TRUE;
     DEBUG ((DEBUG_INFO,"  ProcessDhrd: with INCLUDE ALL\n"));
 
-    Status = ScanPciBus(VtdIndex, DmarDrhd->SegmentNumber, 0);
+    Status = ScanPciBus((VOID *)VtdIndex, DmarDrhd->SegmentNumber, 0, ScanBusCallbackRegisterPciDevice);
     if (EFI_ERROR (Status)) {
       return Status;
     }
@@ -616,15 +643,6 @@ ProcessDhrd (
     if (EFI_ERROR (Status)) {
       return Status;
     }
-    switch (DmarDevScopeEntry->Type) {
-    case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:
-    case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE:
-      IsRealPciDevice = TRUE;
-      break;
-    default:
-      IsRealPciDevice = FALSE;
-      break;
-    }
 
     DEBUG ((DEBUG_INFO,"  ProcessDhrd: "));
     switch (DmarDevScopeEntry->Type) {
@@ -650,7 +668,7 @@ ProcessDhrd (
     SourceId.Bits.Device = Device;
     SourceId.Bits.Function = Function;
 
-    Status = RegisterPciDevice (VtdIndex, DmarDrhd->SegmentNumber, SourceId, IsRealPciDevice, TRUE);
+    Status = RegisterPciDevice (VtdIndex, DmarDrhd->SegmentNumber, SourceId, DmarDevScopeEntry->Type, TRUE);
     if (EFI_ERROR (Status)) {
       //
       // There might be duplication for special device other than standard PCI device.
@@ -665,7 +683,7 @@ ProcessDhrd (
     switch (DmarDevScopeEntry->Type) {
     case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE:
       SecondaryBusNumber = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(DmarDrhd->SegmentNumber, Bus, Device, Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
-      Status = ScanPciBus (VtdIndex, DmarDrhd->SegmentNumber, SecondaryBusNumber);
+      Status = ScanPciBus ((VOID *)VtdIndex, DmarDrhd->SegmentNumber, SecondaryBusNumber, ScanBusCallbackRegisterPciDevice);
       if (EFI_ERROR (Status)) {
         return Status;
       }
diff --git a/IntelSiliconPkg/IntelVTdDxe/PciInfo.c b/IntelSiliconPkg/IntelVTdDxe/PciInfo.c
index 27e253d..36750b3 100644
--- a/IntelSiliconPkg/IntelVTdDxe/PciInfo.c
+++ b/IntelSiliconPkg/IntelVTdDxe/PciInfo.c
@@ -14,32 +14,34 @@
 #include "DmaProtection.h"
 
 /**
-  Return the index of PCI descriptor.
+  Return the index of PCI data.
 
   @param[in]  VtdIndex          The index used to identify a VTd engine.
   @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 descriptor.
-  @retval (UINTN)-1  The PCI descriptor is not found.
+  @return The index of the PCI data.
+  @retval (UINTN)-1  The PCI data is not found.
 **/
 UINTN
-GetPciDescriptor (
+GetPciDataIndex (
   IN UINTN          VtdIndex,
   IN UINT16         Segment,
   IN VTD_SOURCE_ID  SourceId
   )
 {
-  UINTN  Index;
+  UINTN          Index;
+  VTD_SOURCE_ID  *PciSourceId;
 
   if (Segment != mVtdUnitInformation[VtdIndex].Segment) {
     return (UINTN)-1;
   }
 
-  for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptorNumber; Index++) {
-    if ((mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index].Bits.Bus == SourceId.Bits.Bus) &&
-        (mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index].Bits.Device == SourceId.Bits.Device) &&
-        (mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index].Bits.Function == SourceId.Bits.Function) ) {
+  for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {
+    PciSourceId = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId;
+    if ((PciSourceId->Bits.Bus == SourceId.Bits.Bus) &&
+        (PciSourceId->Bits.Device == SourceId.Bits.Device) &&
+        (PciSourceId->Bits.Function == SourceId.Bits.Function) ) {
       return Index;
     }
   }
@@ -48,13 +50,12 @@ GetPciDescriptor (
 }
 
 /**
-  Register PCI device to VTd engine as PCI descriptor.
+  Register PCI device to VTd engine.
 
   @param[in]  VtdIndex              The index of VTd engine.
   @param[in]  Segment               The segment of the source.
   @param[in]  SourceId              The SourceId of the source.
-  @param[in]  IsRealPciDevice       TRUE: It is a real PCI device.
-                                    FALSE: It is not a real PCI device.
+  @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.
 
@@ -67,17 +68,16 @@ RegisterPciDevice (
   IN UINTN          VtdIndex,
   IN UINT16         Segment,
   IN VTD_SOURCE_ID  SourceId,
-  IN BOOLEAN        IsRealPciDevice,
+  IN UINT8          DeviceType,
   IN BOOLEAN        CheckExist
   )
 {
-  PCI_DEVICE_INFORMATION  *PciDeviceInfo;
-  VTD_SOURCE_ID           *PciDescriptor;
-  UINTN                   PciDescriptorIndex;
-  UINTN                   Index;
-  BOOLEAN                 *NewIsRealPciDevice;
-  VTD_SOURCE_ID           *NewPciDescriptors;
-  UINTN                   *NewAccessCount;
+  PCI_DEVICE_INFORMATION           *PciDeviceInfo;
+  VTD_SOURCE_ID                    *PciSourceId;
+  UINTN                            PciDataIndex;
+  UINTN                            Index;
+  PCI_DEVICE_DATA                  *NewPciDeviceData;
+  EDKII_PLATFORM_VTD_PCI_DEVICE_ID *PciDeviceId;
 
   PciDeviceInfo = &mVtdUnitInformation[VtdIndex].PciDeviceInfo;
 
@@ -86,72 +86,71 @@ RegisterPciDevice (
     // Do not register device in other VTD Unit
     //
     for (Index = 0; Index < VtdIndex; Index++) {
-      PciDescriptorIndex = GetPciDescriptor (Index, Segment, SourceId);
-      if (PciDescriptorIndex != (UINTN)-1) {
+      PciDataIndex = GetPciDataIndex (Index, Segment, SourceId);
+      if (PciDataIndex != (UINTN)-1) {
         DEBUG ((DEBUG_INFO, "  RegisterPciDevice: PCI S%04x B%02x D%02x F%02x already registered by Other Vtd(%d)\n", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, Index));
         return EFI_SUCCESS;
       }
     }
   }
 
-  PciDescriptorIndex = GetPciDescriptor (VtdIndex, Segment, SourceId);
-  if (PciDescriptorIndex == (UINTN)-1) {
+  PciDataIndex = GetPciDataIndex (VtdIndex, Segment, SourceId);
+  if (PciDataIndex == (UINTN)-1) {
     //
     // Register new
     //
 
-    if (PciDeviceInfo->PciDescriptorNumber >= PciDeviceInfo->PciDescriptorMaxNumber) {
+    if (PciDeviceInfo->PciDeviceDataNumber >= PciDeviceInfo->PciDeviceDataMaxNumber) {
       //
       // Reallocate
       //
-      NewIsRealPciDevice = AllocateZeroPool (sizeof(*NewIsRealPciDevice) * (PciDeviceInfo->PciDescriptorMaxNumber + MAX_PCI_DESCRIPTORS));
-      if (NewIsRealPciDevice == NULL) {
-        return EFI_OUT_OF_RESOURCES;
-      }
-      NewPciDescriptors = AllocateZeroPool (sizeof(*NewPciDescriptors) * (PciDeviceInfo->PciDescriptorMaxNumber + MAX_PCI_DESCRIPTORS));
-      if (NewPciDescriptors == NULL) {
-        FreePool (NewIsRealPciDevice);
+      NewPciDeviceData = AllocateZeroPool (sizeof(*NewPciDeviceData) * (PciDeviceInfo->PciDeviceDataMaxNumber + MAX_VTD_PCI_DATA_NUMBER));
+      if (NewPciDeviceData == NULL) {
         return EFI_OUT_OF_RESOURCES;
       }
-      NewAccessCount = AllocateZeroPool (sizeof(*NewAccessCount) * (PciDeviceInfo->PciDescriptorMaxNumber + MAX_PCI_DESCRIPTORS));
-      if (NewAccessCount == NULL) {
-        FreePool (NewIsRealPciDevice);
-        FreePool (NewPciDescriptors);
-        return EFI_OUT_OF_RESOURCES;
-      }
-      PciDeviceInfo->PciDescriptorMaxNumber += MAX_PCI_DESCRIPTORS;
-      if (PciDeviceInfo->IsRealPciDevice != NULL) {
-        CopyMem (NewIsRealPciDevice, PciDeviceInfo->IsRealPciDevice, sizeof(*NewIsRealPciDevice) * PciDeviceInfo->PciDescriptorNumber);
-        FreePool (PciDeviceInfo->IsRealPciDevice);
-      }
-      PciDeviceInfo->IsRealPciDevice = NewIsRealPciDevice;
-      if (PciDeviceInfo->PciDescriptors != NULL) {
-        CopyMem (NewPciDescriptors, PciDeviceInfo->PciDescriptors, sizeof(*NewPciDescriptors) * PciDeviceInfo->PciDescriptorNumber);
-        FreePool (PciDeviceInfo->PciDescriptors);
+      PciDeviceInfo->PciDeviceDataMaxNumber += MAX_VTD_PCI_DATA_NUMBER;
+      if (PciDeviceInfo->PciDeviceData != NULL) {
+        CopyMem (NewPciDeviceData, PciDeviceInfo->PciDeviceData, sizeof(*NewPciDeviceData) * PciDeviceInfo->PciDeviceDataNumber);
+        FreePool (PciDeviceInfo->PciDeviceData);
       }
-      PciDeviceInfo->PciDescriptors = NewPciDescriptors;
-      if (PciDeviceInfo->AccessCount != NULL) {
-        CopyMem (NewAccessCount, PciDeviceInfo->AccessCount, sizeof(*NewAccessCount) * PciDeviceInfo->PciDescriptorNumber);
-        FreePool (PciDeviceInfo->AccessCount);
-      }
-      PciDeviceInfo->AccessCount = NewAccessCount;
+      PciDeviceInfo->PciDeviceData = NewPciDeviceData;
     }
 
-    ASSERT (PciDeviceInfo->PciDescriptorNumber < PciDeviceInfo->PciDescriptorMaxNumber);
-
-    PciDescriptor = &PciDeviceInfo->PciDescriptors[PciDeviceInfo->PciDescriptorNumber];
-    PciDescriptor->Bits.Bus = SourceId.Bits.Bus;
-    PciDescriptor->Bits.Device = SourceId.Bits.Device;
-    PciDescriptor->Bits.Function = SourceId.Bits.Function;
-    PciDeviceInfo->IsRealPciDevice[PciDeviceInfo->PciDescriptorNumber] = IsRealPciDevice;
+    ASSERT (PciDeviceInfo->PciDeviceDataNumber < PciDeviceInfo->PciDeviceDataMaxNumber);
 
-    PciDeviceInfo->PciDescriptorNumber++;
+    PciSourceId = &PciDeviceInfo->PciDeviceData[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));
-    if (!IsRealPciDevice) {
+
+    PciDeviceId = &PciDeviceInfo->PciDeviceData[PciDeviceInfo->PciDeviceDataNumber].PciDeviceId;
+    if ((DeviceType == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT) ||
+        (DeviceType == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE)) {
+      PciDeviceId->VendorId   = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_VENDOR_ID_OFFSET));
+      PciDeviceId->DeviceId   = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_DEVICE_ID_OFFSET));
+      PciDeviceId->RevisionId = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_REVISION_ID_OFFSET));
+
+      DEBUG ((DEBUG_INFO, " (%04x:%04x:%02x", PciDeviceId->VendorId, PciDeviceId->DeviceId, PciDeviceId->RevisionId));
+
+      if (DeviceType == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT) {
+        PciDeviceId->SubsystemVendorId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_SUBSYSTEM_VENDOR_ID_OFFSET));
+        PciDeviceId->SubsystemDeviceId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_SUBSYSTEM_ID_OFFSET));
+        DEBUG ((DEBUG_INFO, ":%04x:%04x", PciDeviceId->SubsystemVendorId, PciDeviceId->SubsystemDeviceId));
+      }
+      DEBUG ((DEBUG_INFO, ")"));
+    }
+
+    PciDeviceInfo->PciDeviceData[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));
@@ -163,20 +162,67 @@ RegisterPciDevice (
 }
 
 /**
-  Scan PCI bus and register PCI devices under the bus.
+  The scan bus callback function to register PCI device.
 
-  @param[in]  VtdIndex              The index of VTd engine.
+  @param[in]  Context               The context of the callback.
   @param[in]  Segment               The segment of the source.
   @param[in]  Bus                   The bus of the source.
+  @param[in]  Device                The device of the source.
+  @param[in]  Function              The function of the source.
 
-  @retval EFI_SUCCESS           The PCI devices under the bus are registered.
-  @retval EFI_OUT_OF_RESOURCES  No enough resource to register a new PCI device.
+  @retval EFI_SUCCESS           The PCI device is registered.
 **/
 EFI_STATUS
-ScanPciBus (
-  IN UINTN          VtdIndex,
+EFIAPI
+ScanBusCallbackRegisterPciDevice (
+  IN VOID           *Context,
   IN UINT16         Segment,
-  IN UINT8          Bus
+  IN UINT8          Bus,
+  IN UINT8          Device,
+  IN UINT8          Function
+  )
+{
+  VTD_SOURCE_ID           SourceId;
+  UINTN                   VtdIndex;
+  UINT8                   BaseClass;
+  UINT8                   SubClass;
+  UINT8                   DeviceType;
+  EFI_STATUS              Status;
+
+  VtdIndex = (UINTN)Context;
+  SourceId.Bits.Bus = Bus;
+  SourceId.Bits.Device = Device;
+  SourceId.Bits.Function = Function;
+
+  DeviceType = EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT;
+  BaseClass = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_CLASSCODE_OFFSET + 2));
+  if (BaseClass == PCI_CLASS_BRIDGE) {
+    SubClass = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_CLASSCODE_OFFSET + 1));
+    if (SubClass == PCI_CLASS_BRIDGE_P2P) {
+      DeviceType = EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE;
+    }
+  }
+
+  Status = RegisterPciDevice (VtdIndex, Segment, SourceId, DeviceType, FALSE);
+  return Status;
+}
+
+/**
+  Scan PCI bus and invoke callback function for each PCI devices under the bus.
+
+  @param[in]  Context               The context of the callback function.
+  @param[in]  Segment               The segment of the source.
+  @param[in]  Bus                   The bus of the source.
+  @param[in]  Callback              The callback function in PCI scan.
+
+  @retval EFI_SUCCESS           The PCI devices under the bus are scaned.
+**/
+EFI_STATUS
+ScanPciBus (
+  IN VOID                         *Context,
+  IN UINT16                       Segment,
+  IN UINT8                        Bus,
+  IN SCAN_BUS_FUNC_CALLBACK_FUNC  Callback
   )
 {
   UINT8                   Device;
@@ -189,7 +235,6 @@ ScanPciBus (
   UINT16                  VendorID;
   UINT16                  DeviceID;
   EFI_STATUS              Status;
-  VTD_SOURCE_ID           SourceId;
 
   // Scan the PCI bus for devices
   for (Device = 0; Device < PCI_MAX_DEVICE + 1; Device++) {
@@ -205,10 +250,7 @@ ScanPciBus (
         continue;
       }
 
-      SourceId.Bits.Bus = Bus;
-      SourceId.Bits.Device = Device;
-      SourceId.Bits.Function = Function;
-      Status = RegisterPciDevice (VtdIndex, Segment, SourceId, TRUE, FALSE);
+      Status = Callback (Context, Segment, Bus, Device, Function);
       if (EFI_ERROR (Status)) {
         return Status;
       }
@@ -220,7 +262,7 @@ ScanPciBus (
           SecondaryBusNumber = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
           DEBUG ((DEBUG_INFO,"  ScanPciBus: PCI bridge S%04x B%02x D%02x F%02x (SecondBus:%02x)\n", Segment, Bus, Device, Function, SecondaryBusNumber));
           if (SecondaryBusNumber != 0) {
-            Status = ScanPciBus (VtdIndex, Segment, SecondaryBusNumber);
+            Status = ScanPciBus (Context, Segment, SecondaryBusNumber, Callback);
             if (EFI_ERROR (Status)) {
               return Status;
             }
@@ -246,15 +288,15 @@ DumpPciDeviceInfo (
   UINTN  Index;
 
   DEBUG ((DEBUG_INFO,"PCI Device Information (Number 0x%x, IncludeAll - %d):\n",
-    mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptorNumber,
+    mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber,
     mVtdUnitInformation[VtdIndex].PciDeviceInfo.IncludeAllFlag
     ));
-  for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptorNumber; Index++) {
+  for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {
     DEBUG ((DEBUG_INFO,"  S%04x B%02x D%02x F%02x\n",
       mVtdUnitInformation[VtdIndex].Segment,
-      mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index].Bits.Bus,
-      mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index].Bits.Device,
-      mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index].Bits.Function
+      mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Bus,
+      mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Device,
+      mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Function
       ));
   }
 }
@@ -267,8 +309,8 @@ DumpPciDeviceInfo (
   @param[out] ExtContextEntry       The ExtContextEntry of the source.
   @param[out] ContextEntry          The ContextEntry of the source.
 
-  @return The index of the PCI descriptor.
-  @retval (UINTN)-1  The PCI descriptor is not found.
+  @return The index of the VTd engine.
+  @retval (UINTN)-1  The VTd engine is not found.
 **/
 UINTN
 FindVtdIndexByPciDevice (
@@ -285,15 +327,15 @@ FindVtdIndexByPciDevice (
   VTD_EXT_ROOT_ENTRY      *ExtRootEntry;
   VTD_EXT_CONTEXT_ENTRY   *ExtContextEntryTable;
   VTD_EXT_CONTEXT_ENTRY   *ThisExtContextEntry;
-  UINTN                   PciDescriptorIndex;
+  UINTN                   PciDataIndex;
 
   for (VtdIndex = 0; VtdIndex < mVtdUnitNumber; VtdIndex++) {
     if (Segment != mVtdUnitInformation[VtdIndex].Segment) {
       continue;
     }
 
-    PciDescriptorIndex = GetPciDescriptor (VtdIndex, Segment, SourceId);
-    if (PciDescriptorIndex == (UINTN)-1) {
+    PciDataIndex = GetPciDataIndex (VtdIndex, Segment, SourceId);
+    if (PciDataIndex == (UINTN)-1) {
       continue;
     }
 
diff --git a/IntelSiliconPkg/IntelVTdDxe/TranslationTable.c b/IntelSiliconPkg/IntelVTdDxe/TranslationTable.c
index bc0c24c..cd3111c 100644
--- a/IntelSiliconPkg/IntelVTdDxe/TranslationTable.c
+++ b/IntelSiliconPkg/IntelVTdDxe/TranslationTable.c
@@ -86,16 +86,16 @@ CreateContextEntry (
   VTD_ROOT_ENTRY         *RootEntry;
   VTD_CONTEXT_ENTRY      *ContextEntryTable;
   VTD_CONTEXT_ENTRY      *ContextEntry;
-  VTD_SOURCE_ID          *PciDescriptor;
+  VTD_SOURCE_ID          *PciSourceId;
   VTD_SOURCE_ID          SourceId;
   UINTN                  MaxBusNumber;
   UINTN                  EntryTablePages;
 
   MaxBusNumber = 0;
-  for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptorNumber; Index++) {
-    PciDescriptor = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index];
-    if (PciDescriptor->Bits.Bus > MaxBusNumber) {
-      MaxBusNumber = PciDescriptor->Bits.Bus;
+  for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {
+    PciSourceId = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId;
+    if (PciSourceId->Bits.Bus > MaxBusNumber) {
+      MaxBusNumber = PciSourceId->Bits.Bus;
     }
   }
   DEBUG ((DEBUG_INFO,"  MaxBusNumber - 0x%x\n", MaxBusNumber));
@@ -111,12 +111,12 @@ CreateContextEntry (
   mVtdUnitInformation[VtdIndex].RootEntryTable = (VTD_ROOT_ENTRY *)Buffer;
   Buffer = (UINT8 *)Buffer + EFI_PAGES_TO_SIZE (RootPages);
 
-  for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptorNumber; Index++) {
-    PciDescriptor = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index];
+  for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {
+    PciSourceId = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId;
 
-    SourceId.Bits.Bus = PciDescriptor->Bits.Bus;
-    SourceId.Bits.Device = PciDescriptor->Bits.Device;
-    SourceId.Bits.Function = PciDescriptor->Bits.Function;
+    SourceId.Bits.Bus = PciSourceId->Bits.Bus;
+    SourceId.Bits.Device = PciSourceId->Bits.Device;
+    SourceId.Bits.Function = PciSourceId->Bits.Function;
 
     RootEntry = &mVtdUnitInformation[VtdIndex].RootEntryTable[SourceId.Index.RootIndex];
     if (RootEntry->Bits.Present == 0) {
@@ -886,7 +886,7 @@ SetAccessAttribute (
   VTD_CONTEXT_ENTRY             *ContextEntry;
   VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry;
   UINT64                        Pt;
-  UINTN                         PciDescriptorIndex;
+  UINTN                         PciDataIndex;
   UINT16                        DomainIdentifier;
 
   SecondLevelPagingEntry = NULL;
@@ -899,12 +899,12 @@ SetAccessAttribute (
     return EFI_DEVICE_ERROR;
   }
 
-  PciDescriptorIndex = GetPciDescriptor (VtdIndex, Segment, SourceId);
-  mVtdUnitInformation[VtdIndex].PciDeviceInfo.AccessCount[PciDescriptorIndex]++;
+  PciDataIndex = GetPciDataIndex (VtdIndex, Segment, SourceId);
+  mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[PciDataIndex].AccessCount++;
   //
   // DomainId should not be 0.
   //
-  DomainIdentifier = (UINT16)(PciDescriptorIndex + 1);
+  DomainIdentifier = (UINT16)(PciDataIndex + 1);
 
   if (ExtContextEntry != NULL) {
     if (ExtContextEntry->Bits.Present == 0) {
diff --git a/IntelSiliconPkg/IntelVTdDxe/TranslationTableEx.c b/IntelSiliconPkg/IntelVTdDxe/TranslationTableEx.c
index 9d4e6ea..68b25a7 100644
--- a/IntelSiliconPkg/IntelVTdDxe/TranslationTableEx.c
+++ b/IntelSiliconPkg/IntelVTdDxe/TranslationTableEx.c
@@ -33,16 +33,16 @@ CreateExtContextEntry (
   VTD_EXT_ROOT_ENTRY     *ExtRootEntry;
   VTD_EXT_CONTEXT_ENTRY  *ExtContextEntryTable;
   VTD_EXT_CONTEXT_ENTRY  *ExtContextEntry;
-  VTD_SOURCE_ID          *PciDescriptor;
+  VTD_SOURCE_ID          *PciSourceId;
   VTD_SOURCE_ID          SourceId;
   UINTN                  MaxBusNumber;
   UINTN                  EntryTablePages;
 
   MaxBusNumber = 0;
-  for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptorNumber; Index++) {
-    PciDescriptor = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index];
-    if (PciDescriptor->Bits.Bus > MaxBusNumber) {
-      MaxBusNumber = PciDescriptor->Bits.Bus;
+  for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {
+    PciSourceId = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId;
+    if (PciSourceId->Bits.Bus > MaxBusNumber) {
+      MaxBusNumber = PciSourceId->Bits.Bus;
     }
   }
   DEBUG ((DEBUG_INFO,"  MaxBusNumber - 0x%x\n", MaxBusNumber));
@@ -58,12 +58,12 @@ CreateExtContextEntry (
   mVtdUnitInformation[VtdIndex].ExtRootEntryTable = (VTD_EXT_ROOT_ENTRY *)Buffer;
   Buffer = (UINT8 *)Buffer + EFI_PAGES_TO_SIZE (RootPages);
 
-  for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptorNumber; Index++) {
-    PciDescriptor = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index];
+  for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {
+    PciSourceId = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId;
 
-    SourceId.Bits.Bus = PciDescriptor->Bits.Bus;
-    SourceId.Bits.Device = PciDescriptor->Bits.Device;
-    SourceId.Bits.Function = PciDescriptor->Bits.Function;
+    SourceId.Bits.Bus = PciSourceId->Bits.Bus;
+    SourceId.Bits.Device = PciSourceId->Bits.Device;
+    SourceId.Bits.Function = PciSourceId->Bits.Function;
 
     ExtRootEntry = &mVtdUnitInformation[VtdIndex].ExtRootEntryTable[SourceId.Index.RootIndex];
     if (ExtRootEntry->Bits.LowerPresent == 0) {
diff --git a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
index b1178b7..d78353f 100644
--- a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
+++ b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
@@ -187,8 +187,8 @@ PrepareVtdConfig (
     }
 
     DomainNumber = (UINTN)1 << (UINT8)((UINTN)mVtdUnitInformation[Index].CapReg.Bits.ND * 2 + 4);
-    if (mVtdUnitInformation[Index].PciDeviceInfo.PciDescriptorNumber >= DomainNumber) {
-      DEBUG((DEBUG_ERROR, "!!!! Pci device Number(0x%x) >= DomainNumber(0x%x) !!!!\n", mVtdUnitInformation[Index].PciDeviceInfo.PciDescriptorNumber, DomainNumber));
+    if (mVtdUnitInformation[Index].PciDeviceInfo.PciDeviceDataNumber >= DomainNumber) {
+      DEBUG((DEBUG_ERROR, "!!!! Pci device Number(0x%x) >= DomainNumber(0x%x) !!!!\n", mVtdUnitInformation[Index].PciDeviceInfo.PciDeviceDataNumber, DomainNumber));
       return ;
     }
   }
@@ -305,13 +305,13 @@ DisableDmar (
 
   for (Index = 0; Index < mVtdUnitNumber; Index++) {
     DEBUG((DEBUG_INFO, "engine [%d] access\n", Index));
-    for (SubIndex = 0; SubIndex < mVtdUnitInformation[Index].PciDeviceInfo.PciDescriptorNumber; SubIndex++) {
+    for (SubIndex = 0; SubIndex < mVtdUnitInformation[Index].PciDeviceInfo.PciDeviceDataNumber; SubIndex++) {
       DEBUG ((DEBUG_INFO, "  PCI S%04X B%02x D%02x F%02x - %d\n",
         mVtdUnitInformation[Index].Segment,
-        mVtdUnitInformation[Index].PciDeviceInfo.PciDescriptors[SubIndex].Bits.Bus,
-        mVtdUnitInformation[Index].PciDeviceInfo.PciDescriptors[SubIndex].Bits.Device,
-        mVtdUnitInformation[Index].PciDeviceInfo.PciDescriptors[SubIndex].Bits.Function,
-        mVtdUnitInformation[Index].PciDeviceInfo.AccessCount[SubIndex]
+        mVtdUnitInformation[Index].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Bus,
+        mVtdUnitInformation[Index].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Device,
+        mVtdUnitInformation[Index].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Function,
+        mVtdUnitInformation[Index].PciDeviceInfo.PciDeviceData[Index].AccessCount
         ));
     }
   }
-- 
2.7.4.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel