]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
Update some progress codes name per the PI Spec, 1.2 Errata B.
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciEnumeratorSupport.c
index adf36a5b77a2d4cd22af98bdec95e92fc1bdd2e6..2dd5889afcd6b216468a9d08584e51b9ecf03feb 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   PCI emumeration support functions implementation for PCI Bus module.\r
 \r
-Copyright (c) 2006 - 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
@@ -328,11 +328,9 @@ GatherDeviceInfo (
   UINTN                           Offset;\r
   UINTN                           BarIndex;\r
   PCI_IO_DEVICE                   *PciIoDevice;\r
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
 \r
-  PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
   PciIoDevice = CreatePciIoDevice (\r
-                  PciRootBridgeIo,\r
+                  Bridge,\r
                   Pci,\r
                   Bus,\r
                   Device,\r
@@ -370,7 +368,7 @@ GatherDeviceInfo (
   //\r
   // Parse the SR-IOV VF bars\r
   //\r
-  if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {\r
+  if (PcdGetBool (PcdSrIovSupport) && PciIoDevice->SrIovCapabilityOffset != 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
@@ -403,16 +401,14 @@ GatherPpbInfo (
   IN UINT8                            Func\r
   )\r
 {\r
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
   PCI_IO_DEVICE                   *PciIoDevice;\r
   EFI_STATUS                      Status;\r
   UINT8                           Value;\r
   EFI_PCI_IO_PROTOCOL             *PciIo;\r
   UINT8                           Temp;\r
 \r
-  PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
   PciIoDevice = CreatePciIoDevice (\r
-                  PciRootBridgeIo,\r
+                  Bridge,\r
                   Pci,\r
                   Bus,\r
                   Device,\r
@@ -558,12 +554,10 @@ GatherP2CInfo (
   IN UINT8                            Func\r
   )\r
 {\r
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
   PCI_IO_DEVICE                   *PciIoDevice;\r
 \r
-  PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
   PciIoDevice = CreatePciIoDevice (\r
-                  PciRootBridgeIo,\r
+                  Bridge,\r
                   Pci,\r
                   Bus,\r
                   Device,\r
@@ -916,9 +910,10 @@ PciSetDeviceAttribute (
                   EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM         |\r
                   EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
 \r
-    if ((Attributes & EFI_PCI_IO_ATTRIBUTE_IO) != 0) {\r
-      Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;\r
-      Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
+    if (IS_PCI_LPC (&PciIoDevice->Pci)) {\r
+        Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;\r
+        Attributes |= (mReserveIsaAliases ? EFI_PCI_IO_ATTRIBUTE_ISA_IO : \\r
+                                            EFI_PCI_IO_ATTRIBUTE_ISA_IO_16);\r
     }\r
 \r
     if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
@@ -927,6 +922,14 @@ PciSetDeviceAttribute (
       //\r
       Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;\r
       Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;\r
+\r
+      if (mReserveVgaAliases) {\r
+        Attributes &= ~(UINT64)(EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | \\r
+                                EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16);\r
+      } else {\r
+        Attributes &= ~(UINT64)(EFI_PCI_IO_ATTRIBUTE_VGA_IO | \\r
+                                EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO);\r
+      }\r
     } else {\r
 \r
       if (IS_PCI_IDE (&PciIoDevice->Pci)) {\r
@@ -936,7 +939,8 @@ PciSetDeviceAttribute (
 \r
       if (IS_PCI_VGA (&PciIoDevice->Pci)) {\r
         Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;\r
-        Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;\r
+        Attributes |= (mReserveVgaAliases ? EFI_PCI_IO_ATTRIBUTE_VGA_IO : \\r
+                                            EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);\r
       }\r
     }\r
 \r
@@ -946,6 +950,15 @@ PciSetDeviceAttribute (
                                EFI_PCI_IO_ATTRIBUTE_BUS_MASTER );\r
 \r
   } else {\r
+    //\r
+    // When this attribute is clear, the RomImage and RomSize fields in the PCI IO were\r
+    // initialized based on the PCI option ROM found through the ROM BAR of the PCI controller.\r
+    // When this attribute is set, the PCI option ROM described by the RomImage and RomSize\r
+    // fields is not from the the ROM BAR of the PCI controller.\r
+    //\r
+    if (!PciIoDevice->EmbeddedRom) {\r
+      Attributes |= EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM;\r
+    }\r
     PciIoDevice->Attributes = Attributes;\r
   }\r
 }\r
@@ -1060,6 +1073,9 @@ DetermineDeviceAttribute (
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
+    PciIoDevice->Supports |= (EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE |\r
+                              EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM);\r
+\r
   } else {\r
 \r
     //\r
@@ -1415,12 +1431,12 @@ PciIovParseVfBar (
     //\r
     // Scan all the BARs anyway\r
     //\r
-    PciIoDevice->VfPciBar[BarIndex].Offset = (UINT8) Offset;\r
+    PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16) Offset;\r
     return Offset + 4;\r
   }\r
 \r
-  PciIoDevice->VfPciBar[BarIndex].Offset = (UINT8) Offset;\r
-  if (Value & 0x01) {\r
+  PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16) Offset;\r
+  if ((Value & 0x01) != 0) {\r
     //\r
     // Device I/Os. Impossible\r
     //\r
@@ -1439,7 +1455,7 @@ PciIovParseVfBar (
     //memory space; anywhere in 32 bit address space\r
     //\r
     case 0x00:\r
-      if (Value & 0x08) {\r
+      if ((Value & 0x08) != 0) {\r
         PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem32;\r
       } else {\r
         PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem32;\r
@@ -1465,7 +1481,7 @@ PciIovParseVfBar (
     // memory space; anywhere in 64 bit address space\r
     //\r
     case 0x04:\r
-      if (Value & 0x08) {\r
+      if ((Value & 0x08) != 0) {\r
         PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem64;\r
       } else {\r
         PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem64;\r
@@ -1905,14 +1921,14 @@ InitializeP2C (
 **/\r
 PCI_IO_DEVICE *\r
 CreatePciIoDevice (\r
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,\r
+  IN PCI_IO_DEVICE                    *Bridge,\r
   IN PCI_TYPE00                       *Pci,\r
   IN UINT8                            Bus,\r
   IN UINT8                            Device,\r
   IN UINT8                            Func\r
   )\r
 {\r
-  PCI_IO_DEVICE *PciIoDevice;\r
+  PCI_IO_DEVICE        *PciIoDevice;\r
   EFI_PCI_IO_PROTOCOL  *PciIo;\r
   EFI_STATUS           Status;\r
 \r
@@ -1923,7 +1939,7 @@ CreatePciIoDevice (
 \r
   PciIoDevice->Signature        = PCI_IO_DEVICE_SIGNATURE;\r
   PciIoDevice->Handle           = NULL;\r
-  PciIoDevice->PciRootBridgeIo  = PciRootBridgeIo;\r
+  PciIoDevice->PciRootBridgeIo  = Bridge->PciRootBridgeIo;\r
   PciIoDevice->DevicePath       = NULL;\r
   PciIoDevice->BusNumber        = Bus;\r
   PciIoDevice->DeviceNumber     = Device;\r
@@ -1968,146 +1984,261 @@ CreatePciIoDevice (
     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
+  if (PcdGetBool (PcdAriSupport)) {\r
+    //\r
+    // Check if the device is an ARI device.\r
+    //\r
+    Status = LocatePciExpressCapabilityRegBlock (\r
+               PciIoDevice,\r
+               EFI_PCIE_CAPABILITY_ID_ARI,\r
+               &PciIoDevice->AriCapabilityOffset,\r
+               NULL\r
+               );\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // We need to enable ARI feature before calculate BusReservation,\r
+      // because FirstVFOffset and VFStride may change after that.\r
+      //\r
+      EFI_PCI_IO_PROTOCOL  *ParentPciIo;\r
+      UINT32               Data32;\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
+      // Check if its parent supports ARI forwarding.\r
+      //\r
+      ParentPciIo = &Bridge->PciIo;\r
+      ParentPciIo->Pci.Read (\r
+                          ParentPciIo, \r
+                          EfiPciIoWidthUint32,\r
+                          Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_OFFSET,\r
+                          1,\r
+                          &Data32\r
+                          );\r
+      if ((Data32 & EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING) != 0) {\r
+        //\r
+        // ARI forward support in bridge, so enable it.\r
+        //\r
+        ParentPciIo->Pci.Read (\r
+                            ParentPciIo,\r
+                            EfiPciIoWidthUint32,\r
+                            Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET,\r
+                            1,\r
+                            &Data32\r
+                            );\r
+        if ((Data32 & EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING) == 0) {\r
+          Data32 |= EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING;\r
+          ParentPciIo->Pci.Write (\r
+                              ParentPciIo,\r
+                              EfiPciIoWidthUint32,\r
+                              Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET,\r
+                              1,\r
+                              &Data32\r
+                              );\r
+          DEBUG ((\r
+            EFI_D_INFO,\r
+            "PCI B%x.D%x.F%x - ARI forwarding enabled\n",\r
+            (UINTN)Bridge->BusNumber,\r
+            (UINTN)Bridge->DeviceNumber,\r
+            (UINTN)Bridge->FunctionNumber\r
+            ));\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
+      DEBUG ((\r
+        EFI_D_INFO,\r
+        "PCI ARI 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
 \r
   //\r
-  // Calculate SystemPageSize\r
+  // Initialization for SR-IOV\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
+  if (PcdGetBool (PcdSrIovSupport)) {\r
+    Status = LocatePciExpressCapabilityRegBlock (\r
+               PciIoDevice,\r
+               EFI_PCIE_CAPABILITY_ID_SRIOV,\r
+               &PciIoDevice->SrIovCapabilityOffset,\r
+               NULL\r
+               );\r
+    if (!EFI_ERROR (Status)) {\r
+      UINT16    VFStride;\r
+      UINT16    FirstVFOffset;\r
+      UINT16    Data16;\r
+      UINT32    PFRid;\r
+      UINT32    LastVF;\r
 \r
-    PciIoDevice->SystemPageSize = (PcdGet32(PcdSrIovSystemPageSize) & PciIoDevice->SystemPageSize);\r
-    ASSERT (PciIoDevice->SystemPageSize != 0);\r
+      //\r
+      // If the SR-IOV device is an ARI device, then Set ARI Capable Hierarchy for the device.\r
+      //\r
+      if (PcdGetBool (PcdAriSupport) && PciIoDevice->AriCapabilityOffset != 0) {\r
+        PciIo->Pci.Read (\r
+                     PciIo,\r
+                     EfiPciIoWidthUint16,\r
+                     PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL,\r
+                     1,\r
+                     &Data16\r
+                     );\r
+        Data16 |= EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL_ARI_HIERARCHY;\r
+        PciIo->Pci.Write (\r
+                     PciIo,\r
+                     EfiPciIoWidthUint16,\r
+                     PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL,\r
+                     1,\r
+                     &Data16\r
+                     );\r
+      }\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 SystemPageSize\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
+      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 ((\r
+        EFI_D_INFO,\r
+        "PCI SR-IOV B%x.D%x.F%x - SupportedPageSize - 0x%x\n",\r
+        (UINTN)Bus,\r
+        (UINTN)Device,\r
+        (UINTN)Func,\r
+        PciIoDevice->SystemPageSize\r
+        ));\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 ((\r
+        EFI_D_INFO,\r
+        "PCI SR-IOV B%x.D%x.F%x - SystemPageSize - 0x%x\n",\r
+        (UINTN)Bus,\r
+        (UINTN)Device,\r
+        (UINTN)Func,\r
+        PciIoDevice->SystemPageSize\r
+        ));\r
+      //\r
+      // Adjust SystemPageSize for Alignment usage later\r
+      //\r
+      PciIoDevice->SystemPageSize <<= 12;\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
+      // Calculate BusReservation for PCI IOV\r
+      //\r
 \r
-    //\r
-    // Calculate LastVF\r
-    //\r
-    PFRID = EFI_PCI_RID(Bus, Device, Func);\r
-    LastVF = PFRID + FirstVFOffset + (PciIoDevice->InitialVFs - 1) * VFStride;\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 ((\r
+        EFI_D_INFO,\r
+        "PCI SR-IOV B%x.D%x.F%x - FirstVFOffset - 0x%x\n",\r
+        (UINTN)Bus,\r
+        (UINTN)Device,\r
+        (UINTN)Func,\r
+        (UINTN)FirstVFOffset\r
+        ));\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 ((\r
+        EFI_D_INFO,\r
+        "PCI SR-IOV B%x.D%x.F%x - InitialVFs - 0x%x\n",\r
+        (UINTN)Bus,\r
+        (UINTN)Device,\r
+        (UINTN)Func,\r
+        (UINTN)PciIoDevice->InitialVFs\r
+        ));\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 ((\r
+        EFI_D_INFO,\r
+        "PCI SR-IOV B%x.D%x.F%x - VFStride - 0x%x\n",\r
+        (UINTN)Bus,\r
+        (UINTN)Device,\r
+        (UINTN)Func,\r
+        (UINTN)VFStride\r
+        ));\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
+      // 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 ((\r
+        EFI_D_INFO,\r
+        "PCI SR-IOV B%x.D%x.F%x - reserved bus number - 0x%x\n",\r
+        (UINTN)Bus,\r
+        (UINTN)Device,\r
+        (UINTN)Func,\r
+        (UINTN)PciIoDevice->ReservedBusNum\r
+        ));\r
+\r
+      DEBUG ((\r
+        EFI_D_INFO,\r
+        "PCI SR-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
 \r
+  if (PcdGetBool (PcdMrIovSupport)) {\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 MR-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
   //\r
   // Initialize the reserved resource list\r