From: "Jiahui Cen" <cenjiahui@huawei.com>
To: <devel@edk2.groups.io>
Cc: <jordan.l.justen@intel.com>, <lersek@redhat.com>,
<ard.biesheuvel@arm.com>, <leif@nuviainc.com>,
<xieyingtai@huawei.com>, <miaoyubo@huawei.com>,
Jiahui Cen <cenjiahui@huawei.com>
Subject: [PATCH v2 3/4] OvmfPkg: Extract functions of extra pci roots
Date: Mon, 9 Nov 2020 21:05:10 +0800 [thread overview]
Message-ID: <20201109130511.5946-4-cenjiahui@huawei.com> (raw)
In-Reply-To: <20201109130511.5946-1-cenjiahui@huawei.com>
From: Yubo Miao <miaoyubo@huawei.com>
To use extra pci roots in other lib, it is necessary to extract
UninitRootBridge, PciHostBridgeFreeRootBridges and
PciHostBridgeExtraRoots from Ovmf/PciHostBridgeLib.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Yubo Miao <miaoyubo@huawei.com>
Signed-off-by: Jiahui Cen <cenjiahui@huawei.com>
---
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/PciHostBridgeUtilityLib.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
[Packages]
+ MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
OvmfPkg/OvmfPkg.dec
@@ -38,6 +39,7 @@ [LibraryClasses]
MemoryAllocationLib
PciLib
QemuFwCfgLib
+ PciHostBridgeLib
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase
diff --git a/OvmfPkg/Include/Library/PciHostBridgeUtilityLib.h b/OvmfPkg/Include/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__
+/**
+ Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge().
+
+ param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the caller 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.
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;
}
-
-/**
- Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge().
-
- param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the caller 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.
@@ -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 (
*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 = InitRootBridge (
- Attributes,
- Attributes,
- AllocationAttributes,
- (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 = InitRootBridge (
- Attributes,
- Attributes,
- AllocationAttributes,
- (UINT8) LastRootBridgeNumber,
+ Bridges = 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 = Initialized;
- return Bridges;
-
-FreeBridges:
- while (Initialized > 0) {
- --Initialized;
- UninitRootBridge (&Bridges[Initialized]);
- }
-
- FreePool (Bridges);
return NULL;
}
-
-/**
- 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 == NULL && Count == 0) {
- return;
- }
- ASSERT (Bridges != NULL && Count > 0);
-
- do {
- --Count;
- UninitRootBridge (&Bridges[Count]);
- } while (Count > 0);
-
- FreePool (Bridges);
-}
diff --git a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.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
**/
+#include <IndustryStandard/Pci.h>
#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciHostBridgeLib.h>
#include <Library/PciHostBridgeUtilityLib.h>
+#include <Library/QemuFwCfgLib.h>
+#include <Library/PciLib.h>
+#include "Library/PciHostBridgeLib/PciHostBridge.h"
GLOBAL_REMOVE_IF_UNREFERENCED
@@ -16,6 +22,209 @@ CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
};
+/**
+ Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge().
+
+ param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the caller 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 == NULL && Count == 0) {
+ return;
+ }
+ ASSERT (Bridges != 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 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 > 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 = 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 <= BusMax && 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 = InitRootBridge (
+ Attributes,
+ Attributes,
+ AllocationAttributes,
+ (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 = InitRootBridge (
+ Attributes,
+ Attributes,
+ AllocationAttributes,
+ (UINT8) LastRootBridgeNumber,
+ BusMax,
+ &Io,
+ &Mem,
+ &MemAbove4G,
+ &PMem,
+ &PMemAbove4G,
+ &Bridges[Initialized]
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeBridges;
+ }
+ ++Initialized;
+
+ *Count = Initialized;
+ return Bridges;
+
+FreeBridges:
+ while (Initialized > 0) {
+ --Initialized;
+ UninitRootBridge (&Bridges[Initialized]);
+ }
+
+ FreePool (Bridges);
+ return NULL;
+}
/**
Inform the platform that the resource conflict happens.
--
2.28.0
next prev parent reply other threads:[~2020-11-09 13:05 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-09 13:05 [PATCH v2 0/4] Add extra pci roots support for Arm Jiahui Cen
2020-11-09 13:05 ` [PATCH v2 1/4] OvmfPkg: Extract functions form PciHostBridgeLib Jiahui Cen
2020-11-11 16:45 ` Laszlo Ersek
2020-11-12 3:21 ` Jiahui Cen
2020-11-09 13:05 ` [PATCH v2 2/4] ArmVirtPkg: Use extracted PciHostBridgeUtilityLib Jiahui Cen
2020-11-11 17:27 ` Laszlo Ersek
2020-11-12 3:30 ` [edk2-devel] " Jiahui Cen
2020-11-09 13:05 ` Jiahui Cen [this message]
2020-11-09 13:05 ` [PATCH v2 4/4] ArmVirtPkg: Support extra pci roots Jiahui Cen
2020-11-11 14:33 ` [PATCH v2 0/4] Add extra pci roots support for Arm Laszlo Ersek
2020-11-12 3:20 ` [edk2-devel] " Jiahui Cen
2020-12-04 6:48 ` Jiahui Cen
2020-12-04 15:08 ` Laszlo Ersek
2020-12-11 10:57 ` Ni, Ray
2020-12-15 12:52 ` Jiahui Cen
2020-12-17 13:23 ` Laszlo Ersek
2020-12-17 13:37 ` Ard Biesheuvel
2020-12-17 14:42 ` Jonathan Cameron
2020-12-17 13:52 ` Jiahui Cen
2020-11-12 8:49 ` Ard Biesheuvel
2020-11-13 19:44 ` Laszlo Ersek
2020-11-16 1:33 ` [edk2-devel] " Jiahui Cen
-- strict thread matches above, loose matches on Subject: below --
2020-11-07 7:40 Jiahui Cen
2020-11-07 7:40 ` [PATCH v2 3/4] OvmfPkg: Extract functions of extra pci roots Jiahui Cen
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=20201109130511.5946-4-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