From nobody Mon Feb 9 21:21:27 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+67183+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+67183+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1604930202; cv=none; d=zohomail.com; s=zohoarc; b=Zxve5+tutxyXaUqNFFCaNrXBL6CxZWDUx+QyVmZdpn+fCMRzc8bAl2eXJRo0sw2OfVeeBjMEyHQRSzPIIIPWGXTOKZSRX92vdUepl3EOc0q8gJxkJx356I1JuEKrm95mvZSBwKfxriclDQFlzrJ+5E1BrFVytbsgr3honhrfAEk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604930202; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=5H7hSaYWR0wI7rkiGMUlmu7v8dm0WXEy073deBLaLUo=; b=U22DCIx1XEewQvri3JfwMF4z4WalNKfh7AYBB0LW4lEU4TXKNWajymA7cn0ZCxhb4Fj5/kf6mODUbucYiCXmL4lho/Gxy9lza8kFpqoAYtB8UQgNif1icEyW0wkak1y9C64658gzKHH0ca4AHh82W8lAE2wQdZP9PnlkVTengZg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+67183+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604930202986979.9931668125699; Mon, 9 Nov 2020 05:56:42 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id EmU8YY1788612xvHwWFEyLvs; Mon, 09 Nov 2020 05:56:42 -0800 X-Received: from szxga04-in.huawei.com (szxga04-in.huawei.com [45.249.212.190]) by mx.groups.io with SMTP id smtpd.web08.11083.1604927140021831663 for ; Mon, 09 Nov 2020 05:05:41 -0800 X-Received: from DGGEMS414-HUB.china.huawei.com (unknown [172.30.72.58]) by szxga04-in.huawei.com (SkyGuard) with ESMTP id 4CVB7G2Cz3z15RLf; Mon, 9 Nov 2020 21:05:30 +0800 (CST) X-Received: from localhost (10.174.184.155) by DGGEMS414-HUB.china.huawei.com (10.3.19.214) with Microsoft SMTP Server id 14.3.487.0; Mon, 9 Nov 2020 21:05:27 +0800 From: "Jiahui Cen via groups.io" To: CC: , , , , , , Jiahui Cen Subject: [edk2-devel] [PATCH v2 3/4] OvmfPkg: Extract functions of extra pci roots Date: Mon, 9 Nov 2020 21:05:10 +0800 Message-ID: <20201109130511.5946-4-cenjiahui@huawei.com> In-Reply-To: <20201109130511.5946-1-cenjiahui@huawei.com> References: <20201109130511.5946-1-cenjiahui@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.174.184.155] X-CFilter-Loop: Reflected Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,cenjiahui@huawei.com X-Gm-Message-State: Fs936i7YVp3oatKSr3lYusrEx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604930202; bh=4sfLz/Wv9phcIKpO/OEWS159t5sbDGVIpLmv1lCHo7E=; h=CC:Content-Type:Date:From:Reply-To:Subject:To; b=UXz1NUhDxbjJm52tYb28LI7+/GVuoR0dgGgrBTjhvOcgKn1/Aqu8USoI8jt1/+ooGWe UoJ0As7c8kLD2u22QHWNh00n/5yJoPYj/tPUjigjSpyGm2J/k0XyCmWMjU4aaPzDZFCJM YkEVMVulklKROPt8fvwvZ0o4rpDOJm5N/uA= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" From: Yubo Miao To use extra pci roots in other lib, it is necessary to extract UninitRootBridge, PciHostBridgeFreeRootBridges and PciHostBridgeExtraRoots from Ovmf/PciHostBridgeLib. Cc: Jordan Justen Cc: Laszlo Ersek Cc: Ard Biesheuvel Signed-off-by: Yubo Miao Signed-off-by: Jiahui Cen --- OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf | 2 + OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h | 65 = ++++++ OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c | 170 = ++-------------- OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c | 209 = ++++++++++++++++++++ 4 files changed, 287 insertions(+), 159 deletions(-) diff --git a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLi= b.inf b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf index c88ab8e4155d..1a667870ee2f 100644 --- a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf +++ b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf @@ -28,6 +28,7 @@ [Sources] PciHostBridgeUtilityLib.c =20 [Packages] + MdeModulePkg/MdeModulePkg.dec MdePkg/MdePkg.dec OvmfPkg/OvmfPkg.dec =20 @@ -38,6 +39,7 @@ [LibraryClasses] MemoryAllocationLib PciLib QemuFwCfgLib + PciHostBridgeLib =20 [Pcd] gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase diff --git a/OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h b/OvmfPkg/In= clude/Library/PciHostBridgeUtilityLib.h index d2622fd907e6..35fe237b0801 100644 --- a/OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h +++ b/OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h @@ -9,6 +9,71 @@ #ifndef __PCI_HOST_BRIDGE_UTILITY_LIB_H__ #define __PCI_HOST_BRIDGE_UTILITY_LIB_H__ =20 +/** + Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge(). + + param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the calle= r and + initialized with InitRootBridge(), that should be + uninitialized. This function doesn't free RootBus. +**/ +VOID +UninitRootBridge ( + IN PCI_ROOT_BRIDGE *RootBus + ); + +/** + Free the root bridge instances array returned from + PciHostBridgeGetRootBridges(). + + @param The root bridge instances array. + @param The count of the array. +**/ +VOID +EFIAPI +PciHostBridgeFreeRootBridges ( + PCI_ROOT_BRIDGE *Bridges, + UINTN Count + ); + +/** + Return all the root bridge instances in an array. + + @param Count Return the count of root bridge instances. + + @param[in] PMem Prefetchable MMIO aperture. + + @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G. + + @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. + + @return All the root bridge instances in an array. + The array should be passed into PciHostBridgeFreeRootBridges() + when it's not used. +**/ +PCI_ROOT_BRIDGE * +EFIAPI +PciHostBridgeExtraRoots ( + UINTN *Count, + PCI_ROOT_BRIDGE_APERTURE PMem, + PCI_ROOT_BRIDGE_APERTURE PMemAbove4G, + UINT32 BusMax, + UINT64 Attributes, + UINT64 AllocationAttributes, + PCI_ROOT_BRIDGE_APERTURE Io, + PCI_ROOT_BRIDGE_APERTURE Mem, + PCI_ROOT_BRIDGE_APERTURE MemAbove4G +); + /** Inform the platform that the resource conflict happens. =20 diff --git a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/OvmfPkg/= Library/PciHostBridgeLib/PciHostBridgeLib.c index 1c8f465834f3..cd9896bee14b 100644 --- a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c +++ b/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -159,24 +159,6 @@ InitRootBridge ( return EFI_SUCCESS; } =20 - -/** - Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge(). - - param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the calle= r 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 +174,7 @@ 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,143 +214,20 @@ PciHostBridgeGetRootBridges ( =20 *Count =3D 0; =20 - // - // QEMU provides the number of extra root buses, shortening the exhausti= ve - // search below. If there is no hint, the feature is missing. - // - Status =3D QemuFwCfgFindFile ("etc/extra-pci-roots", &FwCfgItem, &FwCfgS= ize); - 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 *Bridge= s); - 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 retur= ns a - // VendorId register value different from all-bits-one, then that bus is - // alive. - // - for (RootBridgeNumber =3D 1; - RootBridgeNumber <=3D PCI_MAX_BUS && 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, fo= r any - // subordinate buses that might exist behind PCI bridges hanging off= 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 bu= s, if - // we've found no extra root buses). - // - Status =3D InitRootBridge ( - Attributes, - Attributes, - AllocationAttributes, - (UINT8) LastRootBridgeNumber, + Bridges =3D PciHostBridgeExtraRoots ( + Count, + mNonExistAperture, + mNonExistAperture, PCI_MAX_BUS, - &Io, - &Mem, - &MemAbove4G, - &mNonExistAperture, - &mNonExistAperture, - &Bridges[Initialized] + Attributes, + AllocationAttributes, + Io, + Mem, + MemAbove4G ); - if (EFI_ERROR (Status)) { - goto FreeBridges; + if (Bridges) { + return Bridges; } - ++Initialized; - - *Count =3D Initialized; - return Bridges; - -FreeBridges: - while (Initialized > 0) { - --Initialized; - UninitRootBridge (&Bridges[Initialized]); - } - - FreePool (Bridges); return NULL; } =20 - -/** - Free the root bridge instances array returned from - PciHostBridgeGetRootBridges(). - - @param The root bridge instances array. - @param The count of the array. -**/ -VOID -EFIAPI -PciHostBridgeFreeRootBridges ( - 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); -} diff --git a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLi= b.c b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c index 7e9512dc08f1..422f46fef4dd 100644 --- a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c +++ b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c @@ -6,8 +6,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ +#include #include +#include +#include #include +#include +#include +#include "Library/PciHostBridgeLib/PciHostBridge.h" =20 =20 GLOBAL_REMOVE_IF_UNREFERENCED @@ -16,6 +22,209 @@ CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] =3D { }; =20 =20 +/** + Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge(). + + param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the calle= r and + initialized with InitRootBridge(), that should be + uninitialized. This function doesn't free RootBus. +**/ +VOID +UninitRootBridge ( + IN PCI_ROOT_BRIDGE *RootBus + ) +{ + FreePool (RootBus->DevicePath); +} + +/** + Free the root bridge instances array returned from + PciHostBridgeGetRootBridges(). + + @param The root bridge instances array. + @param The count of the array. +**/ +VOID +EFIAPI +PciHostBridgeFreeRootBridges ( + 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); +} + +/** + Return all the root bridge instances in an array. + + @param Count Return the count of root bridge instances. + + @param[in] PMem Prefetchable MMIO aperture. + + @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G. + + @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. + + @return All the root bridge instances in an array. + The array should be passed into PciHostBridgeFreeRootBridges() + when it's not used. +**/ + +PCI_ROOT_BRIDGE * +EFIAPI +PciHostBridgeExtraRoots ( + UINTN *Count, + PCI_ROOT_BRIDGE_APERTURE PMem, + PCI_ROOT_BRIDGE_APERTURE PMemAbove4G, + UINT32 BusMax, + UINT64 Attributes, + UINT64 AllocationAttributes, + PCI_ROOT_BRIDGE_APERTURE Io, + PCI_ROOT_BRIDGE_APERTURE Mem, + PCI_ROOT_BRIDGE_APERTURE MemAbove4G +) +{ + 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 exhausti= ve + // search below. If there is no hint, the feature is missing. + // + Status =3D QemuFwCfgFindFile ("etc/extra-pci-roots", &FwCfgItem, &FwCfgS= ize); + if (EFI_ERROR (Status) || FwCfgSize !=3D sizeof ExtraRootBridges) { + ExtraRootBridges =3D 0; + } else { + QemuFwCfgSelectItem (FwCfgItem); + QemuFwCfgReadBytes (FwCfgSize, &ExtraRootBridges); + + if (ExtraRootBridges > BusMax) { + 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 *Bridge= s); + 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 retur= ns a + // VendorId register value different from all-bits-one, then that bus is + // alive. + // + for (RootBridgeNumber =3D 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, fo= r any + // subordinate buses that might exist behind PCI bridges hanging off= 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 bu= s, 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; +} /** Inform the platform that the resource conflict happens. =20 --=20 2.28.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#67183): https://edk2.groups.io/g/devel/message/67183 Mute This Topic: https://groups.io/mt/78135584/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-