]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelSiliconPkg/IntelVTdDxe/PciInfo.c
IntelSiliconPkg/IntelVTd: update PlatformVtdPolicy
[mirror_edk2.git] / IntelSiliconPkg / IntelVTdDxe / PciInfo.c
index 27e253d42809d4a96e22acdc4de985a50dd91b08..36750b3f1d9cee413c996c681b51ce011aa50252 100644 (file)
 #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
@@ -48,13 +50,12 @@ GetPciDescriptor (
 }\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
@@ -67,17 +68,16 @@ RegisterPciDevice (
   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
@@ -86,72 +86,71 @@ RegisterPciDevice (
     // 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
@@ -163,20 +162,67 @@ RegisterPciDevice (
 }\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
@@ -189,7 +235,6 @@ ScanPciBus (
   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
@@ -205,10 +250,7 @@ ScanPciBus (
         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
@@ -220,7 +262,7 @@ ScanPciBus (
           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
@@ -246,15 +288,15 @@ DumpPciDeviceInfo (
   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
@@ -267,8 +309,8 @@ DumpPciDeviceInfo (
   @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
@@ -285,15 +327,15 @@ FindVtdIndexByPciDevice (
   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