Write the extra roots into the fw_cfg, therefore the uefi could get the extra roots. Only if the uefi knows there are extra roots, the config space of devices behind the root could be obtained.
Signed-off-by: Yubo Miao <miaoy...@huawei.com> --- hw/arm/virt.c | 8 ++++++++ hw/i386/pc.c | 18 ++---------------- hw/nvram/fw_cfg.c | 20 ++++++++++++++++++++ include/hw/nvram/fw_cfg.h | 2 ++ include/hw/pci/pcie_host.h | 4 ++++ 5 files changed, 36 insertions(+), 16 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index c41d5f9778..f64ff42ab5 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -78,6 +78,8 @@ #include "hw/virtio/virtio-iommu.h" #include "hw/char/pl011.h" #include "qemu/guest-random.h" +#include "hw/pci/pci_bus.h" +#include "hw/pci/pcie_host.h" #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ @@ -1457,6 +1459,10 @@ void virt_machine_done(Notifier *notifier, void *data) ARMCPU *cpu = ARM_CPU(first_cpu); struct arm_boot_info *info = &vms->bootinfo; AddressSpace *as = arm_boot_address_space(cpu, info); + PCIHostState *s = PCI_GET_PCIE_HOST_STATE; + + PCIBus *bus = s->bus; + FWCfgState *fw_cfg = vms->fw_cfg; /* * If the user provided a dtb, we assume the dynamic sysbus nodes @@ -1475,6 +1481,8 @@ void virt_machine_done(Notifier *notifier, void *data) exit(1); } + fw_cfg_write_extra_pci_roots(bus, fw_cfg); + virt_acpi_setup(vms); virt_build_smbios(vms); } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 2128f3d6fe..94b1d3df14 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -842,26 +842,12 @@ void pc_machine_done(Notifier *notifier, void *data) PCMachineState, machine_done); X86MachineState *x86ms = X86_MACHINE(pcms); PCIBus *bus = pcms->bus; + FWCfgState *fw_cfg = x86ms->fw_cfg; /* set the number of CPUs */ rtc_set_cpus_count(x86ms->rtc, x86ms->boot_cpus); - if (bus) { - int extra_hosts = 0; - - QLIST_FOREACH(bus, &bus->child, sibling) { - /* look for expander root buses */ - if (pci_bus_is_root(bus)) { - extra_hosts++; - } - } - if (extra_hosts && x86ms->fw_cfg) { - uint64_t *val = g_malloc(sizeof(*val)); - *val = cpu_to_le64(extra_hosts); - fw_cfg_add_file(x86ms->fw_cfg, - "etc/extra-pci-roots", val, sizeof(*val)); - } - } + fw_cfg_write_extra_pci_roots(bus, fw_cfg); acpi_setup(); if (x86ms->fw_cfg) { diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index 8dd50c2c72..824cfcf054 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -40,6 +40,7 @@ #include "qemu/cutils.h" #include "qapi/error.h" #include "hw/acpi/aml-build.h" +#include "hw/pci/pci_bus.h" #define FW_CFG_FILE_SLOTS_DFLT 0x20 @@ -742,6 +743,25 @@ static void *fw_cfg_modify_bytes_read(FWCfgState *s, uint16_t key, return ptr; } +void fw_cfg_write_extra_pci_roots(PCIBus *bus, FWCfgState *s) +{ + if (bus) { + int extra_hosts = 0; + QLIST_FOREACH(bus, &bus->child, sibling) { + /* look for expander root buses */ + if (pci_bus_is_root(bus)) { + extra_hosts++; + } + } + if (extra_hosts && s) { + uint64_t *val = g_malloc(sizeof(*val)); + *val = cpu_to_le64(extra_hosts); + fw_cfg_add_file(s, + "etc/extra-pci-roots", val, sizeof(*val)); + } + } +} + void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len) { trace_fw_cfg_add_bytes(key, trace_key_name(key), len); diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index 25d9307018..eb86ee5ae6 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -79,6 +79,8 @@ struct FWCfgMemState { MemoryRegionOps wide_data_ops; }; +void fw_cfg_write_extra_pci_roots(PCIBus *bus, FWCfgState *s); + /** * fw_cfg_add_bytes: * @s: fw_cfg device being modified diff --git a/include/hw/pci/pcie_host.h b/include/hw/pci/pcie_host.h index 3f7b9886d1..c93f2d7011 100644 --- a/include/hw/pci/pcie_host.h +++ b/include/hw/pci/pcie_host.h @@ -27,6 +27,10 @@ #define TYPE_PCIE_HOST_BRIDGE "pcie-host-bridge" #define PCIE_HOST_BRIDGE(obj) \ OBJECT_CHECK(PCIExpressHost, (obj), TYPE_PCIE_HOST_BRIDGE) +#define PCI_GET_PCIE_HOST_STATE \ + OBJECT_CHECK(PCIHostState, \ + object_resolve_path_type("", "pcie-host-bridge", NULL), \ + TYPE_PCIE_HOST_BRIDGE) #define PCIE_HOST_MCFG_BASE "MCFG" #define PCIE_HOST_MCFG_SIZE "mcfg_size" -- 2.19.1