diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2016-10-17 12:59:54 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2016-10-17 12:59:54 +0100 |
| commit | 7bf59dfec4234e75e31b3f397374cb5bab1a5b2c (patch) | |
| tree | a15d9bc428f48ecdd02c1673402fab933f8e7915 /hw/ppc/spapr_pci.c | |
| parent | ad728364e3916e1159ee94e5cd82b7a9c81d2dcc (diff) | |
| parent | 357d1e3bc7d2d80e5271bc4f3ac8537e30dc8046 (diff) | |
| download | focaccia-qemu-7bf59dfec4234e75e31b3f397374cb5bab1a5b2c.tar.gz focaccia-qemu-7bf59dfec4234e75e31b3f397374cb5bab1a5b2c.zip | |
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.8-20161017' into staging
ppc patch queue 2016-10-17
Highlights:
* Significant rework of how PCI IO windows are placed for the
pseries machine type
* A number of extra tests added for ppc
* Other tests clean up / fixed
* Some cleanups to the XICS interrupt controller in preparation
for the 'powernv' machine type
A number of the test changes aren't strictly in ppc related code, but
are included via my tree because they're primarily focused on
improving test coverage for ppc.
# gpg: Signature made Mon 17 Oct 2016 03:42:41 BST
# gpg: using RSA key 0x6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>"
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392
* remotes/dgibson/tags/ppc-for-2.8-20161017:
spapr: Improved placement of PCI host bridges in guest memory map
spapr_pci: Add a 64-bit MMIO window
spapr: Adjust placement of PCI host bridge to allow > 1TiB RAM
spapr_pci: Delegate placement of PCI host bridges to machine type
libqos: Limit spapr-pci to 32-bit MMIO for now
libqos: Correct error in PCI hole sizing for spapr
libqos: Isolate knowledge of spapr memory map to qpci_init_spapr()
ppc/xics: Split ICS into ics-base and ics class
ppc/xics: Make the ICSState a list
spapr: fix inheritance chain for default machine options
target-ppc: implement vexts[bh]2w and vexts[bhw]2d
tests/boot-sector: Increase time-out to 90 seconds
tests/boot-sector: Use mkstemp() to create a unique file name
tests/boot-sector: Use minimum length for the Forth boot script
qtest: ask endianness of the target in qtest_init()
tests: minor cleanups in usb-hcd-uhci-test
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/ppc/spapr_pci.c')
| -rw-r--r-- | hw/ppc/spapr_pci.c | 95 |
1 files changed, 65 insertions, 30 deletions
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 4f008654d6..2a1ccf59ea 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -363,7 +363,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, } /* Allocate MSIs */ - irq = xics_spapr_alloc_block(spapr->xics, 0, req_num, false, + irq = xics_spapr_alloc_block(spapr->xics, req_num, false, ret_intr_type == RTAS_TYPE_MSI, &err); if (err) { error_reportf_err(err, "Can't allocate MSIs for device %x: ", @@ -1311,32 +1311,27 @@ 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) || (sphb->mem_win_addr != (hwaddr)-1) + || (sphb->mem64_win_addr != (hwaddr)-1) || (sphb->io_win_addr != (hwaddr)-1)) { error_setg(errp, "Either \"index\" or other parameters must" " be specified for PAPR PHB, not both"); 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, &sphb->mem64_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) { @@ -1360,6 +1355,38 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) return; } + if (sphb->mem64_win_size != 0) { + if (sphb->mem64_win_addr == (hwaddr)-1) { + error_setg(errp, + "64-bit memory window address not specified for PHB"); + return; + } + + if (sphb->mem_win_size > SPAPR_PCI_MEM32_WIN_SIZE) { + error_setg(errp, "32-bit memory window of size 0x%"HWADDR_PRIx + " (max 2 GiB)", sphb->mem_win_size); + return; + } + + if (sphb->mem64_win_pciaddr == (hwaddr)-1) { + /* 64-bit window defaults to identity mapping */ + sphb->mem64_win_pciaddr = sphb->mem64_win_addr; + } + } else if (sphb->mem_win_size > SPAPR_PCI_MEM32_WIN_SIZE) { + /* + * For compatibility with old configuration, if no 64-bit MMIO + * window is specified, but the ordinary (32-bit) memory + * window is specified as > 2GiB, we treat it as a 2GiB 32-bit + * window, with a 64-bit MMIO window following on immediately + * afterwards + */ + sphb->mem64_win_size = sphb->mem_win_size - SPAPR_PCI_MEM32_WIN_SIZE; + sphb->mem64_win_addr = sphb->mem_win_addr + SPAPR_PCI_MEM32_WIN_SIZE; + sphb->mem64_win_pciaddr = + SPAPR_PCI_MEM_WIN_BUS_OFFSET + SPAPR_PCI_MEM32_WIN_SIZE; + sphb->mem_win_size = SPAPR_PCI_MEM32_WIN_SIZE; + } + if (spapr_pci_find_phb(spapr, sphb->buid)) { error_setg(errp, "PCI host bridges must have unique BUIDs"); return; @@ -1373,12 +1400,19 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) sprintf(namebuf, "%s.mmio", sphb->dtbusname); memory_region_init(&sphb->memspace, OBJECT(sphb), namebuf, UINT64_MAX); - sprintf(namebuf, "%s.mmio-alias", sphb->dtbusname); - memory_region_init_alias(&sphb->memwindow, OBJECT(sphb), + sprintf(namebuf, "%s.mmio32-alias", sphb->dtbusname); + memory_region_init_alias(&sphb->mem32window, OBJECT(sphb), namebuf, &sphb->memspace, SPAPR_PCI_MEM_WIN_BUS_OFFSET, sphb->mem_win_size); memory_region_add_subregion(get_system_memory(), sphb->mem_win_addr, - &sphb->memwindow); + &sphb->mem32window); + + sprintf(namebuf, "%s.mmio64-alias", sphb->dtbusname); + memory_region_init_alias(&sphb->mem64window, OBJECT(sphb), + namebuf, &sphb->memspace, + sphb->mem64_win_pciaddr, sphb->mem64_win_size); + memory_region_add_subregion(get_system_memory(), sphb->mem64_win_addr, + &sphb->mem64window); /* Initialize IO regions */ sprintf(namebuf, "%s.io", sphb->dtbusname); @@ -1445,8 +1479,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) uint32_t irq; Error *local_err = NULL; - irq = xics_spapr_alloc_block(spapr->xics, 0, 1, true, false, - &local_err); + irq = xics_spapr_alloc_block(spapr->xics, 1, true, false, &local_err); if (local_err) { error_propagate(errp, local_err); error_prepend(errp, "can't allocate LSIs: "); @@ -1531,7 +1564,12 @@ static Property spapr_phb_properties[] = { DEFINE_PROP_UINT32("liobn64", sPAPRPHBState, dma_liobn[1], -1), DEFINE_PROP_UINT64("mem_win_addr", sPAPRPHBState, mem_win_addr, -1), DEFINE_PROP_UINT64("mem_win_size", sPAPRPHBState, mem_win_size, - SPAPR_PCI_MMIO_WIN_SIZE), + SPAPR_PCI_MEM32_WIN_SIZE), + DEFINE_PROP_UINT64("mem64_win_addr", sPAPRPHBState, mem64_win_addr, -1), + DEFINE_PROP_UINT64("mem64_win_size", sPAPRPHBState, mem64_win_size, + SPAPR_PCI_MEM64_WIN_SIZE), + DEFINE_PROP_UINT64("mem64_win_pciaddr", sPAPRPHBState, mem64_win_pciaddr, + -1), DEFINE_PROP_UINT64("io_win_addr", sPAPRPHBState, io_win_addr, -1), DEFINE_PROP_UINT64("io_win_size", sPAPRPHBState, io_win_size, SPAPR_PCI_IO_WIN_SIZE), @@ -1767,10 +1805,6 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, int bus_off, i, j, ret; char nodename[FDT_NAME_MAX]; uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) }; - const uint64_t mmiosize = memory_region_size(&phb->memwindow); - const uint64_t w32max = (1ULL << 32) - SPAPR_PCI_MEM_WIN_BUS_OFFSET; - const uint64_t w32size = MIN(w32max, mmiosize); - const uint64_t w64size = (mmiosize > w32size) ? (mmiosize - w32size) : 0; struct { uint32_t hi; uint64_t child; @@ -1785,15 +1819,16 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, { cpu_to_be32(b_ss(2)), cpu_to_be64(SPAPR_PCI_MEM_WIN_BUS_OFFSET), cpu_to_be64(phb->mem_win_addr), - cpu_to_be64(w32size), + cpu_to_be64(phb->mem_win_size), }, { - cpu_to_be32(b_ss(3)), cpu_to_be64(1ULL << 32), - cpu_to_be64(phb->mem_win_addr + w32size), - cpu_to_be64(w64size) + cpu_to_be32(b_ss(3)), cpu_to_be64(phb->mem64_win_pciaddr), + cpu_to_be64(phb->mem64_win_addr), + cpu_to_be64(phb->mem64_win_size), }, }; - const unsigned sizeof_ranges = (w64size ? 3 : 2) * sizeof(ranges[0]); + const unsigned sizeof_ranges = + (phb->mem64_win_size ? 3 : 2) * sizeof(ranges[0]); uint64_t bus_reg[] = { cpu_to_be64(phb->buid), 0 }; uint32_t interrupt_map_mask[] = { cpu_to_be32(b_ddddd(-1)|b_fff(0)), 0x0, 0x0, cpu_to_be32(-1)}; |