diff options
author | Jonathan Cameron <Jonathan.Cameron@huawei.com> | 2023-02-27 15:31:27 +0000 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2023-03-07 19:51:07 -0500 |
commit | 84344ee2da1f8a23819c15361298d997d9e69dbf (patch) | |
tree | ac01c4fec77128ae7c439f95422f8c1a2cae6410 /hw/pci | |
parent | 415442a1b4ad31521bbe7ae8bf4ee5d25af3977f (diff) |
hw/pci: Add pcie_count_ds_port() and pcie_find_port_first() helpers
These two helpers enable host bridges to operate differently depending on
the number of downstream ports, in particular if there is only a single
port.
Useful for CXL where HDM address decoders are allowed to be implicit in
the host bridge if there is only a single root port.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Message-Id: <20230227153128.8164-2-Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/pci')
-rw-r--r-- | hw/pci/pcie_port.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/hw/pci/pcie_port.c b/hw/pci/pcie_port.c index 000633fec1..20ff2b39e8 100644 --- a/hw/pci/pcie_port.c +++ b/hw/pci/pcie_port.c @@ -161,6 +161,44 @@ PCIDevice *pcie_find_port_by_pn(PCIBus *bus, uint8_t pn) return NULL; } +/* Find first port in devfn number order */ +PCIDevice *pcie_find_port_first(PCIBus *bus) +{ + int devfn; + + for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) { + PCIDevice *d = bus->devices[devfn]; + + if (!d || !pci_is_express(d) || !d->exp.exp_cap) { + continue; + } + + if (object_dynamic_cast(OBJECT(d), TYPE_PCIE_PORT)) { + return d; + } + } + + return NULL; +} + +int pcie_count_ds_ports(PCIBus *bus) +{ + int dsp_count = 0; + int devfn; + + for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) { + PCIDevice *d = bus->devices[devfn]; + + if (!d || !pci_is_express(d) || !d->exp.exp_cap) { + continue; + } + if (object_dynamic_cast(OBJECT(d), TYPE_PCIE_PORT)) { + dsp_count++; + } + } + return dsp_count; +} + static bool pcie_slot_is_hotpluggbale_bus(HotplugHandler *plug_handler, BusState *bus) { |