]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
add SR-IOV support in EDK II.
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / PciBusDxe / PciEnumeratorSupport.c
index 2d5408abe0b4687ee34f833b2cf789b4b0a08b97..66183960f16b3aed78476837b869df6b529ebd2b 100644 (file)
@@ -367,6 +367,16 @@ GatherDeviceInfo (
     Offset = PciParseBar (PciIoDevice, Offset, BarIndex);\r
   }\r
 \r
+  //\r
+  // Parse the SR-IOV VF bars\r
+  //\r
+  if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {\r
+    for (Offset = PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR0, BarIndex = 0;\r
+         Offset <= PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR5;\r
+         BarIndex++) {\r
+      Offset = PciIovParseVfBar (PciIoDevice, Offset, BarIndex);\r
+    }\r
+  }\r
   return PciIoDevice;\r
 }\r
 \r
@@ -597,6 +607,80 @@ CreatePciDevicePath (
   return PciIoDevice->DevicePath;\r
 }\r
 \r
+/**\r
+  Check whether the PCI IOV VF bar is existed or not.\r
+\r
+  @param PciIoDevice       A pointer to the PCI_IO_DEVICE.\r
+  @param Offset            The offset.\r
+  @param BarLengthValue    The bar length value returned.\r
+  @param OriginalBarValue  The original bar value returned.\r
+\r
+  @retval EFI_NOT_FOUND    The bar doesn't exist.\r
+  @retval EFI_SUCCESS      The bar exist.\r
+\r
+**/\r
+EFI_STATUS\r
+VfBarExisted (\r
+  IN PCI_IO_DEVICE *PciIoDevice,\r
+  IN UINTN         Offset,\r
+  OUT UINT32       *BarLengthValue,\r
+  OUT UINT32       *OriginalBarValue\r
+  )\r
+{\r
+  EFI_PCI_IO_PROTOCOL *PciIo;\r
+  UINT32              OriginalValue;\r
+  UINT32              Value;\r
+  EFI_TPL             OldTpl;\r
+\r
+  //\r
+  // Ensure it is called properly\r
+  //\r
+  ASSERT (PciIoDevice->SrIovCapabilityOffset != 0);\r
+  if (PciIoDevice->SrIovCapabilityOffset == 0) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  PciIo = &PciIoDevice->PciIo;\r
+\r
+  //\r
+  // Preserve the original value\r
+  //\r
+\r
+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &OriginalValue);\r
+\r
+  //\r
+  // Raise TPL to high level to disable timer interrupt while the BAR is probed\r
+  //\r
+  OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+\r
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &gAllOne);\r
+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &Value);\r
+\r
+  //\r
+  // Write back the original value\r
+  //\r
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &OriginalValue);\r
+\r
+  //\r
+  // Restore TPL to its original level\r
+  //\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
+  if (BarLengthValue != NULL) {\r
+    *BarLengthValue = Value;\r
+  }\r
+\r
+  if (OriginalBarValue != NULL) {\r
+    *OriginalBarValue = OriginalValue;\r
+  }\r
+\r
+  if (Value == 0) {\r
+    return EFI_NOT_FOUND;\r
+  } else {\r
+    return EFI_SUCCESS;\r
+  }\r
+}\r
+\r
 /**\r
   Check whether the bar is existed or not.\r
 \r
@@ -1249,6 +1333,207 @@ SetNewAlign (
   return ;\r
 }\r
 \r
+/**\r
+  Parse PCI IOV VF bar information and fill them into PCI device instance.\r
+\r
+  @param PciIoDevice  Pci device instance.\r
+  @param Offset       Bar offset.\r
+  @param BarIndex     Bar index.\r
+\r
+  @return Next bar offset.\r
+\r
+**/\r
+UINTN\r
+PciIovParseVfBar (\r
+  IN PCI_IO_DEVICE  *PciIoDevice,\r
+  IN UINTN          Offset,\r
+  IN UINTN          BarIndex\r
+  )\r
+{\r
+  UINT32      Value;\r
+  UINT64      BarValue64;\r
+  UINT32      OriginalValue;\r
+  UINT32      Mask;\r
+  UINT32      Data;\r
+  UINT8       Index;\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Ensure it is called properly\r
+  //\r
+  ASSERT (PciIoDevice->SrIovCapabilityOffset != 0);\r
+  if (PciIoDevice->SrIovCapabilityOffset == 0) {\r
+    return 0;\r
+  }\r
+\r
+  OriginalValue = 0;\r
+  Value         = 0;\r
+  BarValue64    = 0;\r
+\r
+  Status = VfBarExisted (\r
+            PciIoDevice,\r
+            Offset,\r
+            &Value,\r
+            &OriginalValue\r
+            );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    PciIoDevice->VfPciBar[BarIndex].BaseAddress = 0;\r
+    PciIoDevice->VfPciBar[BarIndex].Length      = 0;\r
+    PciIoDevice->VfPciBar[BarIndex].Alignment   = 0;\r
+\r
+    //\r
+    // Scan all the BARs anyway\r
+    //\r
+    PciIoDevice->VfPciBar[BarIndex].Offset = (UINT8) Offset;\r
+    return Offset + 4;\r
+  }\r
+\r
+  PciIoDevice->VfPciBar[BarIndex].Offset = (UINT8) Offset;\r
+  if (Value & 0x01) {\r
+    //\r
+    // Device I/Os. Impossible\r
+    //\r
+    ASSERT (FALSE);\r
+    return Offset + 4;\r
+\r
+  } else {\r
+\r
+    Mask  = 0xfffffff0;\r
+\r
+    PciIoDevice->VfPciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
+\r
+    switch (Value & 0x07) {\r
+\r
+    //\r
+    //memory space; anywhere in 32 bit address space\r
+    //\r
+    case 0x00:\r
+      if (Value & 0x08) {\r
+        PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem32;\r
+      } else {\r
+        PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem32;\r
+      }\r
+\r
+      PciIoDevice->VfPciBar[BarIndex].Length    = (~(Value & Mask)) + 1;\r
+      PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+\r
+      //\r
+      // Adjust Length\r
+      //\r
+      PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs);\r
+      //\r
+      // Adjust Alignment\r
+      //\r
+      if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+        PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+      }\r
+\r
+      break;\r
+\r
+    //\r
+    // memory space; anywhere in 64 bit address space\r
+    //\r
+    case 0x04:\r
+      if (Value & 0x08) {\r
+        PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem64;\r
+      } else {\r
+        PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem64;\r
+      }\r
+\r
+      //\r
+      // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
+      // is regarded as an extension for the first bar. As a result\r
+      // the sizing will be conducted on combined 64 bit value\r
+      // Here just store the masked first 32bit value for future size\r
+      // calculation\r
+      //\r
+      PciIoDevice->VfPciBar[BarIndex].Length    = Value & Mask;\r
+      PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+\r
+      if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+        PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+      }\r
+\r
+      //\r
+      // Increment the offset to point to next DWORD\r
+      //\r
+      Offset += 4;\r
+\r
+      Status = VfBarExisted (\r
+                PciIoDevice,\r
+                Offset,\r
+                &Value,\r
+                &OriginalValue\r
+                );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        return Offset + 4;\r
+      }\r
+\r
+      //\r
+      // Fix the length to support some spefic 64 bit BAR\r
+      //\r
+      Data  = Value;\r
+      Index = 0;\r
+      for (Data = Value; Data != 0; Data >>= 1) {\r
+       Index ++;\r
+      }\r
+      Value |= ((UINT32)(-1) << Index); \r
+\r
+      //\r
+      // Calculate the size of 64bit bar\r
+      //\r
+      PciIoDevice->VfPciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);\r
+\r
+      PciIoDevice->VfPciBar[BarIndex].Length    = PciIoDevice->VfPciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);\r
+      PciIoDevice->VfPciBar[BarIndex].Length    = (~(PciIoDevice->VfPciBar[BarIndex].Length)) + 1;\r
+      PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+\r
+      //\r
+      // Adjust Length\r
+      //\r
+      PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs);\r
+      //\r
+      // Adjust Alignment\r
+      //\r
+      if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+        PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+      }\r
+\r
+      break;\r
+\r
+    //\r
+    // reserved\r
+    //\r
+    default:\r
+      PciIoDevice->VfPciBar[BarIndex].BarType   = PciBarTypeUnknown;\r
+      PciIoDevice->VfPciBar[BarIndex].Length    = (~(Value & Mask)) + 1;\r
+      PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+\r
+      if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+        PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+      }\r
+\r
+      break;\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Check the length again so as to keep compatible with some special bars\r
+  //\r
+  if (PciIoDevice->VfPciBar[BarIndex].Length == 0) {\r
+    PciIoDevice->VfPciBar[BarIndex].BarType     = PciBarTypeUnknown;\r
+    PciIoDevice->VfPciBar[BarIndex].BaseAddress = 0;\r
+    PciIoDevice->VfPciBar[BarIndex].Alignment   = 0;\r
+  }\r
+  \r
+  //\r
+  // Increment number of bar\r
+  //\r
+  return Offset + 4;\r
+}\r
+\r
 /**\r
   Parse PCI bar information and fill them into PCI device instance.\r
 \r
@@ -1349,8 +1634,14 @@ PciParseBar (
       }\r
 \r
       PciIoDevice->PciBar[BarIndex].Length    = (~(Value & Mask)) + 1;\r
-      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-\r
+      if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
+        //\r
+        // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
+        //\r
+        PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
+      } else {\r
+        PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+      }\r
       break;\r
 \r
     //\r
@@ -1386,6 +1677,15 @@ PciParseBar (
                  );\r
 \r
       if (EFI_ERROR (Status)) {\r
+        //\r
+        // the high 32 bit does not claim any BAR, we need to re-check the low 32 bit BAR again\r
+        //\r
+        if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
+          //\r
+          // some device implement MMIO bar with 0 length, need to treat it as no-bar\r
+          //\r
+          PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+        }\r
         return Offset + 4;\r
       }\r
 \r
@@ -1406,7 +1706,14 @@ PciParseBar (
 \r
       PciIoDevice->PciBar[BarIndex].Length    = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);\r
       PciIoDevice->PciBar[BarIndex].Length    = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;\r
-      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+      if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
+        //\r
+        // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
+        //\r
+        PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
+      } else {\r
+        PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+      }\r
 \r
       break;\r
 \r
@@ -1416,8 +1723,14 @@ PciParseBar (
     default:\r
       PciIoDevice->PciBar[BarIndex].BarType   = PciBarTypeUnknown;\r
       PciIoDevice->PciBar[BarIndex].Length    = (~(Value & Mask)) + 1;\r
-      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-\r
+      if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
+        //\r
+        // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
+        //\r
+        PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
+      } else {\r
+        PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+      }\r
       break;\r
     }\r
   }\r
@@ -1570,6 +1883,8 @@ CreatePciIoDevice (
   )\r
 {\r
   PCI_IO_DEVICE *PciIoDevice;\r
+  EFI_PCI_IO_PROTOCOL  *PciIo;\r
+  EFI_STATUS           Status;\r
 \r
   PciIoDevice = AllocateZeroPool (sizeof (PCI_IO_DEVICE));\r
   if (PciIoDevice == NULL) {\r
@@ -1607,6 +1922,162 @@ CreatePciIoDevice (
   InitializePciIoInstance (PciIoDevice);\r
   InitializePciDriverOverrideInstance (PciIoDevice);\r
   InitializePciLoadFile2 (PciIoDevice);\r
+  PciIo = &PciIoDevice->PciIo;\r
+\r
+  //\r
+  // Detect if PCI Express Device\r
+  //\r
+  PciIoDevice->PciExpressCapabilityOffset = 0;\r
+  Status = LocateCapabilityRegBlock (\r
+             PciIoDevice,\r
+             EFI_PCI_CAPABILITY_ID_PCIEXP,\r
+             &PciIoDevice->PciExpressCapabilityOffset,\r
+             NULL\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    PciIoDevice->IsPciExp = TRUE;\r
+  }\r
+\r
+  //\r
+  // Initialize for PCI IOV\r
+  //\r
+\r
+  //\r
+  // Check ARI for function 0 only\r
+  //\r
+  Status = LocatePciExpressCapabilityRegBlock (\r
+             PciIoDevice,\r
+             EFI_PCIE_CAPABILITY_ID_ARI,\r
+             &PciIoDevice->AriCapabilityOffset,\r
+             NULL\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      EFI_D_INFO,\r
+      "PCI-IOV B%x.D%x.F%x - ARI Cap offset - 0x%x\n",\r
+      (UINTN)Bus,\r
+      (UINTN)Device,\r
+      (UINTN)Func,\r
+      (UINTN)PciIoDevice->AriCapabilityOffset\r
+      ));\r
+  }\r
+\r
+  Status = LocatePciExpressCapabilityRegBlock (\r
+             PciIoDevice,\r
+             EFI_PCIE_CAPABILITY_ID_SRIOV,\r
+             &PciIoDevice->SrIovCapabilityOffset,\r
+             NULL\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      EFI_D_INFO,\r
+      "PCI-IOV B%x.D%x.F%x - SRIOV Cap offset - 0x%x\n",\r
+      (UINTN)Bus,\r
+      (UINTN)Device,\r
+      (UINTN)Func,\r
+      (UINTN)PciIoDevice->SrIovCapabilityOffset\r
+      ));\r
+  }\r
+\r
+  Status = LocatePciExpressCapabilityRegBlock (\r
+             PciIoDevice,\r
+             EFI_PCIE_CAPABILITY_ID_MRIOV,\r
+             &PciIoDevice->MrIovCapabilityOffset,\r
+             NULL\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      EFI_D_INFO,\r
+      "PCI-IOV B%x.D%x.F%x - MRIOV Cap offset - 0x%x\n",\r
+      (UINTN)Bus,\r
+      (UINTN)Device,\r
+      (UINTN)Func,\r
+      (UINTN)PciIoDevice->MrIovCapabilityOffset\r
+      ));\r
+  }\r
+\r
+  //\r
+  // Calculate SystemPageSize\r
+  //\r
+  if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {\r
+\r
+    PciIo->Pci.Read (\r
+                 PciIo,\r
+                 EfiPciIoWidthUint32,\r
+                 PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SUPPORTED_PAGE_SIZE,\r
+                 1,\r
+                 &PciIoDevice->SystemPageSize\r
+                 );\r
+    DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - SupportedPageSize - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, PciIoDevice->SystemPageSize));\r
+\r
+    PciIoDevice->SystemPageSize = (PcdGet32(PcdSrIovSystemPageSize) & PciIoDevice->SystemPageSize);\r
+    ASSERT (PciIoDevice->SystemPageSize != 0);\r
+\r
+    PciIo->Pci.Write (\r
+                 PciIo,\r
+                 EfiPciIoWidthUint32,\r
+                 PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SYSTEM_PAGE_SIZE,\r
+                 1,\r
+                 &PciIoDevice->SystemPageSize\r
+                 );\r
+    DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - SystemPageSize - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, PciIoDevice->SystemPageSize));\r
+    //\r
+    // Adjust SystemPageSize for Alignment usage later\r
+    //\r
+    PciIoDevice->SystemPageSize <<= 12;\r
+  }\r
+\r
+  // Calculate BusReservation for PCI IOV\r
+  //\r
+  if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {\r
+    UINT16    VFStride;\r
+    UINT16    FirstVFOffset;\r
+    UINT32    PFRID;\r
+    UINT32    LastVF;\r
+\r
+    //\r
+    // Read First FirstVFOffset, InitialVFs, and VFStride\r
+    //\r
+    PciIo->Pci.Read (\r
+                 PciIo,\r
+                 EfiPciIoWidthUint16,\r
+                 PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_FIRSTVF,\r
+                 1,\r
+                 &FirstVFOffset\r
+                 );\r
+    DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - FirstVFOffset - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, (UINTN)FirstVFOffset));\r
+\r
+    PciIo->Pci.Read (\r
+                 PciIo,\r
+                 EfiPciIoWidthUint16,\r
+                 PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_INITIALVFS,\r
+                 1,\r
+                 &PciIoDevice->InitialVFs\r
+                 );\r
+    DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - InitialVFs - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, (UINTN)PciIoDevice->InitialVFs));\r
+\r
+    PciIo->Pci.Read (\r
+                 PciIo,\r
+                 EfiPciIoWidthUint16,\r
+                 PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_VFSTRIDE,\r
+                 1,\r
+                 &VFStride\r
+                 );\r
+    DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - VFStride - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, (UINTN)VFStride));\r
+\r
+    //\r
+    // Calculate LastVF\r
+    //\r
+    PFRID = EFI_PCI_RID(Bus, Device, Func);\r
+    LastVF = PFRID + FirstVFOffset + (PciIoDevice->InitialVFs - 1) * VFStride;\r
+\r
+    //\r
+    // Calculate ReservedBusNum for this PF\r
+    //\r
+    PciIoDevice->ReservedBusNum = (UINT16)(EFI_PCI_BUS_OF_RID (LastVF) - Bus + 1);\r
+    DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - reserved bus number - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, (UINTN)PciIoDevice->ReservedBusNum));\r
+  }\r
+\r
 \r
   //\r
   // Initialize the reserved resource list\r