Now that viewport memory regions are created on demand, the PCIDevice of the configuration memory can be determined once upon creation of the memory region rather than dynamically resolving it upon each access. This is both more efficient at runtime and resolves an attribute. Furthermore, if an invalid PCI device is configured, a guest error is now logged since the error is now direclty related to a guest action.
Signed-off-by: Bernhard Beschow <shen...@gmail.com> --- include/hw/pci-host/designware.h | 1 - hw/pci-host/designware.c | 54 +++++++++++++++++--------------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h index 7dc8af049d..34beee1285 100644 --- a/include/hw/pci-host/designware.h +++ b/include/hw/pci-host/designware.h @@ -39,7 +39,6 @@ struct DesignwarePCIERootBus { }; typedef struct DesignwarePCIEViewport { - DesignwarePCIERoot *root; const char *name; MemoryRegion mem; diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c index 7d47d8228f..2a676c65a2 100644 --- a/hw/pci-host/designware.c +++ b/hw/pci-host/designware.c @@ -222,26 +222,18 @@ designware_pcie_root_config_read(PCIDevice *d, uint32_t address, int len) static uint64_t designware_pcie_root_data_access(void *opaque, hwaddr addr, uint64_t *val, unsigned len) { - DesignwarePCIEViewport *viewport = opaque; - DesignwarePCIERoot *root = viewport->root; - - const uint8_t busnum = DESIGNWARE_PCIE_ATU_BUS(viewport->target); - const uint8_t devfn = DESIGNWARE_PCIE_ATU_DEVFN(viewport->target); - PCIBus *pcibus = pci_get_bus(PCI_DEVICE(root)); - PCIDevice *pcidev = pci_find_device(pcibus, busnum, devfn); - - if (pcidev) { - addr &= pci_config_size(pcidev) - 1; - - if (val) { - pci_host_config_write_common(pcidev, addr, - pci_config_size(pcidev), - *val, len); - } else { - return pci_host_config_read_common(pcidev, addr, - pci_config_size(pcidev), - len); - } + PCIDevice *pcidev = opaque; + + addr &= pci_config_size(pcidev) - 1; + + if (val) { + pci_host_config_write_common(pcidev, addr, + pci_config_size(pcidev), + *val, len); + } else { + return pci_host_config_read_common(pcidev, addr, + pci_config_size(pcidev), + len); } return UINT64_MAX; @@ -312,11 +304,22 @@ static void designware_pcie_update_viewport(DesignwarePCIERoot *root, * Configure MemoryRegion implementing access to configuration * space */ - memory_region_init_io(&viewport->mem, OBJECT(root), - &designware_pci_host_conf_ops, - viewport, viewport->name, size); - memory_region_add_subregion(get_system_memory(), base, - &viewport->mem); + const uint8_t busnum = DESIGNWARE_PCIE_ATU_BUS(viewport->target); + const uint8_t devfn = DESIGNWARE_PCIE_ATU_DEVFN(viewport->target); + PCIBus *pcibus = pci_get_bus(PCI_DEVICE(root)); + PCIDevice *pcidev = pci_find_device(pcibus, busnum, devfn); + + if (pcidev) { + memory_region_init_io(&viewport->mem, OBJECT(root), + &designware_pci_host_conf_ops, + pcidev, viewport->name, size); + memory_region_add_subregion(get_system_memory(), base, + &viewport->mem); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "%s: No PCI device attached" + " under busnum: %d, devfn: %d\n", __func__, + (int)busnum, (int)devfn); + } } } } @@ -444,7 +447,6 @@ static void designware_pcie_root_realize(PCIDevice *dev, Error **errp) for (size_t j = 0; j < DESIGNWARE_PCIE_NUM_VIEWPORTS; j++) { DesignwarePCIEViewport *viewport = &root->viewports[i][j]; - viewport->root = root; viewport->name = names[i][j]; viewport->inbound = i == DESIGNWARE_PCIE_VIEWPORT_INBOUND; viewport->base = 0x0000000000000000ULL; -- 2.50.1