public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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


  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