From: Ming Huang waip23@foxmail.com
1. Because Hi161x chip doesn't support "ARI Forwarding Enable" function, BIOS will enumerate 32 same devices (Device Number 0~31) when attach a Non-ARI capable device in the RP. Hi161x chip will not fix it, need BIOS patch. 2. Just enlarge iatu for those root port with ARI capable device attached, Non-ARI capable device's RP, keep iatu limitation. 3. Remove previous temporary solution as below commit id: "7d157da88852cc91df2b11b10ade2edbbfbe77da"
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jason zhang zhangjinsong2@huawei.com
Conflicts: Chips/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c --- .../Drivers/PciHostBridgeDxe/PciHostBridge.c | 1 + .../Drivers/PciHostBridgeDxe/PciHostBridge.h | 4 ++ .../Drivers/PciHostBridgeDxe/PciRootBridgeIo.c | 83 ++++++++++++++++++++-- 3 files changed, 81 insertions(+), 7 deletions(-)
diff --git a/Chips/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c b/Chips/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c index 6ecc1e5..5bc04a2 100644 --- a/Chips/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c +++ b/Chips/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.c @@ -839,6 +839,7 @@ NotifyPhase(
case EfiPciHostBridgeEndEnumeration: PCIE_DEBUG("Case EfiPciHostBridgeEndEnumeration\n"); + EnlargeAtuConfig0 (This); break;
case EfiPciHostBridgeBeginBusAllocation: diff --git a/Chips/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h b/Chips/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h index cddda6b..925ed40 100644 --- a/Chips/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h +++ b/Chips/Hisilicon/Drivers/PciHostBridgeDxe/PciHostBridge.h @@ -518,4 +518,8 @@ RootBridgeConstructor ( IN UINT32 Seg );
+VOID +EnlargeAtuConfig0 ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This + ); #endif diff --git a/Chips/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c b/Chips/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c index 2effd7c..b41dbe2 100644 --- a/Chips/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c +++ b/Chips/Hisilicon/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c @@ -14,6 +14,7 @@ **/
#include "PciHostBridge.h" +#include <IndustryStandard/PciExpress30.h> #include <Library/DevicePathLib.h> #include <Library/DmaLib.h> #include <Library/PciExpressLib.h> @@ -1770,13 +1771,6 @@ RootBridgeIoPciRead ( return EFI_INVALID_PARAMETER; }
- if ((EfiPciAddress->Bus == 0x81) && (PrivateData->MemBase == 0xAA000000) && (EfiPciAddress->Device > 0)) { - return EFI_NOT_FOUND; - } - if ((EfiPciAddress->Bus == 0x91) && (EfiPciAddress->Device > 0)) { - return EFI_NOT_FOUND; - } - // The UEFI PCI enumerator scans for devices at all possible addresses, // and ignores some PCI rules - this results in some hardware being // detected multiple times. We work around this by faking absent @@ -2329,3 +2323,78 @@ RootBridgeIoConfiguration ( return EFI_SUCCESS; }
+BOOLEAN +PcieCheckAriFwdEn ( + UINTN PciBaseAddr + ) +{ + UINT8 PciPrimaryStatus; + UINT8 CapabilityOffset; + UINT8 CapId; + UINT8 TempData; + + PciPrimaryStatus = MmioRead16 (PciBaseAddr + PCI_PRIMARY_STATUS_OFFSET); + + if (PciPrimaryStatus & EFI_PCI_STATUS_CAPABILITY) { + CapabilityOffset = MmioRead8 (PciBaseAddr + PCI_CAPBILITY_POINTER_OFFSET); + CapabilityOffset &= ~(BIT0 | BIT1); + + while ((CapabilityOffset != 0) && (CapabilityOffset != 0xff)) { + CapId = MmioRead8 (PciBaseAddr + CapabilityOffset); + if (CapId == EFI_PCI_CAPABILITY_ID_PCIEXP) { + break; + } + CapabilityOffset = MmioRead8 (PciBaseAddr + CapabilityOffset + 1); + CapabilityOffset &= ~(BIT0 | BIT1); + } + } else { + PCIE_DEBUG ("[%a:%d] - No PCIE Capability.\n", __FUNCTION__, __LINE__); + return FALSE; + } + + if ((CapabilityOffset == 0xff) || (CapabilityOffset == 0x0)) { + PCIE_DEBUG ("[%a:%d] - No PCIE Capability.\n", __FUNCTION__, __LINE__); + return FALSE; + } + + TempData = MmioRead16 (PciBaseAddr + CapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET); + TempData &= EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING; + + if (TempData == EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING) { + return TRUE; + } else { + return FALSE; + } +} + +VOID +EnlargeAtuConfig0 ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This + ) +{ + UINTN RbPciBase; + UINT64 MemLimit; + LIST_ENTRY *List; + PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance; + PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance; + + PCIE_DEBUG ("In Enlarge RP iatu Config 0.\n"); + + HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This); + List = HostBridgeInstance->Head.ForwardLink; + + while (List != &HostBridgeInstance->Head) { + PCIE_DEBUG ("HostBridge has data.\n"); + RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List); + + RbPciBase = RootBridgeInstance->RbPciBar; + + // Those ARI FWD Enable Root Bridge, need enlarge iatu window. + if (PcieCheckAriFwdEn (RbPciBase)) { + MemLimit = GetPcieCfgAddress (RootBridgeInstance->Ecam, RootBridgeInstance->BusBase + 2, 0, 0, 0) - 1; + MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_VIEW_POINT, 1); + MmioWrite32 (RbPciBase + IATU_OFFSET + IATU_REGION_BASE_LIMIT, (UINT32) MemLimit); + } + List = List->ForwardLink; + } +}