mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-14 17:07:24 +00:00
target/nios2: Create EXCP_SEMIHOST for semi-hosting
Decode 'break 1' during translation, rather than doing it again during exception processing. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220421151735.31996-32-richard.henderson@linaro.org>
This commit is contained in:
parent
bdb307b4d8
commit
24ca31346e
@ -156,6 +156,7 @@ FIELD(CR_TLBMISC, EE, 24, 1)
|
||||
|
||||
/* Exceptions */
|
||||
#define EXCP_BREAK 0x1000
|
||||
#define EXCP_SEMIHOST 0x1001
|
||||
#define EXCP_RESET 0
|
||||
#define EXCP_PRESET 1
|
||||
#define EXCP_IRQ 2
|
||||
|
@ -152,14 +152,6 @@ void nios2_cpu_do_interrupt(CPUState *cs)
|
||||
|
||||
case EXCP_BREAK:
|
||||
qemu_log_mask(CPU_LOG_INT, "BREAK exception at pc=%x\n", env->pc);
|
||||
/* The semihosting instruction is "break 1". */
|
||||
if (semihosting_enabled() &&
|
||||
cpu_ldl_code(env, env->pc) == 0x003da07a) {
|
||||
qemu_log_mask(CPU_LOG_INT, "Entering semihosting\n");
|
||||
env->pc += 4;
|
||||
do_nios2_semihosting(env);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((env->ctrl[CR_STATUS] & CR_STATUS_EH) == 0) {
|
||||
env->ctrl[CR_BSTATUS] = env->ctrl[CR_STATUS];
|
||||
@ -176,6 +168,12 @@ void nios2_cpu_do_interrupt(CPUState *cs)
|
||||
env->pc = cpu->exception_addr;
|
||||
break;
|
||||
|
||||
case EXCP_SEMIHOST:
|
||||
qemu_log_mask(CPU_LOG_INT, "BREAK semihosting at pc=%x\n", env->pc);
|
||||
env->pc += 4;
|
||||
do_nios2_semihosting(env);
|
||||
break;
|
||||
|
||||
default:
|
||||
cpu_abort(cs, "unhandled exception type=%d\n",
|
||||
cs->exception_index);
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "exec/translator.h"
|
||||
#include "qemu/qemu-print.h"
|
||||
#include "exec/gen-icount.h"
|
||||
#include "semihosting/semihost.h"
|
||||
|
||||
/* is_jmp field values */
|
||||
#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
|
||||
@ -686,6 +687,20 @@ static void trap(DisasContext *dc, uint32_t code, uint32_t flags)
|
||||
t_gen_helper_raise_exception(dc, EXCP_TRAP);
|
||||
}
|
||||
|
||||
static void gen_break(DisasContext *dc, uint32_t code, uint32_t flags)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
/* The semihosting instruction is "break 1". */
|
||||
R_TYPE(instr, code);
|
||||
if (semihosting_enabled() && instr.imm5 == 1) {
|
||||
t_gen_helper_raise_exception(dc, EXCP_SEMIHOST);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
t_gen_helper_raise_exception(dc, EXCP_BREAK);
|
||||
}
|
||||
|
||||
static const Nios2Instruction r_type_instructions[] = {
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
INSTRUCTION(eret), /* eret */
|
||||
@ -739,7 +754,7 @@ static const Nios2Instruction r_type_instructions[] = {
|
||||
INSTRUCTION(add), /* add */
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
INSTRUCTION_FLG(gen_excp, EXCP_BREAK), /* break */
|
||||
INSTRUCTION(gen_break), /* break */
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
INSTRUCTION(nop), /* nop */
|
||||
INSTRUCTION_ILLEGAL(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user