diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/cpu.c | 11 | ||||
-rw-r--r-- | target/arm/cpu.h | 1 | ||||
-rw-r--r-- | target/arm/helper.c | 19 | ||||
-rw-r--r-- | target/arm/op_helper.c | 9 | ||||
-rw-r--r-- | target/arm/translate-a64.c | 7 |
5 files changed, 37 insertions, 10 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 99f0dbebb9..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); @@ -1055,7 +1064,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; 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 = { 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 <http://www.gnu.org/licenses/>. */ #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 */ diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 6dc27a6115..f673d939e1 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; } @@ -2829,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); |