diff options
author | Alex Bennée <alex.bennee@linaro.org> | 2019-09-19 14:18:40 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-09-27 11:41:30 +0100 |
commit | 5651697f1f405a023378cbd35e3528788fed2166 (patch) | |
tree | 990fdc6b99a375623da62c2354d83f00efcc3449 /target/arm | |
parent | 376214e4f499f82900e699c225f18f045f8a3c20 (diff) |
target/arm: handle A-profile semihosting at translate time
As for the other semihosting calls we can resolve this at translate
time.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20190913151845.12582-4-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm')
-rw-r--r-- | target/arm/translate.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/target/arm/translate.c b/target/arm/translate.c index b527211933..698c594e8c 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -10222,14 +10222,25 @@ static bool trans_CBZ(DisasContext *s, arg_CBZ *a) } /* - * Supervisor call + * Supervisor call - both T32 & A32 come here so we need to check + * which mode we are in when checking for semihosting. */ static bool trans_SVC(DisasContext *s, arg_SVC *a) { - gen_set_pc_im(s, s->base.pc_next); - s->svc_imm = a->imm; - s->base.is_jmp = DISAS_SWI; + const uint32_t semihost_imm = s->thumb ? 0xab : 0x123456; + + if (!arm_dc_feature(s, ARM_FEATURE_M) && semihosting_enabled() && +#ifndef CONFIG_USER_ONLY + !IS_USER(s) && +#endif + (a->imm == semihost_imm)) { + gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST); + } else { + gen_set_pc_im(s, s->base.pc_next); + s->svc_imm = a->imm; + s->base.is_jmp = DISAS_SWI; + } return true; } |