Read the "hardware-info" item from fw-cfg to extract specifications of PCI host bridges and analyze the 64-bit apertures of them to find out if 64-bit PCI size needs to be increased in order to allocate enough address space to fit all the host bridges in a valid region.
Using the static Hardware Info Lib API, read the fw-cfg file of hardware information to extract, one by one, all the host bridges. Find the last 64-bit MMIO address of each host bridge, using the HardwareInfoPciHostBridgeLib API, and compare it to an accumulate value to discover the highest address used, which corresponds to the highest value that must be covered by the 64-bit PCI MMIO window. Given that platforms with multiple host bridges may provide the PCI apertures' addresses, the PCD token used to initialize the available address space (PcdPciMmio64Size) must include those addresses for the allocation process to be able to place resources in the intended regions. Since the Pcd entry defining the 64-bit PCI MMIO size is dynamic and initialized with a platform-dependent value, it is updated to a higher value if that is required for all high memory PCI host bridge apertures to fit in the valid address space. As an example, if the PcdPciMmio64Size is initialized to 0x800000000 and the runtime calculated base address produces the value 0x800000000, the last 64-bit MMIO address a PCI host bridge may use would be 0xFFFFFFFFF. If one of the host-specified bridges defines a high memory window 0x1000000000 - 0x17FFFFFFFF (inclusive) it would be outside of the valid range defined by the Base address + PcdPciMmio64Size. Therefore, parsing the HardwwareInfo resource allows to notice the higher requirement and increase the size to 0x1000000000 so that the MMIO address space solicited by the host can be met and the range effectively extended to 0x17FFFFFFFF. Cc: Alexander Graf <g...@amazon.de> Cc: Gerd Hoffmann <kra...@redhat.com> Signed-off-by: Nicolas Ojeda Leon <ncol...@amazon.com> --- OvmfPkg/PlatformPei/MemDetect.c | 110 ++++++++++++++++++++++++++++ OvmfPkg/PlatformPei/PlatformPei.inf | 1 + 2 files changed, 111 insertions(+) diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c index 1bcb5a08bc..b0bdd435cb 100644 --- a/OvmfPkg/PlatformPei/MemDetect.c +++ b/OvmfPkg/PlatformPei/MemDetect.c @@ -36,6 +36,7 @@ Module Name: #include <Library/MtrrLib.h> #include <Library/QemuFwCfgLib.h> #include <Library/QemuFwCfgSimpleParserLib.h> +#include <Library/QemuFwCfgHardwareInfoLib.h> #include "Platform.h" #include "Cmos.h" @@ -369,6 +370,110 @@ GetSystemMemorySizeAbove4gb ( return LShiftU64 (Size, 16); } +/** + Iterate over the PCI host bridges resources information optionally provided + in fw-cfg. + + Find the highest address used by the PCI bridges in 64-bit MMIO space to + calculate and modify the PCI aperture size accordingly (PciMmio64Size) + + @param[in] PciMmio64Base Base address (start) of the 64-bit PCI MMIO + address space. + + @param[inout] PciMmio64Size Size of the PCI 64-bit MMIO aperture provided + as input and modified (output) if the resources + indicated by fw_cfg require a larger address + space. + + @retval EFI_SUCCESS The fw_cfg host-bridges-info was found and + processed. + + @retval EFI_PROTOCOL_ERROR The host bridges information file was found, + but its size wasn't a whole multiple of + sizeof(HOST_BRIDGE_INFO). No entry was processed. + + @retval EFI_NOT_FOUND fw-cfg file with host bridges information was not + found. Does not constitute an errro since the file + is optional and used in special cases. + + @retval EFI_UNSUPPORTED fw-cfg is unavailable + +**/ +STATIC +EFI_STATUS +ScanPci64BitApertureSize ( + IN UINT64 PciMmio64Base, + IN OUT UINT64 *PciMmio64Size + ) +{ + EFI_STATUS Status; + HOST_BRIDGE_INFO HostBridge; + FIRMWARE_CONFIG_ITEM FwCfgItem; + UINTN FwCfgSize; + UINTN FwCfgReadIndex; + UINTN ReadDataSize; + UINT64 PciEnd; + UINT64 PcdPciEnd; + UINT64 Above4GMmioEnd; + + PciEnd = 0; + Above4GMmioEnd = 0; + PcdPciEnd = PciMmio64Base + *PciMmio64Size - 1; + + Status = QemuFwCfgFindFile ("etc/hardware-info", &FwCfgItem, &FwCfgSize); + if (EFI_ERROR (Status)) { + return Status; + } + + QemuFwCfgSelectItem (FwCfgItem); + + FwCfgReadIndex = 0; + while (FwCfgReadIndex < FwCfgSize) { + Status = QemuFwCfgReadNextHardwareInfoByType ( + HardwareInfoTypeHostBridge, + sizeof (HostBridge), + FwCfgSize, + &HostBridge, + &ReadDataSize, + &FwCfgReadIndex + ); + + if (Status != EFI_SUCCESS) { + // + // No more data available to read in the file, break + // loop and finish process + // + break; + } + + Status = HardwareInfoPciHostBridgeLastMmioAddress ( + &HostBridge, + ReadDataSize, + TRUE, + &Above4GMmioEnd + ); + + if (Status != EFI_SUCCESS) { + // + // Error parsing MMIO apertures and extracting last MMIO + // address, bail out and propagate error + // + return Status; + } + + if (Above4GMmioEnd > PciEnd) { + PciEnd = Above4GMmioEnd; + } + } + + if (PciEnd > PcdPciEnd) { + *PciMmio64Size = PciEnd - PciMmio64Base + 1; + *PciMmio64Size = ALIGN_VALUE (*PciMmio64Size, (UINT64)SIZE_1GB); + } + + return EFI_SUCCESS; +} + /** Return the highest address that DXE could possibly use, plus one. **/ @@ -515,6 +620,11 @@ GetFirstNonAddress ( // Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size)); + // + // Extend Pci64Size if fw_cfg Host bridges specification requires it + // + ScanPci64BitApertureSize (Pci64Base, &Pci64Size); + if (mBootMode != BOOT_ON_S3_RESUME) { // // The core PciHostBridgeDxe driver will automatically add this range to diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf index 8ef404168c..413b92b855 100644 --- a/OvmfPkg/PlatformPei/PlatformPei.inf +++ b/OvmfPkg/PlatformPei/PlatformPei.inf @@ -64,6 +64,7 @@ MemEncryptSevLib PcdLib VmgExitLib + QemuFwCfgHardwareInfoLib [Pcd] gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase -- 2.17.1 Amazon Development Center Germany GmbH Krausenstr. 38 10117 Berlin Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B Sitz: Berlin Ust-ID: DE 289 237 879 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#85874): https://edk2.groups.io/g/devel/message/85874 Mute This Topic: https://groups.io/mt/88565405/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-