All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tushar Dave <tdave@nvidia.com>
To: qemu-devel@nongnu.org
Cc: alwilliamson@nvidia.com, jgg@nvidia.com, skolothumtho@nvidia.com,
	qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com,
	marcel.apfelbaum@gmail.com, devel@edk2.groups.io
Subject: [RFC PATCH 6/8] hw/pci: finalize bridge prefetch windows after BAR allocation
Date: Fri,  8 May 2026 13:37:15 -0500	[thread overview]
Message-ID: <20260508183717.193630-7-tdave@nvidia.com> (raw)
In-Reply-To: <20260508183717.193630-1-tdave@nvidia.com>

Add a final reconciliation pass to update bridge prefetch windows
after all BARs have been assigned across all phases.

This ensures bridge windows accurately reflect final BAR placement
across all buses.

SR-IOV virtual functions are not included when sizing bridge prefetch
apertures and may require additional work.

Signed-off-by: Tushar Dave <tdave@nvidia.com>
---
 hw/pci/pci-resource.c | 89 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)

diff --git a/hw/pci/pci-resource.c b/hw/pci/pci-resource.c
index e2d2adc7de..01db59c4af 100644
--- a/hw/pci/pci-resource.c
+++ b/hw/pci/pci-resource.c
@@ -190,6 +190,76 @@ static void pci_update_prefetch_window(PCIBus *bus, uint64_t base, uint64_t limi
                                  4);
 }
 
+static void pci_get_bridge_window(PCIBus *bus, void *opaque)
+{
+    PCIDevice *bridge = pci_bridge_get_device(bus);
+    PciAllocCfg *pci_res = (PciAllocCfg *)opaque;
+
+    if (!bridge) {
+        pci_res->wbase = pci_res->mmio32_base;
+        pci_res->wlimit = pci_res->mmio32_base + pci_res->mmio32_size - 1;
+        pci_res->wbase64 = pci_res->mmio64_base;
+        pci_res->wlimit64 = pci_res->mmio64_base + pci_res->mmio64_size - 1;
+    } else {
+        pci_res->wbase = pci_bridge_get_base(bridge, PCI_BASE_ADDRESS_MEM_TYPE_32);
+        pci_res->wlimit = pci_bridge_get_limit(bridge, PCI_BASE_ADDRESS_MEM_TYPE_32);
+        pci_res->wbase64 = pci_bridge_get_base(bridge, PCI_BASE_ADDRESS_MEM_PREFETCH);
+        pci_res->wlimit64 = pci_bridge_get_limit(bridge, PCI_BASE_ADDRESS_MEM_PREFETCH);
+    }
+}
+
+static void pci_collect_mmio64_window(PCIBus *bus, PCIDevice *dev, void *opaque)
+{
+    PciAllocCfg *pci_res = (PciAllocCfg *)opaque;
+    uint64_t rbase, rlimit;
+    uint32_t idx;
+
+    for (idx = 0; idx < PCI_ROM_SLOT; idx++) {
+        PCIIORegion *res = &dev->io_regions[idx];
+
+        if (!res->size) {
+            continue;
+        }
+        rbase = res->addr;
+        rlimit = res->addr + res->size - 1;
+        /* Entire BAR must lie in the window; do not count partial overlap. */
+        if (rbase < pci_res->wbase64 || rlimit > pci_res->wlimit64) {
+            continue;
+        }
+        pci_res->rbase = MIN(pci_res->rbase, rbase);
+        pci_res->rlimit = MAX(pci_res->rlimit, rlimit);
+    }
+
+    if (IS_PCI_BRIDGE(dev)) {
+        rbase = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
+        rlimit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
+
+        if ((rbase < pci_res->wbase64) ||
+            (rbase > pci_res->wlimit64) ||
+            (rlimit < pci_res->wbase64) ||
+            (rlimit > pci_res->wlimit64)) {
+            return;
+        }
+
+        pci_res->rbase = MIN(pci_res->rbase, rbase);
+        pci_res->rlimit = MAX(pci_res->rlimit, rlimit);
+    }
+}
+
+static void pci_bus_update_prefetch_window(PCIBus *bus, void *opaque)
+{
+    PciAllocCfg *pci_res = (PciAllocCfg *)opaque;
+    pci_res->rbase = ~0;
+    pci_res->rlimit = 0;
+
+    assert(pci_bridge_get_device(bus));
+    pci_for_each_device_under_bus(bus, pci_collect_mmio64_window, pci_res);
+
+    if (pci_res->rlimit > pci_res->rbase) {
+        pci_update_prefetch_window(bus, pci_res->rbase, pci_res->rlimit);
+    }
+}
+
 static inline bool is_64bit_pref_bar(PCIIORegion *r)
 {
     if (!r->size) {
@@ -1004,6 +1074,25 @@ void pci_fixed_bar_allocator(PCIBus *root, const PciFixedBarMmioParams *mmio)
     /* Phase 3: allocate BARs for buses that have no fixed-BAR devices */
     pci_for_each_bus(bus, pci_bus_phase3_allocate_no_fixed_bars, &pctx);
 
+    memset(pci_res, 0, sizeof(PciAllocCfg));
+    pci_resource_init_from_mmio(pci_res, mmio);
+
+    /* TODO: 32-bit MMIO/ROM adjustment */
+    /* TODO: PIO assignment */
+    /* TODO: 64-bit non-prefetchable */
+
+    /* Align bridge prefetch window with assigned BAR ranges */
+    pci_get_bridge_window(bus, pci_res);
+
+    QLIST_FOREACH(bus, &bus->child, sibling) {
+        pci_res->bus = bus;
+        /* Use the full mmio64 window */
+        pci_res->wbase64 = pci_res->mmio64_base;
+        pci_res->wlimit64 = pci_res->mmio64_base + pci_res->mmio64_size - 1;
+
+        pci_for_each_bus(bus, pci_bus_update_prefetch_window, pci_res);
+    }
+
     /* Cleanup */
     g_hash_table_destroy(pctx.had_fixed);
     fixed_claim_regions_reset();
-- 
2.34.1



  parent reply	other threads:[~2026-05-08 20:43 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-08 18:37 [RFC PATCH 0/8] hw/arm/virt, hw/pci: PCI pre-enumeration and fixed BAR allocation Tushar Dave
2026-05-08 18:37 ` [RFC PATCH 1/8] hw/pci: add fixed-bars property to allow fixed BAR addresses Tushar Dave
2026-05-08 18:37 ` [RFC PATCH 2/8] hw/pci: enumerate PCI bus and program bridge bus numbers Tushar Dave
2026-05-08 18:37 ` [RFC PATCH 3/8] hw/pci: introduce allocator for fixed BAR placement Tushar Dave
2026-05-08 18:37 ` [RFC PATCH 4/8] hw/pci: pack remaining BARs and update bridge windows Tushar Dave
2026-05-08 18:37 ` [RFC PATCH 5/8] hw/pci: allocate remaining BARs for buses without fixed BARs Tushar Dave
2026-05-08 18:37 ` Tushar Dave [this message]
2026-05-08 18:37 ` [RFC PATCH 7/8] hw/arm/virt: add pcie-mmio-window machine property Tushar Dave
2026-05-08 18:37 ` [RFC PATCH 8/8] hw/arm/virt: add pci-pre-enum " Tushar Dave
2026-05-11  7:46 ` [RFC PATCH 0/8] hw/arm/virt, hw/pci: PCI pre-enumeration and fixed BAR allocation Peter Maydell
2026-05-11 12:26   ` Jason Gunthorpe
2026-05-11 18:38     ` Mohamed Mediouni
2026-05-11 20:28       ` Jason Gunthorpe
2026-05-11  9:09 ` Michael S. Tsirkin
2026-05-11 18:10   ` Tushar Dave
2026-05-11 22:09     ` Michael S. Tsirkin
2026-05-11 11:43 ` [edk2-devel] " Ard Biesheuvel
2026-05-12 17:25   ` Tushar Dave
2026-05-12 23:06     ` Alex Williamson
2026-05-12 23:12       ` Michael S. Tsirkin
2026-05-12 23:57         ` Alex Williamson
2026-05-13 11:36           ` Jason Gunthorpe
2026-05-13 14:25           ` Ard Biesheuvel

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-all 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=20260508183717.193630-7-tdave@nvidia.com \
    --to=tdave@nvidia.com \
    --cc=alwilliamson@nvidia.com \
    --cc=devel@edk2.groups.io \
    --cc=jgg@nvidia.com \
    --cc=marcel.apfelbaum@gmail.com \
    --cc=mst@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=skolothumtho@nvidia.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.