From 1ef267831621d709d685c6e65856bdf711ea7b79 Mon Sep 17 00:00:00 2001 From: rsun3 Date: Thu, 24 Dec 2009 11:58:04 +0000 Subject: Update PCI bus driver to support non-standard PCI to PCI bridge I/O window alignment, such as 2K/1K/512 byte. Feature PCD PcdPciBridgeIoAlignmentProbe is introduced to turn on/off this feature. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9598 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 6 +++++ MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 2 ++ MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c | 2 +- .../Bus/Pci/PciBusDxe/PciEnumeratorSupport.c | 30 ++++++++++++++++++++++ MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c | 6 ++++- .../Bus/Pci/PciBusDxe/PciResourceSupport.c | 6 ++--- MdeModulePkg/MdeModulePkg.dec | 3 +++ 7 files changed, 49 insertions(+), 6 deletions(-) (limited to 'MdeModulePkg') diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h index 722f31d..90fdaa3 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h @@ -268,6 +268,12 @@ struct _PCI_IO_DEVICE { UINT32 SystemPageSize; UINT16 InitialVFs; UINT16 ReservedBusNum; + // + // Per PCI to PCI Bridge spec, I/O window is 4K aligned, + // but some chipsets support non-stardard I/O window aligments less than 4K. + // This field is used to support this case. + // + UINT16 BridgeIoAlignment; }; #define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \ diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf index cd7865c..5d502f6 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf @@ -104,9 +104,11 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport + gEfiMdeModulePkgTokenSpaceGuid.PcdPciBridgeIoAlignmentProbe [FixedPcd.common] gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize + # [Event] # ## # # Notify event set by CreateEventForHpc () for PCI Hot Plug controller. diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c index bd256cf..ece3ee8 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c @@ -1428,7 +1428,7 @@ PciBridgeResourceAllocator ( IoBridge = CreateResourceNode ( Bridge, 0, - 0xFFF, + Bridge->BridgeIoAlignment, 0, PciBarTypeIo16, PciResUsageTypical diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c index 8f3ed5e..940d8d2 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c @@ -469,6 +469,36 @@ GatherPpbInfo ( } } + // + // if PcdPciBridgeIoAlignmentProbe is TRUE, PCI bus driver probes + // PCI bridge supporting non-stardard I/O window alignment less than 4K. + // + + PciIoDevice->BridgeIoAlignment = 0xFFF; + if (FeaturePcdGet (PcdPciBridgeIoAlignmentProbe)) { + // + // Check any bits of bit 3-1 of I/O Base Register are writable. + // if so, it is assumed non-stardard I/O window alignment is supported by this bridge. + // Per spec, bit 3-1 of I/O Base Register are reserved bits, so its content can't be assumed. + // + Value = Temp ^ (BIT3 | BIT2 | BIT1); + PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value); + PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value); + PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp); + Value = (Value ^ Temp) & (BIT3 | BIT2 | BIT1); + switch (Value) { + case BIT3: + PciIoDevice->BridgeIoAlignment = 0x7FF; + break; + case BIT3 | BIT2: + PciIoDevice->BridgeIoAlignment = 0x3FF; + break; + case BIT3 | BIT2 | BIT1: + PciIoDevice->BridgeIoAlignment = 0x1FF; + break; + } + } + Status = BarExisted ( PciIoDevice, 0x24, diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c index f400006..d01a1f8 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c @@ -236,10 +236,14 @@ PciHostBridgeResourceAllocator ( // enumerator. Several resource tree was created // + // + // If non-stardard PCI Bridge I/O window alignment is supported, + // set I/O aligment to minimum possible alignment for root bridge. + // IoBridge = CreateResourceNode ( RootBridgeDev, 0, - 0xFFF, + FeaturePcdGet (PcdPciBridgeIoAlignmentProbe) ? 0x1FF: 0xFFF, 0, PciBarTypeIo16, PciResUsageTypical diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c index 2cacd44..7fd856e 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c @@ -803,14 +803,12 @@ CreateResourceMap ( // // If the device has children, create a bridge resource node for this PPB // Note: For PPB, memory aperture is aligned with 1MB and IO aperture - // is aligned with 4KB - // This device is typically a bridge device like PPB and P2C - // Note: 0x1000 aligned + // is aligned with 4KB (smaller alignments may be supported). // IoBridge = CreateResourceNode ( Temp, 0, - 0xFFF, + Temp->BridgeIoAlignment, PPB_IO_RANGE, PciBarTypeIo16, PciResUsageTypical diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 3e25d81..d8a2d4c 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -244,6 +244,9 @@ ## This PCD specifies whether the Multi Root I/O virtualization support. gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport|FALSE|BOOLEAN|0x10000046 + ## This PCD specifies whether the PCI bus driver probes non-standard, + # such as 2K/1K/512, granularity for PCI to PCI bridge I/O window. + gEfiMdeModulePkgTokenSpaceGuid.PcdPciBridgeIoAlignmentProbe|FALSE|BOOLEAN|0x10000047 [PcdsFeatureFlag.IA32] ## -- cgit v1.1