typedef struct _PCI_IO_DEVICE PCI_IO_DEVICE;\r
typedef struct _PCI_BAR PCI_BAR;\r
\r
+#define EFI_PCI_RID(Bus, Device, Function) (((UINT32)Bus << 8) + ((UINT32)Device << 3) + (UINT32)Function)\r
+#define EFI_PCI_BUS_OF_RID(RID) ((UINT32)RID >> 8)\r
+\r
+#define EFI_PCI_IOV_POLICY_ARI 0x0001\r
+#define EFI_PCI_IOV_POLICY_SRIOV 0x0002\r
+#define EFI_PCI_IOV_POLICY_MRIOV 0x0004\r
+\r
typedef enum {\r
PciBarTypeUnknown = 0,\r
PciBarTypeIo16,\r
EFI_HPC_PADDING_ATTRIBUTES PaddingAttributes;\r
\r
BOOLEAN IsPciExp;\r
-\r
+ //\r
+ // For SR-IOV\r
+ //\r
+ UINT8 PciExpressCapabilityOffset;\r
+ UINT32 AriCapabilityOffset;\r
+ UINT32 SrIovCapabilityOffset;\r
+ UINT32 MrIovCapabilityOffset;\r
+ PCI_BAR VfPciBar[PCI_MAX_BAR];\r
+ UINT32 SystemPageSize;\r
+ UINT16 InitialVFs;\r
+ UINT16 ReservedBusNum;\r
};\r
\r
#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \\r
\r
[FeaturePcd.common]\r
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport\r
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSrIovSupport\r
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdAriSupport\r
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdMrIovSupport\r
\r
+[FixedPcd.common]\r
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize\r
# [Event]\r
# ##\r
# # Notify event set by CreateEventForHpc () for PCI Hot Plug controller.\r
return EFI_NOT_FOUND;\r
}\r
\r
+/**\r
+ Locate PciExpress capability register block per capability ID.\r
+\r
+ @param PciIoDevice A pointer to the PCI_IO_DEVICE.\r
+ @param CapId The capability ID.\r
+ @param Offset A pointer to the offset returned.\r
+ @param NextRegBlock A pointer to the next block returned.\r
+\r
+ @retval EFI_SUCCESS Successfuly located capability register block.\r
+ @retval EFI_UNSUPPORTED Pci device does not support capability.\r
+ @retval EFI_NOT_FOUND Pci device support but can not find register block.\r
+\r
+**/\r
+EFI_STATUS\r
+LocatePciExpressCapabilityRegBlock (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 CapId,\r
+ IN OUT UINT32 *Offset,\r
+ OUT UINT32 *NextRegBlock OPTIONAL\r
+ )\r
+{\r
+ UINT32 CapabilityPtr;\r
+ UINT32 CapabilityEntry;\r
+ UINT16 CapabilityID;\r
+\r
+ //\r
+ // To check the capability of this device supports\r
+ //\r
+ if (!PciIoDevice->IsPciExp) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if (*Offset != 0) {\r
+ CapabilityPtr = *Offset;\r
+ } else {\r
+ CapabilityPtr = EFI_PCIE_CAPABILITY_BASE_OFFSET;\r
+ }\r
+\r
+ while (CapabilityPtr != 0) {\r
+ //\r
+ // Mask it to DWORD alignment per PCI spec\r
+ //\r
+ CapabilityPtr &= 0xFFC;\r
+ PciIoDevice->PciIo.Pci.Read (\r
+ &PciIoDevice->PciIo,\r
+ EfiPciIoWidthUint32,\r
+ CapabilityPtr,\r
+ 1,\r
+ &CapabilityEntry\r
+ );\r
+\r
+ CapabilityID = (UINT16) CapabilityEntry;\r
+\r
+ if (CapabilityID == CapId) {\r
+ *Offset = CapabilityPtr;\r
+ if (NextRegBlock != NULL) {\r
+ *NextRegBlock = (CapabilityEntry >> 20) & 0xFFF;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ CapabilityPtr = (CapabilityEntry >> 20) & 0xFFF;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
OUT UINT8 *NextRegBlock OPTIONAL\r
);\r
\r
+/**\r
+ Locate PciExpress capability register block per capability ID.\r
+\r
+ @param PciIoDevice A pointer to the PCI_IO_DEVICE.\r
+ @param CapId The capability ID.\r
+ @param Offset A pointer to the offset returned.\r
+ @param NextRegBlock A pointer to the next block returned.\r
+\r
+ @retval EFI_SUCCESS Successfuly located capability register block.\r
+ @retval EFI_UNSUPPORTED Pci device does not support capability.\r
+ @retval EFI_NOT_FOUND Pci device support but can not find register block.\r
+\r
+**/\r
+EFI_STATUS\r
+LocatePciExpressCapabilityRegBlock (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 CapId,\r
+ IN OUT UINT32 *Offset,\r
+ OUT UINT32 *NextRegBlock OPTIONAL\r
+ );\r
+\r
/**\r
Macro that reads command register.\r
\r
EFI_PCI_IO_PROTOCOL *PciIo;\r
UINT8 Data8;\r
BOOLEAN HasEfiImage;\r
+ PCI_IO_DEVICE *ParrentPciIoDevice;\r
+ EFI_PCI_IO_PROTOCOL *ParrentPciIo;\r
+ UINT16 Data16;\r
+ UINT32 Data32;\r
\r
//\r
// Install the pciio protocol, device path protocol\r
PciIo = &(PciIoDevice->PciIo);\r
Data8 = PCI_INT_LINE_UNKNOWN;\r
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Data8);\r
+ \r
+ //\r
+ // PCI-IOV programming\r
+ //\r
+ if (((FeaturePcdGet(PcdAriSupport) & EFI_PCI_IOV_POLICY_ARI) != 0) && (PciIoDevice->AriCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport) & EFI_PCI_IOV_POLICY_SRIOV) != 0) &&\r
+ (PciIoDevice->SrIovCapabilityOffset != 0)) {\r
+ //\r
+ // Check its parrent ARI forwarding capability\r
+ //\r
+ ParrentPciIoDevice = PciIoDevice->Parent;\r
+ ParrentPciIo = &(ParrentPciIoDevice->PciIo);\r
+ ParrentPciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ParrentPciIoDevice->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_OFFSET, 1, &Data32);\r
+ if (Data32 & EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING) {\r
+ //\r
+ // ARI forward support in bridge, so enable it.\r
+ //\r
+ ParrentPciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ParrentPciIoDevice->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET, 1, &Data32);\r
+ Data32 |= EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING;\r
+ ParrentPciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, ParrentPciIoDevice->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET, 1, &Data32);\r
\r
+ //\r
+ // Set ARI Capable Hierarchy for device\r
+ //\r
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL, 1, &Data16);\r
+ Data16 |= EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL_ARI_HIERARCHY;\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL, 1, &Data16);\r
+ }\r
+ }\r
+ \r
//\r
// Process OpRom\r
//\r
Offset = PciParseBar (PciIoDevice, Offset, BarIndex);\r
}\r
\r
+ //\r
+ // Parse the SR-IOV VF bars\r
+ //\r
+ if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {\r
+ for (Offset = PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR0, BarIndex = 0;\r
+ Offset <= PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR5;\r
+ BarIndex++) {\r
+ Offset = PciIovParseVfBar (PciIoDevice, Offset, BarIndex);\r
+ }\r
+ }\r
return PciIoDevice;\r
}\r
\r
return PciIoDevice->DevicePath;\r
}\r
\r
+/**\r
+ Check whether the PCI IOV VF bar is existed or not.\r
+\r
+ @param PciIoDevice A pointer to the PCI_IO_DEVICE.\r
+ @param Offset The offset.\r
+ @param BarLengthValue The bar length value returned.\r
+ @param OriginalBarValue The original bar value returned.\r
+\r
+ @retval EFI_NOT_FOUND The bar doesn't exist.\r
+ @retval EFI_SUCCESS The bar exist.\r
+\r
+**/\r
+EFI_STATUS\r
+VfBarExisted (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINTN Offset,\r
+ OUT UINT32 *BarLengthValue,\r
+ OUT UINT32 *OriginalBarValue\r
+ )\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT32 OriginalValue;\r
+ UINT32 Value;\r
+ EFI_TPL OldTpl;\r
+\r
+ //\r
+ // Ensure it is called properly\r
+ //\r
+ ASSERT (PciIoDevice->SrIovCapabilityOffset != 0);\r
+ if (PciIoDevice->SrIovCapabilityOffset == 0) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ //\r
+ // Preserve the original value\r
+ //\r
+\r
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &OriginalValue);\r
+\r
+ //\r
+ // Raise TPL to high level to disable timer interrupt while the BAR is probed\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &gAllOne);\r
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &Value);\r
+\r
+ //\r
+ // Write back the original value\r
+ //\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &OriginalValue);\r
+\r
+ //\r
+ // Restore TPL to its original level\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ if (BarLengthValue != NULL) {\r
+ *BarLengthValue = Value;\r
+ }\r
+\r
+ if (OriginalBarValue != NULL) {\r
+ *OriginalBarValue = OriginalValue;\r
+ }\r
+\r
+ if (Value == 0) {\r
+ return EFI_NOT_FOUND;\r
+ } else {\r
+ return EFI_SUCCESS;\r
+ }\r
+}\r
+\r
/**\r
Check whether the bar is existed or not.\r
\r
return ;\r
}\r
\r
+/**\r
+ Parse PCI IOV VF bar information and fill them into PCI device instance.\r
+\r
+ @param PciIoDevice Pci device instance.\r
+ @param Offset Bar offset.\r
+ @param BarIndex Bar index.\r
+\r
+ @return Next bar offset.\r
+\r
+**/\r
+UINTN\r
+PciIovParseVfBar (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINTN Offset,\r
+ IN UINTN BarIndex\r
+ )\r
+{\r
+ UINT32 Value;\r
+ UINT64 BarValue64;\r
+ UINT32 OriginalValue;\r
+ UINT32 Mask;\r
+ UINT32 Data;\r
+ UINT8 Index;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Ensure it is called properly\r
+ //\r
+ ASSERT (PciIoDevice->SrIovCapabilityOffset != 0);\r
+ if (PciIoDevice->SrIovCapabilityOffset == 0) {\r
+ return 0;\r
+ }\r
+\r
+ OriginalValue = 0;\r
+ Value = 0;\r
+ BarValue64 = 0;\r
+\r
+ Status = VfBarExisted (\r
+ PciIoDevice,\r
+ Offset,\r
+ &Value,\r
+ &OriginalValue\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ PciIoDevice->VfPciBar[BarIndex].BaseAddress = 0;\r
+ PciIoDevice->VfPciBar[BarIndex].Length = 0;\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = 0;\r
+\r
+ //\r
+ // Scan all the BARs anyway\r
+ //\r
+ PciIoDevice->VfPciBar[BarIndex].Offset = (UINT8) Offset;\r
+ return Offset + 4;\r
+ }\r
+\r
+ PciIoDevice->VfPciBar[BarIndex].Offset = (UINT8) Offset;\r
+ if (Value & 0x01) {\r
+ //\r
+ // Device I/Os. Impossible\r
+ //\r
+ ASSERT (FALSE);\r
+ return Offset + 4;\r
+\r
+ } else {\r
+\r
+ Mask = 0xfffffff0;\r
+\r
+ PciIoDevice->VfPciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
+\r
+ switch (Value & 0x07) {\r
+\r
+ //\r
+ //memory space; anywhere in 32 bit address space\r
+ //\r
+ case 0x00:\r
+ if (Value & 0x08) {\r
+ PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem32;\r
+ } else {\r
+ PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem32;\r
+ }\r
+\r
+ PciIoDevice->VfPciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+\r
+ //\r
+ // Adjust Length\r
+ //\r
+ PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs);\r
+ //\r
+ // Adjust Alignment\r
+ //\r
+ if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+ }\r
+\r
+ break;\r
+\r
+ //\r
+ // memory space; anywhere in 64 bit address space\r
+ //\r
+ case 0x04:\r
+ if (Value & 0x08) {\r
+ PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem64;\r
+ } else {\r
+ PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem64;\r
+ }\r
+\r
+ //\r
+ // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
+ // is regarded as an extension for the first bar. As a result\r
+ // the sizing will be conducted on combined 64 bit value\r
+ // Here just store the masked first 32bit value for future size\r
+ // calculation\r
+ //\r
+ PciIoDevice->VfPciBar[BarIndex].Length = Value & Mask;\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+\r
+ if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+ }\r
+\r
+ //\r
+ // Increment the offset to point to next DWORD\r
+ //\r
+ Offset += 4;\r
+\r
+ Status = VfBarExisted (\r
+ PciIoDevice,\r
+ Offset,\r
+ &Value,\r
+ &OriginalValue\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Offset + 4;\r
+ }\r
+\r
+ //\r
+ // Fix the length to support some spefic 64 bit BAR\r
+ //\r
+ Data = Value;\r
+ Index = 0;\r
+ for (Data = Value; Data != 0; Data >>= 1) {\r
+ Index ++;\r
+ }\r
+ Value |= ((UINT32)(-1) << Index); \r
+\r
+ //\r
+ // Calculate the size of 64bit bar\r
+ //\r
+ PciIoDevice->VfPciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);\r
+\r
+ PciIoDevice->VfPciBar[BarIndex].Length = PciIoDevice->VfPciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);\r
+ PciIoDevice->VfPciBar[BarIndex].Length = (~(PciIoDevice->VfPciBar[BarIndex].Length)) + 1;\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+\r
+ //\r
+ // Adjust Length\r
+ //\r
+ PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs);\r
+ //\r
+ // Adjust Alignment\r
+ //\r
+ if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+ }\r
+\r
+ break;\r
+\r
+ //\r
+ // reserved\r
+ //\r
+ default:\r
+ PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+ PciIoDevice->VfPciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+\r
+ if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+ }\r
+\r
+ break;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Check the length again so as to keep compatible with some special bars\r
+ //\r
+ if (PciIoDevice->VfPciBar[BarIndex].Length == 0) {\r
+ PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+ PciIoDevice->VfPciBar[BarIndex].BaseAddress = 0;\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = 0;\r
+ }\r
+ \r
+ //\r
+ // Increment number of bar\r
+ //\r
+ return Offset + 4;\r
+}\r
+\r
/**\r
Parse PCI bar information and fill them into PCI device instance.\r
\r
}\r
\r
PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
- PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-\r
+ if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
+ //\r
+ // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
+ } else {\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+ }\r
break;\r
\r
//\r
);\r
\r
if (EFI_ERROR (Status)) {\r
+ //\r
+ // the high 32 bit does not claim any BAR, we need to re-check the low 32 bit BAR again\r
+ //\r
+ if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
+ //\r
+ // some device implement MMIO bar with 0 length, need to treat it as no-bar\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+ }\r
return Offset + 4;\r
}\r
\r
\r
PciIoDevice->PciBar[BarIndex].Length = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);\r
PciIoDevice->PciBar[BarIndex].Length = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;\r
- PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+ if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
+ //\r
+ // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
+ } else {\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+ }\r
\r
break;\r
\r
default:\r
PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
- PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-\r
+ if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
+ //\r
+ // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
+ } else {\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+ }\r
break;\r
}\r
}\r
)\r
{\r
PCI_IO_DEVICE *PciIoDevice;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_STATUS Status;\r
\r
PciIoDevice = AllocateZeroPool (sizeof (PCI_IO_DEVICE));\r
if (PciIoDevice == NULL) {\r
InitializePciIoInstance (PciIoDevice);\r
InitializePciDriverOverrideInstance (PciIoDevice);\r
InitializePciLoadFile2 (PciIoDevice);\r
+ PciIo = &PciIoDevice->PciIo;\r
+\r
+ //\r
+ // Detect if PCI Express Device\r
+ //\r
+ PciIoDevice->PciExpressCapabilityOffset = 0;\r
+ Status = LocateCapabilityRegBlock (\r
+ PciIoDevice,\r
+ EFI_PCI_CAPABILITY_ID_PCIEXP,\r
+ &PciIoDevice->PciExpressCapabilityOffset,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ PciIoDevice->IsPciExp = TRUE;\r
+ }\r
+\r
+ //\r
+ // Initialize for PCI IOV\r
+ //\r
+\r
+ //\r
+ // Check ARI for function 0 only\r
+ //\r
+ Status = LocatePciExpressCapabilityRegBlock (\r
+ PciIoDevice,\r
+ EFI_PCIE_CAPABILITY_ID_ARI,\r
+ &PciIoDevice->AriCapabilityOffset,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ "PCI-IOV B%x.D%x.F%x - ARI Cap offset - 0x%x\n",\r
+ (UINTN)Bus,\r
+ (UINTN)Device,\r
+ (UINTN)Func,\r
+ (UINTN)PciIoDevice->AriCapabilityOffset\r
+ ));\r
+ }\r
+\r
+ Status = LocatePciExpressCapabilityRegBlock (\r
+ PciIoDevice,\r
+ EFI_PCIE_CAPABILITY_ID_SRIOV,\r
+ &PciIoDevice->SrIovCapabilityOffset,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ "PCI-IOV B%x.D%x.F%x - SRIOV Cap offset - 0x%x\n",\r
+ (UINTN)Bus,\r
+ (UINTN)Device,\r
+ (UINTN)Func,\r
+ (UINTN)PciIoDevice->SrIovCapabilityOffset\r
+ ));\r
+ }\r
+\r
+ Status = LocatePciExpressCapabilityRegBlock (\r
+ PciIoDevice,\r
+ EFI_PCIE_CAPABILITY_ID_MRIOV,\r
+ &PciIoDevice->MrIovCapabilityOffset,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ "PCI-IOV B%x.D%x.F%x - MRIOV Cap offset - 0x%x\n",\r
+ (UINTN)Bus,\r
+ (UINTN)Device,\r
+ (UINTN)Func,\r
+ (UINTN)PciIoDevice->MrIovCapabilityOffset\r
+ ));\r
+ }\r
+\r
+ //\r
+ // Calculate SystemPageSize\r
+ //\r
+ if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {\r
+\r
+ PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SUPPORTED_PAGE_SIZE,\r
+ 1,\r
+ &PciIoDevice->SystemPageSize\r
+ );\r
+ DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - SupportedPageSize - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, PciIoDevice->SystemPageSize));\r
+\r
+ PciIoDevice->SystemPageSize = (PcdGet32(PcdSrIovSystemPageSize) & PciIoDevice->SystemPageSize);\r
+ ASSERT (PciIoDevice->SystemPageSize != 0);\r
+\r
+ PciIo->Pci.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SYSTEM_PAGE_SIZE,\r
+ 1,\r
+ &PciIoDevice->SystemPageSize\r
+ );\r
+ DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - SystemPageSize - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, PciIoDevice->SystemPageSize));\r
+ //\r
+ // Adjust SystemPageSize for Alignment usage later\r
+ //\r
+ PciIoDevice->SystemPageSize <<= 12;\r
+ }\r
+\r
+ // Calculate BusReservation for PCI IOV\r
+ //\r
+ if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {\r
+ UINT16 VFStride;\r
+ UINT16 FirstVFOffset;\r
+ UINT32 PFRID;\r
+ UINT32 LastVF;\r
+\r
+ //\r
+ // Read First FirstVFOffset, InitialVFs, and VFStride\r
+ //\r
+ PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_FIRSTVF,\r
+ 1,\r
+ &FirstVFOffset\r
+ );\r
+ DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - FirstVFOffset - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, (UINTN)FirstVFOffset));\r
+\r
+ PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_INITIALVFS,\r
+ 1,\r
+ &PciIoDevice->InitialVFs\r
+ );\r
+ DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - InitialVFs - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, (UINTN)PciIoDevice->InitialVFs));\r
+\r
+ PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_VFSTRIDE,\r
+ 1,\r
+ &VFStride\r
+ );\r
+ DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - VFStride - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, (UINTN)VFStride));\r
+\r
+ //\r
+ // Calculate LastVF\r
+ //\r
+ PFRID = EFI_PCI_RID(Bus, Device, Func);\r
+ LastVF = PFRID + FirstVFOffset + (PciIoDevice->InitialVFs - 1) * VFStride;\r
+\r
+ //\r
+ // Calculate ReservedBusNum for this PF\r
+ //\r
+ PciIoDevice->ReservedBusNum = (UINT16)(EFI_PCI_BUS_OF_RID (LastVF) - Bus + 1);\r
+ DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - reserved bus number - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, (UINTN)PciIoDevice->ReservedBusNum));\r
+ }\r
+\r
\r
//\r
// Initialize the reserved resource list\r
IN PCI_IO_DEVICE *PciIoDevice\r
);\r
\r
+/**\r
+ Check whether the PCI IOV VF bar is existed or not.\r
+\r
+ @param PciIoDevice A pointer to the PCI_IO_DEVICE.\r
+ @param Offset The offset.\r
+ @param BarLengthValue The bar length value returned.\r
+ @param OriginalBarValue The original bar value returned.\r
+\r
+ @retval EFI_NOT_FOUND The bar doesn't exist.\r
+ @retval EFI_SUCCESS The bar exist.\r
+\r
+**/\r
+EFI_STATUS\r
+VfBarExisted (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINTN Offset,\r
+ OUT UINT32 *BarLengthValue,\r
+ OUT UINT32 *OriginalBarValue\r
+ );\r
+\r
/**\r
Check whether the bar is existed or not.\r
\r
IN UINTN BarIndex\r
);\r
\r
+/**\r
+ Parse PCI IOV VF bar information and fill them into PCI device instance.\r
+\r
+ @param PciIoDevice Pci device instance.\r
+ @param Offset Bar offset.\r
+ @param BarIndex Bar index.\r
+\r
+ @return Next bar offset.\r
+\r
+**/\r
+UINTN\r
+PciIovParseVfBar (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINTN Offset,\r
+ IN UINTN BarIndex\r
+ );\r
+\r
/**\r
This routine is used to initialize the bar of a PCI device.\r
\r
UINT16 BusRange;\r
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
BOOLEAN BusPadding;\r
+ UINT32 TempReservedBusNum;\r
\r
PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
SecondBus = 0;\r
PciAddress = 0;\r
\r
for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
+ TempReservedBusNum = 0;\r
for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
\r
//\r
continue;\r
}\r
\r
- DEBUG((EFI_D_ERROR, "Found DEV(%02d,%02d,%02d)\n", StartBusNumber, Device, Func ));\r
+ DEBUG((EFI_D_INFO, "Found DEV(%02d,%02d,%02d)\n", StartBusNumber, Device, Func ));\r
\r
if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
//\r
EfiPciBeforeChildBusEnumeration\r
);\r
\r
- DEBUG((EFI_D_ERROR, "Scan PPB(%02d,%02d,%02d)\n", PciDevice->BusNumber, PciDevice->DeviceNumber,PciDevice->FunctionNumber));\r
+ DEBUG((EFI_D_INFO, "Scan PPB(%02d,%02d,%02d)\n", PciDevice->BusNumber, PciDevice->DeviceNumber,PciDevice->FunctionNumber));\r
Status = PciScanBus (\r
PciDevice,\r
(UINT8) (SecondBus),\r
1,\r
SubBusNumber\r
);\r
+ } else {\r
+ //\r
+ // It is device. Check PCI IOV for Bus reservation\r
+ //\r
+\r
+ //\r
+ // Go through each function, just reserve the MAX ReservedBusNum for one device\r
+ //\r
+ if ((PciDevice->AriCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {\r
+\r
+ if (TempReservedBusNum < PciDevice->ReservedBusNum) {\r
+\r
+ (*SubBusNumber) = (UINT8)((*SubBusNumber) + PciDevice->ReservedBusNum - TempReservedBusNum);\r
+ TempReservedBusNum = PciDevice->ReservedBusNum;\r
+\r
+ if (Func == 0) {\r
+ DEBUG ((EFI_D_INFO, "PCI-IOV ScanBus - SubBusNumber - 0x%x\n", *SubBusNumber));\r
+ } else {\r
+ DEBUG ((EFI_D_INFO, "PCI-IOV ScanBus - SubBusNumber - 0x%x (Update)\n", *SubBusNumber));\r
+ }\r
+ }\r
+ }\r
}\r
\r
if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
//\r
NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r
\r
- DEBUG((EFI_D_ERROR, "PCI Bus First Scanning\n"));\r
+ DEBUG((EFI_D_INFO, "PCI Bus First Scanning\n"));\r
RootBridgeHandle = NULL;\r
while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
\r
//\r
NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r
\r
- DEBUG((EFI_D_ERROR, "PCI Bus Second Scanning\n"));\r
+ DEBUG((EFI_D_INFO, "PCI Bus Second Scanning\n"));\r
RootBridgeHandle = NULL;\r
while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
\r
}\r
\r
//\r
+ // Add VF resource\r
+ //\r
+ for (Index = 0; Index < PCI_MAX_BAR; Index++) {\r
+\r
+ switch ((PciDev->VfPciBar)[Index].BarType) {\r
+\r
+ case PciBarTypeMem32:\r
+\r
+ Node = CreateVfResourceNode (\r
+ PciDev,\r
+ (PciDev->VfPciBar)[Index].Length,\r
+ (PciDev->VfPciBar)[Index].Alignment,\r
+ Index,\r
+ PciBarTypeMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ InsertResourceNode (\r
+ Mem32Node,\r
+ Node\r
+ );\r
+\r
+ break;\r
+\r
+ case PciBarTypeMem64:\r
+\r
+ Node = CreateVfResourceNode (\r
+ PciDev,\r
+ (PciDev->VfPciBar)[Index].Length,\r
+ (PciDev->VfPciBar)[Index].Alignment,\r
+ Index,\r
+ PciBarTypeMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ InsertResourceNode (\r
+ Mem64Node,\r
+ Node\r
+ );\r
+\r
+ break;\r
+\r
+ case PciBarTypePMem64:\r
+\r
+ Node = CreateVfResourceNode (\r
+ PciDev,\r
+ (PciDev->VfPciBar)[Index].Length,\r
+ (PciDev->VfPciBar)[Index].Alignment,\r
+ Index,\r
+ PciBarTypePMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ InsertResourceNode (\r
+ PMem64Node,\r
+ Node\r
+ );\r
+\r
+ break;\r
+\r
+ case PciBarTypePMem32:\r
+\r
+ Node = CreateVfResourceNode (\r
+ PciDev,\r
+ (PciDev->VfPciBar)[Index].Length,\r
+ (PciDev->VfPciBar)[Index].Alignment,\r
+ Index,\r
+ PciBarTypePMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ InsertResourceNode (\r
+ PMem32Node,\r
+ Node\r
+ );\r
+ break;\r
+\r
+ case PciBarTypeIo16:\r
+ case PciBarTypeIo32:\r
+ break;\r
+\r
+ case PciBarTypeUnknown:\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
// If there is no resource requested from this device,\r
// then we indicate this device has been allocated naturally.\r
//\r
return Node;\r
}\r
\r
+/**\r
+ This function is used to create a IOV VF resource node.\r
+\r
+ @param PciDev Pci device instance.\r
+ @param Length Length of Io/Memory resource.\r
+ @param Alignment Alignment of resource.\r
+ @param Bar Bar index.\r
+ @param ResType Type of resource: IO/Memory.\r
+ @param ResUsage Resource usage.\r
+\r
+ @return PCI resource node created for given VF PCI device.\r
+ NULL means PCI resource node is not created.\r
+\r
+**/\r
+PCI_RESOURCE_NODE *\r
+CreateVfResourceNode (\r
+ IN PCI_IO_DEVICE *PciDev,\r
+ IN UINT64 Length,\r
+ IN UINT64 Alignment,\r
+ IN UINT8 Bar,\r
+ IN PCI_BAR_TYPE ResType,\r
+ IN PCI_RESOURCE_USAGE ResUsage\r
+ )\r
+{\r
+ PCI_RESOURCE_NODE *Node;\r
+\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ "PCI-IOV B%x.D%x.F%x - VfResource (Bar - 0x%x) (Type - 0x%x) (Length - 0x%x)\n",\r
+ (UINTN)PciDev->BusNumber,\r
+ (UINTN)PciDev->DeviceNumber,\r
+ (UINTN)PciDev->FunctionNumber,\r
+ (UINTN)Bar,\r
+ (UINTN)ResType,\r
+ (UINTN)Length\r
+ ));\r
+\r
+ Node = CreateResourceNode (PciDev, Length, Alignment, Bar, ResType, ResUsage);\r
+ if (Node == NULL) {\r
+ return Node;\r
+ }\r
+\r
+ Node->Virtual = TRUE;\r
+\r
+ return Node;\r
+}\r
+\r
/**\r
This function is used to extract resource request from\r
device node list.\r
UINT64 Address;\r
UINT32 Address32;\r
\r
+ //\r
+ // Check VF BAR\r
+ //\r
+ if (Node->Virtual) {\r
+ ProgramVfBar (Base, Node);\r
+ }\r
+\r
Address = 0;\r
PciIo = &(Node->PciDev->PciIo);\r
\r
}\r
}\r
\r
+/**\r
+ Program IOV VF Bar register for PCI device.\r
+\r
+ @param Base Base address for PCI device resource to be progammed.\r
+ @param Node Point to resoure node structure.\r
+\r
+**/\r
+EFI_STATUS\r
+ProgramVfBar (\r
+ IN UINT64 Base,\r
+ IN PCI_RESOURCE_NODE *Node\r
+ )\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT64 Address;\r
+ UINT32 Address32;\r
+\r
+ ASSERT (Node->Virtual);\r
+ if (!Node->Virtual) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Address = 0;\r
+ PciIo = &(Node->PciDev->PciIo);\r
+\r
+ Address = Base + Node->Offset;\r
+\r
+ //\r
+ // Indicate pci bus driver has allocated\r
+ // resource for this device\r
+ // It might be a temporary solution here since\r
+ // pci device could have multiple bar\r
+ //\r
+ Node->PciDev->Allocated = TRUE;\r
+\r
+ switch ((Node->PciDev->VfPciBar[Node->Bar]).BarType) {\r
+\r
+ case PciBarTypeMem32:\r
+ case PciBarTypePMem32:\r
+\r
+ PciIo->Pci.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ (Node->PciDev->VfPciBar[Node->Bar]).Offset,\r
+ 1,\r
+ &Address\r
+ );\r
+\r
+ Node->PciDev->VfPciBar[Node->Bar].BaseAddress = Address;\r
+\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ "PCI-IOV B%x.D%x.F%x - VF Bar (Offset - 0x%x) 32Mem (Address - 0x%x)\n",\r
+ (UINTN)Node->PciDev->BusNumber,\r
+ (UINTN)Node->PciDev->DeviceNumber,\r
+ (UINTN)Node->PciDev->FunctionNumber,\r
+ (UINTN)(Node->PciDev->VfPciBar[Node->Bar]).Offset,\r
+ (UINTN)Address\r
+ ));\r
+\r
+ break;\r
+\r
+ case PciBarTypeMem64:\r
+ case PciBarTypePMem64:\r
+\r
+ Address32 = (UINT32) (Address & 0x00000000FFFFFFFF);\r
+\r
+ PciIo->Pci.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ (Node->PciDev->VfPciBar[Node->Bar]).Offset,\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Address32 = (UINT32) RShiftU64 (Address, 32);\r
+\r
+ PciIo->Pci.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ ((Node->PciDev->VfPciBar[Node->Bar]).Offset + 4),\r
+ 1,\r
+ &Address32\r
+ );\r
+\r
+ Node->PciDev->VfPciBar[Node->Bar].BaseAddress = Address;\r
+\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ "PCI-IOV B%x.D%x.F%x - VF Bar (Offset - 0x%x) 64Mem (Address - 0x%lx)\n",\r
+ (UINTN)Node->PciDev->BusNumber,\r
+ (UINTN)Node->PciDev->DeviceNumber,\r
+ (UINTN)Node->PciDev->FunctionNumber,\r
+ (UINTN)(Node->PciDev->VfPciBar[Node->Bar]).Offset,\r
+ (UINT64)Address\r
+ ));\r
+\r
+ break;\r
+\r
+ case PciBarTypeIo16:\r
+ case PciBarTypeIo32:\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Program PCI-PCI bridge apperture.\r
\r
UINT64 Length;\r
BOOLEAN Reserved;\r
PCI_RESOURCE_USAGE ResourceUsage;\r
+ BOOLEAN Virtual;\r
} PCI_RESOURCE_NODE;\r
\r
#define RESOURCE_NODE_FROM_LINK(a) \\r
IN PCI_RESOURCE_USAGE ResUsage\r
);\r
\r
+/**\r
+ This function is used to extract resource request from\r
+ IOV VF device node list.\r
+\r
+ @param Bridge Pci device instance.\r
+ @param IoNode Resource info node for IO.\r
+ @param Mem32Node Resource info node for 32-bit memory.\r
+ @param PMem32Node Resource info node for 32-bit Prefetchable Memory.\r
+ @param Mem64Node Resource info node for 64-bit memory.\r
+ @param PMem64Node Resource info node for 64-bit Prefetchable Memory.\r
+\r
+**/\r
+PCI_RESOURCE_NODE *\r
+CreateVfResourceNode (\r
+ IN PCI_IO_DEVICE *PciDev,\r
+ IN UINT64 Length,\r
+ IN UINT64 Alignment,\r
+ IN UINT8 Bar,\r
+ IN PCI_BAR_TYPE ResType,\r
+ IN PCI_RESOURCE_USAGE ResUsage\r
+ );\r
+\r
/**\r
This function is used to extract resource request from\r
device node list.\r
IN PCI_RESOURCE_NODE *Node\r
);\r
\r
+/**\r
+ Program IOV VF Bar register for PCI device.\r
+\r
+ @param Base Base address for PCI device resource to be progammed.\r
+ @param Node Point to resoure node structure.\r
+\r
+**/\r
+EFI_STATUS\r
+ProgramVfBar (\r
+ IN UINT64 Base,\r
+ IN PCI_RESOURCE_NODE *Node\r
+ );\r
+\r
/**\r
Program PCI-PCI bridge apperture.\r
\r
## This PCD specifies whether Serial device use half hand shake.\r
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdIsaBusSerialUseHalfHandshake|FALSE|BOOLEAN|0x00010043\r
\r
+ ## This PCD specifies whether the Single Root I/O virtualization support.\r
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSrIovSupport|TRUE|BOOLEAN|0x10000044\r
+\r
+ ## This PCD specifies whether the Alternative Routing-ID support.\r
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdAriSupport|TRUE|BOOLEAN|0x10000045\r
+\r
+ ## This PCD specifies whether the Multi Root I/O virtualization support.\r
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdMrIovSupport|FALSE|BOOLEAN|0x10000046\r
+\r
+\r
[PcdsFixedAtBuild]\r
## FFS filename to find the default BMP Logo file.\r
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile |{ 0x99, 0x8b, 0xB2, 0x7B, 0xBB, 0x61, 0xD5, 0x11, 0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }|VOID*|16\r
# BIT2 indicates if ISA memory is supported\r
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdIsaBusSupportedFeatures|0x05|UINT8|0x00010040\r
\r
+ ## Single root I/O virtualization virtual function memory BAR alignment\r
+ # BITN set indicates 2 of n+12 power\r
+ # BIT0 set indicates 4KB alignment\r
+ # BIT1 set indicates 8KB alignment\r
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize|0x1|UINT32|0x10000047\r
+\r
[PcdsFixedAtBuild,PcdsPatchableInModule,PcdsDynamic]\r
## PcdStatusCodeMemorySize is used when PcdStatusCodeUseMemory is set to true\r
# (PcdStatusCodeMemorySize * KBytes) is the total taken memory size.\r