IntelSiliconPkg/IntelVTd: update PlatformVtdPolicy

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>
Reviewed-by: Star Zeng <star.zeng@intel.com>
This commit is contained in:
Jiewen Yao 2017-08-25 14:46:07 +08:00
parent 71872f7cda
commit f77d35c7f0
7 changed files with 423 additions and 161 deletions

View File

@ -151,6 +151,132 @@ ReturnUefiMemoryMap (
return ;
}
/**
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.
**/
@ -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);
}

View File

@ -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
EFIAPI
ScanBusCallbackRegisterPciDevice (
IN VOID *Context,
IN UINT16 Segment,
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 UINTN VtdIndex,
IN UINT16 Segment,
IN UINT8 Bus
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

View File

@ -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;
}

View File

@ -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) {
NewPciDeviceData = AllocateZeroPool (sizeof(*NewPciDeviceData) * (PciDeviceInfo->PciDeviceDataMaxNumber + MAX_VTD_PCI_DATA_NUMBER));
if (NewPciDeviceData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
NewPciDescriptors = AllocateZeroPool (sizeof(*NewPciDescriptors) * (PciDeviceInfo->PciDescriptorMaxNumber + MAX_PCI_DESCRIPTORS));
if (NewPciDescriptors == NULL) {
FreePool (NewIsRealPciDevice);
return EFI_OUT_OF_RESOURCES;
PciDeviceInfo->PciDeviceDataMaxNumber += MAX_VTD_PCI_DATA_NUMBER;
if (PciDeviceInfo->PciDeviceData != NULL) {
CopyMem (NewPciDeviceData, PciDeviceInfo->PciDeviceData, sizeof(*NewPciDeviceData) * PciDeviceInfo->PciDeviceDataNumber);
FreePool (PciDeviceInfo->PciDeviceData);
}
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->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);
ASSERT (PciDeviceInfo->PciDeviceDataNumber < PciDeviceInfo->PciDeviceDataMaxNumber);
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;
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
EFIAPI
ScanBusCallbackRegisterPciDevice (
IN VOID *Context,
IN UINT16 Segment,
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 UINTN VtdIndex,
IN UINT16 Segment,
IN UINT8 Bus
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;
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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
));
}
}