From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from huawei.com (huawei.com [45.249.212.35]) by mx.groups.io with SMTP id smtpd.web10.5115.1585829304579309563 for ; Thu, 02 Apr 2020 05:08:25 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: huawei.com, ip: 45.249.212.35, mailfrom: miaoyubo@huawei.com) Received: from DGGEMS402-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id B9E82C7EC6FC15A02DA7; Thu, 2 Apr 2020 20:08:21 +0800 (CST) Received: from DESKTOP-D7EVK5B.china.huawei.com (10.173.221.29) by DGGEMS402-HUB.china.huawei.com (10.3.19.202) with Microsoft SMTP Server id 14.3.487.0; Thu, 2 Apr 2020 20:08:14 +0800 From: Yubo Miao To: , , CC: , , Subject: [PATCH] ArmVirtPkg/FdtPciHostBridgeLib: add extra roots for Arm. Date: Thu, 2 Apr 2020 20:08:03 +0800 Message-ID: <20200402120803.1482-1-miaoyubo@huawei.com> X-Mailer: git-send-email 2.24.1.windows.2 MIME-Version: 1.0 X-Originating-IP: [10.173.221.29] X-CFilter-Loop: Reflected Content-Transfer-Encoding: quoted-printable Content-Type: text/plain From: miaoyubo Add support for extra roots for arm, in this patch, we import the scan for extra root buses therefore the uefi could recognize multiply roots for arm. The logic keeps the same with the logic in "OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c" Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: miaoyubo --- .../FdtPciHostBridgeLib/FdtPciHostBridgeLib.c | 264 +++++++++++++++--- .../FdtPciHostBridgeLib.inf | 3 + 2 files changed, 230 insertions(+), 37 deletions(-) diff --git a/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c b= /ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c index 496b192d22..706efeb416 100644 --- a/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c +++ b/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c @@ -14,6 +14,10 @@ #include =0D #include =0D #include =0D +#include =0D +#include =0D +#include =0D +#include =0D =0D #include =0D #include =0D @@ -306,7 +310,70 @@ ProcessPciHost ( return Status;=0D }=0D =0D -STATIC PCI_ROOT_BRIDGE mRootBridge;=0D +EFI_STATUS=0D +InitRootBridge (=0D + IN UINT64 Supports,=0D + IN UINT64 Attributes,=0D + IN UINT64 AllocAttributes,=0D + IN UINT8 RootBusNumber,=0D + IN UINT8 MaxSubBusNumber,=0D + IN PCI_ROOT_BRIDGE_APERTURE *Io,=0D + IN PCI_ROOT_BRIDGE_APERTURE *Mem,=0D + IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,=0D + IN PCI_ROOT_BRIDGE_APERTURE *PMem,=0D + IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,=0D + OUT PCI_ROOT_BRIDGE *RootBus=0D + )=0D +{=0D + EFI_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;=0D +=0D + //=0D + // Be safe if other fields are added to PCI_ROOT_BRIDGE later.=0D + //=0D + ZeroMem (RootBus, sizeof *RootBus);=0D +=0D + RootBus->Segment =3D 0;=0D + RootBus->ResourceAssigned =3D FALSE;=0D + RootBus->Supports =3D Supports;=0D + RootBus->Attributes =3D Attributes;=0D +=0D + RootBus->DmaAbove4G =3D TRUE;=0D +=0D + RootBus->AllocationAttributes =3D AllocAttributes;=0D + RootBus->Bus.Base =3D RootBusNumber;=0D + RootBus->Bus.Limit =3D MaxSubBusNumber;=0D + CopyMem (&RootBus->Io, Io, sizeof (*Io));=0D + CopyMem (&RootBus->Mem, Mem, sizeof (*Mem));=0D + CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G));=0D + CopyMem (&RootBus->PMem, PMem, sizeof (*PMem));=0D + CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof (*PMemAbove4G));=0D +=0D + RootBus->NoExtendedConfigSpace =3D FALSE;=0D +=0D + DevicePath =3D AllocateCopyPool (sizeof mEfiPciRootBridgeDevicePath,=0D + &mEfiPciRootBridgeDevicePath);=0D + if (DevicePath =3D=3D NULL) {=0D + DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));= =0D + return EFI_OUT_OF_RESOURCES;=0D + }=0D + DevicePath->AcpiDevicePath.UID =3D RootBusNumber;=0D + RootBus->DevicePath =3D (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;=0D +=0D + DEBUG ((EFI_D_INFO,=0D + "%a: populated root bus %d, with room for %d subordinate bus(es)\n",=0D + __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber));=0D + return EFI_SUCCESS;=0D +}=0D +=0D +STATIC=0D +VOID=0D +UninitRootBridge (=0D + IN PCI_ROOT_BRIDGE *RootBus=0D + )=0D +{=0D + FreePool (RootBus->DevicePath);=0D +}=0D +=0D =0D /**=0D Return all the root bridge instances in an array.=0D @@ -323,11 +390,25 @@ PciHostBridgeGetRootBridges ( UINTN *Count=0D )=0D {=0D - UINT64 IoBase, IoSize;=0D - UINT64 Mmio32Base, Mmio32Size;=0D - UINT64 Mmio64Base, Mmio64Size;=0D - UINT32 BusMin, BusMax;=0D - EFI_STATUS Status;=0D + UINT64 IoBase, IoSize;=0D + UINT64 Mmio32Base, Mmio32Size;=0D + UINT64 Mmio64Base, Mmio64Size;=0D + UINT32 BusMin, BusMax;=0D + FIRMWARE_CONFIG_ITEM FwCfgItem;=0D + UINTN FwCfgSize;=0D + UINT64 ExtraRootBridges;=0D + PCI_ROOT_BRIDGE *Bridges;=0D + UINTN Initialized;=0D + UINTN LastRootBridgeNumber;=0D + UINTN RootBridgeNumber;=0D + UINT64 Attributes;=0D + UINT64 AllocationAttributes;=0D + EFI_STATUS Status;=0D + PCI_ROOT_BRIDGE_APERTURE Io;=0D + PCI_ROOT_BRIDGE_APERTURE PMem;=0D + PCI_ROOT_BRIDGE_APERTURE PMemAbove4G;=0D + PCI_ROOT_BRIDGE_APERTURE Mem;=0D + PCI_ROOT_BRIDGE_APERTURE MemAbove4G;=0D =0D if (PcdGet64 (PcdPciExpressBaseAddress) =3D=3D 0) {=0D DEBUG ((EFI_D_INFO, "%a: PCI host bridge not present\n", __FUNCTION__)= );=0D @@ -345,33 +426,27 @@ PciHostBridgeGetRootBridges ( return NULL;=0D }=0D =0D - *Count =3D 1;=0D + ZeroMem (&Io, sizeof (Io));=0D + ZeroMem (&Mem, sizeof (Mem));=0D + ZeroMem (&MemAbove4G, sizeof (MemAbove4G));=0D =0D - mRootBridge.Segment =3D 0;=0D - mRootBridge.Supports =3D EFI_PCI_ATTRIBUTE_ISA_IO_16 |=0D - EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO= |=0D - EFI_PCI_ATTRIBUTE_VGA_IO_16 |=0D - EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;= =0D - mRootBridge.Attributes =3D mRootBridge.Supports;=0D + Attributes =3D EFI_PCI_ATTRIBUTE_ISA_IO_16 |=0D + EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |=0D + EFI_PCI_ATTRIBUTE_VGA_IO_16 |=0D + EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;=0D =0D - mRootBridge.DmaAbove4G =3D TRUE;=0D - mRootBridge.NoExtendedConfigSpace =3D FALSE;=0D - mRootBridge.ResourceAssigned =3D FALSE;=0D + AllocationAttributes =3D EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM;=0D =0D - mRootBridge.AllocationAttributes =3D EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PM= EM;=0D -=0D - mRootBridge.Bus.Base =3D BusMin;=0D - mRootBridge.Bus.Limit =3D BusMax;=0D - mRootBridge.Io.Base =3D IoBase;=0D - mRootBridge.Io.Limit =3D IoBase + IoSize - 1;=0D - mRootBridge.Mem.Base =3D Mmio32Base;=0D - mRootBridge.Mem.Limit =3D Mmio32Base + Mmio32Size - 1;=0D + Io.Base =3D IoBase;=0D + Io.Limit =3D IoBase + IoSize - 1;=0D + Mem.Base =3D Mmio32Base;=0D + Mem.Limit =3D Mmio32Base + Mmio32Size - 1;=0D =0D if (sizeof (UINTN) =3D=3D sizeof (UINT64)) {=0D - mRootBridge.MemAbove4G.Base =3D Mmio64Base;=0D - mRootBridge.MemAbove4G.Limit =3D Mmio64Base + Mmio64Size - 1;=0D + MemAbove4G.Base =3D Mmio64Base;=0D + MemAbove4G.Limit =3D Mmio64Base + Mmio64Size - 1;=0D if (Mmio64Size > 0) {=0D - mRootBridge.AllocationAttributes |=3D EFI_PCI_HOST_BRIDGE_MEM64_DECO= DE;=0D + AllocationAttributes |=3D EFI_PCI_HOST_BRIDGE_MEM64_DECODE;=0D }=0D } else {=0D //=0D @@ -380,21 +455,127 @@ PciHostBridgeGetRootBridges ( // BARs unless they are allocated below 4 GB. So ignore the range abov= e=0D // 4 GB in this case.=0D //=0D - mRootBridge.MemAbove4G.Base =3D MAX_UINT64;=0D - mRootBridge.MemAbove4G.Limit =3D 0;=0D + MemAbove4G.Base =3D MAX_UINT64;=0D + MemAbove4G.Limit =3D 0;=0D }=0D =0D //=0D // No separate ranges for prefetchable and non-prefetchable BARs=0D //=0D - mRootBridge.PMem.Base =3D MAX_UINT64;=0D - mRootBridge.PMem.Limit =3D 0;=0D - mRootBridge.PMemAbove4G.Base =3D MAX_UINT64;=0D - mRootBridge.PMemAbove4G.Limit =3D 0;=0D + PMem.Base =3D MAX_UINT64;=0D + PMem.Limit =3D 0;=0D + PMemAbove4G.Base =3D MAX_UINT64;=0D + PMemAbove4G.Limit =3D 0;=0D +=0D + //=0D + // QEMU provides the number of extra root buses, shortening the exhausti= ve=0D + // search below. If there is no hint, the feature is missing.=0D + //=0D + Status =3D QemuFwCfgFindFile ("etc/extra-pci-roots", &FwCfgItem, &FwCfgS= ize);=0D + if (EFI_ERROR (Status) || FwCfgSize !=3D sizeof ExtraRootBridges) {=0D + ExtraRootBridges =3D 0;=0D + } else {=0D + QemuFwCfgSelectItem (FwCfgItem);=0D + QemuFwCfgReadBytes (FwCfgSize, &ExtraRootBridges);=0D =0D - mRootBridge.DevicePath =3D (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridg= eDevicePath;=0D + if (ExtraRootBridges > BusMax) {=0D + DEBUG ((EFI_D_ERROR, "%a: invalid count of extra root buses (%Lu) "= =0D + "reported by QEMU\n", __FUNCTION__, ExtraRootBridges));=0D + return NULL;=0D + }=0D + DEBUG ((EFI_D_INFO, "%a: %Lu extra root buses reported by QEMU\n",=0D + __FUNCTION__, ExtraRootBridges));=0D + }=0D =0D - return &mRootBridge;=0D + //=0D + // Allocate the "main" root bridge, and any extra root bridges.=0D + //=0D + Bridges =3D AllocatePool ((1 + (UINTN)ExtraRootBridges) * sizeof *Bridge= s);=0D + if (Bridges =3D=3D NULL) {=0D + DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));= =0D + return NULL;=0D + }=0D + Initialized =3D 0;=0D +=0D + //=0D + // The "main" root bus is always there.=0D + //=0D + LastRootBridgeNumber =3D 0;=0D + //=0D + // Scan all other root buses. If function 0 of any device on a bus retur= ns a=0D + // VendorId register value different from all-bits-one, then that bus is= =0D + // alive.=0D + //=0D + for (RootBridgeNumber =3D 1;=0D + RootBridgeNumber <=3D BusMax && Initialized < ExtraRootBridges;=0D + ++RootBridgeNumber) {=0D + UINTN Device;=0D +=0D + for (Device =3D 0; Device <=3D PCI_MAX_DEVICE; ++Device) {=0D + if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0,=0D + PCI_VENDOR_ID_OFFSET)) !=3D MAX_UINT16) {=0D + break;=0D + }=0D + }=0D + if (Device <=3D PCI_MAX_DEVICE) {=0D + //=0D + // Found the next root bus. We can now install the *previous* one,=0D + // because now we know how big a bus number range *that* one has, fo= r any=0D + // subordinate buses that might exist behind PCI bridges hanging off= it.=0D + //=0D + Status =3D InitRootBridge (=0D + Attributes,=0D + Attributes,=0D + AllocationAttributes,=0D + (UINT8) LastRootBridgeNumber,=0D + (UINT8) (RootBridgeNumber - 1),=0D + &Io,=0D + &Mem,=0D + &MemAbove4G,=0D + &PMem,=0D + &PMemAbove4G,=0D + &Bridges[Initialized]=0D + );=0D + if (EFI_ERROR (Status)) {=0D + goto FreeBridges;=0D + }=0D + ++Initialized;=0D + LastRootBridgeNumber =3D RootBridgeNumber;=0D + }=0D + }=0D + //=0D + // Install the last root bus (which might be the only, ie. main, root bu= s, if=0D + // we've found no extra root buses).=0D + //=0D + Status =3D InitRootBridge (=0D + Attributes,=0D + Attributes,=0D + AllocationAttributes,=0D + (UINT8) LastRootBridgeNumber,=0D + BusMax,=0D + &Io,=0D + &Mem,=0D + &MemAbove4G,=0D + &PMem,=0D + &PMemAbove4G,=0D + &Bridges[Initialized]=0D + );=0D + if (EFI_ERROR (Status)) {=0D + goto FreeBridges;=0D + }=0D + ++Initialized;=0D +=0D + *Count =3D Initialized;=0D + return Bridges;=0D +=0D +FreeBridges:=0D + while (Initialized > 0) {=0D + --Initialized;=0D + UninitRootBridge (&Bridges[Initialized]);=0D + }=0D +=0D + FreePool (Bridges);=0D + return NULL;=0D }=0D =0D /**=0D @@ -411,9 +592,18 @@ PciHostBridgeFreeRootBridges ( UINTN Count=0D )=0D {=0D - ASSERT (Count =3D=3D 1);=0D -}=0D + if (Bridges =3D=3D NULL && Count =3D=3D 0) {=0D + return;=0D + }=0D + ASSERT (Bridges !=3D NULL && Count > 0);=0D +=0D + do {=0D + --Count;=0D + UninitRootBridge (&Bridges[Count]);=0D + } while (Count > 0);=0D =0D + FreePool (Bridges);=0D +}=0D /**=0D Inform the platform that the resource conflict happens.=0D =0D diff --git a/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf= b/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf index 277ccfd245..3ac58855af 100644 --- a/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf +++ b/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf @@ -31,11 +31,14 @@ ArmVirtPkg/ArmVirtPkg.dec=0D MdeModulePkg/MdeModulePkg.dec=0D MdePkg/MdePkg.dec=0D + OvmfPkg/OvmfPkg.dec=0D =0D [LibraryClasses]=0D DebugLib=0D DevicePathLib=0D DxeServicesTableLib=0D + BaseMemoryLib=0D + QemuFwCfgLib=0D MemoryAllocationLib=0D PciPcdProducerLib=0D =0D --=20 2.19.1