From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from szxga07-in.huawei.com (szxga07-in.huawei.com [45.249.212.35]) by mx.groups.io with SMTP id smtpd.web11.5332.1611018900402349160 for ; Mon, 18 Jan 2021 17:15:01 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: huawei.com, ip: 45.249.212.35, mailfrom: cenjiahui@huawei.com) Received: from DGGEMS408-HUB.china.huawei.com (unknown [172.30.72.58]) by szxga07-in.huawei.com (SkyGuard) with ESMTP id 4DKVzL2Tsvz7X66; Tue, 19 Jan 2021 09:13:50 +0800 (CST) Received: from localhost (10.174.184.155) by DGGEMS408-HUB.china.huawei.com (10.3.19.208) with Microsoft SMTP Server id 14.3.498.0; Tue, 19 Jan 2021 09:14:48 +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 v6 07/11] OvmfPkg/PciHostBridgeLib: Extract GetRootBridges() / FreeRootBridges() Date: Tue, 19 Jan 2021 09:12:58 +0800 Message-ID: <20210119011302.10908-8-cenjiahui@huawei.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210119011302.10908-1-cenjiahui@huawei.com> References: <20210119011302.10908-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 PciHostBridgeGetRootBridges() / PciHostBridgeFreeRootBridges() to PciHostBridgeUtilityLib as common utility functions to share support for scanning extra root bridges. No change of functionality. 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 | = 1 - OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf | = 6 + OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h | 5= 0 +++++ OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c | 13= 8 +------------- OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c | 19= 7 ++++++++++++++++++++ 5 files changed, 257 insertions(+), 135 deletions(-) diff --git a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Ovmf= Pkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf index 72458262cb42..4610a0c1490b 100644 --- a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf +++ b/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf @@ -41,7 +41,6 @@ [LibraryClasses] PcdLib PciHostBridgeUtilityLib PciLib - QemuFwCfgLib =20 [Pcd] gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase diff --git a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtility= Lib.inf b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib= .inf index 4d6764b702f4..fdae8cfe872e 100644 --- a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf +++ b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf @@ -39,3 +39,9 @@ [LibraryClasses] DebugLib DevicePathLib MemoryAllocationLib + PcdLib + PciLib + QemuFwCfgLib + +[Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId diff --git a/OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h b/OvmfPkg/= Include/Library/PciHostBridgeUtilityLib.h index a44ad5034520..2b7d5d3725c3 100644 --- a/OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h +++ b/OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h @@ -99,6 +99,56 @@ PciHostBridgeUtilityUninitRootBridge ( ); =20 =20 +/** + Utility function to return all the root bridge instances in an array. + + @param[out] Count The number of root bridge instances. + + @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 +PciHostBridgeUtilityGetRootBridges ( + OUT UINTN *Count, + IN UINT64 Attributes, + IN UINT64 AllocationAttributes, + IN PCI_ROOT_BRIDGE_APERTURE *Io, + IN PCI_ROOT_BRIDGE_APERTURE *Mem, + IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G, + IN PCI_ROOT_BRIDGE_APERTURE *PMem, + IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G + ); + + +/** + Utility function to free root bridge instances array from + PciHostBridgeUtilityGetRootBridges(). + + @param[in] Bridges The root bridge instances array. + @param[in] Count The count of the array. +**/ +VOID +EFIAPI +PciHostBridgeUtilityFreeRootBridges ( + IN PCI_ROOT_BRIDGE *Bridges, + IN UINTN Count + ); + + /** 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 8758d7c12bf0..6ac41ff853a9 100644 --- a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c +++ b/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -9,9 +9,6 @@ **/ #include =20 -#include -#include - #include #include =20 @@ -21,8 +18,6 @@ #include #include #include -#include -#include #include "PciHostBridge.h" =20 =20 @@ -44,14 +39,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; @@ -89,123 +76,16 @@ PciHostBridgeGetRootBridges ( Mem.Base =3D PcdGet64 (PcdPciMmio32Base); Mem.Limit =3D PcdGet64 (PcdPciMmio32Base) + (PcdGet64 (PcdPciMmio32Siz= e) - 1); =20 - *Count =3D 0; - - // - // 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 PciHostBridgeUtilityInitRootBridge ( - Attributes, - Attributes, - AllocationAttributes, - FALSE, - PcdGet16 (PcdOvmfHostBridgePciDevId) !=3D INTEL_Q35_MCH_DEVICE_I= D, - (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 PciHostBridgeUtilityInitRootBridge ( - Attributes, + return PciHostBridgeUtilityGetRootBridges ( + Count, Attributes, AllocationAttributes, - FALSE, - PcdGet16 (PcdOvmfHostBridgePciDevId) !=3D INTEL_Q35_MCH_DEVICE_ID, - (UINT8) LastRootBridgeNumber, - PCI_MAX_BUS, &Io, &Mem, &MemAbove4G, &mNonExistAperture, - &mNonExistAperture, - &Bridges[Initialized] + &mNonExistAperture ); - if (EFI_ERROR (Status)) { - goto FreeBridges; - } - ++Initialized; - - *Count =3D Initialized; - return Bridges; - -FreeBridges: - while (Initialized > 0) { - --Initialized; - PciHostBridgeUtilityUninitRootBridge (&Bridges[Initialized]); - } - - FreePool (Bridges); - return NULL; } =20 =20 @@ -223,17 +103,7 @@ PciHostBridgeFreeRootBridges ( UINTN Count ) { - if (Bridges =3D=3D NULL && Count =3D=3D 0) { - return; - } - ASSERT (Bridges !=3D NULL && Count > 0); - - do { - --Count; - PciHostBridgeUtilityUninitRootBridge (&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 bed2d87ea89c..b1e74a469d50 100644 --- a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c +++ b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c @@ -11,11 +11,16 @@ **/ =20 #include +#include +#include #include #include #include #include +#include #include +#include +#include =20 =20 #pragma pack(1) @@ -184,6 +189,198 @@ PciHostBridgeUtilityUninitRootBridge ( } =20 =20 +/** + Utility function to return all the root bridge instances in an array. + + @param[out] Count The number of root bridge instances. + + @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 +PciHostBridgeUtilityGetRootBridges ( + OUT UINTN *Count, + IN UINT64 Attributes, + IN UINT64 AllocationAttributes, + IN PCI_ROOT_BRIDGE_APERTURE *Io, + IN PCI_ROOT_BRIDGE_APERTURE *Mem, + IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G, + IN PCI_ROOT_BRIDGE_APERTURE *PMem, + IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G + ) +{ + EFI_STATUS Status; + FIRMWARE_CONFIG_ITEM FwCfgItem; + UINTN FwCfgSize; + UINT64 ExtraRootBridges; + PCI_ROOT_BRIDGE *Bridges; + 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 > PCI_MAX_BUS) { + DEBUG ((DEBUG_ERROR, "%a: invalid count of extra root buses (%Lu) = " + "reported by QEMU\n", __FUNCTION__, ExtraRootBridges)); + *Count =3D 0; + 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)= ); + *Count =3D 0; + 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 PciHostBridgeUtilityInitRootBridge ( + Attributes, + Attributes, + AllocationAttributes, + FALSE, + PcdGet16 (PcdOvmfHostBridgePciDevId) !=3D INTEL_Q35_MCH_DEVICE_I= D, + (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 PciHostBridgeUtilityInitRootBridge ( + Attributes, + Attributes, + AllocationAttributes, + FALSE, + PcdGet16 (PcdOvmfHostBridgePciDevId) !=3D INTEL_Q35_MCH_DEVICE_ID, + (UINT8) LastRootBridgeNumber, + PCI_MAX_BUS, + Io, + Mem, + MemAbove4G, + PMem, + PMemAbove4G, + &Bridges[Initialized] + ); + if (EFI_ERROR (Status)) { + goto FreeBridges; + } + ++Initialized; + + *Count =3D Initialized; + return Bridges; + +FreeBridges: + while (Initialized > 0) { + --Initialized; + PciHostBridgeUtilityUninitRootBridge (&Bridges[Initialized]); + } + + FreePool (Bridges); + *Count =3D 0; + return NULL; +} + + +/** + Utility function to free root bridge instances array from + PciHostBridgeUtilityGetRootBridges(). + + @param[in] Bridges The root bridge instances array. + @param[in] Count The count of the array. +**/ +VOID +EFIAPI +PciHostBridgeUtilityFreeRootBridges ( + IN PCI_ROOT_BRIDGE *Bridges, + IN UINTN Count + ) +{ + if (Bridges =3D=3D NULL && Count =3D=3D 0) { + return; + } + ASSERT (Bridges !=3D NULL && Count > 0); + + do { + --Count; + PciHostBridgeUtilityUninitRootBridge (&Bridges[Count]); + } while (Count > 0); + + FreePool (Bridges); +} + + /** Utility function to inform the platform that the resource conflict hap= pens. =20 --=20 2.29.2