Fix bugs in the PCI bus driver to support SR-IOV.

1. Expand the type of Offset in the _PCI_BAR structure from UINT8 to UINT16, because a VF BAR’s offset may be >= 0x100;
2. Enable ARI Capable Hierarchy for SR-IOV devices at earlier time because FirstVFOffset and VFStride of a SR-IOV device may change after its ARI Capable Hierarchy is set;
3. Change type of PcdSrIovSupport, PcdAriSupport, PcdMrIovSupport from FeatureFlag to [FixAtBuild, PcdDynamics], which allows SR-IOV/MR-IOV/ARI feature can be turn on/off dynamically, typically via a setup option.
4. Change PCI bus scan algorithm in PciScanBus() to prevent the case where some ARI extended functions may be skipped in the scan loop.


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10644 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
rsun3 2010-07-13 01:58:47 +00:00
parent 78c0686bde
commit d40483911c
6 changed files with 295 additions and 234 deletions

View File

@ -1,7 +1,7 @@
/** @file /** @file
Header files and data structures needed by PCI Bus module. Header files and data structures needed by PCI Bus module.
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -104,7 +104,7 @@ struct _PCI_BAR {
PCI_BAR_TYPE BarType; PCI_BAR_TYPE BarType;
BOOLEAN Prefetchable; BOOLEAN Prefetchable;
UINT8 MemType; UINT8 MemType;
UINT8 Offset; UINT16 Offset;
}; };
// //

View File

@ -100,13 +100,13 @@
[FeaturePcd] [FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport
gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport
gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport
gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport
gEfiMdeModulePkgTokenSpaceGuid.PcdPciBridgeIoAlignmentProbe gEfiMdeModulePkgTokenSpaceGuid.PcdPciBridgeIoAlignmentProbe
[Pcd] [Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize
gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport
gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport
gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport
# [Event] # [Event]
# ## # ##

View File

@ -1,7 +1,7 @@
/** @file /** @file
Supporting functions implementaion for PCI devices management. Supporting functions implementaion for PCI devices management.
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -215,10 +215,6 @@ RegisterPciDevice (
EFI_PCI_IO_PROTOCOL *PciIo; EFI_PCI_IO_PROTOCOL *PciIo;
UINT8 Data8; UINT8 Data8;
BOOLEAN HasEfiImage; BOOLEAN HasEfiImage;
PCI_IO_DEVICE *ParrentPciIoDevice;
EFI_PCI_IO_PROTOCOL *ParrentPciIo;
UINT16 Data16;
UINT32 Data32;
// //
// Install the pciio protocol, device path protocol // Install the pciio protocol, device path protocol
@ -256,34 +252,6 @@ RegisterPciDevice (
Data8 = PCI_INT_LINE_UNKNOWN; Data8 = PCI_INT_LINE_UNKNOWN;
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Data8); PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Data8);
//
// PCI-IOV programming
//
if (((FeaturePcdGet(PcdAriSupport) & EFI_PCI_IOV_POLICY_ARI) != 0) && (PciIoDevice->AriCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport) & EFI_PCI_IOV_POLICY_SRIOV) != 0) &&
(PciIoDevice->SrIovCapabilityOffset != 0)) {
//
// Check its parrent ARI forwarding capability
//
ParrentPciIoDevice = PciIoDevice->Parent;
ParrentPciIo = &(ParrentPciIoDevice->PciIo);
ParrentPciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ParrentPciIoDevice->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_OFFSET, 1, &Data32);
if ((Data32 & EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING) != 0) {
//
// ARI forward support in bridge, so enable it.
//
ParrentPciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ParrentPciIoDevice->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET, 1, &Data32);
Data32 |= EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING;
ParrentPciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, ParrentPciIoDevice->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET, 1, &Data32);
//
// Set ARI Capable Hierarchy for device
//
PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL, 1, &Data16);
Data16 |= EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL_ARI_HIERARCHY;
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL, 1, &Data16);
}
}
// //
// Process OpRom // Process OpRom
// //

View File

@ -328,11 +328,9 @@ GatherDeviceInfo (
UINTN Offset; UINTN Offset;
UINTN BarIndex; UINTN BarIndex;
PCI_IO_DEVICE *PciIoDevice; PCI_IO_DEVICE *PciIoDevice;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
PciRootBridgeIo = Bridge->PciRootBridgeIo;
PciIoDevice = CreatePciIoDevice ( PciIoDevice = CreatePciIoDevice (
PciRootBridgeIo, Bridge,
Pci, Pci,
Bus, Bus,
Device, Device,
@ -370,7 +368,7 @@ GatherDeviceInfo (
// //
// Parse the SR-IOV VF bars // Parse the SR-IOV VF bars
// //
if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) { if (PcdGetBool (PcdSrIovSupport) && PciIoDevice->SrIovCapabilityOffset != 0) {
for (Offset = PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR0, BarIndex = 0; for (Offset = PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR0, BarIndex = 0;
Offset <= PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR5; Offset <= PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR5;
BarIndex++) { BarIndex++) {
@ -403,16 +401,14 @@ GatherPpbInfo (
IN UINT8 Func IN UINT8 Func
) )
{ {
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
PCI_IO_DEVICE *PciIoDevice; PCI_IO_DEVICE *PciIoDevice;
EFI_STATUS Status; EFI_STATUS Status;
UINT8 Value; UINT8 Value;
EFI_PCI_IO_PROTOCOL *PciIo; EFI_PCI_IO_PROTOCOL *PciIo;
UINT8 Temp; UINT8 Temp;
PciRootBridgeIo = Bridge->PciRootBridgeIo;
PciIoDevice = CreatePciIoDevice ( PciIoDevice = CreatePciIoDevice (
PciRootBridgeIo, Bridge,
Pci, Pci,
Bus, Bus,
Device, Device,
@ -558,12 +554,10 @@ GatherP2CInfo (
IN UINT8 Func IN UINT8 Func
) )
{ {
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
PCI_IO_DEVICE *PciIoDevice; PCI_IO_DEVICE *PciIoDevice;
PciRootBridgeIo = Bridge->PciRootBridgeIo;
PciIoDevice = CreatePciIoDevice ( PciIoDevice = CreatePciIoDevice (
PciRootBridgeIo, Bridge,
Pci, Pci,
Bus, Bus,
Device, Device,
@ -1415,11 +1409,11 @@ PciIovParseVfBar (
// //
// Scan all the BARs anyway // Scan all the BARs anyway
// //
PciIoDevice->VfPciBar[BarIndex].Offset = (UINT8) Offset; PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16) Offset;
return Offset + 4; return Offset + 4;
} }
PciIoDevice->VfPciBar[BarIndex].Offset = (UINT8) Offset; PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16) Offset;
if ((Value & 0x01) != 0) { if ((Value & 0x01) != 0) {
// //
// Device I/Os. Impossible // Device I/Os. Impossible
@ -1905,14 +1899,14 @@ InitializeP2C (
**/ **/
PCI_IO_DEVICE * PCI_IO_DEVICE *
CreatePciIoDevice ( CreatePciIoDevice (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, IN PCI_IO_DEVICE *Bridge,
IN PCI_TYPE00 *Pci, IN PCI_TYPE00 *Pci,
IN UINT8 Bus, IN UINT8 Bus,
IN UINT8 Device, IN UINT8 Device,
IN UINT8 Func IN UINT8 Func
) )
{ {
PCI_IO_DEVICE *PciIoDevice; PCI_IO_DEVICE *PciIoDevice;
EFI_PCI_IO_PROTOCOL *PciIo; EFI_PCI_IO_PROTOCOL *PciIo;
EFI_STATUS Status; EFI_STATUS Status;
@ -1923,7 +1917,7 @@ CreatePciIoDevice (
PciIoDevice->Signature = PCI_IO_DEVICE_SIGNATURE; PciIoDevice->Signature = PCI_IO_DEVICE_SIGNATURE;
PciIoDevice->Handle = NULL; PciIoDevice->Handle = NULL;
PciIoDevice->PciRootBridgeIo = PciRootBridgeIo; PciIoDevice->PciRootBridgeIo = Bridge->PciRootBridgeIo;
PciIoDevice->DevicePath = NULL; PciIoDevice->DevicePath = NULL;
PciIoDevice->BusNumber = Bus; PciIoDevice->BusNumber = Bus;
PciIoDevice->DeviceNumber = Device; PciIoDevice->DeviceNumber = Device;
@ -1968,147 +1962,262 @@ CreatePciIoDevice (
PciIoDevice->IsPciExp = TRUE; PciIoDevice->IsPciExp = TRUE;
} }
// if (PcdGetBool (PcdAriSupport)) {
// Initialize for PCI IOV //
// // Check if the device is an ARI device.
//
Status = LocatePciExpressCapabilityRegBlock (
PciIoDevice,
EFI_PCIE_CAPABILITY_ID_ARI,
&PciIoDevice->AriCapabilityOffset,
NULL
);
if (!EFI_ERROR (Status)) {
//
// We need to enable ARI feature before calculate BusReservation,
// because FirstVFOffset and VFStride may change after that.
//
EFI_PCI_IO_PROTOCOL *ParentPciIo;
UINT32 Data32;
// //
// Check ARI for function 0 only // Check if its parent supports ARI forwarding.
// //
Status = LocatePciExpressCapabilityRegBlock ( ParentPciIo = &Bridge->PciIo;
PciIoDevice, ParentPciIo->Pci.Read (
EFI_PCIE_CAPABILITY_ID_ARI, ParentPciIo,
&PciIoDevice->AriCapabilityOffset, EfiPciIoWidthUint32,
NULL Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_OFFSET,
); 1,
if (!EFI_ERROR (Status)) { &Data32
DEBUG (( );
EFI_D_INFO, if ((Data32 & EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING) != 0) {
"PCI-IOV B%x.D%x.F%x - ARI Cap offset - 0x%x\n", //
(UINTN)Bus, // ARI forward support in bridge, so enable it.
(UINTN)Device, //
(UINTN)Func, ParentPciIo->Pci.Read (
(UINTN)PciIoDevice->AriCapabilityOffset ParentPciIo,
)); EfiPciIoWidthUint32,
} Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET,
1,
&Data32
);
if ((Data32 & EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING) == 0) {
Data32 |= EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING;
ParentPciIo->Pci.Write (
ParentPciIo,
EfiPciIoWidthUint32,
Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET,
1,
&Data32
);
DEBUG ((
EFI_D_INFO,
"PCI B%x.D%x.F%x - ARI forwarding enabled\n",
(UINTN)Bridge->BusNumber,
(UINTN)Bridge->DeviceNumber,
(UINTN)Bridge->FunctionNumber
));
}
}
Status = LocatePciExpressCapabilityRegBlock ( DEBUG ((
PciIoDevice, EFI_D_INFO,
EFI_PCIE_CAPABILITY_ID_SRIOV, "PCI ARI B%x.D%x.F%x - ARI Cap offset - 0x%x\n",
&PciIoDevice->SrIovCapabilityOffset, (UINTN)Bus,
NULL (UINTN)Device,
); (UINTN)Func,
if (!EFI_ERROR (Status)) { (UINTN)PciIoDevice->AriCapabilityOffset
DEBUG (( ));
EFI_D_INFO, }
"PCI-IOV B%x.D%x.F%x - SRIOV Cap offset - 0x%x\n",
(UINTN)Bus,
(UINTN)Device,
(UINTN)Func,
(UINTN)PciIoDevice->SrIovCapabilityOffset
));
}
Status = LocatePciExpressCapabilityRegBlock (
PciIoDevice,
EFI_PCIE_CAPABILITY_ID_MRIOV,
&PciIoDevice->MrIovCapabilityOffset,
NULL
);
if (!EFI_ERROR (Status)) {
DEBUG ((
EFI_D_INFO,
"PCI-IOV B%x.D%x.F%x - MRIOV Cap offset - 0x%x\n",
(UINTN)Bus,
(UINTN)Device,
(UINTN)Func,
(UINTN)PciIoDevice->MrIovCapabilityOffset
));
} }
// //
// Calculate SystemPageSize // Initialization for SR-IOV
// //
if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {
PciIo->Pci.Read ( if (PcdGetBool (PcdSrIovSupport)) {
PciIo, Status = LocatePciExpressCapabilityRegBlock (
EfiPciIoWidthUint32, PciIoDevice,
PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SUPPORTED_PAGE_SIZE, EFI_PCIE_CAPABILITY_ID_SRIOV,
1, &PciIoDevice->SrIovCapabilityOffset,
&PciIoDevice->SystemPageSize NULL
); );
DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - SupportedPageSize - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, PciIoDevice->SystemPageSize)); if (!EFI_ERROR (Status)) {
UINT16 VFStride;
UINT16 FirstVFOffset;
UINT16 Data16;
UINT32 PFRid;
UINT32 LastVF;
PciIoDevice->SystemPageSize = (PcdGet32 (PcdSrIovSystemPageSize) & PciIoDevice->SystemPageSize); //
ASSERT (PciIoDevice->SystemPageSize != 0); // If the SR-IOV device is an ARI device, then Set ARI Capable Hierarchy for the device.
//
if (PcdGetBool (PcdAriSupport) && PciIoDevice->AriCapabilityOffset != 0) {
PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint16,
PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL,
1,
&Data16
);
Data16 |= EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL_ARI_HIERARCHY;
PciIo->Pci.Write (
PciIo,
EfiPciIoWidthUint16,
PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL,
1,
&Data16
);
}
PciIo->Pci.Write ( //
PciIo, // Calculate SystemPageSize
EfiPciIoWidthUint32, //
PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SYSTEM_PAGE_SIZE,
1, PciIo->Pci.Read (
&PciIoDevice->SystemPageSize PciIo,
); EfiPciIoWidthUint32,
DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - SystemPageSize - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, PciIoDevice->SystemPageSize)); PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SUPPORTED_PAGE_SIZE,
// 1,
// Adjust SystemPageSize for Alignment usage later &PciIoDevice->SystemPageSize
// );
PciIoDevice->SystemPageSize <<= 12; DEBUG ((
EFI_D_INFO,
"PCI SR-IOV B%x.D%x.F%x - SupportedPageSize - 0x%x\n",
(UINTN)Bus,
(UINTN)Device,
(UINTN)Func,
PciIoDevice->SystemPageSize
));
PciIoDevice->SystemPageSize = (PcdGet32 (PcdSrIovSystemPageSize) & PciIoDevice->SystemPageSize);
ASSERT (PciIoDevice->SystemPageSize != 0);
PciIo->Pci.Write (
PciIo,
EfiPciIoWidthUint32,
PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SYSTEM_PAGE_SIZE,
1,
&PciIoDevice->SystemPageSize
);
DEBUG ((
EFI_D_INFO,
"PCI SR-IOV B%x.D%x.F%x - SystemPageSize - 0x%x\n",
(UINTN)Bus,
(UINTN)Device,
(UINTN)Func,
PciIoDevice->SystemPageSize
));
//
// Adjust SystemPageSize for Alignment usage later
//
PciIoDevice->SystemPageSize <<= 12;
//
// Calculate BusReservation for PCI IOV
//
//
// Read First FirstVFOffset, InitialVFs, and VFStride
//
PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint16,
PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_FIRSTVF,
1,
&FirstVFOffset
);
DEBUG ((
EFI_D_INFO,
"PCI SR-IOV B%x.D%x.F%x - FirstVFOffset - 0x%x\n",
(UINTN)Bus,
(UINTN)Device,
(UINTN)Func,
(UINTN)FirstVFOffset
));
PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint16,
PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_INITIALVFS,
1,
&PciIoDevice->InitialVFs
);
DEBUG ((
EFI_D_INFO,
"PCI SR-IOV B%x.D%x.F%x - InitialVFs - 0x%x\n",
(UINTN)Bus,
(UINTN)Device,
(UINTN)Func,
(UINTN)PciIoDevice->InitialVFs
));
PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint16,
PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_VFSTRIDE,
1,
&VFStride
);
DEBUG ((
EFI_D_INFO,
"PCI SR-IOV B%x.D%x.F%x - VFStride - 0x%x\n",
(UINTN)Bus,
(UINTN)Device,
(UINTN)Func,
(UINTN)VFStride
));
//
// Calculate LastVF
//
PFRid = EFI_PCI_RID(Bus, Device, Func);
LastVF = PFRid + FirstVFOffset + (PciIoDevice->InitialVFs - 1) * VFStride;
//
// Calculate ReservedBusNum for this PF
//
PciIoDevice->ReservedBusNum = (UINT16)(EFI_PCI_BUS_OF_RID (LastVF) - Bus + 1);
DEBUG ((
EFI_D_INFO,
"PCI SR-IOV B%x.D%x.F%x - reserved bus number - 0x%x\n",
(UINTN)Bus,
(UINTN)Device,
(UINTN)Func,
(UINTN)PciIoDevice->ReservedBusNum
));
DEBUG ((
EFI_D_INFO,
"PCI SR-IOV B%x.D%x.F%x - SRIOV Cap offset - 0x%x\n",
(UINTN)Bus,
(UINTN)Device,
(UINTN)Func,
(UINTN)PciIoDevice->SrIovCapabilityOffset
));
}
} }
// Calculate BusReservation for PCI IOV if (PcdGetBool (PcdMrIovSupport)) {
// Status = LocatePciExpressCapabilityRegBlock (
if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) { PciIoDevice,
UINT16 VFStride; EFI_PCIE_CAPABILITY_ID_MRIOV,
UINT16 FirstVFOffset; &PciIoDevice->MrIovCapabilityOffset,
UINT32 PFRid; NULL
UINT32 LastVF; );
if (!EFI_ERROR (Status)) {
// DEBUG ((
// Read First FirstVFOffset, InitialVFs, and VFStride EFI_D_INFO,
// "PCI MR-IOV B%x.D%x.F%x - MRIOV Cap offset - 0x%x\n",
PciIo->Pci.Read ( (UINTN)Bus,
PciIo, (UINTN)Device,
EfiPciIoWidthUint16, (UINTN)Func,
PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_FIRSTVF, (UINTN)PciIoDevice->MrIovCapabilityOffset
1, ));
&FirstVFOffset }
);
DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - FirstVFOffset - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, (UINTN)FirstVFOffset));
PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint16,
PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_INITIALVFS,
1,
&PciIoDevice->InitialVFs
);
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));
PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint16,
PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_VFSTRIDE,
1,
&VFStride
);
DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - VFStride - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, (UINTN)VFStride));
//
// Calculate LastVF
//
PFRid = EFI_PCI_RID(Bus, Device, Func);
LastVF = PFRid + FirstVFOffset + (PciIoDevice->InitialVFs - 1) * VFStride;
//
// Calculate ReservedBusNum for this PF
//
PciIoDevice->ReservedBusNum = (UINT16)(EFI_PCI_BUS_OF_RID (LastVF) - Bus + 1);
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));
} }
// //
// Initialize the reserved resource list // Initialize the reserved resource list
// //

View File

@ -1,7 +1,7 @@
/** @file /** @file
PCI emumeration support functions declaration for PCI Bus module. PCI emumeration support functions declaration for PCI Bus module.
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -364,7 +364,7 @@ InitializeP2C (
Create and initiliaze general PCI I/O device instance for Create and initiliaze general PCI I/O device instance for
PCI device/bridge device/hotplug bridge device. PCI device/bridge device/hotplug bridge device.
@param PciRootBridgeIo Pointer to instance of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. @param Bridge Parent bridge instance.
@param Pci Input Pci information block. @param Pci Input Pci information block.
@param Bus Device Bus NO. @param Bus Device Bus NO.
@param Device Device device NO. @param Device Device device NO.
@ -375,7 +375,7 @@ InitializeP2C (
**/ **/
PCI_IO_DEVICE * PCI_IO_DEVICE *
CreatePciIoDevice ( CreatePciIoDevice (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, IN PCI_IO_DEVICE *Bridge,
IN PCI_TYPE00 *Pci, IN PCI_TYPE00 *Pci,
IN UINT8 Bus, IN UINT8 Bus,
IN UINT8 Device, IN UINT8 Device,

View File

@ -1,7 +1,7 @@
/** @file /** @file
Internal library implementation for PCI Bus module. Internal library implementation for PCI Bus module.
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -738,50 +738,43 @@ PciScanBus (
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
if (Func == 0) {
//
// Skip sub functions, this is not a multi function device
//
Func = PCI_MAX_FUNC;
}
continue; continue;
} }
DEBUG((EFI_D_INFO, "Found DEV(%02d,%02d,%02d)\n", StartBusNumber, Device, Func )); DEBUG((EFI_D_INFO, "Found DEV(%02d,%02d,%02d)\n", StartBusNumber, Device, Func ));
//
// Get the PCI device information
//
Status = PciSearchDevice (
Bridge,
&Pci,
StartBusNumber,
Device,
Func,
&PciDevice
);
ASSERT (!EFI_ERROR (Status));
PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0);
if (!IS_PCI_BRIDGE (&Pci)) {
//
// PCI bridges will be called later
// Here just need for PCI device or PCI to cardbus controller
// EfiPciBeforeChildBusEnumeration for PCI Device Node
//
PreprocessController (
PciDevice,
PciDevice->BusNumber,
PciDevice->DeviceNumber,
PciDevice->FunctionNumber,
EfiPciBeforeChildBusEnumeration
);
}
if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
//
// Get the PCI device information
//
Status = PciSearchDevice (
Bridge,
&Pci,
StartBusNumber,
Device,
Func,
&PciDevice
);
ASSERT (!EFI_ERROR (Status));
PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0);
if (!IS_PCI_BRIDGE (&Pci)) {
//
// PCI bridges will be called later
// Here just need for PCI device or PCI to cardbus controller
// EfiPciBeforeChildBusEnumeration for PCI Device Node
//
PreprocessController (
PciDevice,
PciDevice->BusNumber,
PciDevice->DeviceNumber,
PciDevice->FunctionNumber,
EfiPciBeforeChildBusEnumeration
);
}
// //
// For Pci Hotplug controller devcie only // For Pci Hotplug controller devcie only
// //
@ -976,18 +969,9 @@ PciScanBus (
} else { } else {
// //
// It is device. Check PCI IOV for Bus reservation // It is device. Check PCI IOV for Bus reservation
//
if (PciDevice == NULL) {
//
// No PciDevice found, conitue Scan
//
continue;
}
//
// Go through each function, just reserve the MAX ReservedBusNum for one device // Go through each function, just reserve the MAX ReservedBusNum for one device
// //
if ((PciDevice->AriCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) { if (PcdGetBool (PcdSrIovSupport) && PciDevice->SrIovCapabilityOffset != 0) {
if (TempReservedBusNum < PciDevice->ReservedBusNum) { if (TempReservedBusNum < PciDevice->ReservedBusNum) {
(*SubBusNumber) = (UINT8)((*SubBusNumber) + PciDevice->ReservedBusNum - TempReservedBusNum); (*SubBusNumber) = (UINT8)((*SubBusNumber) + PciDevice->ReservedBusNum - TempReservedBusNum);