From 4edba29651e363bd8ab4881f656df35524d8766a Mon Sep 17 00:00:00 2001 From: "Jiahui Cen via groups.io" Date: Tue, 19 Jan 2021 09:12:58 +0800 Subject: OvmfPkg/PciHostBridgeLib: Extract GetRootBridges() / FreeRootBridges() Extract PciHostBridgeGetRootBridges() / PciHostBridgeFreeRootBridges() to PciHostBridgeUtilityLib as common utility functions to share support for scanning extra root bridges. No change of functionality. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3059 Cc: Jordan Justen Cc: Laszlo Ersek Cc: Ard Biesheuvel Signed-off-by: Jiahui Cen Signed-off-by: Yubo Miao Message-Id: <20210119011302.10908-8-cenjiahui@huawei.com> [lersek@redhat.com: keep zeroing of (*Count) centralized] Reviewed-by: Laszlo Ersek --- .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 138 +-------------- .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 1 - .../PciHostBridgeUtilityLib.c | 196 +++++++++++++++++++++ .../PciHostBridgeUtilityLib.inf | 6 + 4 files changed, 206 insertions(+), 135 deletions(-) (limited to 'OvmfPkg/Library') diff --git a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c index 8758d7c..6ac41ff 100644 --- a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c +++ b/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -9,9 +9,6 @@ **/ #include -#include -#include - #include #include @@ -21,8 +18,6 @@ #include #include #include -#include -#include #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; @@ -89,123 +76,16 @@ PciHostBridgeGetRootBridges ( Mem.Base = PcdGet64 (PcdPciMmio32Base); Mem.Limit = PcdGet64 (PcdPciMmio32Base) + (PcdGet64 (PcdPciMmio32Size) - 1); - *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 +103,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/PciHostBridgeLib/PciHostBridgeLib.inf b/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf index 7245826..4610a0c 100644 --- a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf +++ b/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf @@ -41,7 +41,6 @@ PcdLib PciHostBridgeUtilityLib PciLib - QemuFwCfgLib [Pcd] gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase diff --git a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c index bed2d87..5086e9d 100644 --- a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c +++ b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.c @@ -11,11 +11,16 @@ **/ #include +#include +#include #include #include #include #include +#include #include +#include +#include #pragma pack(1) @@ -185,6 +190,197 @@ 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 ( + OUT UINTN *Count, + IN UINT64 Attributes, + IN UINT64 AllocationAttributes, + IN PCI_ROOT_BRIDGE_APERTURE *Io, + IN PCI_ROOT_BRIDGE_APERTURE *Mem, + IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G, + IN PCI_ROOT_BRIDGE_APERTURE *PMem, + IN 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; + + *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, + 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 ( + IN PCI_ROOT_BRIDGE *Bridges, + IN 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. @param[in] Configuration Pointer to PCI I/O and PCI memory resource diff --git a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf index 4d6764b..fdae8cf 100644 --- a/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf +++ b/OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf @@ -39,3 +39,9 @@ DebugLib DevicePathLib MemoryAllocationLib + PcdLib + PciLib + QemuFwCfgLib + +[Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId -- cgit v1.1