mirror of https://github.com/xemu-project/xemu.git
target/m68k: Perform the semihosting test during translate
Replace EXCP_HALT_INSN by EXCP_SEMIHOSTING. Perform the pre- and post-insn tests during translate, leaving only the actual semihosting operation for the exception. Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
5fae5110ee
commit
f161e723fd
|
@ -66,7 +66,7 @@
|
||||||
#define EXCP_MMU_ACCESS 58 /* MMU Access Level Violation Error */
|
#define EXCP_MMU_ACCESS 58 /* MMU Access Level Violation Error */
|
||||||
|
|
||||||
#define EXCP_RTE 0x100
|
#define EXCP_RTE 0x100
|
||||||
#define EXCP_HALT_INSN 0x101
|
#define EXCP_SEMIHOSTING 0x101
|
||||||
|
|
||||||
#define M68K_DTTR0 0
|
#define M68K_DTTR0 0
|
||||||
#define M68K_DTTR1 1
|
#define M68K_DTTR1 1
|
||||||
|
|
|
@ -202,18 +202,8 @@ static void cf_interrupt_all(CPUM68KState *env, int is_hw)
|
||||||
/* Return from an exception. */
|
/* Return from an exception. */
|
||||||
cf_rte(env);
|
cf_rte(env);
|
||||||
return;
|
return;
|
||||||
case EXCP_HALT_INSN:
|
case EXCP_SEMIHOSTING:
|
||||||
if (semihosting_enabled((env->sr & SR_S) == 0)
|
do_m68k_semihosting(env, env->dregs[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;
|
|
||||||
}
|
|
||||||
cs->halted = 1;
|
|
||||||
cs->exception_index = EXCP_HLT;
|
|
||||||
cpu_loop_exit(cs);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,11 @@
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
#include "qemu/qemu-print.h"
|
#include "qemu/qemu-print.h"
|
||||||
#include "exec/translator.h"
|
#include "exec/translator.h"
|
||||||
|
|
||||||
#include "exec/helper-proto.h"
|
#include "exec/helper-proto.h"
|
||||||
#include "exec/helper-gen.h"
|
#include "exec/helper-gen.h"
|
||||||
|
|
||||||
#include "exec/log.h"
|
#include "exec/log.h"
|
||||||
#include "fpu/softfloat.h"
|
#include "fpu/softfloat.h"
|
||||||
|
#include "semihosting/semihost.h"
|
||||||
|
|
||||||
#define HELPER_H "helper.h"
|
#define HELPER_H "helper.h"
|
||||||
#include "exec/helper-info.c.inc"
|
#include "exec/helper-info.c.inc"
|
||||||
|
@ -1401,6 +1400,40 @@ static void gen_jmp_tb(DisasContext *s, int n, target_ulong dest,
|
||||||
s->base.is_jmp = DISAS_NORETURN;
|
s->base.is_jmp = DISAS_NORETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
static bool semihosting_test(DisasContext *s)
|
||||||
|
{
|
||||||
|
uint32_t test;
|
||||||
|
|
||||||
|
if (!semihosting_enabled(IS_USER(s))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "The semihosting instruction is immediately preceded by a
|
||||||
|
* nop aligned to a 4-byte boundary..."
|
||||||
|
* The preceding 2-byte (aligned) nop plus the 2-byte halt/bkpt
|
||||||
|
* means that we have advanced 4 bytes from the required nop.
|
||||||
|
*/
|
||||||
|
if (s->pc % 4 != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
test = translator_lduw(s->env, &s->base, s->pc - 4);
|
||||||
|
if (test != 0x4e71) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* "... and followed by an invalid sentinel instruction movec %sp,0." */
|
||||||
|
test = translator_ldl(s->env, &s->base, s->pc);
|
||||||
|
if (test != 0x4e7bf000) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Consume the sentinel. */
|
||||||
|
s->pc += 4;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif /* !CONFIG_USER_ONLY */
|
||||||
|
|
||||||
DISAS_INSN(scc)
|
DISAS_INSN(scc)
|
||||||
{
|
{
|
||||||
DisasCompare c;
|
DisasCompare c;
|
||||||
|
@ -4465,8 +4498,12 @@ DISAS_INSN(halt)
|
||||||
gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
|
gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (semihosting_test(s)) {
|
||||||
gen_exception(s, s->pc, EXCP_HALT_INSN);
|
gen_exception(s, s->pc, EXCP_SEMIHOSTING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tcg_gen_movi_i32(cpu_halted, 1);
|
||||||
|
gen_exception(s, s->pc, EXCP_HLT);
|
||||||
}
|
}
|
||||||
|
|
||||||
DISAS_INSN(stop)
|
DISAS_INSN(stop)
|
||||||
|
|
Loading…
Reference in New Issue