summaryrefslogtreecommitdiff
path: root/IntelFrameworkModulePkg
diff options
context:
space:
mode:
authorhtao <htao@6f19259b-4bc3-4df7-8a09-765794883524>2009-09-16 09:32:06 +0000
committerhtao <htao@6f19259b-4bc3-4df7-8a09-765794883524>2009-09-16 09:32:06 +0000
commit7fc72ecb0d6db6699d9b3e2d3c7b059eb1b53a14 (patch)
tree5507b5dd68e6ba4abfa685a52cef6e95a9df90ce /IntelFrameworkModulePkg
parentfd53905e69bb94a5175125a32ffbaa9cae718cef (diff)
downloadedk2-platforms-7fc72ecb0d6db6699d9b3e2d3c7b059eb1b53a14.tar.xz
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
Diffstat (limited to 'IntelFrameworkModulePkg')
-rw-r--r--IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBus.h19
-rw-r--r--IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf5
-rw-r--r--IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.c67
-rw-r--r--IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.h21
-rw-r--r--IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c32
-rw-r--r--IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c481
-rw-r--r--IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h37
-rw-r--r--IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.c32
-rw-r--r--IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c252
-rw-r--r--IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.h36
-rw-r--r--IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec16
11 files changed, 988 insertions, 10 deletions
diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBus.h
index df224d12c4..0c1c864bc8 100644
--- a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBus.h
+++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBus.h
@@ -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) \
diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
index a3a13d55a0..a0f1e44e28 100644
--- a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
@@ -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.
diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.c
index 39f5271e9b..601af309b7 100644
--- a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.c
+++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.c
@@ -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;
+}
diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.h
index 7019b5ea19..942bea941e 100644
--- a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.h
+++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.h
@@ -119,6 +119,27 @@ LocateCapabilityRegBlock (
);
/**
+ 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.
@param a[in] Pointer to instance of PCI_IO_DEVICE.
diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
index baad1ccd72..0eb9f9a9d1 100644
--- a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
+++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
@@ -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
//
diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
index 2d5408abe0..66183960f1 100644
--- a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
+++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
@@ -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;
}
@@ -598,6 +608,80 @@ CreatePciDevicePath (
}
/**
+ 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.
@param PciIoDevice A pointer to the PCI_IO_DEVICE.
@@ -1250,6 +1334,207 @@ SetNewAlign (
}
/**
+ 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.
@param PciIoDevice 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
diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h
index 6f2f1e6ea5..31238b45cf 100644
--- a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h
+++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h
@@ -159,6 +159,26 @@ CreatePciDevicePath (
);
/**
+ 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.
@param PciIoDevice A pointer to the PCI_IO_DEVICE.
@@ -289,6 +309,23 @@ PciParseBar (
);
/**
+ 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.
@param PciIoDevice Pci device instance.
diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.c
index 16c0cce99a..70b28df0b1 100644
--- a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.c
+++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciLib.c
@@ -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) {
diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c
index 40d02354eb..17c864029b 100644
--- a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c
+++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c
@@ -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.
//
@@ -600,6 +688,53 @@ CreateResourceNode (
}
/**
+ 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);
@@ -1160,6 +1302,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.
@param Base Base address for resource.
diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.h b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.h
index 96396fe869..faa6c0d60c 100644
--- a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.h
+++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.h
@@ -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) \
@@ -176,6 +177,28 @@ CreateResourceNode (
/**
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.
@param Bridge Pci device instance.
@@ -288,6 +311,19 @@ 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
+ );
+
+/**
Program PCI-PCI bridge apperture.
@param Base Base address for resource.
diff --git a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
index e7f496bbed..62225a6be7 100644
--- a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+++ b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
@@ -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.