diff options
-rw-r--r-- | hw/ppc/spapr.c | 31 | ||||
-rw-r--r-- | hw/ppc/spapr_pci.c | 21 | ||||
-rw-r--r-- | include/hw/pci-host/spapr.h | 11 | ||||
-rw-r--r-- | include/hw/ppc/spapr.h | 3 |
4 files changed, 42 insertions, 24 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index fc4c3c98c8..2bfd187bc5 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2370,6 +2370,36 @@ static HotpluggableCPUList *spapr_query_hotpluggable_cpus(MachineState *machine) return head; } +static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index, + uint64_t *buid, hwaddr *pio, hwaddr *mmio, + unsigned n_dma, uint32_t *liobns, Error **errp) +{ + const uint64_t base_buid = 0x800000020000000ULL; + const hwaddr phb0_base = 0x10000000000ULL; /* 1 TiB */ + const hwaddr phb_spacing = 0x1000000000ULL; /* 64 GiB */ + const hwaddr mmio_offset = 0xa0000000; /* 2 GiB + 512 MiB */ + const hwaddr pio_offset = 0x80000000; /* 2 GiB */ + const uint32_t max_index = 255; + + hwaddr phb_base; + int i; + + if (index > max_index) { + error_setg(errp, "\"index\" for PAPR PHB is too large (max %u)", + max_index); + return; + } + + *buid = base_buid + index; + for (i = 0; i < n_dma; ++i) { + liobns[i] = SPAPR_PCI_LIOBN(index, i); + } + + phb_base = phb0_base + index * phb_spacing; + *pio = phb_base + pio_offset; + *mmio = phb_base + mmio_offset; +} + static void spapr_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -2406,6 +2436,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) mc->query_hotpluggable_cpus = spapr_query_hotpluggable_cpus; fwc->get_dev_path = spapr_get_fw_dev_path; nc->nmi_monitor_handler = spapr_nmi; + smc->phb_placement = spapr_phb_placement; } static const TypeInfo spapr_machine_info = { diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index a7ca988387..8bd7f598a0 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1311,7 +1311,8 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1; if (sphb->index != (uint32_t)-1) { - hwaddr windows_base; + sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); + Error *local_err = NULL; if ((sphb->buid != (uint64_t)-1) || (sphb->dma_liobn[0] != (uint32_t)-1) || (sphb->dma_liobn[1] != (uint32_t)-1 && windows_supported == 2) @@ -1322,21 +1323,13 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) return; } - if (sphb->index > SPAPR_PCI_MAX_INDEX) { - error_setg(errp, "\"index\" for PAPR PHB is too large (max %u)", - SPAPR_PCI_MAX_INDEX); + smc->phb_placement(spapr, sphb->index, &sphb->buid, + &sphb->io_win_addr, &sphb->mem_win_addr, + windows_supported, sphb->dma_liobn, &local_err); + if (local_err) { + error_propagate(errp, local_err); return; } - - sphb->buid = SPAPR_PCI_BASE_BUID + sphb->index; - for (i = 0; i < windows_supported; ++i) { - sphb->dma_liobn[i] = SPAPR_PCI_LIOBN(sphb->index, i); - } - - windows_base = SPAPR_PCI_WINDOW_BASE - + sphb->index * SPAPR_PCI_WINDOW_SPACING; - sphb->mem_win_addr = windows_base + SPAPR_PCI_MMIO_WIN_OFF; - sphb->io_win_addr = windows_base + SPAPR_PCI_IO_WIN_OFF; } if (sphb->buid == (uint64_t)-1) { diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 30dbd461d4..8c9ebfda41 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -79,18 +79,9 @@ struct sPAPRPHBState { uint32_t numa_node; }; -#define SPAPR_PCI_MAX_INDEX 255 - -#define SPAPR_PCI_BASE_BUID 0x800000020000000ULL - #define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL -#define SPAPR_PCI_WINDOW_BASE 0x10000000000ULL -#define SPAPR_PCI_WINDOW_SPACING 0x1000000000ULL -#define SPAPR_PCI_MMIO_WIN_OFF 0xA0000000 -#define SPAPR_PCI_MMIO_WIN_SIZE (SPAPR_PCI_WINDOW_SPACING - \ - SPAPR_PCI_MEM_WIN_BUS_OFFSET) -#define SPAPR_PCI_IO_WIN_OFF 0x80000000 +#define SPAPR_PCI_MMIO_WIN_SIZE 0xf80000000 #define SPAPR_PCI_IO_WIN_SIZE 0x10000 #define SPAPR_PCI_MSI_WINDOW 0x40000000000ULL diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 39dadaa9ce..a05783cb3f 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -40,6 +40,9 @@ struct sPAPRMachineClass { bool dr_lmb_enabled; /* enable dynamic-reconfig/hotplug of LMBs */ bool use_ohci_by_default; /* use USB-OHCI instead of XHCI */ const char *tcg_default_cpu; /* which (TCG) CPU to simulate by default */ + void (*phb_placement)(sPAPRMachineState *spapr, uint32_t index, + uint64_t *buid, hwaddr *pio, hwaddr *mmio, + unsigned n_dma, uint32_t *liobns, Error **errp); }; /** |