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.web08.11083.1604927140021831663 for ; Mon, 09 Nov 2020 05:05:41 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: huawei.com, ip: 45.249.212.190, mailfrom: cenjiahui@huawei.com) 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) 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" To: CC: , , , , , , Jiahui Cen Subject: [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> X-Mailer: git-send-email 2.25.1 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 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain 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=0D =0D [Packages]=0D + MdeModulePkg/MdeModulePkg.dec=0D MdePkg/MdePkg.dec=0D OvmfPkg/OvmfPkg.dec=0D =0D @@ -38,6 +39,7 @@ [LibraryClasses] MemoryAllocationLib=0D PciLib=0D QemuFwCfgLib=0D + PciHostBridgeLib=0D =0D [Pcd]=0D gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase=0D 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__=0D #define __PCI_HOST_BRIDGE_UTILITY_LIB_H__=0D =0D +/**=0D + Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge().=0D +=0D + param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the calle= r and=0D + initialized with InitRootBridge(), that should be=0D + uninitialized. This function doesn't free RootBus.=0D +**/=0D +VOID=0D +UninitRootBridge (=0D + IN PCI_ROOT_BRIDGE *RootBus=0D + );=0D +=0D +/**=0D + Free the root bridge instances array returned from=0D + PciHostBridgeGetRootBridges().=0D +=0D + @param The root bridge instances array.=0D + @param The count of the array.=0D +**/=0D +VOID=0D +EFIAPI=0D +PciHostBridgeFreeRootBridges (=0D + PCI_ROOT_BRIDGE *Bridges,=0D + UINTN Count=0D + );=0D +=0D +/**=0D + Return all the root bridge instances in an array.=0D +=0D + @param Count Return the count of root bridge instances.=0D +=0D + @param[in] PMem Prefetchable MMIO aperture.=0D +=0D + @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.=0D +=0D + @param[in] BusMax The max bus number.=0D +=0D + @param[in] Attributes Initial attributes.=0D +=0D + @param[in] AllocAttributes Allocation attributes.=0D +=0D + @param[in] Io IO aperture.=0D +=0D + @param[in] Mem MMIO aperture.=0D +=0D + @param[in] MemAbove4G MMIO aperture above 4G.=0D +=0D + @return All the root bridge instances in an array.=0D + The array should be passed into PciHostBridgeFreeRootBridges()=0D + when it's not used.=0D +**/=0D +PCI_ROOT_BRIDGE *=0D +EFIAPI=0D +PciHostBridgeExtraRoots (=0D + UINTN *Count,=0D + PCI_ROOT_BRIDGE_APERTURE PMem,=0D + PCI_ROOT_BRIDGE_APERTURE PMemAbove4G,=0D + UINT32 BusMax,=0D + UINT64 Attributes,=0D + UINT64 AllocationAttributes,=0D + PCI_ROOT_BRIDGE_APERTURE Io,=0D + PCI_ROOT_BRIDGE_APERTURE Mem,=0D + PCI_ROOT_BRIDGE_APERTURE MemAbove4G=0D +);=0D +=0D /**=0D Inform the platform that the resource conflict happens.=0D =0D 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;=0D }=0D =0D -=0D -/**=0D - Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge().=0D -=0D - param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the calle= r and=0D - initialized with InitRootBridge(), that should be=0D - uninitialized. This function doesn't free RootBus.=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 =0D @@ -192,14 +174,7 @@ PciHostBridgeGetRootBridges ( UINTN *Count=0D )=0D {=0D - EFI_STATUS Status;=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 PCI_ROOT_BRIDGE_APERTURE Io;=0D @@ -239,143 +214,20 @@ PciHostBridgeGetRootBridges ( =0D *Count =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 - if (ExtraRootBridges > PCI_MAX_BUS) {=0D - DEBUG ((DEBUG_ERROR, "%a: invalid count of extra root buses (%Lu) "= =0D - "reported by QEMU\n", __FUNCTION__, ExtraRootBridges));=0D - return NULL;=0D - }=0D - DEBUG ((DEBUG_INFO, "%a: %Lu extra root buses reported by QEMU\n",=0D - __FUNCTION__, ExtraRootBridges));=0D - }=0D -=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 ((DEBUG_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 - //=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 PCI_MAX_BUS && 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 - &mNonExistAperture,=0D - &mNonExistAperture,=0D - &Bridges[Initialized]=0D - );=0D - if (EFI_ERROR (Status)) {=0D - goto FreeBridges;=0D - }=0D - ++Initialized;=0D - LastRootBridgeNumber =3D RootBridgeNumber;=0D - }=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 + Bridges =3D PciHostBridgeExtraRoots (=0D + Count,=0D + mNonExistAperture,=0D + mNonExistAperture,=0D PCI_MAX_BUS,=0D - &Io,=0D - &Mem,=0D - &MemAbove4G,=0D - &mNonExistAperture,=0D - &mNonExistAperture,=0D - &Bridges[Initialized]=0D + Attributes,=0D + AllocationAttributes,=0D + Io,=0D + Mem,=0D + MemAbove4G=0D );=0D - if (EFI_ERROR (Status)) {=0D - goto FreeBridges;=0D + if (Bridges) {=0D + return Bridges;=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 -/**=0D - Free the root bridge instances array returned from=0D - PciHostBridgeGetRootBridges().=0D -=0D - @param The root bridge instances array.=0D - @param The count of the array.=0D -**/=0D -VOID=0D -EFIAPI=0D -PciHostBridgeFreeRootBridges (=0D - PCI_ROOT_BRIDGE *Bridges,=0D - UINTN Count=0D - )=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 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=0D =0D **/=0D +#include =0D #include =0D +#include =0D +#include =0D #include =0D +#include =0D +#include =0D +#include "Library/PciHostBridgeLib/PciHostBridge.h"=0D =0D =0D GLOBAL_REMOVE_IF_UNREFERENCED=0D @@ -16,6 +22,209 @@ CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] =3D { };=0D =0D =0D +/**=0D + Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge().=0D +=0D + param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the calle= r and=0D + initialized with InitRootBridge(), that should be=0D + uninitialized. This function doesn't free RootBus.=0D +**/=0D +VOID=0D +UninitRootBridge (=0D + IN PCI_ROOT_BRIDGE *RootBus=0D + )=0D +{=0D + FreePool (RootBus->DevicePath);=0D +}=0D +=0D +/**=0D + Free the root bridge instances array returned from=0D + PciHostBridgeGetRootBridges().=0D +=0D + @param The root bridge instances array.=0D + @param The count of the array.=0D +**/=0D +VOID=0D +EFIAPI=0D +PciHostBridgeFreeRootBridges (=0D + PCI_ROOT_BRIDGE *Bridges,=0D + UINTN Count=0D + )=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 +/**=0D + Return all the root bridge instances in an array.=0D +=0D + @param Count Return the count of root bridge instances.=0D +=0D + @param[in] PMem Prefetchable MMIO aperture.=0D +=0D + @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.=0D +=0D + @param[in] BusMax The max bus number.=0D +=0D + @param[in] Attributes Initial attributes.=0D +=0D + @param[in] AllocAttributes Allocation attributes.=0D +=0D + @param[in] Io IO aperture.=0D +=0D + @param[in] Mem MMIO aperture.=0D +=0D + @param[in] MemAbove4G MMIO aperture above 4G.=0D +=0D + @return All the root bridge instances in an array.=0D + The array should be passed into PciHostBridgeFreeRootBridges()=0D + when it's not used.=0D +**/=0D +=0D +PCI_ROOT_BRIDGE *=0D +EFIAPI=0D +PciHostBridgeExtraRoots (=0D + UINTN *Count,=0D + PCI_ROOT_BRIDGE_APERTURE PMem,=0D + PCI_ROOT_BRIDGE_APERTURE PMemAbove4G,=0D + UINT32 BusMax,=0D + UINT64 Attributes,=0D + UINT64 AllocationAttributes,=0D + PCI_ROOT_BRIDGE_APERTURE Io,=0D + PCI_ROOT_BRIDGE_APERTURE Mem,=0D + PCI_ROOT_BRIDGE_APERTURE MemAbove4G=0D +)=0D +{=0D + EFI_STATUS Status;=0D + PCI_ROOT_BRIDGE *Bridges;=0D + FIRMWARE_CONFIG_ITEM FwCfgItem;=0D + UINTN FwCfgSize;=0D + UINT64 ExtraRootBridges;=0D + UINTN Initialized;=0D + UINTN LastRootBridgeNumber;=0D + UINTN RootBridgeNumber;=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 + if (ExtraRootBridges > BusMax) {=0D + DEBUG ((DEBUG_ERROR, "%a: invalid count of extra root buses (%Lu) "= =0D + "reported by QEMU\n", __FUNCTION__, ExtraRootBridges));=0D + return NULL;=0D + }=0D + DEBUG ((DEBUG_INFO, "%a: %Lu extra root buses reported by QEMU\n",=0D + __FUNCTION__, ExtraRootBridges));=0D + }=0D +=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 ((DEBUG_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 + //=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 + //=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 Inform the platform that the resource conflict happens.=0D =0D --=20 2.28.0