According to the m68k semihosting spec: "The instruction used to trigger a semihosting request depends on the m68k processor variant. On ColdFire, "halt" is used; on other processors (which don't implement "halt"), "bkpt #0" may be used."
Add support for non-CodeFire processors by matching BKPT #0 instructions. When semihosting is disabled, convert those back to illegal op exceptions. Signed-off-by: Keith Packard <kei...@keithp.com> --- target/m68k/cpu.h | 1 + target/m68k/op_helper.c | 16 ++++++++++++++++ target/m68k/translate.c | 4 ++++ 3 files changed, 21 insertions(+) diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index cf70282717..b741c50a8f 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -67,6 +67,7 @@ #define EXCP_RTE 0x100 #define EXCP_HALT_INSN 0x101 +#define EXCP_BKPT_INSN 0x102 #define M68K_DTTR0 0 #define M68K_DTTR1 1 diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c index 1ce850bbc5..2d89db6dde 100644 --- a/target/m68k/op_helper.c +++ b/target/m68k/op_helper.c @@ -295,6 +295,22 @@ static void m68k_interrupt_all(CPUM68KState *env, int is_hw) /* Return from an exception. */ m68k_rte(env); return; + case EXCP_BKPT_INSN: + if (semihosting_enabled((env->sr & SR_S) == 0) + && (env->pc & 3) == 0 + && cpu_lduw_code(env, env->pc - 4) == 0x4e71 + && cpu_ldl_code(env, env->pc) == 0x4e7bf000) { + env->pc += 4; + do_m68k_semihosting(env, env->dregs[0]); + return; + } + /* + * When semihosting is not enabled, translate this back to + * an illegal op exception. + */ + cs->exception_index = EXCP_ILLEGAL; + env->pc += 2; + break; } } diff --git a/target/m68k/translate.c b/target/m68k/translate.c index e07161d76f..d037c57453 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -2640,6 +2640,10 @@ DISAS_INSN(bkpt) #if defined(CONFIG_USER_ONLY) gen_exception(s, s->base.pc_next, EXCP_DEBUG); #else + if ((insn & 7) == 0) { + gen_exception(s, s->pc, EXCP_BKPT_INSN); + return; + } gen_exception(s, s->base.pc_next, EXCP_ILLEGAL); #endif } -- 2.40.1