From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from szxga04-in.huawei.com (szxga04-in.huawei.com [45.249.212.190]) by mx.groups.io with SMTP id smtpd.web12.9685.1608631235616125676 for ; Tue, 22 Dec 2020 02:00:36 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: huawei.com, ip: 45.249.212.190, mailfrom: cenjiahui@huawei.com) Received: from DGGEMS411-HUB.china.huawei.com (unknown [172.30.72.59]) by szxga04-in.huawei.com (SkyGuard) with ESMTP id 4D0Wyy733Lzkv3K; Tue, 22 Dec 2020 17:59:38 +0800 (CST) Received: from localhost (10.174.184.155) by DGGEMS411-HUB.china.huawei.com (10.3.19.211) with Microsoft SMTP Server id 14.3.498.0; Tue, 22 Dec 2020 18:00:23 +0800 From: "Jiahui Cen" To: CC: Jordan Justen , Laszlo Ersek , Ard Biesheuvel , Rebecca Cran , Peter Grehan , Anthony Perard , Julien Grall , Leif Lindholm , Sami Mujawar , , , Jiahui Cen , Yubo Miao Subject: [PATCH v3 3/5] OvmfPkg: Extract functions for extra pci roots Date: Tue, 22 Dec 2020 17:59:42 +0800 Message-ID: <20201222095944.8686-4-cenjiahui@huawei.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201222095944.8686-1-cenjiahui@huawei.com> References: <20201222095944.8686-1-cenjiahui@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.174.184.155] X-CFilter-Loop: Reflected Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Extract functions that support extra pci roots from OvmfPkg/PciHostBridgeLib to share this feature with other packages. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3059 Cc: Jordan Justen Cc: Laszlo Ersek Cc: Ard Biesheuvel Signed-off-by: Jiahui Cen Signed-off-by: Yubo Miao --- OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf | = 2 - OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf | = 4 + OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h | 5= 8 ++++++ OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c | 15= 8 +-------------- OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c | 21= 2 ++++++++++++++++++++ 5 files changed, 285 insertions(+), 149 deletions(-) diff --git a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Ovmf= Pkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf index 4c56f3c90b3b..8bdb76899111 100644 --- a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf +++ b/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf @@ -40,8 +40,6 @@ [LibraryClasses] DevicePathLib MemoryAllocationLib PciHostBridgeUtilityLib - PciLib - QemuFwCfgLib =20 [Pcd] gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase diff --git a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtility= Lib.inf b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib= .inf index 1ba8ec3e03c7..a10afbe30c6b 100644 --- a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf +++ b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf @@ -30,8 +30,12 @@ [Sources] PciHostBridgeUtilityLib.c =20 [Packages] + MdeModulePkg/MdeModulePkg.dec MdePkg/MdePkg.dec OvmfPkg/OvmfPkg.dec =20 [LibraryClasses] DebugLib + MemoryAllocationLib + PciLib + QemuFwCfgLib diff --git a/OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h b/OvmfPkg/= Include/Library/PciHostBridgeUtilityLib.h index f932d412aa10..1d1c86c69064 100644 --- a/OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h +++ b/OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h @@ -14,6 +14,64 @@ #define __PCI_HOST_BRIDGE_UTILITY_LIB_H__ =20 =20 +#include + + +/** + Utility function to free root bridge instances array. + + @param The root bridge instances array. + @param The count of the array. +**/ +VOID +EFIAPI +PciHostBridgeUtilityFreeRootBridges ( + PCI_ROOT_BRIDGE *Bridges, + UINTN Count + ); + + +/** + Utility function to return all the root bridge instances in an array. + + @param Count The number of root bridge instances. + + @param[in] BusMin The min bus number. + + @param[in] BusMax The max bus number. + + @param[in] Attributes Initial attributes. + + @param[in] AllocAttributes Allocation attributes. + + @param[in] Io IO aperture. + + @param[in] Mem MMIO aperture. + + @param[in] MemAbove4G MMIO aperture above 4G. + + @param[in] PMem Prefetchable MMIO aperture. + + @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G. + + @return All the root bridge instances in an array= . +**/ +PCI_ROOT_BRIDGE * +EFIAPI +PciHostBridgeUtilityExtraRoots ( + UINTN *Count, + UINT32 BusMin, + UINT32 BusMax, + UINT64 Attributes, + UINT64 AllocationAttributes, + PCI_ROOT_BRIDGE_APERTURE Io, + PCI_ROOT_BRIDGE_APERTURE Mem, + PCI_ROOT_BRIDGE_APERTURE MemAbove4G, + PCI_ROOT_BRIDGE_APERTURE PMem, + PCI_ROOT_BRIDGE_APERTURE PMemAbove4G + ); + + /** Utility function to inform the platform that the resource conflict hap= pens. =20 diff --git a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/OvmfPk= g/Library/PciHostBridgeLib/PciHostBridgeLib.c index 4a176347fd49..19c6e9fa421a 100644 --- a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c +++ b/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -21,8 +21,6 @@ #include #include #include -#include -#include #include "PciHostBridge.h" =20 =20 @@ -160,23 +158,6 @@ InitRootBridge ( } =20 =20 -/** - Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge(). - - param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the cal= ler and - initialized with InitRootBridge(), that should be - uninitialized. This function doesn't free RootBus. -**/ -STATIC -VOID -UninitRootBridge ( - IN PCI_ROOT_BRIDGE *RootBus - ) -{ - FreePool (RootBus->DevicePath); -} - - /** Return all the root bridge instances in an array. =20 @@ -192,14 +173,6 @@ PciHostBridgeGetRootBridges ( UINTN *Count ) { - EFI_STATUS Status; - FIRMWARE_CONFIG_ITEM FwCfgItem; - UINTN FwCfgSize; - UINT64 ExtraRootBridges; - PCI_ROOT_BRIDGE *Bridges; - UINTN Initialized; - UINTN LastRootBridgeNumber; - UINTN RootBridgeNumber; UINT64 Attributes; UINT64 AllocationAttributes; PCI_ROOT_BRIDGE_APERTURE Io; @@ -239,117 +212,18 @@ PciHostBridgeGetRootBridges ( =20 *Count =3D 0; =20 - // - // QEMU provides the number of extra root buses, shortening the exhaus= tive - // search below. If there is no hint, the feature is missing. - // - Status =3D QemuFwCfgFindFile ("etc/extra-pci-roots", &FwCfgItem, &FwCf= gSize); - if (EFI_ERROR (Status) || FwCfgSize !=3D sizeof ExtraRootBridges) { - ExtraRootBridges =3D 0; - } else { - QemuFwCfgSelectItem (FwCfgItem); - QemuFwCfgReadBytes (FwCfgSize, &ExtraRootBridges); - - if (ExtraRootBridges > PCI_MAX_BUS) { - DEBUG ((DEBUG_ERROR, "%a: invalid count of extra root buses (%Lu) = " - "reported by QEMU\n", __FUNCTION__, ExtraRootBridges)); - return NULL; - } - DEBUG ((DEBUG_INFO, "%a: %Lu extra root buses reported by QEMU\n", - __FUNCTION__, ExtraRootBridges)); - } - - // - // Allocate the "main" root bridge, and any extra root bridges. - // - Bridges =3D AllocatePool ((1 + (UINTN)ExtraRootBridges) * sizeof *Brid= ges); - if (Bridges =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES)= ); - return NULL; - } - Initialized =3D 0; - - // - // The "main" root bus is always there. - // - LastRootBridgeNumber =3D 0; - - // - // Scan all other root buses. If function 0 of any device on a bus ret= urns a - // VendorId register value different from all-bits-one, then that bus = is - // alive. - // - for (RootBridgeNumber =3D 1; - RootBridgeNumber <=3D PCI_MAX_BUS && Initialized < ExtraRootBridg= es; - ++RootBridgeNumber) { - UINTN Device; - - for (Device =3D 0; Device <=3D PCI_MAX_DEVICE; ++Device) { - if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0, - PCI_VENDOR_ID_OFFSET)) !=3D MAX_UINT16) { - break; - } - } - if (Device <=3D PCI_MAX_DEVICE) { - // - // Found the next root bus. We can now install the *previous* one, - // because now we know how big a bus number range *that* one has, = for any - // subordinate buses that might exist behind PCI bridges hanging o= ff it. - // - Status =3D InitRootBridge ( - Attributes, - Attributes, - AllocationAttributes, - (UINT8) LastRootBridgeNumber, - (UINT8) (RootBridgeNumber - 1), - &Io, - &Mem, - &MemAbove4G, - &mNonExistAperture, - &mNonExistAperture, - &Bridges[Initialized] - ); - if (EFI_ERROR (Status)) { - goto FreeBridges; - } - ++Initialized; - LastRootBridgeNumber =3D RootBridgeNumber; - } - } - - // - // Install the last root bus (which might be the only, ie. main, root = bus, if - // we've found no extra root buses). - // - Status =3D InitRootBridge ( - Attributes, - Attributes, - AllocationAttributes, - (UINT8) LastRootBridgeNumber, + return PciHostBridgeUtilityExtraRoots ( + Count, + 0, PCI_MAX_BUS, - &Io, - &Mem, - &MemAbove4G, - &mNonExistAperture, - &mNonExistAperture, - &Bridges[Initialized] + Attributes, + AllocationAttributes, + Io, + Mem, + MemAbove4G, + mNonExistAperture, + mNonExistAperture ); - if (EFI_ERROR (Status)) { - goto FreeBridges; - } - ++Initialized; - - *Count =3D Initialized; - return Bridges; - -FreeBridges: - while (Initialized > 0) { - --Initialized; - UninitRootBridge (&Bridges[Initialized]); - } - - FreePool (Bridges); - return NULL; } =20 =20 @@ -367,17 +241,7 @@ PciHostBridgeFreeRootBridges ( UINTN Count ) { - if (Bridges =3D=3D NULL && Count =3D=3D 0) { - return; - } - ASSERT (Bridges !=3D NULL && Count > 0); - - do { - --Count; - UninitRootBridge (&Bridges[Count]); - } while (Count > 0); - - FreePool (Bridges); + PciHostBridgeUtilityFreeRootBridges (Bridges, Count); } =20 =20 diff --git a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtility= Lib.c b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c index bbaa5f830c98..a0cfd24ce477 100644 --- a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c +++ b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c @@ -11,8 +11,13 @@ **/ =20 #include +#include #include +#include #include +#include +#include +#include "Library/PciHostBridgeLib/PciHostBridge.h" =20 =20 GLOBAL_REMOVE_IF_UNREFERENCED @@ -21,6 +26,213 @@ CHAR16 *mPciHostBridgeUtilityLibAcpiAddressSpaceTypeS= tr[] =3D { }; =20 =20 +/** + Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge(). + + param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the cal= ler and + initialized with InitRootBridge(), that should be + uninitialized. This function doesn't free RootBus. +**/ +STATIC +VOID +UninitRootBridge ( + IN PCI_ROOT_BRIDGE *RootBus + ) +{ + FreePool (RootBus->DevicePath); +} + + +/** + Utility function to free root bridge instances array. + + @param The root bridge instances array. + @param The count of the array. +**/ +VOID +EFIAPI +PciHostBridgeUtilityFreeRootBridges ( + PCI_ROOT_BRIDGE *Bridges, + UINTN Count + ) +{ + if (Bridges =3D=3D NULL && Count =3D=3D 0) { + return; + } + ASSERT (Bridges !=3D NULL && Count > 0); + + do { + --Count; + UninitRootBridge (&Bridges[Count]); + } while (Count > 0); + + FreePool (Bridges); +} + + +/** + Utility function to return all the root bridge instances in an array. + + @param Count The number of root bridge instances. + + @param[in] BusMin The min bus number. + + @param[in] BusMax The max bus number. + + @param[in] Attributes Initial attributes. + + @param[in] AllocAttributes Allocation attributes. + + @param[in] Io IO aperture. + + @param[in] Mem MMIO aperture. + + @param[in] MemAbove4G MMIO aperture above 4G. + + @param[in] PMem Prefetchable MMIO aperture. + + @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G. + + @return All the root bridge instances in an array= . +**/ +PCI_ROOT_BRIDGE * +EFIAPI +PciHostBridgeUtilityExtraRoots ( + UINTN *Count, + UINT32 BusMin, + UINT32 BusMax, + UINT64 Attributes, + UINT64 AllocationAttributes, + PCI_ROOT_BRIDGE_APERTURE Io, + PCI_ROOT_BRIDGE_APERTURE Mem, + PCI_ROOT_BRIDGE_APERTURE MemAbove4G, + PCI_ROOT_BRIDGE_APERTURE PMem, + PCI_ROOT_BRIDGE_APERTURE PMemAbove4G + ) +{ + EFI_STATUS Status; + PCI_ROOT_BRIDGE *Bridges; + FIRMWARE_CONFIG_ITEM FwCfgItem; + UINTN FwCfgSize; + UINT64 ExtraRootBridges; + UINTN Initialized; + UINTN LastRootBridgeNumber; + UINTN RootBridgeNumber; + + // + // QEMU provides the number of extra root buses, shortening the exhaus= tive + // search below. If there is no hint, the feature is missing. + // + Status =3D QemuFwCfgFindFile ("etc/extra-pci-roots", &FwCfgItem, &FwCf= gSize); + if (EFI_ERROR (Status) || FwCfgSize !=3D sizeof ExtraRootBridges) { + ExtraRootBridges =3D 0; + } else { + QemuFwCfgSelectItem (FwCfgItem); + QemuFwCfgReadBytes (FwCfgSize, &ExtraRootBridges); + + if (ExtraRootBridges > BusMax - BusMin) { + DEBUG ((DEBUG_ERROR, "%a: invalid count of extra root buses (%Lu) = " + "reported by QEMU\n", __FUNCTION__, ExtraRootBridges)); + return NULL; + } + DEBUG ((DEBUG_INFO, "%a: %Lu extra root buses reported by QEMU\n", + __FUNCTION__, ExtraRootBridges)); + } + + // + // Allocate the "main" root bridge, and any extra root bridges. + // + Bridges =3D AllocatePool ((1 + (UINTN)ExtraRootBridges) * sizeof *Brid= ges); + if (Bridges =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES)= ); + return NULL; + } + Initialized =3D 0; + + // + // The "main" root bus is always there. + // + LastRootBridgeNumber =3D BusMin; + + // + // Scan all other root buses. If function 0 of any device on a bus ret= urns a + // VendorId register value different from all-bits-one, then that bus = is + // alive. + // + for (RootBridgeNumber =3D BusMin + 1; + RootBridgeNumber <=3D BusMax && Initialized < ExtraRootBridges; + ++RootBridgeNumber) { + UINTN Device; + + for (Device =3D 0; Device <=3D PCI_MAX_DEVICE; ++Device) { + if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0, + PCI_VENDOR_ID_OFFSET)) !=3D MAX_UINT16) { + break; + } + } + if (Device <=3D PCI_MAX_DEVICE) { + // + // Found the next root bus. We can now install the *previous* one, + // because now we know how big a bus number range *that* one has, = for any + // subordinate buses that might exist behind PCI bridges hanging o= ff it. + // + Status =3D InitRootBridge ( + Attributes, + Attributes, + AllocationAttributes, + (UINT8) LastRootBridgeNumber, + (UINT8) (RootBridgeNumber - 1), + &Io, + &Mem, + &MemAbove4G, + &PMem, + &PMemAbove4G, + &Bridges[Initialized] + ); + if (EFI_ERROR (Status)) { + goto FreeBridges; + } + ++Initialized; + LastRootBridgeNumber =3D RootBridgeNumber; + } + } + + // + // Install the last root bus (which might be the only, ie. main, root = bus, if + // we've found no extra root buses). + // + Status =3D InitRootBridge ( + Attributes, + Attributes, + AllocationAttributes, + (UINT8) LastRootBridgeNumber, + BusMax, + &Io, + &Mem, + &MemAbove4G, + &PMem, + &PMemAbove4G, + &Bridges[Initialized] + ); + if (EFI_ERROR (Status)) { + goto FreeBridges; + } + ++Initialized; + + *Count =3D Initialized; + return Bridges; + +FreeBridges: + while (Initialized > 0) { + --Initialized; + UninitRootBridge (&Bridges[Initialized]); + } + + FreePool (Bridges); + return NULL; +} + + /** Utility function to inform the platform that the resource conflict hap= pens. =20 --=20 2.28.0