mirror of https://github.com/acidanthera/audk.git
add SR-IOV support in EDK II.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9269 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
fd53905e69
commit
7fc72ecb0d
|
@ -50,6 +50,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
typedef struct _PCI_IO_DEVICE PCI_IO_DEVICE;
|
||||
typedef struct _PCI_BAR PCI_BAR;
|
||||
|
||||
#define EFI_PCI_RID(Bus, Device, Function) (((UINT32)Bus << 8) + ((UINT32)Device << 3) + (UINT32)Function)
|
||||
#define EFI_PCI_BUS_OF_RID(RID) ((UINT32)RID >> 8)
|
||||
|
||||
#define EFI_PCI_IOV_POLICY_ARI 0x0001
|
||||
#define EFI_PCI_IOV_POLICY_SRIOV 0x0002
|
||||
#define EFI_PCI_IOV_POLICY_MRIOV 0x0004
|
||||
|
||||
typedef enum {
|
||||
PciBarTypeUnknown = 0,
|
||||
PciBarTypeIo16,
|
||||
|
@ -248,7 +255,17 @@ struct _PCI_IO_DEVICE {
|
|||
EFI_HPC_PADDING_ATTRIBUTES PaddingAttributes;
|
||||
|
||||
BOOLEAN IsPciExp;
|
||||
|
||||
//
|
||||
// For SR-IOV
|
||||
//
|
||||
UINT8 PciExpressCapabilityOffset;
|
||||
UINT32 AriCapabilityOffset;
|
||||
UINT32 SrIovCapabilityOffset;
|
||||
UINT32 MrIovCapabilityOffset;
|
||||
PCI_BAR VfPciBar[PCI_MAX_BAR];
|
||||
UINT32 SystemPageSize;
|
||||
UINT16 InitialVFs;
|
||||
UINT16 ReservedBusNum;
|
||||
};
|
||||
|
||||
#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \
|
||||
|
|
|
@ -101,7 +101,12 @@
|
|||
|
||||
[FeaturePcd.common]
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSrIovSupport
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdAriSupport
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdMrIovSupport
|
||||
|
||||
[FixedPcd.common]
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize
|
||||
# [Event]
|
||||
# ##
|
||||
# # Notify event set by CreateEventForHpc () for PCI Hot Plug controller.
|
||||
|
|
|
@ -179,3 +179,70 @@ LocateCapabilityRegBlock (
|
|||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
Locate PciExpress capability register block per capability ID.
|
||||
|
||||
@param PciIoDevice A pointer to the PCI_IO_DEVICE.
|
||||
@param CapId The capability ID.
|
||||
@param Offset A pointer to the offset returned.
|
||||
@param NextRegBlock A pointer to the next block returned.
|
||||
|
||||
@retval EFI_SUCCESS Successfuly located capability register block.
|
||||
@retval EFI_UNSUPPORTED Pci device does not support capability.
|
||||
@retval EFI_NOT_FOUND Pci device support but can not find register block.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
LocatePciExpressCapabilityRegBlock (
|
||||
IN PCI_IO_DEVICE *PciIoDevice,
|
||||
IN UINT16 CapId,
|
||||
IN OUT UINT32 *Offset,
|
||||
OUT UINT32 *NextRegBlock OPTIONAL
|
||||
)
|
||||
{
|
||||
UINT32 CapabilityPtr;
|
||||
UINT32 CapabilityEntry;
|
||||
UINT16 CapabilityID;
|
||||
|
||||
//
|
||||
// To check the capability of this device supports
|
||||
//
|
||||
if (!PciIoDevice->IsPciExp) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (*Offset != 0) {
|
||||
CapabilityPtr = *Offset;
|
||||
} else {
|
||||
CapabilityPtr = EFI_PCIE_CAPABILITY_BASE_OFFSET;
|
||||
}
|
||||
|
||||
while (CapabilityPtr != 0) {
|
||||
//
|
||||
// Mask it to DWORD alignment per PCI spec
|
||||
//
|
||||
CapabilityPtr &= 0xFFC;
|
||||
PciIoDevice->PciIo.Pci.Read (
|
||||
&PciIoDevice->PciIo,
|
||||
EfiPciIoWidthUint32,
|
||||
CapabilityPtr,
|
||||
1,
|
||||
&CapabilityEntry
|
||||
);
|
||||
|
||||
CapabilityID = (UINT16) CapabilityEntry;
|
||||
|
||||
if (CapabilityID == CapId) {
|
||||
*Offset = CapabilityPtr;
|
||||
if (NextRegBlock != NULL) {
|
||||
*NextRegBlock = (CapabilityEntry >> 20) & 0xFFF;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
CapabilityPtr = (CapabilityEntry >> 20) & 0xFFF;
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
|
|
@ -118,6 +118,27 @@ LocateCapabilityRegBlock (
|
|||
OUT UINT8 *NextRegBlock OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Locate PciExpress capability register block per capability ID.
|
||||
|
||||
@param PciIoDevice A pointer to the PCI_IO_DEVICE.
|
||||
@param CapId The capability ID.
|
||||
@param Offset A pointer to the offset returned.
|
||||
@param NextRegBlock A pointer to the next block returned.
|
||||
|
||||
@retval EFI_SUCCESS Successfuly located capability register block.
|
||||
@retval EFI_UNSUPPORTED Pci device does not support capability.
|
||||
@retval EFI_NOT_FOUND Pci device support but can not find register block.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
LocatePciExpressCapabilityRegBlock (
|
||||
IN PCI_IO_DEVICE *PciIoDevice,
|
||||
IN UINT16 CapId,
|
||||
IN OUT UINT32 *Offset,
|
||||
OUT UINT32 *NextRegBlock OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Macro that reads command register.
|
||||
|
||||
|
|
|
@ -215,6 +215,10 @@ RegisterPciDevice (
|
|||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
UINT8 Data8;
|
||||
BOOLEAN HasEfiImage;
|
||||
PCI_IO_DEVICE *ParrentPciIoDevice;
|
||||
EFI_PCI_IO_PROTOCOL *ParrentPciIo;
|
||||
UINT16 Data16;
|
||||
UINT32 Data32;
|
||||
|
||||
//
|
||||
// Install the pciio protocol, device path protocol
|
||||
|
@ -251,7 +255,35 @@ RegisterPciDevice (
|
|||
PciIo = &(PciIoDevice->PciIo);
|
||||
Data8 = PCI_INT_LINE_UNKNOWN;
|
||||
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) {
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
|
|
@ -367,6 +367,16 @@ GatherDeviceInfo (
|
|||
Offset = PciParseBar (PciIoDevice, Offset, BarIndex);
|
||||
}
|
||||
|
||||
//
|
||||
// Parse the SR-IOV VF bars
|
||||
//
|
||||
if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {
|
||||
for (Offset = PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR0, BarIndex = 0;
|
||||
Offset <= PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR5;
|
||||
BarIndex++) {
|
||||
Offset = PciIovParseVfBar (PciIoDevice, Offset, BarIndex);
|
||||
}
|
||||
}
|
||||
return PciIoDevice;
|
||||
}
|
||||
|
||||
|
@ -597,6 +607,80 @@ CreatePciDevicePath (
|
|||
return PciIoDevice->DevicePath;
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether the PCI IOV VF bar is existed or not.
|
||||
|
||||
@param PciIoDevice A pointer to the PCI_IO_DEVICE.
|
||||
@param Offset The offset.
|
||||
@param BarLengthValue The bar length value returned.
|
||||
@param OriginalBarValue The original bar value returned.
|
||||
|
||||
@retval EFI_NOT_FOUND The bar doesn't exist.
|
||||
@retval EFI_SUCCESS The bar exist.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
VfBarExisted (
|
||||
IN PCI_IO_DEVICE *PciIoDevice,
|
||||
IN UINTN Offset,
|
||||
OUT UINT32 *BarLengthValue,
|
||||
OUT UINT32 *OriginalBarValue
|
||||
)
|
||||
{
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
UINT32 OriginalValue;
|
||||
UINT32 Value;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
//
|
||||
// Ensure it is called properly
|
||||
//
|
||||
ASSERT (PciIoDevice->SrIovCapabilityOffset != 0);
|
||||
if (PciIoDevice->SrIovCapabilityOffset == 0) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
PciIo = &PciIoDevice->PciIo;
|
||||
|
||||
//
|
||||
// Preserve the original value
|
||||
//
|
||||
|
||||
PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &OriginalValue);
|
||||
|
||||
//
|
||||
// Raise TPL to high level to disable timer interrupt while the BAR is probed
|
||||
//
|
||||
OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
||||
|
||||
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &gAllOne);
|
||||
PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &Value);
|
||||
|
||||
//
|
||||
// Write back the original value
|
||||
//
|
||||
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &OriginalValue);
|
||||
|
||||
//
|
||||
// Restore TPL to its original level
|
||||
//
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
if (BarLengthValue != NULL) {
|
||||
*BarLengthValue = Value;
|
||||
}
|
||||
|
||||
if (OriginalBarValue != NULL) {
|
||||
*OriginalBarValue = OriginalValue;
|
||||
}
|
||||
|
||||
if (Value == 0) {
|
||||
return EFI_NOT_FOUND;
|
||||
} else {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether the bar is existed or not.
|
||||
|
||||
|
@ -1249,6 +1333,207 @@ SetNewAlign (
|
|||
return ;
|
||||
}
|
||||
|
||||
/**
|
||||
Parse PCI IOV VF bar information and fill them into PCI device instance.
|
||||
|
||||
@param PciIoDevice Pci device instance.
|
||||
@param Offset Bar offset.
|
||||
@param BarIndex Bar index.
|
||||
|
||||
@return Next bar offset.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
PciIovParseVfBar (
|
||||
IN PCI_IO_DEVICE *PciIoDevice,
|
||||
IN UINTN Offset,
|
||||
IN UINTN BarIndex
|
||||
)
|
||||
{
|
||||
UINT32 Value;
|
||||
UINT64 BarValue64;
|
||||
UINT32 OriginalValue;
|
||||
UINT32 Mask;
|
||||
UINT32 Data;
|
||||
UINT8 Index;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Ensure it is called properly
|
||||
//
|
||||
ASSERT (PciIoDevice->SrIovCapabilityOffset != 0);
|
||||
if (PciIoDevice->SrIovCapabilityOffset == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
OriginalValue = 0;
|
||||
Value = 0;
|
||||
BarValue64 = 0;
|
||||
|
||||
Status = VfBarExisted (
|
||||
PciIoDevice,
|
||||
Offset,
|
||||
&Value,
|
||||
&OriginalValue
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
PciIoDevice->VfPciBar[BarIndex].BaseAddress = 0;
|
||||
PciIoDevice->VfPciBar[BarIndex].Length = 0;
|
||||
PciIoDevice->VfPciBar[BarIndex].Alignment = 0;
|
||||
|
||||
//
|
||||
// Scan all the BARs anyway
|
||||
//
|
||||
PciIoDevice->VfPciBar[BarIndex].Offset = (UINT8) Offset;
|
||||
return Offset + 4;
|
||||
}
|
||||
|
||||
PciIoDevice->VfPciBar[BarIndex].Offset = (UINT8) Offset;
|
||||
if (Value & 0x01) {
|
||||
//
|
||||
// Device I/Os. Impossible
|
||||
//
|
||||
ASSERT (FALSE);
|
||||
return Offset + 4;
|
||||
|
||||
} else {
|
||||
|
||||
Mask = 0xfffffff0;
|
||||
|
||||
PciIoDevice->VfPciBar[BarIndex].BaseAddress = OriginalValue & Mask;
|
||||
|
||||
switch (Value & 0x07) {
|
||||
|
||||
//
|
||||
//memory space; anywhere in 32 bit address space
|
||||
//
|
||||
case 0x00:
|
||||
if (Value & 0x08) {
|
||||
PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem32;
|
||||
} else {
|
||||
PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem32;
|
||||
}
|
||||
|
||||
PciIoDevice->VfPciBar[BarIndex].Length = (~(Value & Mask)) + 1;
|
||||
PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;
|
||||
|
||||
//
|
||||
// Adjust Length
|
||||
//
|
||||
PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs);
|
||||
//
|
||||
// Adjust Alignment
|
||||
//
|
||||
if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {
|
||||
PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
//
|
||||
// memory space; anywhere in 64 bit address space
|
||||
//
|
||||
case 0x04:
|
||||
if (Value & 0x08) {
|
||||
PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem64;
|
||||
} else {
|
||||
PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem64;
|
||||
}
|
||||
|
||||
//
|
||||
// According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar
|
||||
// is regarded as an extension for the first bar. As a result
|
||||
// the sizing will be conducted on combined 64 bit value
|
||||
// Here just store the masked first 32bit value for future size
|
||||
// calculation
|
||||
//
|
||||
PciIoDevice->VfPciBar[BarIndex].Length = Value & Mask;
|
||||
PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;
|
||||
|
||||
if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {
|
||||
PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Increment the offset to point to next DWORD
|
||||
//
|
||||
Offset += 4;
|
||||
|
||||
Status = VfBarExisted (
|
||||
PciIoDevice,
|
||||
Offset,
|
||||
&Value,
|
||||
&OriginalValue
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Offset + 4;
|
||||
}
|
||||
|
||||
//
|
||||
// Fix the length to support some spefic 64 bit BAR
|
||||
//
|
||||
Data = Value;
|
||||
Index = 0;
|
||||
for (Data = Value; Data != 0; Data >>= 1) {
|
||||
Index ++;
|
||||
}
|
||||
Value |= ((UINT32)(-1) << Index);
|
||||
|
||||
//
|
||||
// Calculate the size of 64bit bar
|
||||
//
|
||||
PciIoDevice->VfPciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);
|
||||
|
||||
PciIoDevice->VfPciBar[BarIndex].Length = PciIoDevice->VfPciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);
|
||||
PciIoDevice->VfPciBar[BarIndex].Length = (~(PciIoDevice->VfPciBar[BarIndex].Length)) + 1;
|
||||
PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;
|
||||
|
||||
//
|
||||
// Adjust Length
|
||||
//
|
||||
PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs);
|
||||
//
|
||||
// Adjust Alignment
|
||||
//
|
||||
if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {
|
||||
PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
//
|
||||
// reserved
|
||||
//
|
||||
default:
|
||||
PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeUnknown;
|
||||
PciIoDevice->VfPciBar[BarIndex].Length = (~(Value & Mask)) + 1;
|
||||
PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;
|
||||
|
||||
if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {
|
||||
PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check the length again so as to keep compatible with some special bars
|
||||
//
|
||||
if (PciIoDevice->VfPciBar[BarIndex].Length == 0) {
|
||||
PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeUnknown;
|
||||
PciIoDevice->VfPciBar[BarIndex].BaseAddress = 0;
|
||||
PciIoDevice->VfPciBar[BarIndex].Alignment = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Increment number of bar
|
||||
//
|
||||
return Offset + 4;
|
||||
}
|
||||
|
||||
/**
|
||||
Parse PCI bar information and fill them into PCI device instance.
|
||||
|
||||
|
@ -1349,8 +1634,14 @@ PciParseBar (
|
|||
}
|
||||
|
||||
PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;
|
||||
PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
|
||||
|
||||
if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {
|
||||
//
|
||||
// Force minimum 4KByte alignment for Virtualization technology for Directed I/O
|
||||
//
|
||||
PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);
|
||||
} else {
|
||||
PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
|
@ -1386,6 +1677,15 @@ PciParseBar (
|
|||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// the high 32 bit does not claim any BAR, we need to re-check the low 32 bit BAR again
|
||||
//
|
||||
if (PciIoDevice->PciBar[BarIndex].Length == 0) {
|
||||
//
|
||||
// some device implement MMIO bar with 0 length, need to treat it as no-bar
|
||||
//
|
||||
PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;
|
||||
}
|
||||
return Offset + 4;
|
||||
}
|
||||
|
||||
|
@ -1406,7 +1706,14 @@ PciParseBar (
|
|||
|
||||
PciIoDevice->PciBar[BarIndex].Length = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);
|
||||
PciIoDevice->PciBar[BarIndex].Length = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;
|
||||
PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
|
||||
if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {
|
||||
//
|
||||
// Force minimum 4KByte alignment for Virtualization technology for Directed I/O
|
||||
//
|
||||
PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);
|
||||
} else {
|
||||
PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
@ -1416,8 +1723,14 @@ PciParseBar (
|
|||
default:
|
||||
PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;
|
||||
PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;
|
||||
PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
|
||||
|
||||
if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {
|
||||
//
|
||||
// Force minimum 4KByte alignment for Virtualization technology for Directed I/O
|
||||
//
|
||||
PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);
|
||||
} else {
|
||||
PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1570,6 +1883,8 @@ CreatePciIoDevice (
|
|||
)
|
||||
{
|
||||
PCI_IO_DEVICE *PciIoDevice;
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
EFI_STATUS Status;
|
||||
|
||||
PciIoDevice = AllocateZeroPool (sizeof (PCI_IO_DEVICE));
|
||||
if (PciIoDevice == NULL) {
|
||||
|
@ -1607,6 +1922,162 @@ CreatePciIoDevice (
|
|||
InitializePciIoInstance (PciIoDevice);
|
||||
InitializePciDriverOverrideInstance (PciIoDevice);
|
||||
InitializePciLoadFile2 (PciIoDevice);
|
||||
PciIo = &PciIoDevice->PciIo;
|
||||
|
||||
//
|
||||
// Detect if PCI Express Device
|
||||
//
|
||||
PciIoDevice->PciExpressCapabilityOffset = 0;
|
||||
Status = LocateCapabilityRegBlock (
|
||||
PciIoDevice,
|
||||
EFI_PCI_CAPABILITY_ID_PCIEXP,
|
||||
&PciIoDevice->PciExpressCapabilityOffset,
|
||||
NULL
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
PciIoDevice->IsPciExp = TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize for PCI IOV
|
||||
//
|
||||
|
||||
//
|
||||
// Check ARI for function 0 only
|
||||
//
|
||||
Status = LocatePciExpressCapabilityRegBlock (
|
||||
PciIoDevice,
|
||||
EFI_PCIE_CAPABILITY_ID_ARI,
|
||||
&PciIoDevice->AriCapabilityOffset,
|
||||
NULL
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
EFI_D_INFO,
|
||||
"PCI-IOV B%x.D%x.F%x - ARI Cap offset - 0x%x\n",
|
||||
(UINTN)Bus,
|
||||
(UINTN)Device,
|
||||
(UINTN)Func,
|
||||
(UINTN)PciIoDevice->AriCapabilityOffset
|
||||
));
|
||||
}
|
||||
|
||||
Status = LocatePciExpressCapabilityRegBlock (
|
||||
PciIoDevice,
|
||||
EFI_PCIE_CAPABILITY_ID_SRIOV,
|
||||
&PciIoDevice->SrIovCapabilityOffset,
|
||||
NULL
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
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
|
||||
//
|
||||
if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {
|
||||
|
||||
PciIo->Pci.Read (
|
||||
PciIo,
|
||||
EfiPciIoWidthUint32,
|
||||
PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SUPPORTED_PAGE_SIZE,
|
||||
1,
|
||||
&PciIoDevice->SystemPageSize
|
||||
);
|
||||
DEBUG ((EFI_D_INFO, "PCI-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-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
|
||||
//
|
||||
if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {
|
||||
UINT16 VFStride;
|
||||
UINT16 FirstVFOffset;
|
||||
UINT32 PFRID;
|
||||
UINT32 LastVF;
|
||||
|
||||
//
|
||||
// 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-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
|
||||
|
|
|
@ -158,6 +158,26 @@ CreatePciDevicePath (
|
|||
IN PCI_IO_DEVICE *PciIoDevice
|
||||
);
|
||||
|
||||
/**
|
||||
Check whether the PCI IOV VF bar is existed or not.
|
||||
|
||||
@param PciIoDevice A pointer to the PCI_IO_DEVICE.
|
||||
@param Offset The offset.
|
||||
@param BarLengthValue The bar length value returned.
|
||||
@param OriginalBarValue The original bar value returned.
|
||||
|
||||
@retval EFI_NOT_FOUND The bar doesn't exist.
|
||||
@retval EFI_SUCCESS The bar exist.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
VfBarExisted (
|
||||
IN PCI_IO_DEVICE *PciIoDevice,
|
||||
IN UINTN Offset,
|
||||
OUT UINT32 *BarLengthValue,
|
||||
OUT UINT32 *OriginalBarValue
|
||||
);
|
||||
|
||||
/**
|
||||
Check whether the bar is existed or not.
|
||||
|
||||
|
@ -288,6 +308,23 @@ PciParseBar (
|
|||
IN UINTN BarIndex
|
||||
);
|
||||
|
||||
/**
|
||||
Parse PCI IOV VF bar information and fill them into PCI device instance.
|
||||
|
||||
@param PciIoDevice Pci device instance.
|
||||
@param Offset Bar offset.
|
||||
@param BarIndex Bar index.
|
||||
|
||||
@return Next bar offset.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
PciIovParseVfBar (
|
||||
IN PCI_IO_DEVICE *PciIoDevice,
|
||||
IN UINTN Offset,
|
||||
IN UINTN BarIndex
|
||||
);
|
||||
|
||||
/**
|
||||
This routine is used to initialize the bar of a PCI device.
|
||||
|
||||
|
|
|
@ -706,6 +706,7 @@ PciScanBus (
|
|||
UINT16 BusRange;
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
|
||||
BOOLEAN BusPadding;
|
||||
UINT32 TempReservedBusNum;
|
||||
|
||||
PciRootBridgeIo = Bridge->PciRootBridgeIo;
|
||||
SecondBus = 0;
|
||||
|
@ -718,6 +719,7 @@ PciScanBus (
|
|||
PciAddress = 0;
|
||||
|
||||
for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
|
||||
TempReservedBusNum = 0;
|
||||
for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
|
||||
|
||||
//
|
||||
|
@ -742,7 +744,7 @@ PciScanBus (
|
|||
continue;
|
||||
}
|
||||
|
||||
DEBUG((EFI_D_ERROR, "Found DEV(%02d,%02d,%02d)\n", StartBusNumber, Device, Func ));
|
||||
DEBUG((EFI_D_INFO, "Found DEV(%02d,%02d,%02d)\n", StartBusNumber, Device, Func ));
|
||||
|
||||
if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
|
||||
//
|
||||
|
@ -930,7 +932,7 @@ PciScanBus (
|
|||
EfiPciBeforeChildBusEnumeration
|
||||
);
|
||||
|
||||
DEBUG((EFI_D_ERROR, "Scan PPB(%02d,%02d,%02d)\n", PciDevice->BusNumber, PciDevice->DeviceNumber,PciDevice->FunctionNumber));
|
||||
DEBUG((EFI_D_INFO, "Scan PPB(%02d,%02d,%02d)\n", PciDevice->BusNumber, PciDevice->DeviceNumber,PciDevice->FunctionNumber));
|
||||
Status = PciScanBus (
|
||||
PciDevice,
|
||||
(UINT8) (SecondBus),
|
||||
|
@ -967,6 +969,28 @@ PciScanBus (
|
|||
1,
|
||||
SubBusNumber
|
||||
);
|
||||
} else {
|
||||
//
|
||||
// It is device. Check PCI IOV for Bus reservation
|
||||
//
|
||||
|
||||
//
|
||||
// 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 (TempReservedBusNum < PciDevice->ReservedBusNum) {
|
||||
|
||||
(*SubBusNumber) = (UINT8)((*SubBusNumber) + PciDevice->ReservedBusNum - TempReservedBusNum);
|
||||
TempReservedBusNum = PciDevice->ReservedBusNum;
|
||||
|
||||
if (Func == 0) {
|
||||
DEBUG ((EFI_D_INFO, "PCI-IOV ScanBus - SubBusNumber - 0x%x\n", *SubBusNumber));
|
||||
} else {
|
||||
DEBUG ((EFI_D_INFO, "PCI-IOV ScanBus - SubBusNumber - 0x%x (Update)\n", *SubBusNumber));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {
|
||||
|
@ -1139,7 +1163,7 @@ PciHostBridgeEnumerator (
|
|||
//
|
||||
NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);
|
||||
|
||||
DEBUG((EFI_D_ERROR, "PCI Bus First Scanning\n"));
|
||||
DEBUG((EFI_D_INFO, "PCI Bus First Scanning\n"));
|
||||
RootBridgeHandle = NULL;
|
||||
while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
|
||||
|
||||
|
@ -1226,7 +1250,7 @@ PciHostBridgeEnumerator (
|
|||
//
|
||||
NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);
|
||||
|
||||
DEBUG((EFI_D_ERROR, "PCI Bus Second Scanning\n"));
|
||||
DEBUG((EFI_D_INFO, "PCI Bus Second Scanning\n"));
|
||||
RootBridgeHandle = NULL;
|
||||
while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
|
||||
|
||||
|
|
|
@ -544,6 +544,94 @@ GetResourceFromDevice (
|
|||
}
|
||||
|
||||
//
|
||||
// Add VF resource
|
||||
//
|
||||
for (Index = 0; Index < PCI_MAX_BAR; Index++) {
|
||||
|
||||
switch ((PciDev->VfPciBar)[Index].BarType) {
|
||||
|
||||
case PciBarTypeMem32:
|
||||
|
||||
Node = CreateVfResourceNode (
|
||||
PciDev,
|
||||
(PciDev->VfPciBar)[Index].Length,
|
||||
(PciDev->VfPciBar)[Index].Alignment,
|
||||
Index,
|
||||
PciBarTypeMem32,
|
||||
PciResUsageTypical
|
||||
);
|
||||
|
||||
InsertResourceNode (
|
||||
Mem32Node,
|
||||
Node
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case PciBarTypeMem64:
|
||||
|
||||
Node = CreateVfResourceNode (
|
||||
PciDev,
|
||||
(PciDev->VfPciBar)[Index].Length,
|
||||
(PciDev->VfPciBar)[Index].Alignment,
|
||||
Index,
|
||||
PciBarTypeMem64,
|
||||
PciResUsageTypical
|
||||
);
|
||||
|
||||
InsertResourceNode (
|
||||
Mem64Node,
|
||||
Node
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case PciBarTypePMem64:
|
||||
|
||||
Node = CreateVfResourceNode (
|
||||
PciDev,
|
||||
(PciDev->VfPciBar)[Index].Length,
|
||||
(PciDev->VfPciBar)[Index].Alignment,
|
||||
Index,
|
||||
PciBarTypePMem64,
|
||||
PciResUsageTypical
|
||||
);
|
||||
|
||||
InsertResourceNode (
|
||||
PMem64Node,
|
||||
Node
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case PciBarTypePMem32:
|
||||
|
||||
Node = CreateVfResourceNode (
|
||||
PciDev,
|
||||
(PciDev->VfPciBar)[Index].Length,
|
||||
(PciDev->VfPciBar)[Index].Alignment,
|
||||
Index,
|
||||
PciBarTypePMem32,
|
||||
PciResUsageTypical
|
||||
);
|
||||
|
||||
InsertResourceNode (
|
||||
PMem32Node,
|
||||
Node
|
||||
);
|
||||
break;
|
||||
|
||||
case PciBarTypeIo16:
|
||||
case PciBarTypeIo32:
|
||||
break;
|
||||
|
||||
case PciBarTypeUnknown:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If there is no resource requested from this device,
|
||||
// then we indicate this device has been allocated naturally.
|
||||
//
|
||||
|
@ -599,6 +687,53 @@ CreateResourceNode (
|
|||
return Node;
|
||||
}
|
||||
|
||||
/**
|
||||
This function is used to create a IOV VF resource node.
|
||||
|
||||
@param PciDev Pci device instance.
|
||||
@param Length Length of Io/Memory resource.
|
||||
@param Alignment Alignment of resource.
|
||||
@param Bar Bar index.
|
||||
@param ResType Type of resource: IO/Memory.
|
||||
@param ResUsage Resource usage.
|
||||
|
||||
@return PCI resource node created for given VF PCI device.
|
||||
NULL means PCI resource node is not created.
|
||||
|
||||
**/
|
||||
PCI_RESOURCE_NODE *
|
||||
CreateVfResourceNode (
|
||||
IN PCI_IO_DEVICE *PciDev,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Alignment,
|
||||
IN UINT8 Bar,
|
||||
IN PCI_BAR_TYPE ResType,
|
||||
IN PCI_RESOURCE_USAGE ResUsage
|
||||
)
|
||||
{
|
||||
PCI_RESOURCE_NODE *Node;
|
||||
|
||||
DEBUG ((
|
||||
EFI_D_INFO,
|
||||
"PCI-IOV B%x.D%x.F%x - VfResource (Bar - 0x%x) (Type - 0x%x) (Length - 0x%x)\n",
|
||||
(UINTN)PciDev->BusNumber,
|
||||
(UINTN)PciDev->DeviceNumber,
|
||||
(UINTN)PciDev->FunctionNumber,
|
||||
(UINTN)Bar,
|
||||
(UINTN)ResType,
|
||||
(UINTN)Length
|
||||
));
|
||||
|
||||
Node = CreateResourceNode (PciDev, Length, Alignment, Bar, ResType, ResUsage);
|
||||
if (Node == NULL) {
|
||||
return Node;
|
||||
}
|
||||
|
||||
Node->Virtual = TRUE;
|
||||
|
||||
return Node;
|
||||
}
|
||||
|
||||
/**
|
||||
This function is used to extract resource request from
|
||||
device node list.
|
||||
|
@ -1094,6 +1229,13 @@ ProgramBar (
|
|||
UINT64 Address;
|
||||
UINT32 Address32;
|
||||
|
||||
//
|
||||
// Check VF BAR
|
||||
//
|
||||
if (Node->Virtual) {
|
||||
ProgramVfBar (Base, Node);
|
||||
}
|
||||
|
||||
Address = 0;
|
||||
PciIo = &(Node->PciDev->PciIo);
|
||||
|
||||
|
@ -1159,6 +1301,116 @@ ProgramBar (
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Program IOV VF Bar register for PCI device.
|
||||
|
||||
@param Base Base address for PCI device resource to be progammed.
|
||||
@param Node Point to resoure node structure.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ProgramVfBar (
|
||||
IN UINT64 Base,
|
||||
IN PCI_RESOURCE_NODE *Node
|
||||
)
|
||||
{
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
UINT64 Address;
|
||||
UINT32 Address32;
|
||||
|
||||
ASSERT (Node->Virtual);
|
||||
if (!Node->Virtual) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Address = 0;
|
||||
PciIo = &(Node->PciDev->PciIo);
|
||||
|
||||
Address = Base + Node->Offset;
|
||||
|
||||
//
|
||||
// Indicate pci bus driver has allocated
|
||||
// resource for this device
|
||||
// It might be a temporary solution here since
|
||||
// pci device could have multiple bar
|
||||
//
|
||||
Node->PciDev->Allocated = TRUE;
|
||||
|
||||
switch ((Node->PciDev->VfPciBar[Node->Bar]).BarType) {
|
||||
|
||||
case PciBarTypeMem32:
|
||||
case PciBarTypePMem32:
|
||||
|
||||
PciIo->Pci.Write (
|
||||
PciIo,
|
||||
EfiPciIoWidthUint32,
|
||||
(Node->PciDev->VfPciBar[Node->Bar]).Offset,
|
||||
1,
|
||||
&Address
|
||||
);
|
||||
|
||||
Node->PciDev->VfPciBar[Node->Bar].BaseAddress = Address;
|
||||
|
||||
DEBUG ((
|
||||
EFI_D_INFO,
|
||||
"PCI-IOV B%x.D%x.F%x - VF Bar (Offset - 0x%x) 32Mem (Address - 0x%x)\n",
|
||||
(UINTN)Node->PciDev->BusNumber,
|
||||
(UINTN)Node->PciDev->DeviceNumber,
|
||||
(UINTN)Node->PciDev->FunctionNumber,
|
||||
(UINTN)(Node->PciDev->VfPciBar[Node->Bar]).Offset,
|
||||
(UINTN)Address
|
||||
));
|
||||
|
||||
break;
|
||||
|
||||
case PciBarTypeMem64:
|
||||
case PciBarTypePMem64:
|
||||
|
||||
Address32 = (UINT32) (Address & 0x00000000FFFFFFFF);
|
||||
|
||||
PciIo->Pci.Write (
|
||||
PciIo,
|
||||
EfiPciIoWidthUint32,
|
||||
(Node->PciDev->VfPciBar[Node->Bar]).Offset,
|
||||
1,
|
||||
&Address32
|
||||
);
|
||||
|
||||
Address32 = (UINT32) RShiftU64 (Address, 32);
|
||||
|
||||
PciIo->Pci.Write (
|
||||
PciIo,
|
||||
EfiPciIoWidthUint32,
|
||||
((Node->PciDev->VfPciBar[Node->Bar]).Offset + 4),
|
||||
1,
|
||||
&Address32
|
||||
);
|
||||
|
||||
Node->PciDev->VfPciBar[Node->Bar].BaseAddress = Address;
|
||||
|
||||
DEBUG ((
|
||||
EFI_D_INFO,
|
||||
"PCI-IOV B%x.D%x.F%x - VF Bar (Offset - 0x%x) 64Mem (Address - 0x%lx)\n",
|
||||
(UINTN)Node->PciDev->BusNumber,
|
||||
(UINTN)Node->PciDev->DeviceNumber,
|
||||
(UINTN)Node->PciDev->FunctionNumber,
|
||||
(UINTN)(Node->PciDev->VfPciBar[Node->Bar]).Offset,
|
||||
(UINT64)Address
|
||||
));
|
||||
|
||||
break;
|
||||
|
||||
case PciBarTypeIo16:
|
||||
case PciBarTypeIo32:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Program PCI-PCI bridge apperture.
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ typedef struct {
|
|||
UINT64 Length;
|
||||
BOOLEAN Reserved;
|
||||
PCI_RESOURCE_USAGE ResourceUsage;
|
||||
BOOLEAN Virtual;
|
||||
} PCI_RESOURCE_NODE;
|
||||
|
||||
#define RESOURCE_NODE_FROM_LINK(a) \
|
||||
|
@ -174,6 +175,28 @@ CreateResourceNode (
|
|||
IN PCI_RESOURCE_USAGE ResUsage
|
||||
);
|
||||
|
||||
/**
|
||||
This function is used to extract resource request from
|
||||
IOV VF device node list.
|
||||
|
||||
@param Bridge Pci device instance.
|
||||
@param IoNode Resource info node for IO.
|
||||
@param Mem32Node Resource info node for 32-bit memory.
|
||||
@param PMem32Node Resource info node for 32-bit Prefetchable Memory.
|
||||
@param Mem64Node Resource info node for 64-bit memory.
|
||||
@param PMem64Node Resource info node for 64-bit Prefetchable Memory.
|
||||
|
||||
**/
|
||||
PCI_RESOURCE_NODE *
|
||||
CreateVfResourceNode (
|
||||
IN PCI_IO_DEVICE *PciDev,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Alignment,
|
||||
IN UINT8 Bar,
|
||||
IN PCI_BAR_TYPE ResType,
|
||||
IN PCI_RESOURCE_USAGE ResUsage
|
||||
);
|
||||
|
||||
/**
|
||||
This function is used to extract resource request from
|
||||
device node list.
|
||||
|
@ -287,6 +310,19 @@ ProgramBar (
|
|||
IN PCI_RESOURCE_NODE *Node
|
||||
);
|
||||
|
||||
/**
|
||||
Program IOV VF Bar register for PCI device.
|
||||
|
||||
@param Base Base address for PCI device resource to be progammed.
|
||||
@param Node Point to resoure node structure.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ProgramVfBar (
|
||||
IN UINT64 Base,
|
||||
IN PCI_RESOURCE_NODE *Node
|
||||
);
|
||||
|
||||
/**
|
||||
Program PCI-PCI bridge apperture.
|
||||
|
||||
|
|
|
@ -102,6 +102,16 @@
|
|||
## This PCD specifies whether Serial device use half hand shake.
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdIsaBusSerialUseHalfHandshake|FALSE|BOOLEAN|0x00010043
|
||||
|
||||
## This PCD specifies whether the Single Root I/O virtualization support.
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSrIovSupport|TRUE|BOOLEAN|0x10000044
|
||||
|
||||
## This PCD specifies whether the Alternative Routing-ID support.
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdAriSupport|TRUE|BOOLEAN|0x10000045
|
||||
|
||||
## This PCD specifies whether the Multi Root I/O virtualization support.
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdMrIovSupport|FALSE|BOOLEAN|0x10000046
|
||||
|
||||
|
||||
[PcdsFixedAtBuild]
|
||||
## FFS filename to find the default BMP Logo file.
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile |{ 0x99, 0x8b, 0xB2, 0x7B, 0xBB, 0x61, 0xD5, 0x11, 0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }|VOID*|16
|
||||
|
@ -115,6 +125,12 @@
|
|||
# BIT2 indicates if ISA memory is supported
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdIsaBusSupportedFeatures|0x05|UINT8|0x00010040
|
||||
|
||||
## Single root I/O virtualization virtual function memory BAR alignment
|
||||
# BITN set indicates 2 of n+12 power
|
||||
# BIT0 set indicates 4KB alignment
|
||||
# BIT1 set indicates 8KB alignment
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize|0x1|UINT32|0x10000047
|
||||
|
||||
[PcdsFixedAtBuild,PcdsPatchableInModule,PcdsDynamic]
|
||||
## PcdStatusCodeMemorySize is used when PcdStatusCodeUseMemory is set to true
|
||||
# (PcdStatusCodeMemorySize * KBytes) is the total taken memory size.
|
||||
|
|
Loading…
Reference in New Issue