Previously PCI bus setup was done in 3 steps: 1) create a PCI bus, configure DMA 2) create PCI devices on the bus 3) populate a PCI bus node in the Device Tree
As some bus parameters can be configured only when some or all the devices got attached to the bus and initialized, the spapr_finalize_pci_setup has been introduced. As an example, such a handler can setup DMA window parameters taken from an IOMMU file descriptor available from a VFIO PCI device. Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru> --- hw/spapr.c | 7 +++++++ hw/spapr_pci.c | 13 ++++++++++--- hw/spapr_pci.h | 2 ++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index b83f83b..688a135 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -516,7 +516,14 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr, } QLIST_FOREACH(phb, &spapr->phbs, list) { + ret = spapr_finalize_pci_setup(phb); + if (ret < 0) { + break; + } ret = spapr_populate_pci_dt(phb, PHANDLE_XICP, fdt); + if (ret < 0) { + break; + } } if (ret < 0) { diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 014297b..5f89003 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -573,9 +573,6 @@ static int spapr_phb_init(SysBusDevice *s) phb->host_state.bus = bus; phb->dma_liobn = SPAPR_PCI_BASE_LIOBN | (pci_find_domain(bus) << 16); - phb->dma_window_start = 0; - phb->dma_window_size = 0x40000000; - phb->dma = spapr_tce_new_dma_context(phb->dma_liobn, phb->dma_window_size); pci_setup_iommu(bus, spapr_pci_dma_context_fn, phb); QLIST_INSERT_HEAD(&spapr->phbs, phb, list); @@ -639,6 +636,16 @@ void spapr_create_phb(sPAPREnvironment *spapr, qdev_init_nofail(dev); } +/* Finalize PCI setup, called when all devices are already created */ +int spapr_finalize_pci_setup(sPAPRPHBState *phb) +{ + phb->dma_window_start = 0; + phb->dma_window_size = 0x40000000; + phb->dma = spapr_tce_new_dma_context(phb->dma_liobn, + phb->dma_window_size); + return 0; +} + /* Macros to operate with address in OF binding to PCI */ #define b_x(x, p, l) (((x) & ((1<<(l))-1)) << (p)) #define b_n(x) b_x((x), 31, 1) /* 0 if relocatable */ diff --git a/hw/spapr_pci.h b/hw/spapr_pci.h index 145071c..3aae273 100644 --- a/hw/spapr_pci.h +++ b/hw/spapr_pci.h @@ -68,6 +68,8 @@ void spapr_create_phb(sPAPREnvironment *spapr, uint64_t mem_win_addr, uint64_t mem_win_size, uint64_t io_win_addr, uint64_t msi_win_addr); +int spapr_finalize_pci_setup(sPAPRPHBState *phb); + int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle, void *fdt); -- 1.7.10