+ 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