From 450aaae8638e4c75ac6547ce6e09d63281a5a925 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Tue, 27 Dec 2016 14:59:22 +0000 Subject: [PATCH 01/25] cadence_uart: Check baud rate generator and divider values on migration The Cadence UART device emulator calculates speed by dividing the baud rate by a 'baud rate generator' & 'baud rate divider' value. The device specification defines these register values to be non-zero and within certain limits. Checks were recently added when writing to these registers but not when restoring from migration. This patch adds checks when restoring from migration to avoid divide by zero errors. Reported-by: Huawei PSIRT Signed-off-by: Alistair Francis Message-id: 04ae30ed8ee1758cd2d2af880da4d28f74c67738.1481132150.git.alistair.francis@xilinx.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/char/cadence_uart.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index 0215d6518d..dba1c53586 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -502,6 +502,13 @@ static int cadence_uart_post_load(void *opaque, int version_id) { CadenceUARTState *s = opaque; + /* Ensure these two aren't invalid numbers */ + if (s->r[R_BRGR] < 1 || s->r[R_BRGR] & ~0xFFFF || + s->r[R_BDIV] <= 3 || s->r[R_BDIV] & ~0xFF) { + /* Value is invalid, abort */ + return 1; + } + uart_parameters_setup(s); uart_update_status(s); return 0; From 2494c9f6405a1979319f12d1bb4e9a6eb28a529d Mon Sep 17 00:00:00 2001 From: Andrew Gacek Date: Tue, 27 Dec 2016 14:59:23 +0000 Subject: [PATCH 02/25] cadence_uart: Check if receiver timeout counter is disabled When register Rcvr_timeout_reg0 (R_RTOR in cadence_uart.c) is set to 0, the receiver timeout counter should be disabled. See page 1801 of "Zynq-7000 AP SoC Technical Reference Manual". This commit adds a such a check before setting the receive timeout interrupt. Signed-off-by: Andrew Gacek Reviewed-by: Edgar E. Iglesias Signed-off-by: Peter Maydell --- hw/char/cadence_uart.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index dba1c53586..4dcee571c0 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -138,9 +138,10 @@ static void fifo_trigger_update(void *opaque) { CadenceUARTState *s = opaque; - s->r[R_CISR] |= UART_INTR_TIMEOUT; - - uart_update_status(s); + if (s->r[R_RTOR]) { + s->r[R_CISR] |= UART_INTR_TIMEOUT; + uart_update_status(s); + } } static void uart_rx_reset(CadenceUARTState *s) From 0f1944735b6bac810b067e8a7a5154744536fd59 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 27 Dec 2016 14:59:23 +0000 Subject: [PATCH 03/25] Correct value of ARM Cortex-A8 MVFR1 register. The value of the MVFR1 (Media and VFP Feature Register 1) register for the Cortex-A8 appears to be incorrect (according to the TRM, DDI0344K), with the "full denormal arithmetic" and "propagation of NaN" fields holding both 0 instead of both 1. I had a go tracing the history of the use of this value, and it seems it's always just been wrong in QEMU: maybe it was derived from early documentation, or guessed based on the use of a "VFP Lite" implementation in the Cortex-A8. Depending on the startup/early-boot code in use, this can manifest as failure to perform denormal arithmetic properly: in our case, selecting a Cortex-A8 CPU when using QEMU as an instruction-set simulator for bare-metal GCC testing caused tests using denormal arithmetic to fail. Problems might be masked (or not occur) when using a full OS kernel with suitable trap handlers (I'm not sure). Signed-off-by: Julian Brown Message-id: 1481130858-31767-1-git-send-email-julian@codesourcery.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- target/arm/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 99f0dbebb9..98e2c68bc4 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1055,7 +1055,7 @@ static void cortex_a8_initfn(Object *obj) cpu->midr = 0x410fc080; cpu->reset_fpsid = 0x410330c0; cpu->mvfr0 = 0x11110222; - cpu->mvfr1 = 0x00011100; + cpu->mvfr1 = 0x00011111; cpu->ctr = 0x82048004; cpu->reset_sctlr = 0x00c50078; cpu->id_pfr0 = 0x1031; From 416d72b97b01d6cb769ad0fd0e10614583354a45 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 27 Dec 2016 14:59:24 +0000 Subject: [PATCH 04/25] target-arm: Fix aarch64 vec_reg_offset Since CPUARMState.vfp.regs is not 16 byte aligned, the ^ 8 fixup used for a big-endian host doesn't do what's intended. Fix this by adding in the vfp.regs offset after computing the inter-register offset. Signed-off-by: Richard Henderson Message-id: 1481085020-2614-2-git-send-email-rth@twiddle.net Reviewed-by: Peter Maydell 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 6dc27a6115..ef7601b5e6 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -527,7 +527,7 @@ static inline void assert_fp_access_checked(DisasContext *s) static inline int vec_reg_offset(DisasContext *s, int regno, int element, TCGMemOp size) { - int offs = offsetof(CPUARMState, vfp.regs[regno * 2]); + int offs = 0; #ifdef HOST_WORDS_BIGENDIAN /* This is complicated slightly because vfp.regs[2n] is * still the low half and vfp.regs[2n+1] the high half @@ -540,6 +540,7 @@ static inline int vec_reg_offset(DisasContext *s, int regno, #else offs += element * (1 << size); #endif + offs += offsetof(CPUARMState, vfp.regs[regno * 2]); assert_fp_access_checked(s); return offs; } From 0a97c40f8e7172ac3d8db97fb22d0ef3025de307 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 27 Dec 2016 14:59:24 +0000 Subject: [PATCH 05/25] target-arm: Fix aarch64 disas_ldst_single_struct We add s->be_data within do_vec_ld/st. Adding it here means that we have the wrong bits set in SIZE for a big-endian host, leading to g_assert_not_reached in write_vec_element and read_vec_element. Signed-off-by: Richard Henderson Message-id: 1481085020-2614-3-git-send-email-rth@twiddle.net Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- target/arm/translate-a64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index ef7601b5e6..f673d939e1 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -2830,9 +2830,9 @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn) } else { /* Load/store one element per register */ if (is_load) { - do_vec_ld(s, rt, index, tcg_addr, s->be_data + scale); + do_vec_ld(s, rt, index, tcg_addr, scale); } else { - do_vec_st(s, rt, index, tcg_addr, s->be_data + scale); + do_vec_st(s, rt, index, tcg_addr, scale); } } tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes); From 92204403ef939a1baa1b31bd76716f4566c2a6f1 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 27 Dec 2016 14:59:24 +0000 Subject: [PATCH 06/25] hw/intc/arm_gicv3_common: fix aff3 in typer Signed-off-by: Andrew Jones Message-id: 20161209143703.29457-1-drjones@redhat.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/intc/arm_gicv3_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c index 0f8c4b86e0..0aa9b9ca66 100644 --- a/hw/intc/arm_gicv3_common.c +++ b/hw/intc/arm_gicv3_common.c @@ -204,7 +204,8 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp) /* The CPU mp-affinity property is in MPIDR register format; squash * the affinity bytes into 32 bits as the GICR_TYPER has them. */ - cpu_affid = (cpu_affid & 0xFF00000000ULL >> 8) | (cpu_affid & 0xFFFFFF); + cpu_affid = ((cpu_affid & 0xFF00000000ULL) >> 8) | + (cpu_affid & 0xFFFFFF); s->cpu[i].gicr_typer = (cpu_affid << 32) | (1 << 24) | (i << 8) | From c9b61d9aa1ad234b0961f8add023cdc999cda3da Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 27 Dec 2016 14:59:25 +0000 Subject: [PATCH 07/25] target-arm: Log AArch64 exception returns We already log exception entry; add logging of the AArch64 exception return path as well. Signed-off-by: Peter Maydell Reviewed-by: Edgar E. Iglesias --- target/arm/op_helper.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index cd94216591..ba796d898e 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -17,6 +17,7 @@ * License along with this library; if not, see . */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "cpu.h" #include "exec/helper-proto.h" #include "internals.h" @@ -972,6 +973,9 @@ void HELPER(exception_return)(CPUARMState *env) } else { env->regs[15] = env->elr_el[cur_el] & ~0x3; } + qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to " + "AArch32 EL%d PC 0x%" PRIx32 "\n", + cur_el, new_el, env->regs[15]); } else { env->aarch64 = 1; pstate_write(env, spsr); @@ -980,6 +984,9 @@ void HELPER(exception_return)(CPUARMState *env) } aarch64_restore_sp(env, new_el); env->pc = env->elr_el[cur_el]; + qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to " + "AArch64 EL%d PC 0x%" PRIx64 "\n", + cur_el, new_el, env->pc); } arm_call_el_change_hook(arm_env_get_cpu(env)); @@ -1002,6 +1009,8 @@ illegal_return: if (!arm_singlestep_active(env)) { env->pstate &= ~PSTATE_SS; } + qemu_log_mask(LOG_GUEST_ERROR, "Illegal exception return at EL%d: " + "resuming execution at 0x%" PRIx64 "\n", cur_el, env->pc); } /* Return true if the linked breakpoint entry lbn passes its checks */ From e971fa042253ed36e602a2c1bc01144da3e8832f Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 27 Dec 2016 14:59:25 +0000 Subject: [PATCH 08/25] hw/intc/arm_gicv3: Remove incorrect usage of fieldoffset In the ARMCPRegInfo definitions for the GICv3 CPU interface registers, we were trying to use .fieldoffset to specify the locations of data fields within the GICv3CPUState struct. This is completely broken, because .fieldoffset is for offsets into the CPUARMState struct. We didn't notice because we were only using this for reads to BPR0, AP0R, IGRPEN0 and CTLR_EL3, and Linux doesn't use these registers. Replace the .fieldoffset uses with explicit read functions. Signed-off-by: Peter Maydell Reviewed-by: Edgar E. Iglesias --- hw/intc/arm_gicv3_cpuif.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c index bca30c49da..35e8eb30fc 100644 --- a/hw/intc/arm_gicv3_cpuif.c +++ b/hw/intc/arm_gicv3_cpuif.c @@ -1118,35 +1118,35 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = { .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 3, .type = ARM_CP_IO | ARM_CP_NO_RAW, .access = PL1_RW, .accessfn = gicv3_fiq_access, - .fieldoffset = offsetof(GICv3CPUState, icc_bpr[GICV3_G0]), + .readfn = icc_bpr_read, .writefn = icc_bpr_write, }, { .name = "ICC_AP0R0_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 4, .type = ARM_CP_IO | ARM_CP_NO_RAW, .access = PL1_RW, .accessfn = gicv3_fiq_access, - .fieldoffset = offsetof(GICv3CPUState, icc_apr[GICV3_G0][0]), + .readfn = icc_ap_read, .writefn = icc_ap_write, }, { .name = "ICC_AP0R1_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 5, .type = ARM_CP_IO | ARM_CP_NO_RAW, .access = PL1_RW, .accessfn = gicv3_fiq_access, - .fieldoffset = offsetof(GICv3CPUState, icc_apr[GICV3_G0][1]), + .readfn = icc_ap_read, .writefn = icc_ap_write, }, { .name = "ICC_AP0R2_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 6, .type = ARM_CP_IO | ARM_CP_NO_RAW, .access = PL1_RW, .accessfn = gicv3_fiq_access, - .fieldoffset = offsetof(GICv3CPUState, icc_apr[GICV3_G0][2]), + .readfn = icc_ap_read, .writefn = icc_ap_write, }, { .name = "ICC_AP0R3_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 7, .type = ARM_CP_IO | ARM_CP_NO_RAW, .access = PL1_RW, .accessfn = gicv3_fiq_access, - .fieldoffset = offsetof(GICv3CPUState, icc_apr[GICV3_G0][3]), + .readfn = icc_ap_read, .writefn = icc_ap_write, }, /* All the ICC_AP1R*_EL1 registers are banked */ @@ -1275,7 +1275,7 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = { .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 6, .type = ARM_CP_IO | ARM_CP_NO_RAW, .access = PL1_RW, .accessfn = gicv3_fiq_access, - .fieldoffset = offsetof(GICv3CPUState, icc_igrpen[GICV3_G0]), + .readfn = icc_igrpen_read, .writefn = icc_igrpen_write, }, /* This register is banked */ @@ -1299,7 +1299,6 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = { .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 12, .opc2 = 4, .type = ARM_CP_IO | ARM_CP_NO_RAW, .access = PL3_RW, - .fieldoffset = offsetof(GICv3CPUState, icc_ctlr_el3), .readfn = icc_ctlr_el3_read, .writefn = icc_ctlr_el3_write, }, From 0bfa02595aa2b887d1e7f56600a5aec7067c71b0 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 27 Dec 2016 14:59:25 +0000 Subject: [PATCH 09/25] hw/intc/arm_gicv3: Don't signal Pending+Active interrupts to CPU The GICv3 requires that we only signal Pending interrupts to the CPU. This category does not include Pending+Active interrupts, which means we need to check whether the interrupt is Active in the gicr_int_pending() and gicd_int_pending() functions. Interrupts are rarely in the Active+Pending state, but KVM uses this as part of its handling of the virtual timer, so this bug was causing KVM to go into an infinite loop of taking the vtimer interrupt when the guest first triggered it. Signed-off-by: Peter Maydell Reviewed-by: Edgar E. Iglesias --- hw/intc/arm_gicv3.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c index 8a6c647219..f0c967b304 100644 --- a/hw/intc/arm_gicv3.c +++ b/hw/intc/arm_gicv3.c @@ -54,6 +54,7 @@ static uint32_t gicd_int_pending(GICv3State *s, int irq) * + the PENDING latch is set OR it is level triggered and the input is 1 * + its ENABLE bit is set * + the GICD enable bit for its group is set + * + its ACTIVE bit is not set (otherwise it would be Active+Pending) * Conveniently we can bulk-calculate this with bitwise operations. */ uint32_t pend, grpmask; @@ -63,9 +64,11 @@ static uint32_t gicd_int_pending(GICv3State *s, int irq) uint32_t group = *gic_bmp_ptr32(s->group, irq); uint32_t grpmod = *gic_bmp_ptr32(s->grpmod, irq); uint32_t enable = *gic_bmp_ptr32(s->enabled, irq); + uint32_t active = *gic_bmp_ptr32(s->active, irq); pend = pending | (~edge_trigger & level); pend &= enable; + pend &= ~active; if (s->gicd_ctlr & GICD_CTLR_DS) { grpmod = 0; @@ -96,12 +99,14 @@ static uint32_t gicr_int_pending(GICv3CPUState *cs) * + the PENDING latch is set OR it is level triggered and the input is 1 * + its ENABLE bit is set * + the GICD enable bit for its group is set + * + its ACTIVE bit is not set (otherwise it would be Active+Pending) * Conveniently we can bulk-calculate this with bitwise operations. */ uint32_t pend, grpmask, grpmod; pend = cs->gicr_ipendr0 | (~cs->edge_trigger & cs->level); pend &= cs->gicr_ienabler0; + pend &= ~cs->gicr_iactiver0; if (cs->gic->gicd_ctlr & GICD_CTLR_DS) { grpmod = 0; From e353aac51b944de9cfce5c6cee6b5c28eddbbd77 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 27 Dec 2016 14:59:26 +0000 Subject: [PATCH 10/25] hw/arm/virt: add 2.9 machine type Signed-off-by: Peter Maydell Reviewed-by: Andrew Jones --- hw/arm/virt.c | 21 ++++++++++++++++++--- include/hw/compat.h | 3 +++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index d04e4acbd9..11c53a56e0 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1525,7 +1525,7 @@ static void machvirt_machine_init(void) } type_init(machvirt_machine_init); -static void virt_2_8_instance_init(Object *obj) +static void virt_2_9_instance_init(Object *obj) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -1558,10 +1558,25 @@ static void virt_2_8_instance_init(Object *obj) "Valid values are 2, 3 and host", NULL); } -static void virt_machine_2_8_options(MachineClass *mc) +static void virt_machine_2_9_options(MachineClass *mc) { } -DEFINE_VIRT_MACHINE_AS_LATEST(2, 8) +DEFINE_VIRT_MACHINE_AS_LATEST(2, 9) + +#define VIRT_COMPAT_2_8 \ + HW_COMPAT_2_8 + +static void virt_2_8_instance_init(Object *obj) +{ + virt_2_9_instance_init(obj); +} + +static void virt_machine_2_8_options(MachineClass *mc) +{ + virt_machine_2_9_options(mc); + SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_8); +} +DEFINE_VIRT_MACHINE(2, 8) #define VIRT_COMPAT_2_7 \ HW_COMPAT_2_7 diff --git a/include/hw/compat.h b/include/hw/compat.h index 8dfc7a38c0..4fe44d1c7a 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -1,6 +1,9 @@ #ifndef HW_COMPAT_H #define HW_COMPAT_H +#define HW_COMPAT_2_8 \ + /* empty */ + #define HW_COMPAT_2_7 \ {\ .driver = "virtio-pci",\ From e03192fd62d9d673b42e010f6fab3ef4cf44903e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 27 Dec 2016 14:59:26 +0000 Subject: [PATCH 11/25] m25p80: add support for the mx66l1g45g MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cédric Le Goater Reviewed-by: Marcin Krzeminski Reviewed-by: Joel Stanley Reviewed-by: Andrew Jeffery Message-id: 1480434248-27138-3-git-send-email-clg@kaod.org Signed-off-by: Peter Maydell --- hw/block/m25p80.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index d29ff4cb4f..e3c1166ea6 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -203,6 +203,7 @@ static const FlashPartInfo known_devices[] = { { INFO("mx25l25655e", 0xc22619, 0, 64 << 10, 512, 0) }, { INFO("mx66u51235f", 0xc2253a, 0, 64 << 10, 1024, ER_4K | ER_32K) }, { INFO("mx66u1g45g", 0xc2253b, 0, 64 << 10, 2048, ER_4K | ER_32K) }, + { INFO("mx66l1g45g", 0xc2201b, 0, 64 << 10, 2048, ER_4K | ER_32K) }, /* Micron */ { INFO("n25q032a11", 0x20bb16, 0, 64 << 10, 64, ER_4K) }, From 2d105bd6b58d83295310915f5503ef14d97f4c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 27 Dec 2016 14:59:26 +0000 Subject: [PATCH 12/25] aspeed: QOMify the CPU object and attach it to the SoC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cédric Le Goater Reviewed-by: Joel Stanley Reviewed-by: Andrew Jeffery Message-id: 1480434248-27138-4-git-send-email-clg@kaod.org Signed-off-by: Peter Maydell --- hw/arm/aspeed_soc.c | 17 ++++++++++++++--- include/hw/arm/aspeed_soc.h | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c index e14f5c217e..db145e2014 100644 --- a/hw/arm/aspeed_soc.c +++ b/hw/arm/aspeed_soc.c @@ -87,9 +87,13 @@ static void aspeed_soc_init(Object *obj) { AspeedSoCState *s = ASPEED_SOC(obj); AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); + char *cpu_typename; int i; - s->cpu = cpu_arm_init(sc->info->cpu_model); + cpu_typename = g_strdup_printf("%s-" TYPE_ARM_CPU, sc->info->cpu_model); + object_initialize(&s->cpu, sizeof(s->cpu), cpu_typename); + object_property_add_child(obj, "cpu", OBJECT(&s->cpu), NULL); + g_free(cpu_typename); object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC); object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL); @@ -146,6 +150,13 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) memory_region_add_subregion_overlap(get_system_memory(), ASPEED_SOC_IOMEM_BASE, &s->iomem, -1); + /* CPU */ + object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + /* VIC */ object_property_set_bool(OBJECT(&s->vic), true, "realized", &err); if (err) { @@ -154,9 +165,9 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) } sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, ASPEED_SOC_VIC_BASE); sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0, - qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); + qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1, - qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ)); + qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); /* Timer */ object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err); diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index 5406b498d7..6f1b679c97 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h @@ -27,7 +27,7 @@ typedef struct AspeedSoCState { DeviceState parent; /*< public >*/ - ARMCPU *cpu; + ARMCPU cpu; MemoryRegion iomem; AspeedVICState vic; AspeedTimerCtrlState timerctrl; From 4c3386f42102652f2b75e135cf09c9ea31cdec88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 27 Dec 2016 14:59:26 +0000 Subject: [PATCH 13/25] aspeed: remove cannot_destroy_with_object_finalize_yet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With commit ce5b1bbf624b ("exec: move cpu_exec_init() calls to realize functions"), we can now remove cannot_destroy_with_object_finalize_yet. Suggested-by: Andrew Jeffery Signed-off-by: Cédric Le Goater Message-id: 1480434248-27138-5-git-send-email-clg@kaod.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/aspeed_soc.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c index db145e2014..3a6b91f14b 100644 --- a/hw/arm/aspeed_soc.c +++ b/hw/arm/aspeed_soc.c @@ -251,12 +251,6 @@ static void aspeed_soc_class_init(ObjectClass *oc, void *data) sc->info = (AspeedSoCInfo *) data; dc->realize = aspeed_soc_realize; - - /* - * Reason: creates an ARM CPU, thus use after free(), see - * arm_cpu_class_init() - */ - dc->cannot_destroy_with_object_finalize_yet = true; } static const TypeInfo aspeed_soc_type_info = { From bd673bd8aba8b9f316c3c95f7be872087bb55695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 27 Dec 2016 14:59:27 +0000 Subject: [PATCH 14/25] aspeed: attach the second SPI controller object to the SoC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cédric Le Goater Reviewed-by: Andrew Jeffery Message-id: 1480434248-27138-6-git-send-email-clg@kaod.org Signed-off-by: Peter Maydell --- hw/arm/aspeed_soc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c index 3a6b91f14b..82e27129a9 100644 --- a/hw/arm/aspeed_soc.c +++ b/hw/arm/aspeed_soc.c @@ -124,7 +124,7 @@ static void aspeed_soc_init(Object *obj) for (i = 0; i < sc->info->spis_num; i++) { object_initialize(&s->spi[i], sizeof(s->spi[i]), sc->info->spi_typename[i]); - object_property_add_child(obj, "spi", OBJECT(&s->spi[i]), NULL); + object_property_add_child(obj, "spi[*]", OBJECT(&s->spi[i]), NULL); qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default()); } From 6a0e947b125f5727d3e59f13cb15a5284404c27e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 27 Dec 2016 14:59:27 +0000 Subject: [PATCH 15/25] aspeed: extend the board configuration with flash models MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Future machine will use different flash models for the FMC and the SPI controllers. Signed-off-by: Cédric Le Goater Reviewed-by: Joel Stanley Reviewed-by: Andrew Jeffery Message-id: 1480434248-27138-7-git-send-email-clg@kaod.org Signed-off-by: Peter Maydell --- hw/arm/aspeed.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index c7206fda6d..159d562e89 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -34,6 +34,8 @@ typedef struct AspeedBoardState { typedef struct AspeedBoardConfig { const char *soc_name; uint32_t hw_strap1; + const char *fmc_model; + const char *spi_model; } AspeedBoardConfig; enum { @@ -65,8 +67,18 @@ enum { ~SCU_HW_STRAP_2ND_BOOT_WDT) static const AspeedBoardConfig aspeed_boards[] = { - [PALMETTO_BMC] = { "ast2400-a0", PALMETTO_BMC_HW_STRAP1 }, - [AST2500_EVB] = { "ast2500-a1", AST2500_EVB_HW_STRAP1 }, + [PALMETTO_BMC] = { + .soc_name = "ast2400-a0", + .hw_strap1 = PALMETTO_BMC_HW_STRAP1, + .fmc_model = "n25q256a", + .spi_model = "mx25l25635e", + }, + [AST2500_EVB] = { + .soc_name = "ast2500-a1", + .hw_strap1 = AST2500_EVB_HW_STRAP1, + .fmc_model = "n25q256a", + .spi_model = "mx25l25635e", + }, }; static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype, @@ -128,8 +140,8 @@ static void aspeed_board_init(MachineState *machine, object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram), &error_abort); - aspeed_board_init_flashes(&bmc->soc.fmc, "n25q256a", &error_abort); - aspeed_board_init_flashes(&bmc->soc.spi[0], "mx25l25635e", &error_abort); + aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort); + aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort); aspeed_board_binfo.kernel_filename = machine->kernel_filename; aspeed_board_binfo.initrd_filename = machine->initrd_filename; From ef17f8366173aa28e3b32469725b221ab03fc421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 27 Dec 2016 14:59:27 +0000 Subject: [PATCH 16/25] aspeed: add support for the romulus-bmc board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Romulus machine is an OpenPOWER system with an AST2500 SoC for the BMC and a POWER9 chip for the host. It does not make much difference for qemu a part from the fact that the FMC controller has two SPI flash module. Signed-off-by: Cédric Le Goater Reviewed-by: Joel Stanley Message-id: 1480434248-27138-8-git-send-email-clg@kaod.org Signed-off-by: Peter Maydell --- hw/arm/aspeed.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index 159d562e89..3509011ae9 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -41,8 +41,10 @@ typedef struct AspeedBoardConfig { enum { PALMETTO_BMC, AST2500_EVB, + ROMULUS_BMC, }; +/* Palmetto hardware value: 0x120CE416 */ #define PALMETTO_BMC_HW_STRAP1 ( \ SCU_AST2400_HW_STRAP_DRAM_SIZE(DRAM_SIZE_256MB) | \ SCU_AST2400_HW_STRAP_DRAM_CONFIG(2 /* DDR3 with CL=6, CWL=5 */) | \ @@ -56,6 +58,7 @@ enum { SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) | \ SCU_AST2400_HW_STRAP_BOOT_MODE(AST2400_SPI_BOOT)) +/* AST2500 evb hardware value: 0xF100C2E6 */ #define AST2500_EVB_HW_STRAP1 (( \ AST2500_HW_STRAP1_DEFAULTS | \ SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \ @@ -66,6 +69,16 @@ enum { SCU_HW_STRAP_MAC0_RGMII) & \ ~SCU_HW_STRAP_2ND_BOOT_WDT) +/* Romulus hardware value: 0xF10AD206 */ +#define ROMULUS_BMC_HW_STRAP1 ( \ + AST2500_HW_STRAP1_DEFAULTS | \ + SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \ + SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE | \ + SCU_AST2500_HW_STRAP_UART_DEBUG | \ + SCU_AST2500_HW_STRAP_DDR4_ENABLE | \ + SCU_AST2500_HW_STRAP_ACPI_ENABLE | \ + SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER)) + static const AspeedBoardConfig aspeed_boards[] = { [PALMETTO_BMC] = { .soc_name = "ast2400-a0", @@ -79,6 +92,12 @@ static const AspeedBoardConfig aspeed_boards[] = { .fmc_model = "n25q256a", .spi_model = "mx25l25635e", }, + [ROMULUS_BMC] = { + .soc_name = "ast2500-a1", + .hw_strap1 = ROMULUS_BMC_HW_STRAP1, + .fmc_model = "n25q256a", + .spi_model = "mx66l1g45g", + }, }; static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype, @@ -200,10 +219,35 @@ static const TypeInfo ast2500_evb_type = { .class_init = ast2500_evb_class_init, }; +static void romulus_bmc_init(MachineState *machine) +{ + aspeed_board_init(machine, &aspeed_boards[ROMULUS_BMC]); +} + +static void romulus_bmc_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "OpenPOWER Romulus BMC (ARM1176)"; + mc->init = romulus_bmc_init; + mc->max_cpus = 1; + mc->no_sdcard = 1; + mc->no_floppy = 1; + mc->no_cdrom = 1; + mc->no_parallel = 1; +} + +static const TypeInfo romulus_bmc_type = { + .name = MACHINE_TYPE_NAME("romulus-bmc"), + .parent = TYPE_MACHINE, + .class_init = romulus_bmc_class_init, +}; + static void aspeed_machine_init(void) { type_register_static(&palmetto_bmc_type); type_register_static(&ast2500_evb_type); + type_register_static(&romulus_bmc_type); } type_init(aspeed_machine_init) From 74af4eec29f828b8ddf51d9f071264866c868ccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 27 Dec 2016 14:59:27 +0000 Subject: [PATCH 17/25] aspeed: add a memory region for SRAM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The size of the SRAM depends on the SoC model, so use a per-soc definition when creating the region. Signed-off-by: Cédric Le Goater Reviewed-by: Joel Stanley Reviewed-by: Andrew Jeffery Message-id: 1480434248-27138-9-git-send-email-clg@kaod.org Signed-off-by: Peter Maydell --- hw/arm/aspeed_soc.c | 52 ++++++++++++++++++++++++++++++------- include/hw/arm/aspeed_soc.h | 2 ++ 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c index 82e27129a9..233a6b9bf5 100644 --- a/hw/arm/aspeed_soc.c +++ b/hw/arm/aspeed_soc.c @@ -29,6 +29,7 @@ #define ASPEED_SOC_VIC_BASE 0x1E6C0000 #define ASPEED_SOC_SDMC_BASE 0x1E6E0000 #define ASPEED_SOC_SCU_BASE 0x1E6E2000 +#define ASPEED_SOC_SRAM_BASE 0x1E720000 #define ASPEED_SOC_TIMER_BASE 0x1E782000 #define ASPEED_SOC_I2C_BASE 0x1E78A000 @@ -47,15 +48,37 @@ static const char *aspeed_soc_ast2500_typenames[] = { "aspeed.smc.ast2500-spi1", "aspeed.smc.ast2500-spi2" }; static const AspeedSoCInfo aspeed_socs[] = { - { "ast2400-a0", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE, - 1, aspeed_soc_ast2400_spi_bases, - "aspeed.smc.fmc", aspeed_soc_ast2400_typenames }, - { "ast2400", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE, - 1, aspeed_soc_ast2400_spi_bases, - "aspeed.smc.fmc", aspeed_soc_ast2400_typenames }, - { "ast2500-a1", "arm1176", AST2500_A1_SILICON_REV, AST2500_SDRAM_BASE, - 2, aspeed_soc_ast2500_spi_bases, - "aspeed.smc.ast2500-fmc", aspeed_soc_ast2500_typenames }, + { + .name = "ast2400-a0", + .cpu_model = "arm926", + .silicon_rev = AST2400_A0_SILICON_REV, + .sdram_base = AST2400_SDRAM_BASE, + .sram_size = 0x8000, + .spis_num = 1, + .spi_bases = aspeed_soc_ast2400_spi_bases, + .fmc_typename = "aspeed.smc.fmc", + .spi_typename = aspeed_soc_ast2400_typenames, + }, { + .name = "ast2400", + .cpu_model = "arm926", + .silicon_rev = AST2400_A0_SILICON_REV, + .sdram_base = AST2400_SDRAM_BASE, + .sram_size = 0x8000, + .spis_num = 1, + .spi_bases = aspeed_soc_ast2400_spi_bases, + .fmc_typename = "aspeed.smc.fmc", + .spi_typename = aspeed_soc_ast2400_typenames, + }, { + .name = "ast2500-a1", + .cpu_model = "arm1176", + .silicon_rev = AST2500_A1_SILICON_REV, + .sdram_base = AST2500_SDRAM_BASE, + .sram_size = 0x9000, + .spis_num = 2, + .spi_bases = aspeed_soc_ast2500_spi_bases, + .fmc_typename = "aspeed.smc.ast2500-fmc", + .spi_typename = aspeed_soc_ast2500_typenames, + }, }; /* @@ -157,6 +180,17 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) return; } + /* SRAM */ + memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram", + sc->info->sram_size, &err); + if (err) { + error_propagate(errp, err); + return; + } + vmstate_register_ram_global(&s->sram); + memory_region_add_subregion(get_system_memory(), ASPEED_SOC_SRAM_BASE, + &s->sram); + /* VIC */ object_property_set_bool(OBJECT(&s->vic), true, "realized", &err); if (err) { diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index 6f1b679c97..1ab5deaa08 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h @@ -29,6 +29,7 @@ typedef struct AspeedSoCState { /*< public >*/ ARMCPU cpu; MemoryRegion iomem; + MemoryRegion sram; AspeedVICState vic; AspeedTimerCtrlState timerctrl; AspeedI2CState i2c; @@ -46,6 +47,7 @@ typedef struct AspeedSoCInfo { const char *cpu_model; uint32_t silicon_rev; hwaddr sdram_base; + uint64_t sram_size; int spis_num; const hwaddr *spi_bases; const char *fmc_typename; From 6efbac908f3052a88eb466e2afd75f333de3b17d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 27 Dec 2016 14:59:28 +0000 Subject: [PATCH 18/25] aspeed: add the definitions for the AST2400 A1 SoC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is not much differences with the A0 revision apart from the DDR calibration. Signed-off-by: Cédric Le Goater Reviewed-by: Joel Stanley Reviewed-by: Andrew Jeffery Message-id: 1480434248-27138-10-git-send-email-clg@kaod.org Signed-off-by: Peter Maydell --- hw/arm/aspeed_soc.c | 10 ++++++++++ hw/misc/aspeed_scu.c | 2 ++ hw/misc/aspeed_sdmc.c | 3 +++ include/hw/misc/aspeed_scu.h | 1 + 4 files changed, 16 insertions(+) diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c index 233a6b9bf5..d111d2e1fe 100644 --- a/hw/arm/aspeed_soc.c +++ b/hw/arm/aspeed_soc.c @@ -58,6 +58,16 @@ static const AspeedSoCInfo aspeed_socs[] = { .spi_bases = aspeed_soc_ast2400_spi_bases, .fmc_typename = "aspeed.smc.fmc", .spi_typename = aspeed_soc_ast2400_typenames, + }, { + .name = "ast2400-a1", + .cpu_model = "arm926", + .silicon_rev = AST2400_A1_SILICON_REV, + .sdram_base = AST2400_SDRAM_BASE, + .sram_size = 0x8000, + .spis_num = 1, + .spi_bases = aspeed_soc_ast2400_spi_bases, + .fmc_typename = "aspeed.smc.fmc", + .spi_typename = aspeed_soc_ast2400_typenames, }, { .name = "ast2400", .cpu_model = "arm926", diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index b1f3e6f6b8..34e86385d8 100644 --- a/hw/misc/aspeed_scu.c +++ b/hw/misc/aspeed_scu.c @@ -231,6 +231,7 @@ static void aspeed_scu_reset(DeviceState *dev) switch (s->silicon_rev) { case AST2400_A0_SILICON_REV: + case AST2400_A1_SILICON_REV: reset = ast2400_a0_resets; break; case AST2500_A0_SILICON_REV: @@ -249,6 +250,7 @@ static void aspeed_scu_reset(DeviceState *dev) static uint32_t aspeed_silicon_revs[] = { AST2400_A0_SILICON_REV, + AST2400_A1_SILICON_REV, AST2500_A0_SILICON_REV, AST2500_A1_SILICON_REV, }; diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c index 8830dc084c..5f3ac0b6f6 100644 --- a/hw/misc/aspeed_sdmc.c +++ b/hw/misc/aspeed_sdmc.c @@ -119,6 +119,7 @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data, /* Make sure readonly bits are kept */ switch (s->silicon_rev) { case AST2400_A0_SILICON_REV: + case AST2400_A1_SILICON_REV: data &= ~ASPEED_SDMC_READONLY_MASK; break; case AST2500_A0_SILICON_REV: @@ -193,6 +194,7 @@ static void aspeed_sdmc_reset(DeviceState *dev) /* Set ram size bit and defaults values */ switch (s->silicon_rev) { case AST2400_A0_SILICON_REV: + case AST2400_A1_SILICON_REV: s->regs[R_CONF] |= ASPEED_SDMC_VGA_COMPAT | ASPEED_SDMC_DRAM_SIZE(s->ram_bits); @@ -224,6 +226,7 @@ static void aspeed_sdmc_realize(DeviceState *dev, Error **errp) switch (s->silicon_rev) { case AST2400_A0_SILICON_REV: + case AST2400_A1_SILICON_REV: s->ram_bits = ast2400_rambits(s); break; case AST2500_A0_SILICON_REV: diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h index 14ffc43de8..bd4ac013f9 100644 --- a/include/hw/misc/aspeed_scu.h +++ b/include/hw/misc/aspeed_scu.h @@ -32,6 +32,7 @@ typedef struct AspeedSCUState { } AspeedSCUState; #define AST2400_A0_SILICON_REV 0x02000303U +#define AST2400_A1_SILICON_REV 0x02010303U #define AST2500_A0_SILICON_REV 0x04000303U #define AST2500_A1_SILICON_REV 0x04010303U From bd407a21a9927acf2c02a2c44923af52f279e2ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 27 Dec 2016 14:59:28 +0000 Subject: [PATCH 19/25] aspeed: change SoC revision of the palmetto-bmc machine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The palmetto BMC machine uses a AST2400 revision A1 SoC. Signed-off-by: Cédric Le Goater Reviewed-by: Joel Stanley Reviewed-by: Andrew Jeffery Message-id: 1480434248-27138-11-git-send-email-clg@kaod.org Signed-off-by: Peter Maydell --- hw/arm/aspeed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index 3509011ae9..bc70b38789 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -81,7 +81,7 @@ enum { static const AspeedBoardConfig aspeed_boards[] = { [PALMETTO_BMC] = { - .soc_name = "ast2400-a0", + .soc_name = "ast2400-a1", .hw_strap1 = PALMETTO_BMC_HW_STRAP1, .fmc_model = "n25q256a", .spi_model = "mx25l25635e", From c491e1521f20a44517c68ea920f10c03b864c140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 27 Dec 2016 14:59:28 +0000 Subject: [PATCH 20/25] aspeed/scu: fix SCU region size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cédric Le Goater Reviewed-by: Joel Stanley Reviewed-by: Andrew Jeffery Message-id: 1480434248-27138-12-git-send-email-clg@kaod.org Signed-off-by: Peter Maydell --- hw/misc/aspeed_scu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index 34e86385d8..95022d3607 100644 --- a/hw/misc/aspeed_scu.c +++ b/hw/misc/aspeed_scu.c @@ -86,7 +86,7 @@ #define BMC_DEV_ID TO_REG(0x1A4) #define PROT_KEY_UNLOCK 0x1688A8A8 -#define SCU_IO_REGION_SIZE 0x20000 +#define SCU_IO_REGION_SIZE 0x1000 static const uint32_t ast2400_a0_resets[ASPEED_SCU_NR_REGS] = { [SYS_RST_CTRL] = 0xFFCFFEDCU, From 0584d3c33f70445085d3f223015c67dfcea97ba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 27 Dec 2016 14:59:28 +0000 Subject: [PATCH 21/25] aspeed/smc: improve segment register support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The HW does not enforce all the rules in the specs and allows a few "curious" setups like zero size segments and overlaps. So change the model to be in sync but keep the warnings which are always interesting for debug. Signed-off-by: Cédric Le Goater Reviewed-by: Joel Stanley Message-id: 1480434248-27138-13-git-send-email-clg@kaod.org Signed-off-by: Peter Maydell --- hw/ssi/aspeed_smc.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index 6e8403ebc2..78f5aed532 100644 --- a/hw/ssi/aspeed_smc.c +++ b/hw/ssi/aspeed_smc.c @@ -253,7 +253,8 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs, qemu_log_mask(LOG_GUEST_ERROR, "%s: Tried to change CS0 start address to 0x%" HWADDR_PRIx "\n", s->ctrl->name, seg.addr); - return; + seg.addr = s->ctrl->flash_window_base; + new = aspeed_smc_segment_to_reg(&seg); } /* @@ -267,8 +268,10 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs, s->ctrl->segments[cs].size) { qemu_log_mask(LOG_GUEST_ERROR, "%s: Tried to change CS%d end address to 0x%" - HWADDR_PRIx "\n", s->ctrl->name, cs, seg.addr); - return; + HWADDR_PRIx "\n", s->ctrl->name, cs, seg.addr + seg.size); + seg.size = s->ctrl->segments[cs].addr + s->ctrl->segments[cs].size - + seg.addr; + new = aspeed_smc_segment_to_reg(&seg); } /* Keep the segment in the overall flash window */ @@ -281,16 +284,14 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs, } /* Check start address vs. alignment */ - if (seg.addr % seg.size) { + if (seg.size && !QEMU_IS_ALIGNED(seg.addr, seg.size)) { qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is not " "aligned : [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n", s->ctrl->name, cs, seg.addr, seg.addr + seg.size); } - /* And segments should not overlap */ - if (aspeed_smc_flash_overlap(s, &seg, cs)) { - return; - } + /* And segments should not overlap (in the specs) */ + aspeed_smc_flash_overlap(s, &seg, cs); /* All should be fine now to move the region */ memory_region_transaction_begin(); From 26d5df9578927fce97a83975feecf1a3c2511610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 27 Dec 2016 14:59:29 +0000 Subject: [PATCH 22/25] aspeed/smc: set the number of flash modules for the FMC controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new configuration field at the board level and propagate the value using the "num-cs" property of the FMC controller model. Signed-off-by: Cédric Le Goater Message-id: 1480434248-27138-14-git-send-email-clg@kaod.org Signed-off-by: Peter Maydell --- hw/arm/aspeed.c | 6 ++++++ hw/arm/aspeed_soc.c | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index bc70b38789..40c13838fb 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -36,6 +36,7 @@ typedef struct AspeedBoardConfig { uint32_t hw_strap1; const char *fmc_model; const char *spi_model; + uint32_t num_cs; } AspeedBoardConfig; enum { @@ -85,18 +86,21 @@ static const AspeedBoardConfig aspeed_boards[] = { .hw_strap1 = PALMETTO_BMC_HW_STRAP1, .fmc_model = "n25q256a", .spi_model = "mx25l25635e", + .num_cs = 1, }, [AST2500_EVB] = { .soc_name = "ast2500-a1", .hw_strap1 = AST2500_EVB_HW_STRAP1, .fmc_model = "n25q256a", .spi_model = "mx25l25635e", + .num_cs = 1, }, [ROMULUS_BMC] = { .soc_name = "ast2500-a1", .hw_strap1 = ROMULUS_BMC_HW_STRAP1, .fmc_model = "n25q256a", .spi_model = "mx66l1g45g", + .num_cs = 2, }, }; @@ -143,6 +147,8 @@ static void aspeed_board_init(MachineState *machine, &error_abort); object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1", &error_abort); + object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs", + &error_abort); object_property_set_bool(OBJECT(&bmc->soc), true, "realized", &error_abort); diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c index d111d2e1fe..b3e7f07b61 100644 --- a/hw/arm/aspeed_soc.c +++ b/hw/arm/aspeed_soc.c @@ -153,6 +153,8 @@ static void aspeed_soc_init(Object *obj) object_initialize(&s->fmc, sizeof(s->fmc), sc->info->fmc_typename); object_property_add_child(obj, "fmc", OBJECT(&s->fmc), NULL); qdev_set_parent_bus(DEVICE(&s->fmc), sysbus_get_default()); + object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs", + &error_abort); for (i = 0; i < sc->info->spis_num; i++) { object_initialize(&s->spi[i], sizeof(s->spi[i]), @@ -250,10 +252,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0, qdev_get_gpio_in(DEVICE(&s->vic), 12)); - /* FMC */ - object_property_set_int(OBJECT(&s->fmc), 1, "num-cs", &err); - object_property_set_bool(OBJECT(&s->fmc), true, "realized", &local_err); - error_propagate(&err, local_err); + /* FMC, The number of CS is set at the board level */ + object_property_set_bool(OBJECT(&s->fmc), true, "realized", &err); if (err) { error_propagate(errp, err); return; From 8e953a658fa13b05bea67899a91d8b65f2b89f11 Mon Sep 17 00:00:00 2001 From: Alastair D'Silva Date: Tue, 27 Dec 2016 14:59:29 +0000 Subject: [PATCH 23/25] hw/arm: remove trailing whitespace Remove trailing whitespace in hw/arm/pxa2xx.c Signed-off-by: Alastair D'Silva Message-id: 20161202054617.6749-3-alastair@au1.ibm.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/pxa2xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c index 21ea1d6210..8aa0f8a23a 100644 --- a/hw/arm/pxa2xx.c +++ b/hw/arm/pxa2xx.c @@ -2070,7 +2070,7 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space, } if (!revision) revision = "pxa270"; - + s->cpu = cpu_arm_init(revision); if (s->cpu == NULL) { fprintf(stderr, "Unable to find CPU definition\n"); From 9e41bade85ef338afd983c109368d1bbbe931f80 Mon Sep 17 00:00:00 2001 From: Alastair D'Silva Date: Tue, 27 Dec 2016 14:59:29 +0000 Subject: [PATCH 24/25] hw/i2c: Add a NULL check for i2c slave init callbacks Add a NULL check for i2c slave init callbacks, so that we no longer need to implement empty init functions. Signed-off-by: Alastair D'Silva Message-id: 20161202054617.6749-4-alastair@au1.ibm.com Reviewed-by: Peter Maydell [PMM: squashed in later tweak from Alistair to if() phrasing] Signed-off-by: Peter Maydell --- hw/arm/pxa2xx.c | 7 ------- hw/arm/tosa.c | 7 ------- hw/arm/z2.c | 7 ------- hw/i2c/core.c | 6 +++++- hw/timer/ds1338.c | 6 ------ 5 files changed, 5 insertions(+), 28 deletions(-) diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c index 8aa0f8a23a..bdcf6bcce7 100644 --- a/hw/arm/pxa2xx.c +++ b/hw/arm/pxa2xx.c @@ -1449,17 +1449,10 @@ static const VMStateDescription vmstate_pxa2xx_i2c = { } }; -static int pxa2xx_i2c_slave_init(I2CSlave *i2c) -{ - /* Nothing to do. */ - return 0; -} - static void pxa2xx_i2c_slave_class_init(ObjectClass *klass, void *data) { I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); - k->init = pxa2xx_i2c_slave_init; k->event = pxa2xx_i2c_event; k->recv = pxa2xx_i2c_rx; k->send = pxa2xx_i2c_tx; diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c index 1ee12f49b3..39d9dbbae6 100644 --- a/hw/arm/tosa.c +++ b/hw/arm/tosa.c @@ -202,12 +202,6 @@ static int tosa_dac_recv(I2CSlave *s) return -1; } -static int tosa_dac_init(I2CSlave *i2c) -{ - /* Nothing to do. */ - return 0; -} - static void tosa_tg_init(PXA2xxState *cpu) { I2CBus *bus = pxa2xx_i2c_bus(cpu->i2c[0]); @@ -275,7 +269,6 @@ static void tosa_dac_class_init(ObjectClass *klass, void *data) { I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); - k->init = tosa_dac_init; k->event = tosa_dac_event; k->recv = tosa_dac_recv; k->send = tosa_dac_send; diff --git a/hw/arm/z2.c b/hw/arm/z2.c index 68a92f3184..b3a6bbd210 100644 --- a/hw/arm/z2.c +++ b/hw/arm/z2.c @@ -263,12 +263,6 @@ static int aer915_recv(I2CSlave *slave) return retval; } -static int aer915_init(I2CSlave *i2c) -{ - /* Nothing to do. */ - return 0; -} - static VMStateDescription vmstate_aer915_state = { .name = "aer915", .version_id = 1, @@ -285,7 +279,6 @@ static void aer915_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); - k->init = aer915_init; k->event = aer915_event; k->recv = aer915_recv; k->send = aer915_send; diff --git a/hw/i2c/core.c b/hw/i2c/core.c index abd4c4cddb..e40781ea3b 100644 --- a/hw/i2c/core.c +++ b/hw/i2c/core.c @@ -260,7 +260,11 @@ static int i2c_slave_qdev_init(DeviceState *dev) I2CSlave *s = I2C_SLAVE(dev); I2CSlaveClass *sc = I2C_SLAVE_GET_CLASS(s); - return sc->init(s); + if (sc->init) { + return sc->init(s); + } + + return 0; } DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr) diff --git a/hw/timer/ds1338.c b/hw/timer/ds1338.c index 0112949e23..f5d04dd5d7 100644 --- a/hw/timer/ds1338.c +++ b/hw/timer/ds1338.c @@ -198,11 +198,6 @@ static int ds1338_send(I2CSlave *i2c, uint8_t data) return 0; } -static int ds1338_init(I2CSlave *i2c) -{ - return 0; -} - static void ds1338_reset(DeviceState *dev) { DS1338State *s = DS1338(dev); @@ -220,7 +215,6 @@ static void ds1338_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); - k->init = ds1338_init; k->event = ds1338_event; k->recv = ds1338_recv; k->send = ds1338_send; From 91db4642f868cf2e591b62d31a19d35b02ea791e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 27 Dec 2016 14:59:30 +0000 Subject: [PATCH 25/25] target-arm: Add VBAR support to ARM1176 CPUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ARM1176 CPUs have TrustZone support and can use the Vector Base Address Register, but currently, qemu only adds VBAR support to ARMv7 CPUs. Fix this by adding a new feature ARM_FEATURE_VBAR which can used for ARMv7 and ARM1176 CPUs. The VBAR feature is always set for ARMv7 because some legacy boards require it even if this is not architecturally correct. Signed-off-by: Cédric Le Goater Message-id: 1481810970-9692-1-git-send-email-clg@kaod.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- target/arm/cpu.c | 9 +++++++++ target/arm/cpu.h | 1 + target/arm/helper.c | 19 +++++++++++++------ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 98e2c68bc4..f5cb30af6c 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -597,6 +597,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) } else { set_feature(env, ARM_FEATURE_V6); } + + /* Always define VBAR for V7 CPUs even if it doesn't exist in + * non-EL3 configs. This is needed by some legacy boards. + */ + set_feature(env, ARM_FEATURE_VBAR); } if (arm_feature(env, ARM_FEATURE_V6K)) { set_feature(env, ARM_FEATURE_V6); @@ -721,6 +726,10 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) } } + if (arm_feature(env, ARM_FEATURE_EL3)) { + set_feature(env, ARM_FEATURE_VBAR); + } + register_cp_regs_for_features(cpu); arm_cpu_register_gdb_regs_for_features(cpu); diff --git a/target/arm/cpu.h b/target/arm/cpu.h index ca5c849ed6..ab119e62ab 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1125,6 +1125,7 @@ enum arm_features { ARM_FEATURE_V8_PMULL, /* implements PMULL part of v8 Crypto Extensions */ ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */ ARM_FEATURE_PMU, /* has PMU support */ + ARM_FEATURE_VBAR, /* has cp15 VBAR */ }; static inline int arm_feature(CPUARMState *env, int feature) diff --git a/target/arm/helper.c b/target/arm/helper.c index b5b65caadf..8dcabbf576 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -1252,12 +1252,6 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .access = PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS, .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), .writefn = pmintenclr_write }, - { .name = "VBAR", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .writefn = vbar_write, - .bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s), - offsetof(CPUARMState, cp15.vbar_ns) }, - .resetvalue = 0 }, { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0, .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW }, @@ -5094,6 +5088,19 @@ void register_cp_regs_for_features(ARMCPU *cpu) } } + if (arm_feature(env, ARM_FEATURE_VBAR)) { + ARMCPRegInfo vbar_cp_reginfo[] = { + { .name = "VBAR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .writefn = vbar_write, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s), + offsetof(CPUARMState, cp15.vbar_ns) }, + .resetvalue = 0 }, + REGINFO_SENTINEL + }; + define_arm_cp_regs(cpu, vbar_cp_reginfo); + } + /* Generic registers whose values depend on the implementation */ { ARMCPRegInfo sctlr = {