public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 0/3] Add flexible exception device reporting
@ 2017-08-25  7:40 Jiewen Yao
  2017-08-25  7:40 ` [PATCH 1/3] IntelSiliconPkg/header: update PlatformVtdPolicy Jiewen Yao
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Jiewen Yao @ 2017-08-25  7:40 UTC (permalink / raw)
  To: edk2-devel

During VTd enabling, we notice a platform may want to
add exception device based upon VendorId/DeviceId.

We update GetExceptionDeviceList() function to support both style.

1) Support Device scope based reporting:
Such as, Seg:0/StartBus:0/(Dev:1C|Func:0)/(Dev:0|Func:0)

2) Support PCI VendorId/DeviceId based reporting
Such as, VID:8086|DID:9D2F|Rev:21|SVID:8086|SDID:7270

Jiewen Yao (3):
  IntelSiliconPkg/header: update PlatformVtdPolicy
  IntelSiliconPkg/IntelVTd: update PlatformVtdPolicy
  IntelSiliconPkg/PlatformVTdSample: update ExceptionDevice

 IntelSiliconPkg/Include/Protocol/PlatformVtdPolicy.h        |  51 ++++-
 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 +-
 IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c |  80 +++++++-
 9 files changed, 543 insertions(+), 172 deletions(-)

-- 
2.7.4.windows.1



^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] IntelSiliconPkg/header: update PlatformVtdPolicy
  2017-08-25  7:40 [PATCH 0/3] Add flexible exception device reporting Jiewen Yao
@ 2017-08-25  7:40 ` Jiewen Yao
  2017-08-25  7:40 ` [PATCH 2/3] IntelSiliconPkg/IntelVTd: " Jiewen Yao
  2017-08-25  7:40 ` [PATCH 3/3] IntelSiliconPkg/PlatformVTdSample: update ExceptionDevice Jiewen Yao
  2 siblings, 0 replies; 6+ messages in thread
From: Jiewen Yao @ 2017-08-25  7:40 UTC (permalink / raw)
  To: edk2-devel; +Cc: Star Zeng

Add flexible exception list format:
1) Support Device scope based reporting:
Such as, Seg:0/StartBus:0/(Dev:1C|Func:0)/(Dev:0|Func:0)

2) Support PCI VendorId/DeviceId based reporting
Such as, VID:8086|DID:9D2F|Rev:21|SVID:8086|SDID:7270

Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
 IntelSiliconPkg/Include/Protocol/PlatformVtdPolicy.h | 51 +++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/IntelSiliconPkg/Include/Protocol/PlatformVtdPolicy.h b/IntelSiliconPkg/Include/Protocol/PlatformVtdPolicy.h
index 29774c1..441da5c 100644
--- a/IntelSiliconPkg/Include/Protocol/PlatformVtdPolicy.h
+++ b/IntelSiliconPkg/Include/Protocol/PlatformVtdPolicy.h
@@ -16,6 +16,7 @@
 #define __PLATFORM_VTD_POLICY_PROTOCOL_H__
 
 #include <IndustryStandard/Vtd.h>
+#include <IndustryStandard/DmaRemappingReportingTable.h>
 
 #define EDKII_PLATFORM_VTD_POLICY_PROTOCOL_GUID \
     { \
@@ -66,6 +67,53 @@ EFI_STATUS
   OUT EDKII_PLATFORM_VTD_DEVICE_INFO           *DeviceInfo
   );
 
+#pragma pack(1)
+
+typedef struct {
+  //
+  // The segment number of the device
+  //
+  UINT16                                          SegmentNumber;
+  //
+  // Device scope definition in DMAR table
+  //
+  EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER     DeviceScope;
+  //
+  // Pci path definition in DMAR table
+  //
+//EFI_ACPI_DMAR_PCI_PATH                          PciPath[];
+} EDKII_PLATFORM_VTD_DEVICE_SCOPE;
+
+typedef struct {
+  UINT16                                   VendorId;
+  UINT16                                   DeviceId;
+  UINT8                                    RevisionId;
+  UINT16                                   SubsystemVendorId;
+  UINT16                                   SubsystemDeviceId;
+} EDKII_PLATFORM_VTD_PCI_DEVICE_ID;
+
+#define EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_END           0
+#define EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_DEVICE_SCOPE  1
+#define EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_PCI_DEVICE_ID 2
+
+typedef struct {
+  //
+  // EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_xxx defined above.
+  //
+  UINT8             Type;
+  //
+  // The length of the full data structure including EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO and Data.
+  //
+  UINT8             Length;
+  //
+  // Data can be EDKII_PLATFORM_VTD_DEVICE_SCOPE or EDKII_PLATFORM_VTD_PCI_DEVICE_ID
+  //
+//UINT8             Data[Length - sizeof(EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO)];
+} EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO;
+
+#pragma pack()
+
+
 /**
   Get a list of the exception devices.
 
@@ -74,6 +122,7 @@ EFI_STATUS
   @param[in]  This                  The protocol instance pointer.
   @param[out] DeviceInfoCount       The count of the list of DeviceInfo.
   @param[out] DeviceInfo            A callee allocated buffer to hold a list of DeviceInfo.
+                                    Each DeviceInfo pointer points to EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO.
 
   @retval EFI_SUCCESS           The DeviceInfoCount and DeviceInfo are returned.
   @retval EFI_INVALID_PARAMETER DeviceInfoCount is NULL, or DeviceInfo is NULL.
@@ -85,7 +134,7 @@ EFI_STATUS
 (EFIAPI *EDKII_PLATFORM_VTD_POLICY_GET_EXCEPTION_DEVICE_LIST) (
   IN  EDKII_PLATFORM_VTD_POLICY_PROTOCOL       *This,
   OUT UINTN                                    *DeviceInfoCount,
-  OUT EDKII_PLATFORM_VTD_DEVICE_INFO           **DeviceInfo
+  OUT VOID                                     **DeviceInfo
   );
 
 struct _EDKII_PLATFORM_VTD_POLICY_PROTOCOL {
-- 
2.7.4.windows.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] IntelSiliconPkg/IntelVTd: update PlatformVtdPolicy
  2017-08-25  7:40 [PATCH 0/3] Add flexible exception device reporting Jiewen Yao
  2017-08-25  7:40 ` [PATCH 1/3] IntelSiliconPkg/header: update PlatformVtdPolicy Jiewen Yao
@ 2017-08-25  7:40 ` Jiewen Yao
  2017-08-25  7:40 ` [PATCH 3/3] IntelSiliconPkg/PlatformVTdSample: update ExceptionDevice Jiewen Yao
  2 siblings, 0 replies; 6+ messages in thread
From: Jiewen Yao @ 2017-08-25  7:40 UTC (permalink / raw)
  To: edk2-devel; +Cc: Star Zeng

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



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] IntelSiliconPkg/PlatformVTdSample: update ExceptionDevice
  2017-08-25  7:40 [PATCH 0/3] Add flexible exception device reporting Jiewen Yao
  2017-08-25  7:40 ` [PATCH 1/3] IntelSiliconPkg/header: update PlatformVtdPolicy Jiewen Yao
  2017-08-25  7:40 ` [PATCH 2/3] IntelSiliconPkg/IntelVTd: " Jiewen Yao
@ 2017-08-25  7:40 ` Jiewen Yao
  2017-08-25  9:39   ` Zeng, Star
  2 siblings, 1 reply; 6+ messages in thread
From: Jiewen Yao @ 2017-08-25  7:40 UTC (permalink / raw)
  To: edk2-devel; +Cc: Star Zeng

Add sample for device scope based exception list
and PCI vendor id based exception list.

Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
 IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c | 80 +++++++++++++++++---
 1 file changed, 70 insertions(+), 10 deletions(-)

diff --git a/IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c b/IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c
index f181b94..95e0f3a 100644
--- a/IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c
+++ b/IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c
@@ -27,6 +27,8 @@
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/DevicePathLib.h>
 
+#include <IndustryStandard/DmaRemappingReportingTable.h>
+
 typedef struct {
   ACPI_EXTENDED_HID_DEVICE_PATH      I2cController;
   UINT8                              HidStr[8];
@@ -137,10 +139,57 @@ PLATFORM_PCI_BRIDGE_DEVICE_PATH mPlatformPciBridgeDevicePath = {
   PLATFORM_END_ENTIRE
 };
 
-EDKII_PLATFORM_VTD_DEVICE_INFO  mExceptionDeviceList[] = {
+#pragma pack(1)
+
+typedef struct {
+  EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO     ExceptionDeviceInfo;
+  EDKII_PLATFORM_VTD_DEVICE_SCOPE              DeviceScope;
+  EFI_ACPI_DMAR_PCI_PATH                       PciBridge;
+  EFI_ACPI_DMAR_PCI_PATH                       PciDevice;
+} PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT;
+
+typedef struct {
+  EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO     ExceptionDeviceInfo;
+  EDKII_PLATFORM_VTD_PCI_DEVICE_ID             PciDeviceId;
+} PLATFORM_EXCEPTION_PCI_DEVICE_ID_STRUCT;
+
+#pragma pack()
+
+PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT  mExceptionDeviceScopeList[] = {
   {
-    0x0,                 // Segment
-    {{0x00, 0x00, 0x02}} // Function, Device, Bus
+    {
+      EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_DEVICE_SCOPE,
+      sizeof(PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT)
+    },  // ExceptionDeviceInfo
+    {
+      0,                                                    // SegmentNumber
+      {
+        EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT,      // Type
+        sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER) +
+          2 * sizeof(EFI_ACPI_DMAR_PCI_PATH),               // Length
+        0,                                                  // Reserved2
+        0,                                                  // EnumerationId
+        0,                                                  // StartBusNumber
+      },
+    },                                                      // DeviceScope
+    { 0x1C, 1 },                                            // PciBridge
+    { 0x0,  0 },                                            // PciDevice
+  },
+};
+
+PLATFORM_EXCEPTION_PCI_DEVICE_ID_STRUCT  mExceptionPciDeviceIdList[] = {
+  {
+    {
+      EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_PCI_DEVICE_ID,
+      sizeof(PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT)
+    },  // ExceptionDeviceInfo
+    {
+      0x8086,                                               // VendorId
+      0x9D2F,                                               // DeviceId
+      0x21,                                                 // RevisionId
+      0x8086,                                               // SubsystemVendorId
+      0x7270,                                               // SubsystemDeviceId
+    },
   },
 };
 
@@ -269,6 +318,7 @@ PlatformVTdGetDeviceId (
   @param[in]  This                  The protocol instance pointer.
   @param[out] DeviceInfoCount       The count of the list of DeviceInfo.
   @param[out] DeviceInfo            A callee allocated buffer to hold a list of DeviceInfo.
+                                    Each DeviceInfo pointer points to EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO.
 
   @retval EFI_SUCCESS           The DeviceInfoCount and DeviceInfo are returned.
   @retval EFI_INVALID_PARAMETER DeviceInfoCount is NULL, or DeviceInfo is NULL.
@@ -280,7 +330,7 @@ EFIAPI
 PlatformVTdGetExceptionDeviceList (
   IN  EDKII_PLATFORM_VTD_POLICY_PROTOCOL       *This,
   OUT UINTN                                    *DeviceInfoCount,
-  OUT EDKII_PLATFORM_VTD_DEVICE_INFO           **DeviceInfo
+  OUT VOID                                     **DeviceInfo
   )
 {
   DEBUG ((DEBUG_VERBOSE, "PlatformVTdGetExceptionDeviceList\n"));
@@ -289,13 +339,23 @@ PlatformVTdGetExceptionDeviceList (
     return EFI_INVALID_PARAMETER;
   }
 
-  *DeviceInfo = AllocateZeroPool (sizeof(mExceptionDeviceList));
-  if (*DeviceInfo == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-  CopyMem (*DeviceInfo, mExceptionDeviceList, sizeof(mExceptionDeviceList));
+  if (0) {
+    *DeviceInfo = AllocateZeroPool (sizeof(mExceptionDeviceScopeList));
+    if (*DeviceInfo == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    CopyMem (*DeviceInfo, mExceptionDeviceScopeList, sizeof(mExceptionDeviceScopeList));
+
+    *DeviceInfoCount = ARRAY_SIZE(mExceptionDeviceScopeList);
+  } else {
+    *DeviceInfo = AllocateZeroPool (sizeof(mExceptionPciDeviceIdList));
+    if (*DeviceInfo == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    CopyMem (*DeviceInfo, mExceptionPciDeviceIdList, sizeof(mExceptionPciDeviceIdList));
 
-  *DeviceInfoCount = ARRAY_SIZE(mExceptionDeviceList);
+    *DeviceInfoCount = ARRAY_SIZE(mExceptionPciDeviceIdList);
+  }
 
   return EFI_SUCCESS;
 }
-- 
2.7.4.windows.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 3/3] IntelSiliconPkg/PlatformVTdSample: update ExceptionDevice
  2017-08-25  7:40 ` [PATCH 3/3] IntelSiliconPkg/PlatformVTdSample: update ExceptionDevice Jiewen Yao
@ 2017-08-25  9:39   ` Zeng, Star
  2017-08-25 13:34     ` Yao, Jiewen
  0 siblings, 1 reply; 6+ messages in thread
From: Zeng, Star @ 2017-08-25  9:39 UTC (permalink / raw)
  To: Yao, Jiewen, edk2-devel@lists.01.org; +Cc: Zeng, Star

PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT is used in mExceptionPciDeviceIdList, that is wrong and should be PLATFORM_EXCEPTION_PCI_DEVICE_ID_STRUCT.
Others are good to me. Reviewed-by: Star Zeng <star.zeng@intel.com>

+PLATFORM_EXCEPTION_PCI_DEVICE_ID_STRUCT  mExceptionPciDeviceIdList[] = 
+{
+  {
+    {
+      EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_PCI_DEVICE_ID,
+      sizeof(PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT)


Thanks,
Star
-----Original Message-----
From: Yao, Jiewen 
Sent: Friday, August 25, 2017 3:41 PM
To: edk2-devel@lists.01.org
Cc: Zeng, Star <star.zeng@intel.com>
Subject: [PATCH 3/3] IntelSiliconPkg/PlatformVTdSample: update ExceptionDevice

Add sample for device scope based exception list and PCI vendor id based exception list.

Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
 IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c | 80 +++++++++++++++++---
 1 file changed, 70 insertions(+), 10 deletions(-)

diff --git a/IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c b/IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c
index f181b94..95e0f3a 100644
--- a/IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c
+++ b/IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c
@@ -27,6 +27,8 @@
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/DevicePathLib.h>
 
+#include <IndustryStandard/DmaRemappingReportingTable.h>
+
 typedef struct {
   ACPI_EXTENDED_HID_DEVICE_PATH      I2cController;
   UINT8                              HidStr[8];
@@ -137,10 +139,57 @@ PLATFORM_PCI_BRIDGE_DEVICE_PATH mPlatformPciBridgeDevicePath = {
   PLATFORM_END_ENTIRE
 };
 
-EDKII_PLATFORM_VTD_DEVICE_INFO  mExceptionDeviceList[] = {
+#pragma pack(1)
+
+typedef struct {
+  EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO     ExceptionDeviceInfo;
+  EDKII_PLATFORM_VTD_DEVICE_SCOPE              DeviceScope;
+  EFI_ACPI_DMAR_PCI_PATH                       PciBridge;
+  EFI_ACPI_DMAR_PCI_PATH                       PciDevice;
+} PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT;
+
+typedef struct {
+  EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO     ExceptionDeviceInfo;
+  EDKII_PLATFORM_VTD_PCI_DEVICE_ID             PciDeviceId;
+} PLATFORM_EXCEPTION_PCI_DEVICE_ID_STRUCT;
+
+#pragma pack()
+
+PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT  mExceptionDeviceScopeList[] = {
   {
-    0x0,                 // Segment
-    {{0x00, 0x00, 0x02}} // Function, Device, Bus
+    {
+      EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_DEVICE_SCOPE,
+      sizeof(PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT)
+    },  // ExceptionDeviceInfo
+    {
+      0,                                                    // SegmentNumber
+      {
+        EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT,      // Type
+        sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER) +
+          2 * sizeof(EFI_ACPI_DMAR_PCI_PATH),               // Length
+        0,                                                  // Reserved2
+        0,                                                  // EnumerationId
+        0,                                                  // StartBusNumber
+      },
+    },                                                      // DeviceScope
+    { 0x1C, 1 },                                            // PciBridge
+    { 0x0,  0 },                                            // PciDevice
+  },
+};
+
+PLATFORM_EXCEPTION_PCI_DEVICE_ID_STRUCT  mExceptionPciDeviceIdList[] = 
+{
+  {
+    {
+      EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_PCI_DEVICE_ID,
+      sizeof(PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT)
+    },  // ExceptionDeviceInfo
+    {
+      0x8086,                                               // VendorId
+      0x9D2F,                                               // DeviceId
+      0x21,                                                 // RevisionId
+      0x8086,                                               // SubsystemVendorId
+      0x7270,                                               // SubsystemDeviceId
+    },
   },
 };
 
@@ -269,6 +318,7 @@ PlatformVTdGetDeviceId (
   @param[in]  This                  The protocol instance pointer.
   @param[out] DeviceInfoCount       The count of the list of DeviceInfo.
   @param[out] DeviceInfo            A callee allocated buffer to hold a list of DeviceInfo.
+                                    Each DeviceInfo pointer points to EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO.
 
   @retval EFI_SUCCESS           The DeviceInfoCount and DeviceInfo are returned.
   @retval EFI_INVALID_PARAMETER DeviceInfoCount is NULL, or DeviceInfo is NULL.
@@ -280,7 +330,7 @@ EFIAPI
 PlatformVTdGetExceptionDeviceList (
   IN  EDKII_PLATFORM_VTD_POLICY_PROTOCOL       *This,
   OUT UINTN                                    *DeviceInfoCount,
-  OUT EDKII_PLATFORM_VTD_DEVICE_INFO           **DeviceInfo
+  OUT VOID                                     **DeviceInfo
   )
 {
   DEBUG ((DEBUG_VERBOSE, "PlatformVTdGetExceptionDeviceList\n"));
@@ -289,13 +339,23 @@ PlatformVTdGetExceptionDeviceList (
     return EFI_INVALID_PARAMETER;
   }
 
-  *DeviceInfo = AllocateZeroPool (sizeof(mExceptionDeviceList));
-  if (*DeviceInfo == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-  CopyMem (*DeviceInfo, mExceptionDeviceList, sizeof(mExceptionDeviceList));
+  if (0) {
+    *DeviceInfo = AllocateZeroPool (sizeof(mExceptionDeviceScopeList));
+    if (*DeviceInfo == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    CopyMem (*DeviceInfo, mExceptionDeviceScopeList, 
+ sizeof(mExceptionDeviceScopeList));
+
+    *DeviceInfoCount = ARRAY_SIZE(mExceptionDeviceScopeList);
+  } else {
+    *DeviceInfo = AllocateZeroPool (sizeof(mExceptionPciDeviceIdList));
+    if (*DeviceInfo == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    CopyMem (*DeviceInfo, mExceptionPciDeviceIdList, 
+ sizeof(mExceptionPciDeviceIdList));
 
-  *DeviceInfoCount = ARRAY_SIZE(mExceptionDeviceList);
+    *DeviceInfoCount = ARRAY_SIZE(mExceptionPciDeviceIdList);
+  }
 
   return EFI_SUCCESS;
 }
--
2.7.4.windows.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 3/3] IntelSiliconPkg/PlatformVTdSample: update ExceptionDevice
  2017-08-25  9:39   ` Zeng, Star
@ 2017-08-25 13:34     ` Yao, Jiewen
  0 siblings, 0 replies; 6+ messages in thread
From: Yao, Jiewen @ 2017-08-25 13:34 UTC (permalink / raw)
  To: Zeng, Star, edk2-devel@lists.01.org; +Cc: Yao, Jiewen

Yes. Typical copy-paste issue.

Thanks to correct me.


> -----Original Message-----
> From: Zeng, Star
> Sent: Friday, August 25, 2017 5:39 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; edk2-devel@lists.01.org
> Cc: Zeng, Star <star.zeng@intel.com>
> Subject: RE: [PATCH 3/3] IntelSiliconPkg/PlatformVTdSample: update
> ExceptionDevice
> 
> PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT is used in
> mExceptionPciDeviceIdList, that is wrong and should be
> PLATFORM_EXCEPTION_PCI_DEVICE_ID_STRUCT.
> Others are good to me. Reviewed-by: Star Zeng <star.zeng@intel.com>
> 
> +PLATFORM_EXCEPTION_PCI_DEVICE_ID_STRUCT  mExceptionPciDeviceIdList[]
> =
> +{
> +  {
> +    {
> +
> EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_PCI_DEVICE_ID,
> +      sizeof(PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT)
> 
> 
> Thanks,
> Star
> -----Original Message-----
> From: Yao, Jiewen
> Sent: Friday, August 25, 2017 3:41 PM
> To: edk2-devel@lists.01.org
> Cc: Zeng, Star <star.zeng@intel.com>
> Subject: [PATCH 3/3] IntelSiliconPkg/PlatformVTdSample: update
> ExceptionDevice
> 
> Add sample for device scope based exception list and PCI vendor id based
> exception list.
> 
> Cc: Star Zeng <star.zeng@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
>  IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c | 80
> +++++++++++++++++---
>  1 file changed, 70 insertions(+), 10 deletions(-)
> 
> diff --git a/IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c
> b/IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c
> index f181b94..95e0f3a 100644
> --- a/IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c
> +++ b/IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.c
> @@ -27,6 +27,8 @@
>  #include <Library/UefiBootServicesTableLib.h>
>  #include <Library/DevicePathLib.h>
> 
> +#include <IndustryStandard/DmaRemappingReportingTable.h>
> +
>  typedef struct {
>    ACPI_EXTENDED_HID_DEVICE_PATH      I2cController;
>    UINT8                              HidStr[8];
> @@ -137,10 +139,57 @@ PLATFORM_PCI_BRIDGE_DEVICE_PATH
> mPlatformPciBridgeDevicePath = {
>    PLATFORM_END_ENTIRE
>  };
> 
> -EDKII_PLATFORM_VTD_DEVICE_INFO  mExceptionDeviceList[] = {
> +#pragma pack(1)
> +
> +typedef struct {
> +  EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO     ExceptionDeviceInfo;
> +  EDKII_PLATFORM_VTD_DEVICE_SCOPE              DeviceScope;
> +  EFI_ACPI_DMAR_PCI_PATH                       PciBridge;
> +  EFI_ACPI_DMAR_PCI_PATH                       PciDevice;
> +} PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT;
> +
> +typedef struct {
> +  EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO     ExceptionDeviceInfo;
> +  EDKII_PLATFORM_VTD_PCI_DEVICE_ID             PciDeviceId;
> +} PLATFORM_EXCEPTION_PCI_DEVICE_ID_STRUCT;
> +
> +#pragma pack()
> +
> +PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT
> mExceptionDeviceScopeList[] = {
>    {
> -    0x0,                 // Segment
> -    {{0x00, 0x00, 0x02}} // Function, Device, Bus
> +    {
> +
> EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_DEVICE_SCOPE,
> +      sizeof(PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT)
> +    },  // ExceptionDeviceInfo
> +    {
> +      0,                                                    //
> SegmentNumber
> +      {
> +        EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT,      // Type
> +        sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER) +
> +          2 * sizeof(EFI_ACPI_DMAR_PCI_PATH),               // Length
> +        0,                                                  //
> Reserved2
> +        0,                                                  //
> EnumerationId
> +        0,                                                  //
> StartBusNumber
> +      },
> +    },                                                      //
> DeviceScope
> +    { 0x1C, 1 },                                            // PciBridge
> +    { 0x0,  0 },                                            // PciDevice
> +  },
> +};
> +
> +PLATFORM_EXCEPTION_PCI_DEVICE_ID_STRUCT  mExceptionPciDeviceIdList[]
> =
> +{
> +  {
> +    {
> +
> EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_PCI_DEVICE_ID,
> +      sizeof(PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT)
> +    },  // ExceptionDeviceInfo
> +    {
> +      0x8086,                                               //
> VendorId
> +      0x9D2F,                                               // DeviceId
> +      0x21,                                                 //
> RevisionId
> +      0x8086,                                               //
> SubsystemVendorId
> +      0x7270,                                               //
> SubsystemDeviceId
> +    },
>    },
>  };
> 
> @@ -269,6 +318,7 @@ PlatformVTdGetDeviceId (
>    @param[in]  This                  The protocol instance pointer.
>    @param[out] DeviceInfoCount       The count of the list of DeviceInfo.
>    @param[out] DeviceInfo            A callee allocated buffer to hold a list
> of DeviceInfo.
> +                                    Each DeviceInfo pointer points to
> EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO.
> 
>    @retval EFI_SUCCESS           The DeviceInfoCount and DeviceInfo are
> returned.
>    @retval EFI_INVALID_PARAMETER DeviceInfoCount is NULL, or DeviceInfo is
> NULL.
> @@ -280,7 +330,7 @@ EFIAPI
>  PlatformVTdGetExceptionDeviceList (
>    IN  EDKII_PLATFORM_VTD_POLICY_PROTOCOL       *This,
>    OUT UINTN                                    *DeviceInfoCount,
> -  OUT EDKII_PLATFORM_VTD_DEVICE_INFO           **DeviceInfo
> +  OUT VOID                                     **DeviceInfo
>    )
>  {
>    DEBUG ((DEBUG_VERBOSE, "PlatformVTdGetExceptionDeviceList\n"));
> @@ -289,13 +339,23 @@ PlatformVTdGetExceptionDeviceList (
>      return EFI_INVALID_PARAMETER;
>    }
> 
> -  *DeviceInfo = AllocateZeroPool (sizeof(mExceptionDeviceList));
> -  if (*DeviceInfo == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -  CopyMem (*DeviceInfo, mExceptionDeviceList,
> sizeof(mExceptionDeviceList));
> +  if (0) {
> +    *DeviceInfo = AllocateZeroPool (sizeof(mExceptionDeviceScopeList));
> +    if (*DeviceInfo == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +    CopyMem (*DeviceInfo, mExceptionDeviceScopeList,
> + sizeof(mExceptionDeviceScopeList));
> +
> +    *DeviceInfoCount = ARRAY_SIZE(mExceptionDeviceScopeList);
> +  } else {
> +    *DeviceInfo = AllocateZeroPool (sizeof(mExceptionPciDeviceIdList));
> +    if (*DeviceInfo == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +    CopyMem (*DeviceInfo, mExceptionPciDeviceIdList,
> + sizeof(mExceptionPciDeviceIdList));
> 
> -  *DeviceInfoCount = ARRAY_SIZE(mExceptionDeviceList);
> +    *DeviceInfoCount = ARRAY_SIZE(mExceptionPciDeviceIdList);
> +  }
> 
>    return EFI_SUCCESS;
>  }
> --
> 2.7.4.windows.1



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-08-25 13:32 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-25  7:40 [PATCH 0/3] Add flexible exception device reporting Jiewen Yao
2017-08-25  7:40 ` [PATCH 1/3] IntelSiliconPkg/header: update PlatformVtdPolicy Jiewen Yao
2017-08-25  7:40 ` [PATCH 2/3] IntelSiliconPkg/IntelVTd: " Jiewen Yao
2017-08-25  7:40 ` [PATCH 3/3] IntelSiliconPkg/PlatformVTdSample: update ExceptionDevice Jiewen Yao
2017-08-25  9:39   ` Zeng, Star
2017-08-25 13:34     ` Yao, Jiewen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox