qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v4 3/4] arm: Add PCIe host bridge in virt machin


From: Peter Maydell
Subject: Re: [Qemu-devel] [PATCH v4 3/4] arm: Add PCIe host bridge in virt machine
Date: Thu, 5 Feb 2015 15:49:22 +0000

On 5 February 2015 at 14:55, Alexander Graf <address@hidden> wrote:
> Now that we have a working "generic" PCIe host bridge driver, we can plug
> it into ARM's virt machine to always have PCIe available to normal ARM VMs.
>
> I've successfully managed to expose a Bochs VGA device, XHCI and an e1000
> into an AArch64 VM with this and they all lived happily ever after.
>
> Signed-off-by: Alexander Graf <address@hidden>
> Tested-by: Claudio Fontana <address@hidden>

> +static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
> +                        uint32_t gic_phandle)
> +{
> +    hwaddr base = vbi->memmap[VIRT_PCIE].base;
> +    hwaddr size = vbi->memmap[VIRT_PCIE].size;
> +    hwaddr end = base + size;
> +    hwaddr size_mmio;
> +    hwaddr size_ioport = 64 * 1024;
> +    hwaddr size_ecam = PCIE_MMCFG_SIZE_MIN * 16; /* 16 PCIe buses */
> +    hwaddr base_mmio = base;
> +    hwaddr base_ioport;
> +    hwaddr base_ecam;
> +    int irq = vbi->irqmap[VIRT_PCIE];
> +    MemoryRegion *mmio_alias;
> +    MemoryRegion *mmio_reg;
> +    MemoryRegion *ecam_alias;
> +    MemoryRegion *ecam_reg;
> +    DeviceState *dev;
> +    char *nodename;
> +    int i;
> +
> +    base_ecam = QEMU_ALIGN_DOWN(end - size_ecam, size_ecam);
> +    size_ecam = end - base_ecam;

Why do we do this? If we've had to align down a 256MB ECAM
that doesn't mean the space gets bigger -- it's still 256MB.

> +    base_ioport = QEMU_ALIGN_DOWN(end - size_ecam - size_ioport, 
> size_ioport);

Shouldn't the first argument here be 'base_ecam - size_ioport' ?
Otherwise if we did have to align down the ECAM window we
won't have started the ioport far enough down...

> +    size_ioport = base_ecam - base_ioport;

Again, I don't think the ioport size should get bigger.

> +    size_mmio = base_ioport - base;
> +
> +    dev = qdev_create(NULL, TYPE_GPEX_HOST);
> +    qdev_init_nofail(dev);
> +
> +    /* Map only the first size_ecam bytes of ECAM space */
> +    ecam_alias = g_new0(MemoryRegion, 1);
> +    ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
> +    memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam",
> +                             ecam_reg, 0, size_ecam);
> +    memory_region_add_subregion(get_system_memory(), base_ecam, ecam_alias);
> +
> +    /* Map the MMIO window at the same spot in bus and cpu layouts */

I still think this comment is a little cryptic. I suggest:

    /* Map the MMIO window into system address space so as to expose
     * the section of PCI MMIO space which starts at the same base address
     * (ie 1:1 mapping for that part of PCI MMIO space visible through
     * the window).
     */

> +    mmio_alias = g_new0(MemoryRegion, 1);
> +    mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
> +    memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio",
> +                             mmio_reg, base_mmio, size_mmio);
> +    memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias);
> +
> +    /* Map IO port space */
> +    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_ioport);
> +
> +    for (i = 0; i < GPEX_NUM_IRQS; i++) {
> +        sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
> +    }
> +
> +    nodename = g_strdup_printf("/address@hidden" PRIx64, base);
> +    qemu_fdt_add_subnode(vbi->fdt, nodename);
> +    qemu_fdt_setprop_string(vbi->fdt, nodename,
> +                            "compatible", "pci-host-ecam-generic");
> +    qemu_fdt_setprop_string(vbi->fdt, nodename, "device_type", "pci");
> +    qemu_fdt_setprop_cell(vbi->fdt, nodename, "#address-cells", 3);
> +    qemu_fdt_setprop_cell(vbi->fdt, nodename, "#size-cells", 2);
> +    qemu_fdt_setprop_cells(vbi->fdt, nodename, "bus-range", 0, 1);

Is this right? It doesn't seem to match the expanded eCAM size
we've used above. (Maybe we should calculate this based on the
size_ecam or something?)

> +
> +    qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
> +                                 2, base_ecam, 2, size_ecam);
> +    qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "ranges",
> +                                 1, FDT_PCI_RANGE_IOPORT, 2, 0,
> +                                 2, base_ioport, 2, size_ioport,
> +

I guess this blank line is deliberate to separate out the io from
the mmio part of this definition...

> +                                 1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
> +                                 2, base_mmio, 2, size_mmio);
> +
> +    qemu_fdt_setprop_cell(vbi->fdt, nodename, "#interrupt-cells", 1);
> +    create_pcie_irq_map(vbi, gic_phandle, irq, nodename);
> +
> +    g_free(nodename);
> +}

Otherwise looks OK.

thanks
-- PMM



reply via email to

[Prev in Thread] Current Thread [Next in Thread]