Message ID | 1414763612-4939-7-git-send-email-eric.auger@linaro.org |
---|---|
State | New |
Headers | show |
On 31.10.14 14:53, Eric Auger wrote: > Allows sysbus devices to be instantiated from command line by > using -device option. Machvirt creates a platform bus at init. > The dynamic sysbus devices are attached to a platform bus device. > > The platform bus device registers a machine init done notifier > whose role will be to bind the dynamic sysbus devices. Indeed > dynamic sysbus devices are created after machine init. > > machvirt also registers a notifier that will start the VFIO > dynamic device IRQ handling. > > Signed-off-by: Alexander Graf <agraf@suse.de> > Signed-off-by: Eric Auger <eric.auger@linaro.org> > > --- > v3 -> v4: > - use platform bus object, instantiated in create_platform_bus > - device tree generation for platform bus and children dynamic > sysbus devices is no more handled at reset but in a > machine_init_done_notifier (due to the change in implementaion > of ARM load dtb using rom_add_blob_fixed). > - device tree enhancement now takes into account the case of > user provided dtb. Before the user dtb was overwritten which > was wrong. However in case the dtb is provided by the user, > dynamic sysbus nodes are not added there. > - renaming of MACHVIRT_PLATFORM defines > - MACHVIRT_PLATFORM_PAGE_SHIFT and SIZE_PAGES not needed anymore, > hence removed. > - DynSysbusParams struct renamed into ARMPlatformBusSystemParams > and above params removed. > - separation of dt creation and QEMU binding is not mandated anymore > since the device tree is not created from scratch anymore. Instead > the modify_dtb function is used. > - create_platform_bus registers another machine init done notifier > to start VFIO IRQ handling. This latter executes after the > dynamic sysbus device binding. > > v2 -> v3: > - renaming of arm_platform_bus_create_devtree and arm_load_dtb > - add copyright in hw/arm/dyn_sysbus_devtree.c > > v1 -> v2: > - remove useless vfio-platform.h include file > - s/MACHVIRT_PLATFORM_HOLE/MACHVIRT_PLATFORM_SIZE > - use dyn_sysbus_binding and dyn_sysbus_devtree > - dynamic sysbus platform buse size shrinked to 4MB and > moved between RTC and MMIO > > v1: > > Inspired from what Alex Graf did in ppc e500 > https://lists.gnu.org/archive/html/qemu-ppc/2014-07/msg00012.html > > Conflicts: > hw/arm/sysbus-fdt.c > --- > hw/arm/virt.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 59 insertions(+) > > diff --git a/hw/arm/virt.c b/hw/arm/virt.c > index 78f618d..3a09d58 100644 > --- a/hw/arm/virt.c > +++ b/hw/arm/virt.c > @@ -42,6 +42,8 @@ > #include "exec/address-spaces.h" > #include "qemu/bitops.h" > #include "qemu/error-report.h" > +#include "hw/arm/sysbus-fdt.h" > +#include "hw/platform-bus.h" > > #define NUM_VIRTIO_TRANSPORTS 32 > > @@ -59,6 +61,11 @@ > #define GIC_FDT_IRQ_PPI_CPU_START 8 > #define GIC_FDT_IRQ_PPI_CPU_WIDTH 8 > > +#define PLATFORM_BUS_BASE 0x9400000 > +#define PLATFORM_BUS_SIZE (4ULL * 1024 * 1024) > +#define PLATFORM_BUS_FIRST_IRQ 48 > +#define PLATFORM_BUS_NUM_IRQS 20 > + > enum { > VIRT_FLASH, > VIRT_MEM, > @@ -68,6 +75,7 @@ enum { > VIRT_UART, > VIRT_MMIO, > VIRT_RTC, > + VIRT_PLATFORM_BUS, > }; > > typedef struct MemMapEntry { > @@ -107,6 +115,7 @@ static const MemMapEntry a15memmap[] = { > [VIRT_GIC_CPU] = { 0x08010000, 0x00010000 }, > [VIRT_UART] = { 0x09000000, 0x00001000 }, > [VIRT_RTC] = { 0x09010000, 0x00001000 }, > + [VIRT_PLATFORM_BUS] = {PLATFORM_BUS_BASE , PLATFORM_BUS_SIZE}, > [VIRT_MMIO] = { 0x0a000000, 0x00000200 }, > /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ > /* 0x10000000 .. 0x40000000 reserved for PCI */ > @@ -117,6 +126,14 @@ static const int a15irqmap[] = { > [VIRT_UART] = 1, > [VIRT_RTC] = 2, > [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */ > + [VIRT_PLATFORM_BUS] = PLATFORM_BUS_FIRST_IRQ, > +}; > + > +ARMPlatformBusSystemParams platform_bus_params = { static const? Alex
diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 78f618d..3a09d58 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -42,6 +42,8 @@ #include "exec/address-spaces.h" #include "qemu/bitops.h" #include "qemu/error-report.h" +#include "hw/arm/sysbus-fdt.h" +#include "hw/platform-bus.h" #define NUM_VIRTIO_TRANSPORTS 32 @@ -59,6 +61,11 @@ #define GIC_FDT_IRQ_PPI_CPU_START 8 #define GIC_FDT_IRQ_PPI_CPU_WIDTH 8 +#define PLATFORM_BUS_BASE 0x9400000 +#define PLATFORM_BUS_SIZE (4ULL * 1024 * 1024) +#define PLATFORM_BUS_FIRST_IRQ 48 +#define PLATFORM_BUS_NUM_IRQS 20 + enum { VIRT_FLASH, VIRT_MEM, @@ -68,6 +75,7 @@ enum { VIRT_UART, VIRT_MMIO, VIRT_RTC, + VIRT_PLATFORM_BUS, }; typedef struct MemMapEntry { @@ -107,6 +115,7 @@ static const MemMapEntry a15memmap[] = { [VIRT_GIC_CPU] = { 0x08010000, 0x00010000 }, [VIRT_UART] = { 0x09000000, 0x00001000 }, [VIRT_RTC] = { 0x09010000, 0x00001000 }, + [VIRT_PLATFORM_BUS] = {PLATFORM_BUS_BASE , PLATFORM_BUS_SIZE}, [VIRT_MMIO] = { 0x0a000000, 0x00000200 }, /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ /* 0x10000000 .. 0x40000000 reserved for PCI */ @@ -117,6 +126,14 @@ static const int a15irqmap[] = { [VIRT_UART] = 1, [VIRT_RTC] = 2, [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */ + [VIRT_PLATFORM_BUS] = PLATFORM_BUS_FIRST_IRQ, +}; + +ARMPlatformBusSystemParams platform_bus_params = { + .platform_bus_base = PLATFORM_BUS_BASE, + .platform_bus_size = PLATFORM_BUS_SIZE, + .platform_bus_first_irq = PLATFORM_BUS_FIRST_IRQ, + .platform_bus_num_irqs = PLATFORM_BUS_NUM_IRQS, }; static VirtBoardInfo machines[] = { @@ -519,6 +536,45 @@ static void create_flash(const VirtBoardInfo *vbi) g_free(nodename); } +static void create_platform_bus(VirtBoardInfo *vbi, qemu_irq *pic, + ARMPlatformBusSystemParams *system_params) +{ + DeviceState *dev; + SysBusDevice *s; + int i; + ARMPlatformBusFdtParams *fdt_params = g_new(ARMPlatformBusFdtParams, 1); + MemoryRegion *sysmem = get_system_memory(); + + /* + * register the notifier that will update the device tree with + * the platform bus and device tree nodes. Must be done before + * the instantiation of the platform bus device that registers + * the notifier that instantiates the dynamic sysbus devices + */ + fdt_params->system_params = system_params; + fdt_params->binfo = &vbi->bootinfo; + fdt_params->intc = "/intc"; + arm_register_platform_bus_fdt_creator(fdt_params); + + dev = qdev_create(NULL, TYPE_PLATFORM_BUS_DEVICE); + dev->id = TYPE_PLATFORM_BUS_DEVICE; + qdev_prop_set_uint32(dev, "num_irqs", + system_params->platform_bus_num_irqs); + qdev_prop_set_uint32(dev, "mmio_size", + system_params->platform_bus_size); + qdev_init_nofail(dev); + s = SYS_BUS_DEVICE(dev); + + for (i = 0; i < system_params->platform_bus_num_irqs; i++) { + int irqn = system_params->platform_bus_first_irq + i; + sysbus_connect_irq(s, i, pic[irqn]); + } + + memory_region_add_subregion(sysmem, + system_params->platform_bus_base, + sysbus_mmio_get_region(s, 0)); +} + static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size) { const VirtBoardInfo *board = (const VirtBoardInfo *)binfo; @@ -604,6 +660,8 @@ static void machvirt_init(MachineState *machine) */ create_virtio_devices(vbi, pic); + create_platform_bus(vbi, pic, &platform_bus_params); + vbi->bootinfo.ram_size = machine->ram_size; vbi->bootinfo.kernel_filename = machine->kernel_filename; vbi->bootinfo.kernel_cmdline = machine->kernel_cmdline; @@ -620,6 +678,7 @@ static QEMUMachine machvirt_a15_machine = { .desc = "ARM Virtual Machine", .init = machvirt_init, .max_cpus = 8, + .has_dynamic_sysbus = true, }; static void machvirt_machine_init(void)