UINT32 SystemPageSize;\r
UINT16 InitialVFs;\r
UINT16 ReservedBusNum;\r
+ //\r
+ // Per PCI to PCI Bridge spec, I/O window is 4K aligned,\r
+ // but some chipsets support non-stardard I/O window aligments less than 4K.\r
+ // This field is used to support this case.\r
+ //\r
+ UINT16 BridgeIoAlignment;\r
};\r
\r
#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \\r
gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport\r
gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport\r
gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport\r
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciBridgeIoAlignmentProbe\r
\r
[FixedPcd.common]\r
gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize\r
+\r
# [Event]\r
# ##\r
# # Notify event set by CreateEventForHpc () for PCI Hot Plug controller.\r
IoBridge = CreateResourceNode (\r
Bridge,\r
0,\r
- 0xFFF,\r
+ Bridge->BridgeIoAlignment,\r
0,\r
PciBarTypeIo16,\r
PciResUsageTypical\r
}\r
}\r
\r
+ //\r
+ // if PcdPciBridgeIoAlignmentProbe is TRUE, PCI bus driver probes\r
+ // PCI bridge supporting non-stardard I/O window alignment less than 4K.\r
+ //\r
+\r
+ PciIoDevice->BridgeIoAlignment = 0xFFF;\r
+ if (FeaturePcdGet (PcdPciBridgeIoAlignmentProbe)) {\r
+ //\r
+ // Check any bits of bit 3-1 of I/O Base Register are writable.\r
+ // if so, it is assumed non-stardard I/O window alignment is supported by this bridge.\r
+ // Per spec, bit 3-1 of I/O Base Register are reserved bits, so its content can't be assumed.\r
+ //\r
+ Value = Temp ^ (BIT3 | BIT2 | BIT1);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value);\r
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);\r
+ Value = (Value ^ Temp) & (BIT3 | BIT2 | BIT1);\r
+ switch (Value) {\r
+ case BIT3:\r
+ PciIoDevice->BridgeIoAlignment = 0x7FF;\r
+ break;\r
+ case BIT3 | BIT2:\r
+ PciIoDevice->BridgeIoAlignment = 0x3FF;\r
+ break;\r
+ case BIT3 | BIT2 | BIT1:\r
+ PciIoDevice->BridgeIoAlignment = 0x1FF;\r
+ break;\r
+ }\r
+ }\r
+\r
Status = BarExisted (\r
PciIoDevice,\r
0x24,\r
// enumerator. Several resource tree was created\r
//\r
\r
+ //\r
+ // If non-stardard PCI Bridge I/O window alignment is supported,\r
+ // set I/O aligment to minimum possible alignment for root bridge.\r
+ //\r
IoBridge = CreateResourceNode (\r
RootBridgeDev,\r
0,\r
- 0xFFF,\r
+ FeaturePcdGet (PcdPciBridgeIoAlignmentProbe) ? 0x1FF: 0xFFF,\r
0,\r
PciBarTypeIo16,\r
PciResUsageTypical\r
//\r
// If the device has children, create a bridge resource node for this PPB\r
// Note: For PPB, memory aperture is aligned with 1MB and IO aperture\r
- // is aligned with 4KB\r
- // This device is typically a bridge device like PPB and P2C\r
- // Note: 0x1000 aligned\r
+ // is aligned with 4KB (smaller alignments may be supported).\r
//\r
IoBridge = CreateResourceNode (\r
Temp,\r
0,\r
- 0xFFF,\r
+ Temp->BridgeIoAlignment,\r
PPB_IO_RANGE,\r
PciBarTypeIo16,\r
PciResUsageTypical\r
## This PCD specifies whether the Multi Root I/O virtualization support.\r
gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport|FALSE|BOOLEAN|0x10000046\r
\r
+ ## This PCD specifies whether the PCI bus driver probes non-standard, \r
+ # such as 2K/1K/512, granularity for PCI to PCI bridge I/O window.\r
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciBridgeIoAlignmentProbe|FALSE|BOOLEAN|0x10000047\r
\r
[PcdsFeatureFlag.IA32]\r
##\r