#include "DmaProtection.h"\r
\r
/**\r
- Return the index of PCI descriptor.\r
+ Return the index of PCI data.\r
\r
@param[in] VtdIndex The index used to identify a VTd engine.\r
@param[in] Segment The Segment used to identify a VTd engine.\r
@param[in] SourceId The SourceId used to identify a VTd engine and table entry.\r
\r
- @return The index of the PCI descriptor.\r
- @retval (UINTN)-1 The PCI descriptor is not found.\r
+ @return The index of the PCI data.\r
+ @retval (UINTN)-1 The PCI data is not found.\r
**/\r
UINTN\r
-GetPciDescriptor (\r
+GetPciDataIndex (\r
IN UINTN VtdIndex,\r
IN UINT16 Segment,\r
IN VTD_SOURCE_ID SourceId\r
)\r
{\r
- UINTN Index;\r
+ UINTN Index;\r
+ VTD_SOURCE_ID *PciSourceId;\r
\r
if (Segment != mVtdUnitInformation[VtdIndex].Segment) {\r
return (UINTN)-1;\r
}\r
\r
- for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptorNumber; Index++) {\r
- if ((mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index].Bits.Bus == SourceId.Bits.Bus) &&\r
- (mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index].Bits.Device == SourceId.Bits.Device) &&\r
- (mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index].Bits.Function == SourceId.Bits.Function) ) {\r
+ for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {\r
+ PciSourceId = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId;\r
+ if ((PciSourceId->Bits.Bus == SourceId.Bits.Bus) &&\r
+ (PciSourceId->Bits.Device == SourceId.Bits.Device) &&\r
+ (PciSourceId->Bits.Function == SourceId.Bits.Function) ) {\r
return Index;\r
}\r
}\r
}\r
\r
/**\r
- Register PCI device to VTd engine as PCI descriptor.\r
+ Register PCI device to VTd engine.\r
\r
@param[in] VtdIndex The index of VTd engine.\r
@param[in] Segment The segment of the source.\r
@param[in] SourceId The SourceId of the source.\r
- @param[in] IsRealPciDevice TRUE: It is a real PCI device.\r
- FALSE: It is not a real PCI device.\r
+ @param[in] DeviceType The DMAR device scope type.\r
@param[in] CheckExist TRUE: ERROR will be returned if the PCI device is already registered.\r
FALSE: SUCCESS will be returned if the PCI device is registered.\r
\r
IN UINTN VtdIndex,\r
IN UINT16 Segment,\r
IN VTD_SOURCE_ID SourceId,\r
- IN BOOLEAN IsRealPciDevice,\r
+ IN UINT8 DeviceType,\r
IN BOOLEAN CheckExist\r
)\r
{\r
- PCI_DEVICE_INFORMATION *PciDeviceInfo;\r
- VTD_SOURCE_ID *PciDescriptor;\r
- UINTN PciDescriptorIndex;\r
- UINTN Index;\r
- BOOLEAN *NewIsRealPciDevice;\r
- VTD_SOURCE_ID *NewPciDescriptors;\r
- UINTN *NewAccessCount;\r
+ PCI_DEVICE_INFORMATION *PciDeviceInfo;\r
+ VTD_SOURCE_ID *PciSourceId;\r
+ UINTN PciDataIndex;\r
+ UINTN Index;\r
+ PCI_DEVICE_DATA *NewPciDeviceData;\r
+ EDKII_PLATFORM_VTD_PCI_DEVICE_ID *PciDeviceId;\r
\r
PciDeviceInfo = &mVtdUnitInformation[VtdIndex].PciDeviceInfo;\r
\r
// Do not register device in other VTD Unit\r
//\r
for (Index = 0; Index < VtdIndex; Index++) {\r
- PciDescriptorIndex = GetPciDescriptor (Index, Segment, SourceId);\r
- if (PciDescriptorIndex != (UINTN)-1) {\r
+ PciDataIndex = GetPciDataIndex (Index, Segment, SourceId);\r
+ if (PciDataIndex != (UINTN)-1) {\r
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));\r
return EFI_SUCCESS;\r
}\r
}\r
}\r
\r
- PciDescriptorIndex = GetPciDescriptor (VtdIndex, Segment, SourceId);\r
- if (PciDescriptorIndex == (UINTN)-1) {\r
+ PciDataIndex = GetPciDataIndex (VtdIndex, Segment, SourceId);\r
+ if (PciDataIndex == (UINTN)-1) {\r
//\r
// Register new\r
//\r
\r
- if (PciDeviceInfo->PciDescriptorNumber >= PciDeviceInfo->PciDescriptorMaxNumber) {\r
+ if (PciDeviceInfo->PciDeviceDataNumber >= PciDeviceInfo->PciDeviceDataMaxNumber) {\r
//\r
// Reallocate\r
//\r
- NewIsRealPciDevice = AllocateZeroPool (sizeof(*NewIsRealPciDevice) * (PciDeviceInfo->PciDescriptorMaxNumber + MAX_PCI_DESCRIPTORS));\r
- if (NewIsRealPciDevice == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- NewPciDescriptors = AllocateZeroPool (sizeof(*NewPciDescriptors) * (PciDeviceInfo->PciDescriptorMaxNumber + MAX_PCI_DESCRIPTORS));\r
- if (NewPciDescriptors == NULL) {\r
- FreePool (NewIsRealPciDevice);\r
+ NewPciDeviceData = AllocateZeroPool (sizeof(*NewPciDeviceData) * (PciDeviceInfo->PciDeviceDataMaxNumber + MAX_VTD_PCI_DATA_NUMBER));\r
+ if (NewPciDeviceData == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
- NewAccessCount = AllocateZeroPool (sizeof(*NewAccessCount) * (PciDeviceInfo->PciDescriptorMaxNumber + MAX_PCI_DESCRIPTORS));\r
- if (NewAccessCount == NULL) {\r
- FreePool (NewIsRealPciDevice);\r
- FreePool (NewPciDescriptors);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- PciDeviceInfo->PciDescriptorMaxNumber += MAX_PCI_DESCRIPTORS;\r
- if (PciDeviceInfo->IsRealPciDevice != NULL) {\r
- CopyMem (NewIsRealPciDevice, PciDeviceInfo->IsRealPciDevice, sizeof(*NewIsRealPciDevice) * PciDeviceInfo->PciDescriptorNumber);\r
- FreePool (PciDeviceInfo->IsRealPciDevice);\r
- }\r
- PciDeviceInfo->IsRealPciDevice = NewIsRealPciDevice;\r
- if (PciDeviceInfo->PciDescriptors != NULL) {\r
- CopyMem (NewPciDescriptors, PciDeviceInfo->PciDescriptors, sizeof(*NewPciDescriptors) * PciDeviceInfo->PciDescriptorNumber);\r
- FreePool (PciDeviceInfo->PciDescriptors);\r
+ PciDeviceInfo->PciDeviceDataMaxNumber += MAX_VTD_PCI_DATA_NUMBER;\r
+ if (PciDeviceInfo->PciDeviceData != NULL) {\r
+ CopyMem (NewPciDeviceData, PciDeviceInfo->PciDeviceData, sizeof(*NewPciDeviceData) * PciDeviceInfo->PciDeviceDataNumber);\r
+ FreePool (PciDeviceInfo->PciDeviceData);\r
}\r
- PciDeviceInfo->PciDescriptors = NewPciDescriptors;\r
- if (PciDeviceInfo->AccessCount != NULL) {\r
- CopyMem (NewAccessCount, PciDeviceInfo->AccessCount, sizeof(*NewAccessCount) * PciDeviceInfo->PciDescriptorNumber);\r
- FreePool (PciDeviceInfo->AccessCount);\r
- }\r
- PciDeviceInfo->AccessCount = NewAccessCount;\r
+ PciDeviceInfo->PciDeviceData = NewPciDeviceData;\r
}\r
\r
- ASSERT (PciDeviceInfo->PciDescriptorNumber < PciDeviceInfo->PciDescriptorMaxNumber);\r
-\r
- PciDescriptor = &PciDeviceInfo->PciDescriptors[PciDeviceInfo->PciDescriptorNumber];\r
- PciDescriptor->Bits.Bus = SourceId.Bits.Bus;\r
- PciDescriptor->Bits.Device = SourceId.Bits.Device;\r
- PciDescriptor->Bits.Function = SourceId.Bits.Function;\r
- PciDeviceInfo->IsRealPciDevice[PciDeviceInfo->PciDescriptorNumber] = IsRealPciDevice;\r
+ ASSERT (PciDeviceInfo->PciDeviceDataNumber < PciDeviceInfo->PciDeviceDataMaxNumber);\r
\r
- PciDeviceInfo->PciDescriptorNumber++;\r
+ PciSourceId = &PciDeviceInfo->PciDeviceData[PciDeviceInfo->PciDeviceDataNumber].PciSourceId;\r
+ PciSourceId->Bits.Bus = SourceId.Bits.Bus;\r
+ PciSourceId->Bits.Device = SourceId.Bits.Device;\r
+ PciSourceId->Bits.Function = SourceId.Bits.Function;\r
\r
DEBUG ((DEBUG_INFO, " RegisterPciDevice: PCI S%04x B%02x D%02x F%02x", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));\r
- if (!IsRealPciDevice) {\r
+\r
+ PciDeviceId = &PciDeviceInfo->PciDeviceData[PciDeviceInfo->PciDeviceDataNumber].PciDeviceId;\r
+ if ((DeviceType == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT) ||\r
+ (DeviceType == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE)) {\r
+ PciDeviceId->VendorId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_VENDOR_ID_OFFSET));\r
+ PciDeviceId->DeviceId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_DEVICE_ID_OFFSET));\r
+ PciDeviceId->RevisionId = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_REVISION_ID_OFFSET));\r
+\r
+ DEBUG ((DEBUG_INFO, " (%04x:%04x:%02x", PciDeviceId->VendorId, PciDeviceId->DeviceId, PciDeviceId->RevisionId));\r
+\r
+ if (DeviceType == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT) {\r
+ PciDeviceId->SubsystemVendorId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_SUBSYSTEM_VENDOR_ID_OFFSET));\r
+ PciDeviceId->SubsystemDeviceId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_SUBSYSTEM_ID_OFFSET));\r
+ DEBUG ((DEBUG_INFO, ":%04x:%04x", PciDeviceId->SubsystemVendorId, PciDeviceId->SubsystemDeviceId));\r
+ }\r
+ DEBUG ((DEBUG_INFO, ")"));\r
+ }\r
+\r
+ PciDeviceInfo->PciDeviceData[PciDeviceInfo->PciDeviceDataNumber].DeviceType = DeviceType;\r
+\r
+ if ((DeviceType != EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT) &&\r
+ (DeviceType != EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE)) {\r
DEBUG ((DEBUG_INFO, " (*)"));\r
}\r
DEBUG ((DEBUG_INFO, "\n"));\r
+\r
+ PciDeviceInfo->PciDeviceDataNumber++;\r
} else {\r
if (CheckExist) {\r
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));\r
}\r
\r
/**\r
- Scan PCI bus and register PCI devices under the bus.\r
+ The scan bus callback function to register PCI device.\r
\r
- @param[in] VtdIndex The index of VTd engine.\r
+ @param[in] Context The context of the callback.\r
@param[in] Segment The segment of the source.\r
@param[in] Bus The bus of the source.\r
+ @param[in] Device The device of the source.\r
+ @param[in] Function The function of the source.\r
\r
- @retval EFI_SUCCESS The PCI devices under the bus are registered.\r
- @retval EFI_OUT_OF_RESOURCES No enough resource to register a new PCI device.\r
+ @retval EFI_SUCCESS The PCI device is registered.\r
**/\r
EFI_STATUS\r
-ScanPciBus (\r
- IN UINTN VtdIndex,\r
+EFIAPI\r
+ScanBusCallbackRegisterPciDevice (\r
+ IN VOID *Context,\r
IN UINT16 Segment,\r
- IN UINT8 Bus\r
+ IN UINT8 Bus,\r
+ IN UINT8 Device,\r
+ IN UINT8 Function\r
+ )\r
+{\r
+ VTD_SOURCE_ID SourceId;\r
+ UINTN VtdIndex;\r
+ UINT8 BaseClass;\r
+ UINT8 SubClass;\r
+ UINT8 DeviceType;\r
+ EFI_STATUS Status;\r
+\r
+ VtdIndex = (UINTN)Context;\r
+ SourceId.Bits.Bus = Bus;\r
+ SourceId.Bits.Device = Device;\r
+ SourceId.Bits.Function = Function;\r
+\r
+ DeviceType = EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT;\r
+ BaseClass = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_CLASSCODE_OFFSET + 2));\r
+ if (BaseClass == PCI_CLASS_BRIDGE) {\r
+ SubClass = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_CLASSCODE_OFFSET + 1));\r
+ if (SubClass == PCI_CLASS_BRIDGE_P2P) {\r
+ DeviceType = EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE;\r
+ }\r
+ }\r
+\r
+ Status = RegisterPciDevice (VtdIndex, Segment, SourceId, DeviceType, FALSE);\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Scan PCI bus and invoke callback function for each PCI devices under the bus.\r
+\r
+ @param[in] Context The context of the callback function.\r
+ @param[in] Segment The segment of the source.\r
+ @param[in] Bus The bus of the source.\r
+ @param[in] Callback The callback function in PCI scan.\r
+\r
+ @retval EFI_SUCCESS The PCI devices under the bus are scaned.\r
+**/\r
+EFI_STATUS\r
+ScanPciBus (\r
+ IN VOID *Context,\r
+ IN UINT16 Segment,\r
+ IN UINT8 Bus,\r
+ IN SCAN_BUS_FUNC_CALLBACK_FUNC Callback\r
)\r
{\r
UINT8 Device;\r
UINT16 VendorID;\r
UINT16 DeviceID;\r
EFI_STATUS Status;\r
- VTD_SOURCE_ID SourceId;\r
\r
// Scan the PCI bus for devices\r
for (Device = 0; Device < PCI_MAX_DEVICE + 1; Device++) {\r
continue;\r
}\r
\r
- SourceId.Bits.Bus = Bus;\r
- SourceId.Bits.Device = Device;\r
- SourceId.Bits.Function = Function;\r
- Status = RegisterPciDevice (VtdIndex, Segment, SourceId, TRUE, FALSE);\r
+ Status = Callback (Context, Segment, Bus, Device, Function);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
SecondaryBusNumber = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));\r
DEBUG ((DEBUG_INFO," ScanPciBus: PCI bridge S%04x B%02x D%02x F%02x (SecondBus:%02x)\n", Segment, Bus, Device, Function, SecondaryBusNumber));\r
if (SecondaryBusNumber != 0) {\r
- Status = ScanPciBus (VtdIndex, Segment, SecondaryBusNumber);\r
+ Status = ScanPciBus (Context, Segment, SecondaryBusNumber, Callback);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
UINTN Index;\r
\r
DEBUG ((DEBUG_INFO,"PCI Device Information (Number 0x%x, IncludeAll - %d):\n",\r
- mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptorNumber,\r
+ mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber,\r
mVtdUnitInformation[VtdIndex].PciDeviceInfo.IncludeAllFlag\r
));\r
- for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptorNumber; Index++) {\r
+ for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {\r
DEBUG ((DEBUG_INFO," S%04x B%02x D%02x F%02x\n",\r
mVtdUnitInformation[VtdIndex].Segment,\r
- mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index].Bits.Bus,\r
- mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index].Bits.Device,\r
- mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDescriptors[Index].Bits.Function\r
+ mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Bus,\r
+ mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Device,\r
+ mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Function\r
));\r
}\r
}\r
@param[out] ExtContextEntry The ExtContextEntry of the source.\r
@param[out] ContextEntry The ContextEntry of the source.\r
\r
- @return The index of the PCI descriptor.\r
- @retval (UINTN)-1 The PCI descriptor is not found.\r
+ @return The index of the VTd engine.\r
+ @retval (UINTN)-1 The VTd engine is not found.\r
**/\r
UINTN\r
FindVtdIndexByPciDevice (\r
VTD_EXT_ROOT_ENTRY *ExtRootEntry;\r
VTD_EXT_CONTEXT_ENTRY *ExtContextEntryTable;\r
VTD_EXT_CONTEXT_ENTRY *ThisExtContextEntry;\r
- UINTN PciDescriptorIndex;\r
+ UINTN PciDataIndex;\r
\r
for (VtdIndex = 0; VtdIndex < mVtdUnitNumber; VtdIndex++) {\r
if (Segment != mVtdUnitInformation[VtdIndex].Segment) {\r
continue;\r
}\r
\r
- PciDescriptorIndex = GetPciDescriptor (VtdIndex, Segment, SourceId);\r
- if (PciDescriptorIndex == (UINTN)-1) {\r
+ PciDataIndex = GetPciDataIndex (VtdIndex, Segment, SourceId);\r
+ if (PciDataIndex == (UINTN)-1) {\r
continue;\r
}\r
\r