From: "Jiahui Cen" <cenjiahui@huawei.com>
To: <devel@edk2.groups.io>
Cc: Jordan Justen <jordan.l.justen@intel.com>,
Laszlo Ersek <lersek@redhat.com>,
Ard Biesheuvel <ard.biesheuvel@arm.com>,
Rebecca Cran <rebecca@bsdio.com>,
Peter Grehan <grehan@freebsd.org>,
Anthony Perard <anthony.perard@citrix.com>,
Julien Grall <julien@xen.org>, Leif Lindholm <leif@nuviainc.com>,
Sami Mujawar <sami.mujawar@arm.com>, <xieyingtai@huawei.com>,
<wu.wubin@huawei.com>, Jiahui Cen <cenjiahui@huawei.com>,
Yubo Miao <miaoyubo@huawei.com>
Subject: [PATCH v5 07/10] OvmfPkg/PciHostBridgeLib: Extract Get/FreeRootBridges
Date: Wed, 13 Jan 2021 18:33:28 +0800 [thread overview]
Message-ID: <20210113103331.10375-8-cenjiahui@huawei.com> (raw)
In-Reply-To: <20210113103331.10375-1-cenjiahui@huawei.com>
Extract PciHostBridgeGetRootBridges()/PciHostBridgeFreeRootBridges() to
PciHostBridgeUtilityLib as common utility functions.
No change of functionality.
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3059
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Jiahui Cen <cenjiahui@huawei.com>
Signed-off-by: Yubo Miao <miaoyubo@huawei.com>
---
OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf | 1 -
OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf | 6 +
OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h | 50 +++++
OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c | 136 +-------------
OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c | 194 ++++++++++++++++++++
5 files changed, 254 insertions(+), 133 deletions(-)
diff --git a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/OvmfPkg/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
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase
diff --git a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.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 13c591641d7a..29ea19f2d7e5 100644
--- a/OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h
+++ b/OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h
@@ -97,6 +97,56 @@ PciHostBridgeUtilityUninitRootBridge (
);
+/**
+ 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 (
+ UINTN *Count,
+ 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 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 (
+ PCI_ROOT_BRIDGE *Bridges,
+ UINTN Count
+ );
+
+
/**
Utility function to inform the platform that the resource conflict happens.
diff --git a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
index 8758d7c12bf0..62e0a517a938 100644
--- a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
+++ b/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -9,9 +9,6 @@
**/
#include <PiDxe.h>
-#include <IndustryStandard/Pci.h>
-#include <IndustryStandard/Q35MchIch9.h>
-
#include <Protocol/PciHostBridgeResourceAllocation.h>
#include <Protocol/PciRootBridgeIo.h>
@@ -21,8 +18,6 @@
#include <Library/PcdLib.h>
#include <Library/PciHostBridgeLib.h>
#include <Library/PciHostBridgeUtilityLib.h>
-#include <Library/PciLib.h>
-#include <Library/QemuFwCfgLib.h>
#include "PciHostBridge.h"
@@ -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;
@@ -91,121 +78,16 @@ PciHostBridgeGetRootBridges (
*Count = 0;
- //
- // QEMU provides the number of extra root buses, shortening the exhaustive
- // search below. If there is no hint, the feature is missing.
- //
- Status = QemuFwCfgFindFile ("etc/extra-pci-roots", &FwCfgItem, &FwCfgSize);
- if (EFI_ERROR (Status) || FwCfgSize != sizeof ExtraRootBridges) {
- ExtraRootBridges = 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 = AllocatePool ((1 + (UINTN)ExtraRootBridges) * sizeof *Bridges);
- if (Bridges == NULL) {
- DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));
- return NULL;
- }
- Initialized = 0;
-
- //
- // The "main" root bus is always there.
- //
- LastRootBridgeNumber = 0;
-
- //
- // Scan all other root buses. If function 0 of any device on a bus returns a
- // VendorId register value different from all-bits-one, then that bus is
- // alive.
- //
- for (RootBridgeNumber = 1;
- RootBridgeNumber <= PCI_MAX_BUS && Initialized < ExtraRootBridges;
- ++RootBridgeNumber) {
- UINTN Device;
-
- for (Device = 0; Device <= PCI_MAX_DEVICE; ++Device) {
- if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0,
- PCI_VENDOR_ID_OFFSET)) != MAX_UINT16) {
- break;
- }
- }
- if (Device <= 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 off it.
- //
- Status = PciHostBridgeUtilityInitRootBridge (
- Attributes,
- Attributes,
- AllocationAttributes,
- FALSE,
- PcdGet16 (PcdOvmfHostBridgePciDevId) != INTEL_Q35_MCH_DEVICE_ID,
- (UINT8) LastRootBridgeNumber,
- (UINT8) (RootBridgeNumber - 1),
- &Io,
- &Mem,
- &MemAbove4G,
- &mNonExistAperture,
- &mNonExistAperture,
- &Bridges[Initialized]
- );
- if (EFI_ERROR (Status)) {
- goto FreeBridges;
- }
- ++Initialized;
- LastRootBridgeNumber = RootBridgeNumber;
- }
- }
-
- //
- // Install the last root bus (which might be the only, ie. main, root bus, if
- // we've found no extra root buses).
- //
- Status = PciHostBridgeUtilityInitRootBridge (
- Attributes,
+ return PciHostBridgeUtilityGetRootBridges (
+ Count,
Attributes,
AllocationAttributes,
- FALSE,
- PcdGet16 (PcdOvmfHostBridgePciDevId) != 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 = Initialized;
- return Bridges;
-
-FreeBridges:
- while (Initialized > 0) {
- --Initialized;
- PciHostBridgeUtilityUninitRootBridge (&Bridges[Initialized]);
- }
-
- FreePool (Bridges);
- return NULL;
}
@@ -223,17 +105,7 @@ PciHostBridgeFreeRootBridges (
UINTN Count
)
{
- if (Bridges == NULL && Count == 0) {
- return;
- }
- ASSERT (Bridges != NULL && Count > 0);
-
- do {
- --Count;
- PciHostBridgeUtilityUninitRootBridge (&Bridges[Count]);
- } while (Count > 0);
-
- FreePool (Bridges);
+ PciHostBridgeUtilityFreeRootBridges (Bridges, Count);
}
diff --git a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c
index 15b2045197a8..31a8c19d4f7f 100644
--- a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c
+++ b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c
@@ -11,11 +11,16 @@
**/
#include <IndustryStandard/Acpi10.h>
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Q35MchIch9.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
#include <Library/PciHostBridgeUtilityLib.h>
+#include <Library/PciLib.h>
+#include <Library/QemuFwCfgLib.h>
#pragma pack(1)
@@ -182,6 +187,195 @@ PciHostBridgeUtilityUninitRootBridge (
}
+/**
+ 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 (
+ UINTN *Count,
+ 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;
+ 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 exhaustive
+ // search below. If there is no hint, the feature is missing.
+ //
+ Status = QemuFwCfgFindFile ("etc/extra-pci-roots", &FwCfgItem, &FwCfgSize);
+ if (EFI_ERROR (Status) || FwCfgSize != sizeof ExtraRootBridges) {
+ ExtraRootBridges = 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 = AllocatePool ((1 + (UINTN)ExtraRootBridges) * sizeof *Bridges);
+ if (Bridges == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));
+ return NULL;
+ }
+ Initialized = 0;
+
+ //
+ // The "main" root bus is always there.
+ //
+ LastRootBridgeNumber = 0;
+
+ //
+ // Scan all other root buses. If function 0 of any device on a bus returns a
+ // VendorId register value different from all-bits-one, then that bus is
+ // alive.
+ //
+ for (RootBridgeNumber = 1;
+ RootBridgeNumber <= PCI_MAX_BUS && Initialized < ExtraRootBridges;
+ ++RootBridgeNumber) {
+ UINTN Device;
+
+ for (Device = 0; Device <= PCI_MAX_DEVICE; ++Device) {
+ if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0,
+ PCI_VENDOR_ID_OFFSET)) != MAX_UINT16) {
+ break;
+ }
+ }
+ if (Device <= 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 off it.
+ //
+ Status = PciHostBridgeUtilityInitRootBridge (
+ Attributes,
+ Attributes,
+ AllocationAttributes,
+ FALSE,
+ PcdGet16 (PcdOvmfHostBridgePciDevId) != INTEL_Q35_MCH_DEVICE_ID,
+ (UINT8) LastRootBridgeNumber,
+ (UINT8) (RootBridgeNumber - 1),
+ Io,
+ Mem,
+ MemAbove4G,
+ PMem,
+ PMemAbove4G,
+ &Bridges[Initialized]
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeBridges;
+ }
+ ++Initialized;
+ LastRootBridgeNumber = RootBridgeNumber;
+ }
+ }
+
+ //
+ // Install the last root bus (which might be the only, ie. main, root bus, if
+ // we've found no extra root buses).
+ //
+ Status = PciHostBridgeUtilityInitRootBridge (
+ Attributes,
+ Attributes,
+ AllocationAttributes,
+ FALSE,
+ PcdGet16 (PcdOvmfHostBridgePciDevId) != 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 = Initialized;
+ return Bridges;
+
+FreeBridges:
+ while (Initialized > 0) {
+ --Initialized;
+ PciHostBridgeUtilityUninitRootBridge (&Bridges[Initialized]);
+ }
+
+ FreePool (Bridges);
+ 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 (
+ PCI_ROOT_BRIDGE *Bridges,
+ UINTN Count
+ )
+{
+ if (Bridges == NULL && Count == 0) {
+ return;
+ }
+ ASSERT (Bridges != NULL && Count > 0);
+
+ do {
+ --Count;
+ PciHostBridgeUtilityUninitRootBridge (&Bridges[Count]);
+ } while (Count > 0);
+
+ FreePool (Bridges);
+}
+
+
/**
Utility function to inform the platform that the resource conflict happens.
--
2.29.2
next prev parent reply other threads:[~2021-01-13 10:33 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-13 10:33 [PATCH v5 00/10] Add extra pci roots support for Arm Jiahui Cen
2021-01-13 10:33 ` [PATCH v5 01/10] OvmfPkg: Introduce PciHostBridgeUtilityLib class Jiahui Cen
2021-01-13 10:33 ` [PATCH v5 02/10] ArmVirtPkg: Refactor with PciHostBridgeUtilityLib Jiahui Cen
2021-01-13 10:33 ` [PATCH v5 03/10] OvmfPkg/PciHostBridgeLib: List missing PcdLib dependency Jiahui Cen
2021-01-13 10:33 ` [PATCH v5 04/10] OvmfPkg/PciHostBridgeLib: Extract Init/UninitRootBridge Jiahui Cen
2021-01-13 10:33 ` [PATCH v5 05/10] OvmfPkg/PciHostBridgeUtilityLib: Extend parameter list of InitRootBridge Jiahui Cen
2021-01-13 10:33 ` [PATCH v5 06/10] ArmVirtPkg/FdtPciHostBridgeLib: Refactor Init/UninitRootBridge() Jiahui Cen
2021-01-13 10:33 ` Jiahui Cen [this message]
2021-01-13 10:33 ` [PATCH v5 08/10] OvmfPkg/PciHostBridgeUtilityLib: Extend parameter list of GetRootBridges Jiahui Cen
2021-01-13 10:33 ` [PATCH v5 09/10] ArmVirtPkg/FdtPciHostBridgeLib: Refactor Get/FreeRootBridges() Jiahui Cen
2021-01-13 10:33 ` [PATCH v5 10/10] ArmVirtPkg/ArmVirtQemu: Add support for HotPlug Jiahui Cen
2021-01-13 10:42 ` [PATCH v5 00/10] Add extra pci roots support for Arm Laszlo Ersek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210113103331.10375-8-cenjiahui@huawei.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox