aboutsummaryrefslogtreecommitdiff
path: root/target/arm/translate.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-03-23 18:26:46 +0000
committerPeter Maydell <peter.maydell@linaro.org>2018-03-23 18:26:46 +0000
commitc900a2e62dd6dde11c8f5249b638caad05bb15be (patch)
tree8e3892e6c2310de09348acadd594c96a9f69d52c /target/arm/translate.c
parentdfadc3bfb458efefb72e13a57b62f138c464a577 (diff)
downloadqemu-c900a2e62dd6dde11c8f5249b638caad05bb15be.zip
qemu-c900a2e62dd6dde11c8f5249b638caad05bb15be.tar.gz
qemu-c900a2e62dd6dde11c8f5249b638caad05bb15be.tar.bz2
target/arm: Honour MDCR_EL2.TDE when routing exceptions due to BKPT/BRK
The MDCR_EL2.TDE bit allows the exception level targeted by debug exceptions to be set to EL2 for code executing at EL0. We handle this in the arm_debug_target_el() function, but this is only used for hardware breakpoint and watchpoint exceptions, not for the exception generated when the guest executes an AArch32 BKPT or AArch64 BRK instruction. We don't have enough information for a translate-time equivalent of arm_debug_target_el(), so instead make BKPT and BRK call a special purpose helper which can do the routing, rather than the generic exception_with_syndrome helper. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180320134114.30418-2-peter.maydell@linaro.org
Diffstat (limited to 'target/arm/translate.c')
-rw-r--r--target/arm/translate.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/target/arm/translate.c b/target/arm/translate.c
index ba6ab7d..fc03b5b 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -1248,6 +1248,18 @@ static void gen_exception_insn(DisasContext *s, int offset, int excp,
s->base.is_jmp = DISAS_NORETURN;
}
+static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
+{
+ TCGv_i32 tcg_syn;
+
+ gen_set_condexec(s);
+ gen_set_pc_im(s, s->pc - offset);
+ tcg_syn = tcg_const_i32(syn);
+ gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
+ tcg_temp_free_i32(tcg_syn);
+ s->base.is_jmp = DISAS_NORETURN;
+}
+
/* Force a TB lookup after an instruction that changes the CPU state. */
static inline void gen_lookup_tb(DisasContext *s)
{
@@ -8774,9 +8786,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
case 1:
/* bkpt */
ARCH(5);
- gen_exception_insn(s, 4, EXCP_BKPT,
- syn_aa32_bkpt(imm16, false),
- default_exception_el(s));
+ gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
break;
case 2:
/* Hypervisor call (v7) */
@@ -11983,8 +11993,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
{
int imm8 = extract32(insn, 0, 8);
ARCH(5);
- gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
- default_exception_el(s));
+ gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
break;
}