diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2016-06-14 16:04:25 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2016-06-14 16:04:25 +0100 |
| commit | 1be08a0946b1a189ac72822182c37367e8cd3d87 (patch) | |
| tree | 2c41b2e3abf67957ea1b75e7d5330ab2b1dff4fe /hw/arm/virt.c | |
| parent | 7474f1be701f136b224af5e1abe55e97dc3f29a5 (diff) | |
| parent | fe8fcf3d642b4de1369841bf6acac13e0ec8770d (diff) | |
| download | focaccia-qemu-1be08a0946b1a189ac72822182c37367e8cd3d87.tar.gz focaccia-qemu-1be08a0946b1a189ac72822182c37367e8cd3d87.zip | |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20160614-2' into staging
target-arm queue: * add PMU support for virt machine under KVM * fix reset and migration of TTBCR(S) * add virt-2.7 machine type * QOMify various ARM devices * implement xilinx DisplayPort device * don't permit ARMv8-only Neon insns to work on ARMv7 # gpg: Signature made Tue 14 Jun 2016 16:01:45 BST # gpg: using RSA key 0x3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20160614-2: (30 commits) target-arm: Don't permit ARMv8-only Neon insns on ARMv7 arm: xlnx-zynqmp: Add xlnx-dp and xlnx-dpdma introduce xlnx-dp introduce xlnx-dpdma hw/i2c-ddc.c: Implement DDC I2C slave introduce dpcd module introduce aux-bus i2c: Factor our send() and recv() common logic i2c: implement broadcast write i2cbus: remove unused dev field hw/sd: QOM'ify pl181.c hw/dma: QOM'ify pxa2xx_dma.c hw/misc: QOM'ify mst_fpga.c hw/misc: QOM'ify exynos4210_pmu.c hw/misc: QOM'ify arm_l2x0.c hw/gpio: QOM'ify zaurus.c hw/gpio: QOM'ify pl061.c hw/gpio: QOM'ify omap_gpio.c hw/i2c: QOM'ify versatile_i2c.c hw/i2c: QOM'ify omap_i2c.c ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/arm/virt.c')
| -rw-r--r-- | hw/arm/virt.c | 99 |
1 files changed, 83 insertions, 16 deletions
diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 73113cfc4d..c5c125e920 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -42,6 +42,7 @@ #include "sysemu/sysemu.h" #include "sysemu/kvm.h" #include "hw/boards.h" +#include "hw/compat.h" #include "hw/loader.h" #include "exec/address-spaces.h" #include "qemu/bitops.h" @@ -98,6 +99,36 @@ typedef struct { #define VIRT_MACHINE_CLASS(klass) \ OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_VIRT_MACHINE) + +#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ + static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ + void *data) \ + { \ + MachineClass *mc = MACHINE_CLASS(oc); \ + virt_machine_##major##_##minor##_options(mc); \ + mc->desc = "QEMU " # major "." # minor " ARM Virtual Machine"; \ + if (latest) { \ + mc->alias = "virt"; \ + } \ + } \ + static const TypeInfo machvirt_##major##_##minor##_info = { \ + .name = MACHINE_TYPE_NAME("virt-" # major "." # minor), \ + .parent = TYPE_VIRT_MACHINE, \ + .instance_init = virt_##major##_##minor##_instance_init, \ + .class_init = virt_##major##_##minor##_class_init, \ + }; \ + static void machvirt_machine_##major##_##minor##_init(void) \ + { \ + type_register_static(&machvirt_##major##_##minor##_info); \ + } \ + type_init(machvirt_machine_##major##_##minor##_init); + +#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \ + DEFINE_VIRT_MACHINE_LATEST(major, minor, true) +#define DEFINE_VIRT_MACHINE(major, minor) \ + DEFINE_VIRT_MACHINE_LATEST(major, minor, false) + + /* RAM limit in GB. Since VIRT_MEM starts at the 1GB mark, this means * RAM can go up to the 256GB mark, leaving 256GB of the physical * address space unallocated and free for future use between 256G and 512G. @@ -436,6 +467,37 @@ static void fdt_add_gic_node(VirtBoardInfo *vbi, int type) qemu_fdt_setprop_cell(vbi->fdt, "/intc", "phandle", vbi->gic_phandle); } +static void fdt_add_pmu_nodes(const VirtBoardInfo *vbi, int gictype) +{ + CPUState *cpu; + ARMCPU *armcpu; + uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI; + + CPU_FOREACH(cpu) { + armcpu = ARM_CPU(cpu); + if (!armcpu->has_pmu || + !kvm_arm_pmu_create(cpu, PPI(VIRTUAL_PMU_IRQ))) { + return; + } + } + + if (gictype == 2) { + irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START, + GIC_FDT_IRQ_PPI_CPU_WIDTH, + (1 << vbi->smp_cpus) - 1); + } + + armcpu = ARM_CPU(qemu_get_cpu(0)); + qemu_fdt_add_subnode(vbi->fdt, "/pmu"); + if (arm_feature(&armcpu->env, ARM_FEATURE_V8)) { + const char compat[] = "arm,armv8-pmuv3"; + qemu_fdt_setprop(vbi->fdt, "/pmu", "compatible", + compat, sizeof(compat)); + qemu_fdt_setprop_cells(vbi->fdt, "/pmu", "interrupts", + GIC_FDT_IRQ_TYPE_PPI, VIRTUAL_PMU_IRQ, irqflags); + } +} + static void create_v2m(VirtBoardInfo *vbi, qemu_irq *pic) { int i; @@ -1259,6 +1321,8 @@ static void machvirt_init(MachineState *machine) create_gic(vbi, pic, gic_version, vms->secure); + fdt_add_pmu_nodes(vbi, gic_version); + create_uart(vbi, pic, VIRT_UART, sysmem, serial_hds[0]); if (vms->secure) { @@ -1387,7 +1451,13 @@ static const TypeInfo virt_machine_info = { .class_init = virt_machine_class_init, }; -static void virt_2_6_instance_init(Object *obj) +static void machvirt_machine_init(void) +{ + type_register_static(&virt_machine_info); +} +type_init(machvirt_machine_init); + +static void virt_2_7_instance_init(Object *obj) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -1420,25 +1490,22 @@ static void virt_2_6_instance_init(Object *obj) "Valid values are 2, 3 and host", NULL); } -static void virt_2_6_class_init(ObjectClass *oc, void *data) +static void virt_machine_2_7_options(MachineClass *mc) { - MachineClass *mc = MACHINE_CLASS(oc); - - mc->desc = "QEMU 2.6 ARM Virtual Machine"; - mc->alias = "virt"; } +DEFINE_VIRT_MACHINE_AS_LATEST(2, 7) -static const TypeInfo machvirt_info = { - .name = MACHINE_TYPE_NAME("virt-2.6"), - .parent = TYPE_VIRT_MACHINE, - .instance_init = virt_2_6_instance_init, - .class_init = virt_2_6_class_init, -}; +#define VIRT_COMPAT_2_6 \ + HW_COMPAT_2_6 -static void machvirt_machine_init(void) +static void virt_2_6_instance_init(Object *obj) { - type_register_static(&virt_machine_info); - type_register_static(&machvirt_info); + virt_2_7_instance_init(obj); } -type_init(machvirt_machine_init); +static void virt_machine_2_6_options(MachineClass *mc) +{ + virt_machine_2_7_options(mc); + SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_6); +} +DEFINE_VIRT_MACHINE(2, 6) |