Skip to content

Commit f0ae989

Browse files
rth7680stephanosio
authored andcommitted
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 <[email protected]> Signed-off-by: Richard Henderson <[email protected]> Message-Id: <[email protected]> (cherry picked from commit 24ca313)
1 parent 5d18baa commit f0ae989

File tree

3 files changed

+23
-9
lines changed

3 files changed

+23
-9
lines changed

target/nios2/cpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ struct Nios2CPUClass {
133133

134134
/* Exceptions */
135135
#define EXCP_BREAK 0x1000
136+
#define EXCP_SEMIHOST 0x1001
136137
#define EXCP_RESET 0
137138
#define EXCP_PRESET 1
138139
#define EXCP_IRQ 2

target/nios2/helper.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,6 @@ void nios2_cpu_do_interrupt(CPUState *cs)
171171
case EXCP_BREAK:
172172
qemu_log_mask(CPU_LOG_INT, "BREAK exception at pc=%x\n",
173173
env->regs[R_PC]);
174-
/* The semihosting instruction is "break 1". */
175-
if (semihosting_enabled() &&
176-
cpu_ldl_code(env, env->regs[R_PC]) == 0x003da07a) {
177-
qemu_log_mask(CPU_LOG_INT, "Entering semihosting\n");
178-
env->regs[R_PC] += 4;
179-
do_nios2_semihosting(env);
180-
break;
181-
}
182174

183175
if ((env->regs[CR_STATUS] & CR_STATUS_EH) == 0) {
184176
env->regs[CR_BSTATUS] = env->regs[CR_STATUS];
@@ -194,6 +186,12 @@ void nios2_cpu_do_interrupt(CPUState *cs)
194186
env->regs[R_PC] = cpu->exception_addr;
195187
break;
196188

189+
case EXCP_SEMIHOST:
190+
qemu_log_mask(CPU_LOG_INT, "BREAK semihosting at pc=%x\n", env->regs[R_PC]);
191+
env->regs[R_PC] += 4;
192+
do_nios2_semihosting(env);
193+
break;
194+
197195
default:
198196
cpu_abort(cs, "unhandled exception type=%d\n",
199197
cs->exception_index);

target/nios2/translate.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "exec/translator.h"
3434
#include "qemu/qemu-print.h"
3535
#include "exec/gen-icount.h"
36+
#include "semihosting/semihost.h"
3637

3738
/* is_jmp field values */
3839
#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
@@ -644,6 +645,20 @@ static void trap(DisasContext *dc, uint32_t code, uint32_t flags)
644645
t_gen_helper_raise_exception(dc, EXCP_TRAP);
645646
}
646647

648+
static void gen_break(DisasContext *dc, uint32_t code, uint32_t flags)
649+
{
650+
#ifndef CONFIG_USER_ONLY
651+
/* The semihosting instruction is "break 1". */
652+
R_TYPE(instr, code);
653+
if (semihosting_enabled() && instr.imm5 == 1) {
654+
t_gen_helper_raise_exception(dc, EXCP_SEMIHOST);
655+
return;
656+
}
657+
#endif
658+
659+
t_gen_helper_raise_exception(dc, EXCP_BREAK);
660+
}
661+
647662
static const Nios2Instruction r_type_instructions[] = {
648663
INSTRUCTION_ILLEGAL(),
649664
INSTRUCTION(eret), /* eret */
@@ -697,7 +712,7 @@ static const Nios2Instruction r_type_instructions[] = {
697712
INSTRUCTION(add), /* add */
698713
INSTRUCTION_ILLEGAL(),
699714
INSTRUCTION_ILLEGAL(),
700-
INSTRUCTION_FLG(gen_excp, EXCP_BREAK), /* break */
715+
INSTRUCTION(gen_break), /* break */
701716
INSTRUCTION_ILLEGAL(),
702717
INSTRUCTION(nop), /* nop */
703718
INSTRUCTION_ILLEGAL(),

0 commit comments

Comments
 (0)