summaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/arm/cpu.c11
-rw-r--r--target/arm/cpu.h1
-rw-r--r--target/arm/helper.c19
-rw-r--r--target/arm/op_helper.c9
-rw-r--r--target/arm/translate-a64.c7
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);