From: Nicolas Ojeda Leon <ncoleon@amazon.com>
To: <devel@edk2.groups.io>
Cc: Nicolas Ojeda Leon <ncoleon@amazon.com>, Alexander Graf <graf@amazon.de>
Subject: [PATCH 1/5] OvmfPkg/PlatformPei: Extend 64-bit PCI range for multiple host bridges
Date: Sat, 4 Sep 2021 16:37:52 +0200 [thread overview]
Message-ID: <2002ab24b91e9007619febab837d2c29aee5f93f.1630676569.git.ncoleon@amazon.com> (raw)
In-Reply-To: <cover.1630676569.git.ncoleon@amazon.com>
Create host_bridge_info struct describing PCI host bridges' resources
so that one or more host bridges can be specified by the hypervisor
and their information propagated through fw-cfg. The host is able to
determine the bus number, the bus number range, the NUMA proximity and
all MMIO resources each root bridge uses (low and high memory both
prefetchable and non-prefetchable).
With the increased control we give for the host to define the resources
each root bridge can use, the case may arise in which one of the
ranges, particularly the 64-bit MMIO window, exceeds the usable range.
Taking into account that PcdPciMmio64Size token determines, together with
PcdPciMmio64Base, the usable 64-bit range, we verify if the MMIO windows
set in the specification fit inside the valid range. If one of the root
bridges is set to use a higher memory address space, PcdPciMmio64Size
token is increased so that the intended window lies inside the valid range.
For example, using PcdPciMmio64Size of 0x800000000 and a runtime calculated
base address also of 0x800000000, the high memory usable addresses are
restricted to 0x1000000000. With the increased flexibility to specify
host bridge resources, a feasible example would be:
struct host_bridge_info pci_hb_spec[] = {
{
.set_pxm = true,
.mark_prefetchable_resources_as_cacheable = true,
.root_bus_nr = 0x00,
.pxm = 1,
.num_hot_plug_slots = 32,
.root_bur_nr_start = 0x00,
.root_bus_nr_end = 0x7F,
.lowmem_start = 0xC0000000,
.lowmem_end = 0xD0000000 - 1,
.lowmem_pref_start = 0xFFFFFFFF,
.lowmem_pref_end = 0xFFFFFFFF,
.highmem_start = 0xFFFFFFFFFFFFFFFF,
.highmem_end = 0xFFFFFFFFFFFFFFFF,
.highmem_pref_start = 0x800000000,
.highmem_pref_end = 0x1000000000 - 1
},
{
.set_pxm = true,
.mark_prefetchable_resources_as_cacheable = true,
.root_bus_nr = 0x80,
.pxm = 1,
.num_hot_plug_slots = 32,
.root_bur_nr_start = 0x80,
.root_bus_nr_end = 0xFF,
.lowmem_start = 0xD0000000,
.lowmem_end = 0xE0000000 - 1,
.lowmem_pref_start = 0xFFFFFFFF,
.lowmem_pref_end = 0xFFFFFFFF,
.highmem_start = 0xFFFFFFFFFFFFFFFF,
.highmem_end = 0xFFFFFFFFFFFFFFFF,
.highmem_pref_start = 0x1000000000,
.highmem_pref_end = 0x1800000000 - 1
}
};
The first host bridge already uses all the available space. Consequently,
the 64-bit PCI size needs to be extended. For that, the resource spec
exemplified is read from fw-cfg and PcdPciMmio64Size extended to
0x1000000000 so that both host bridges fit inside the valid window.
Signed-off-by: Nicolas Ojeda Leon <ncoleon@amazon.com>
Cc: Alexander Graf <graf@amazon.de>
---
.../Include/Library/PciHostBridgeInfoLib.h | 43 ++++++++++
OvmfPkg/PlatformPei/MemDetect.c | 83 +++++++++++++++++++
2 files changed, 126 insertions(+)
create mode 100644 OvmfPkg/Include/Library/PciHostBridgeInfoLib.h
diff --git a/OvmfPkg/Include/Library/PciHostBridgeInfoLib.h b/OvmfPkg/Include/Library/PciHostBridgeInfoLib.h
new file mode 100644
index 0000000000..e09e6c496e
--- /dev/null
+++ b/OvmfPkg/Include/Library/PciHostBridgeInfoLib.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * This program and the accompanying materials
+ * are licensed and made available under the terms and conditions of the BSD License
+ * which accompanies this distribution. The full text of the license may be found at
+ * http://opensource.org/licenses/bsd-license.php
+ *
+ * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ */
+
+#ifndef __PCI_HOST_BRIDGE_INFO_LIB_H__
+#define __PCI_HOST_BRIDGE_INFO_LIB_H__
+
+//
+// Root bridge resource information for parsing fw-cfg data
+//
+#pragma pack(1)
+typedef struct {
+ BOOLEAN set_pxm;
+ BOOLEAN mark_prefetchable_resources_as_cacheable;
+
+ UINT8 root_bus_nr;
+ UINT8 pxm;
+ UINT8 num_hot_plug_slots;
+
+ UINT8 root_bur_nr_start;
+ UINT8 root_bus_nr_end;
+
+ UINT32 lowmem_start;
+ UINT32 lowmem_end;
+ UINT32 lowmem_pref_start;
+ UINT32 lowmem_pref_end;
+
+ UINT64 highmem_start;
+ UINT64 highmem_end;
+ UINT64 highmem_pref_start;
+ UINT64 highmem_pref_end;
+} HOST_BRIDGE_INFO;
+#pragma pack()
+
+#endif
diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index 2c2c4641ec..2872e805a4 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -30,6 +30,7 @@ Module Name:
#include <Library/MemEncryptSevLib.h>
#include <Library/PcdLib.h>
#include <Library/PciLib.h>
+#include <Library/PciHostBridgeInfoLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/ResourcePublicationLib.h>
#include <Library/MtrrLib.h>
@@ -323,6 +324,83 @@ GetSystemMemorySizeAbove4gb (
}
+/**
+ 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;
+ FIRMWARE_CONFIG_ITEM FwCfgItem;
+ HOST_BRIDGE_INFO HostBridge;
+ UINTN FwCfgSize;
+ UINTN Processed;
+ UINT64 PciEnd;
+ UINT64 PcdPciEnd;
+
+ Status = QemuFwCfgFindFile ("etc/host-bridge-info", &FwCfgItem, &FwCfgSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if (FwCfgSize % sizeof HostBridge != 0) {
+ return EFI_PROTOCOL_ERROR;
+ }
+
+ PciEnd = 0;
+ QemuFwCfgSelectItem (FwCfgItem);
+ for (Processed = 0; Processed < FwCfgSize; Processed += sizeof HostBridge) {
+ QemuFwCfgReadBytes (sizeof HostBridge, &HostBridge);
+
+ if (HostBridge.highmem_end != MAX_UINT64 &&
+ HostBridge.highmem_end > PciEnd) {
+ PciEnd = HostBridge.highmem_end;
+ }
+ if (HostBridge.highmem_pref_end != MAX_UINT64 &&
+ HostBridge.highmem_pref_end > PciEnd) {
+ PciEnd = HostBridge.highmem_pref_end;
+ }
+ }
+
+ PcdPciEnd = PciMmio64Base + *PciMmio64Size;
+ if (PciEnd > PcdPciEnd) {
+ *PciMmio64Size = PciEnd - PciMmio64Base;
+ *PciMmio64Size = ALIGN_VALUE (*PciMmio64Size, (UINT64)SIZE_1GB);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
/**
Return the highest address that DXE could possibly use, plus one.
**/
@@ -452,6 +530,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
--
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
next prev parent reply other threads:[~2021-09-04 14:39 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-04 14:37 [PATCH 0/5] Handling of multiple PCI host bridges with pre-populated resources in Ovmf Nicolas Ojeda Leon
2021-09-04 14:37 ` Nicolas Ojeda Leon [this message]
2021-09-08 8:03 ` [edk2-devel] [PATCH 1/5] OvmfPkg/PlatformPei: Extend 64-bit PCI range for multiple host bridges Gerd Hoffmann
2021-09-04 14:37 ` [PATCH 2/5] OvmfPkg/PciHostBridgeUtilityLib: Initialize RootBridges apertures with spec Nicolas Ojeda Leon
2021-09-04 14:37 ` [PATCH 3/5] MdeModulePkg OvmfPkg: Add Pcd token for PCI pre-populated BARs Nicolas Ojeda Leon
2021-09-04 14:37 ` [PATCH 4/5] MdeModulePkg/Pci MdePkg: Create service to retrieve PCI base addresses Nicolas Ojeda Leon
2021-09-04 14:37 ` [PATCH 5/5] MdeModulePkg/PciBusDxe: Handling of pre-populated PCI BARs Nicolas Ojeda Leon
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=2002ab24b91e9007619febab837d2c29aee5f93f.1630676569.git.ncoleon@amazon.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