From 3b7715796401ad1b00f752217fe8f425915e801b Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 1 May 2014 15:24:44 +0100 Subject: [PATCH 01/10] target-arm: Implement XScale cache lockdown operations as NOPs XScale defines some implementation-specific coprocessor registers for doing cache lockdown operations. Since QEMU doesn't model a cache no proper implementation is possible, but NOP out the registers so that guest code like u-boot that tries to use them doesn't crash. Reported-by: Signed-off-by: Peter Maydell --- target-arm/helper.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/target-arm/helper.c b/target-arm/helper.c index 43c1b4f01d..7c083c33a0 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1578,6 +1578,21 @@ static const ARMCPRegInfo xscale_cp_reginfo[] = { .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1, .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_xscaleauxcr), .resetvalue = 0, }, + /* XScale specific cache-lockdown: since we have no cache we NOP these + * and hope the guest does not really rely on cache behaviour. + */ + { .name = "XSCALE_LOCK_ICACHE_LINE", + .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "XSCALE_UNLOCK_ICACHE", + .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "XSCALE_DCACHE_LOCK", + .cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_NOP }, + { .name = "XSCALE_UNLOCK_DCACHE", + .cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NOP }, REGINFO_SENTINEL }; From e3da9921ebc554fad3224a9fdda9a7425ffd9ef7 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 1 May 2014 15:24:44 +0100 Subject: [PATCH 02/10] armv7m_nvic: fix CPUID Base Register cp15.c0_cpuid is never initialized for ARMv7-M; take the value directly from cpu->midr instead. Signed-off-by: Rabin Vincent Message-id: 1398036308-32166-1-git-send-email-rabin@rab.in Signed-off-by: Peter Maydell --- hw/intc/armv7m_nvic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 6066fa6838..f5b0c3be6f 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -173,7 +173,7 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset) return 10000; case 0xd00: /* CPUID Base. */ cpu = ARM_CPU(current_cpu); - return cpu->env.cp15.c0_cpuid; + return cpu->midr; case 0xd04: /* Interrupt Control State. */ /* VECTACTIVE */ val = s->gic.running_irq[0]; From 252ec4057685cd9bf6a13f96528c843754af8fad Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 1 May 2014 15:24:45 +0100 Subject: [PATCH 03/10] target-arm: implement WFE/YIELD as a yield for AArch64 Like was done for AArch32 for WFE, implement both WFE and YIELD as a yield operation. This speeds up multi-core system emulation. Signed-off-by: Rob Herring Message-id: 1397588401-20366-1-git-send-email-robherring2@gmail.com Signed-off-by: Peter Maydell --- target-arm/translate-a64.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index d86b8ffa55..e31e069041 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -1151,6 +1151,8 @@ static void handle_hint(DisasContext *s, uint32_t insn, return; case 1: /* YIELD */ case 2: /* WFE */ + s->is_jmp = DISAS_WFE; + return; case 4: /* SEV */ case 5: /* SEVL */ /* we treat all as NOP at least for now */ @@ -10765,6 +10767,10 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu, case DISAS_EXC: case DISAS_SWI: break; + case DISAS_WFE: + gen_a64_set_pc_im(dc->pc); + gen_helper_wfe(cpu_env); + break; case DISAS_WFI: /* This is a special case because we don't want to just halt the CPU * if trying to debug across a WFI. From fed3ffb9f157f33bc9b2b1c3ef68e710ee6b7b4b Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Thu, 1 May 2014 15:24:45 +0100 Subject: [PATCH 04/10] target-arm: Make vbar_write 64bit friendly on 32bit hosts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Edgar E. Iglesias Reviewed-by: Alex Bennée Message-id: 1398926097-28097-2-git-send-email-edgar.iglesias@gmail.com Signed-off-by: Peter Maydell --- target-arm/helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 7c083c33a0..7823e8c3dd 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -657,7 +657,7 @@ static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri, * contexts. (ARMv8 would permit us to do no masking at all, but ARMv7 * requires the bottom five bits to be RAZ/WI because they're UNK/SBZP.) */ - env->cp15.c12_vbar = value & ~0x1Ful; + env->cp15.c12_vbar = value & ~0x1FULL; } static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri) From 1b505f93bcf605e7c4144fef83bd039b0d4f2576 Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Thu, 1 May 2014 15:24:45 +0100 Subject: [PATCH 05/10] target-arm: A64: Handle blr lr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For linked branches, updates to the link register happen conceptually after the read of the branch target register. Signed-off-by: Edgar E. Iglesias Reviewed-by: Alex Bennée Cc: qemu-stable@nongnu.org Message-id: 1398926097-28097-3-git-send-email-edgar.iglesias@gmail.com Signed-off-by: Peter Maydell --- target-arm/translate-a64.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index e31e069041..b62db4d566 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -1509,8 +1509,10 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn) switch (opc) { case 0: /* BR */ case 2: /* RET */ + tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn)); break; case 1: /* BLR */ + tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn)); tcg_gen_movi_i64(cpu_reg(s, 30), s->pc); break; case 4: /* ERET */ @@ -1529,7 +1531,6 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn) return; } - tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn)); s->is_jmp = DISAS_JUMP; } From 6ab9f49934664f33ad4b449333fc8036c01c4eeb Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Thu, 1 May 2014 15:24:46 +0100 Subject: [PATCH 06/10] target-arm: A64: Fix a typo when declaring TLBI ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Harmless typo as opc1 defaults to zero and opc2 gets re-declared to its correct value. Signed-off-by: Edgar E. Iglesias Reviewed-by: Alex Bennée Message-id: 1398926097-28097-4-git-send-email-edgar.iglesias@gmail.com Signed-off-by: Peter Maydell --- target-arm/helper.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 7823e8c3dd..3be917c22e 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1908,51 +1908,51 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { .access = PL1_W, .type = ARM_CP_NOP }, /* TLBI operations */ { .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 3, .opc2 = 0, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0, .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = tlbiall_write }, { .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 3, .opc2 = 1, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1, .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = tlbi_aa64_va_write }, { .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 3, .opc2 = 2, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2, .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = tlbi_aa64_asid_write }, { .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 3, .opc2 = 3, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3, .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = tlbi_aa64_vaa_write }, { .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 3, .opc2 = 5, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5, .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = tlbi_aa64_va_write }, { .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 3, .opc2 = 7, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7, .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = tlbi_aa64_vaa_write }, { .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 7, .opc2 = 0, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0, .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = tlbiall_write }, { .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 7, .opc2 = 1, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1, .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = tlbi_aa64_va_write }, { .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 7, .opc2 = 2, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2, .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = tlbi_aa64_asid_write }, { .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 7, .opc2 = 3, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = tlbi_aa64_vaa_write }, { .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 7, .opc2 = 5, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5, .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = tlbi_aa64_va_write }, { .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 7, .opc2 = 7, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = tlbi_aa64_vaa_write }, #ifndef CONFIG_USER_ONLY From 37f0806ed9ebaa3b7a7840048818b8916639f2db Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Thu, 1 May 2014 15:24:46 +0100 Subject: [PATCH 07/10] target-arm: Correct a comment refering to EL0 Signed-off-by: Edgar E. Iglesias Message-id: 1398926097-28097-5-git-send-email-edgar.iglesias@gmail.com Signed-off-by: Peter Maydell --- target-arm/op_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index 57e7d9c480..fb90676bd5 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -418,7 +418,7 @@ void HELPER(exception_return)(CPUARMState *env) goto illegal_return; } if (new_el == 0 && (spsr & PSTATE_SP)) { - /* Return to EL1 with M[0] bit set */ + /* Return to EL0 with M[0] bit set */ goto illegal_return; } env->aarch64 = 1; From 642047438446246d98d96f7528a5dc9763473112 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 1 May 2014 15:24:46 +0100 Subject: [PATCH 08/10] hw/arm/virt: Create the GIC ourselves rather than (ab)using a15mpcore_priv Rather than having the virt machine model create an a15mpcore_priv device regardless of the actual CPU type in order to instantiate the GIC, move to having the machine model create the GIC directly. This corresponds to a system which uses a standalone GIC (eg the GIC-400) rather than the one built in to the CPU core. The primary motivation for this is to support the Cortex-A57, which for a KVM configuration will use a GICv2, which is not built into the CPU. Signed-off-by: Peter Maydell Message-id: 1398362083-17737-2-git-send-email-peter.maydell@linaro.org --- hw/arm/virt.c | 82 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 29 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 2bbc9313d2..ecff256dac 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -75,8 +75,6 @@ typedef struct MemMapEntry { typedef struct VirtBoardInfo { struct arm_boot_info bootinfo; const char *cpu_model; - const char *qdevname; - const char *gic_compatible; const MemMapEntry *memmap; const int *irqmap; int smp_cpus; @@ -117,16 +115,11 @@ static const int a15irqmap[] = { static VirtBoardInfo machines[] = { { .cpu_model = "cortex-a15", - .qdevname = "a15mpcore_priv", - .gic_compatible = "arm,cortex-a15-gic", .memmap = a15memmap, .irqmap = a15irqmap, }, { .cpu_model = "host", - /* We use the A15 private peripheral model to get a V2 GIC */ - .qdevname = "a15mpcore_priv", - .gic_compatible = "arm,cortex-a15-gic", .memmap = a15memmap, .irqmap = a15irqmap, }, @@ -251,8 +244,9 @@ static void fdt_add_gic_node(const VirtBoardInfo *vbi) qemu_fdt_setprop_cell(vbi->fdt, "/", "interrupt-parent", gic_phandle); qemu_fdt_add_subnode(vbi->fdt, "/intc"); + /* 'cortex-a15-gic' means 'GIC v2' */ qemu_fdt_setprop_string(vbi->fdt, "/intc", "compatible", - vbi->gic_compatible); + "arm,cortex-a15-gic"); qemu_fdt_setprop_cell(vbi->fdt, "/intc", "#interrupt-cells", 3); qemu_fdt_setprop(vbi->fdt, "/intc", "interrupt-controller", NULL, 0); qemu_fdt_setprop_sized_cells(vbi->fdt, "/intc", "reg", @@ -263,6 +257,56 @@ static void fdt_add_gic_node(const VirtBoardInfo *vbi) qemu_fdt_setprop_cell(vbi->fdt, "/intc", "phandle", gic_phandle); } +static void create_gic(const VirtBoardInfo *vbi, qemu_irq *pic) +{ + /* We create a standalone GIC v2 */ + DeviceState *gicdev; + SysBusDevice *gicbusdev; + const char *gictype = "arm_gic"; + int i; + + if (kvm_irqchip_in_kernel()) { + gictype = "kvm-arm-gic"; + } + + gicdev = qdev_create(NULL, gictype); + qdev_prop_set_uint32(gicdev, "revision", 2); + qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus); + /* Note that the num-irq property counts both internal and external + * interrupts; there are always 32 of the former (mandated by GIC spec). + */ + qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32); + qdev_init_nofail(gicdev); + gicbusdev = SYS_BUS_DEVICE(gicdev); + sysbus_mmio_map(gicbusdev, 0, vbi->memmap[VIRT_GIC_DIST].base); + sysbus_mmio_map(gicbusdev, 1, vbi->memmap[VIRT_GIC_CPU].base); + + /* Wire the outputs from each CPU's generic timer to the + * appropriate GIC PPI inputs, and the GIC's IRQ output to + * the CPU's IRQ input. + */ + for (i = 0; i < smp_cpus; i++) { + DeviceState *cpudev = DEVICE(qemu_get_cpu(i)); + int ppibase = NUM_IRQS + i * 32; + /* physical timer; we wire it up to the non-secure timer's ID, + * since a real A15 always has TrustZone but QEMU doesn't. + */ + qdev_connect_gpio_out(cpudev, 0, + qdev_get_gpio_in(gicdev, ppibase + 30)); + /* virtual timer */ + qdev_connect_gpio_out(cpudev, 1, + qdev_get_gpio_in(gicdev, ppibase + 27)); + + sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ)); + } + + for (i = 0; i < NUM_IRQS; i++) { + pic[i] = qdev_get_gpio_in(gicdev, i); + } + + fdt_add_gic_node(vbi); +} + static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic) { char *nodename; @@ -340,8 +384,6 @@ static void machvirt_init(QEMUMachineInitArgs *args) MemoryRegion *sysmem = get_system_memory(); int n; MemoryRegion *ram = g_new(MemoryRegion, 1); - DeviceState *dev; - SysBusDevice *busdev; const char *cpu_model = args->cpu_model; VirtBoardInfo *vbi; @@ -404,25 +446,7 @@ static void machvirt_init(QEMUMachineInitArgs *args) vmstate_register_ram_global(ram); memory_region_add_subregion(sysmem, vbi->memmap[VIRT_MEM].base, ram); - dev = qdev_create(NULL, vbi->qdevname); - qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); - /* Note that the num-irq property counts both internal and external - * interrupts; there are always 32 of the former (mandated by GIC spec). - */ - qdev_prop_set_uint32(dev, "num-irq", NUM_IRQS + 32); - qdev_init_nofail(dev); - busdev = SYS_BUS_DEVICE(dev); - sysbus_mmio_map(busdev, 0, vbi->memmap[VIRT_CPUPERIPHS].base); - fdt_add_gic_node(vbi); - for (n = 0; n < smp_cpus; n++) { - DeviceState *cpudev = DEVICE(qemu_get_cpu(n)); - - sysbus_connect_irq(busdev, n, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ)); - } - - for (n = 0; n < NUM_IRQS; n++) { - pic[n] = qdev_get_gpio_in(dev, n); - } + create_gic(vbi, pic); create_uart(vbi, pic); From 3078e848faed0d6bf03d1ae789975abab9cb7778 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 24 Apr 2014 18:54:42 +0100 Subject: [PATCH 09/10] hw/arm/virt: Put GIC register banks on 64K boundaries For an AArch64 CPU which supports 64K pages, having the GIC register banks at 4K offsets is potentially awkward. Move them out to being at 64K offsets. (This is harmless for AArch32 CPUs and for AArch64 CPUs with 4K pages, so it is simpler to use the same offsets everywhere than to try to use 64K offsets only for AArch64 host CPUs.) Signed-off-by: Peter Maydell Message-id: 1398362083-17737-3-git-send-email-peter.maydell@linaro.org --- hw/arm/virt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index ecff256dac..9c4d337b1b 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -96,10 +96,10 @@ typedef struct VirtBoardInfo { static const MemMapEntry a15memmap[] = { /* Space up to 0x8000000 is reserved for a boot ROM */ [VIRT_FLASH] = { 0, 0x8000000 }, - [VIRT_CPUPERIPHS] = { 0x8000000, 0x8000 }, + [VIRT_CPUPERIPHS] = { 0x8000000, 0x20000 }, /* GIC distributor and CPU interfaces sit inside the CPU peripheral space */ - [VIRT_GIC_DIST] = { 0x8001000, 0x1000 }, - [VIRT_GIC_CPU] = { 0x8002000, 0x1000 }, + [VIRT_GIC_DIST] = { 0x8000000, 0x10000 }, + [VIRT_GIC_CPU] = { 0x8010000, 0x10000 }, [VIRT_UART] = { 0x9000000, 0x1000 }, [VIRT_MMIO] = { 0xa000000, 0x200 }, /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ From f42c5c8ec8aa0e15583487ffee62964830751623 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 24 Apr 2014 18:54:43 +0100 Subject: [PATCH 10/10] hw/arm/virt: Add support for Cortex-A57 Support the Cortex-A57 in the virt machine model. Signed-off-by: Peter Maydell Message-id: 1398362083-17737-4-git-send-email-peter.maydell@linaro.org --- hw/arm/virt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 9c4d337b1b..ea4f02d32e 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -118,6 +118,11 @@ static VirtBoardInfo machines[] = { .memmap = a15memmap, .irqmap = a15irqmap, }, + { + .cpu_model = "cortex-a57", + .memmap = a15memmap, + .irqmap = a15irqmap, + }, { .cpu_model = "host", .memmap = a15memmap,