diff mbox series

[v4,27/33] target/nios2: Create EXCP_SEMIHOST for semi-hosting

Message ID 20220308072005.307955-28-richard.henderson@linaro.org
State New
Headers show
Series target/nios2: Shadow register set, EIC and VIC | expand

Commit Message

Richard Henderson March 8, 2022, 7:19 a.m. UTC
Decode 'break 1' during translation, rather than doing
it again during exception processing.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/nios2/cpu.h       |  1 +
 target/nios2/helper.c    | 15 ++++++---------
 target/nios2/translate.c | 17 ++++++++++++++++-
 3 files changed, 23 insertions(+), 10 deletions(-)

Comments

Peter Maydell March 8, 2022, 11:24 a.m. UTC | #1
On Tue, 8 Mar 2022 at 07:20, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Decode 'break 1' during translation, rather than doing
> it again during exception processing.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/nios2/cpu.h       |  1 +
>  target/nios2/helper.c    | 15 ++++++---------
>  target/nios2/translate.c | 17 ++++++++++++++++-
>  3 files changed, 23 insertions(+), 10 deletions(-)
>
> diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
> index c48daa5640..13e1d49f38 100644
> --- a/target/nios2/cpu.h
> +++ b/target/nios2/cpu.h
> @@ -162,6 +162,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
> diff --git a/target/nios2/helper.c b/target/nios2/helper.c
> index 007496b957..a338d02f6b 100644
> --- a/target/nios2/helper.c
> +++ b/target/nios2/helper.c
> @@ -146,17 +146,14 @@ 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);
> +        return;

Ah, here's the "return" I asked for in the earlier patch :-)

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM
diff mbox series

Patch

diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index c48daa5640..13e1d49f38 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -162,6 +162,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
diff --git a/target/nios2/helper.c b/target/nios2/helper.c
index 007496b957..a338d02f6b 100644
--- a/target/nios2/helper.c
+++ b/target/nios2/helper.c
@@ -146,17 +146,14 @@  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);
+        return;
+
     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->status & CR_STATUS_EH) == 0) {
             env->bstatus = env->status;
             nios2_crs(env)[R_BA] = env->pc + 4;
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 7730735639..f9b84e31d7 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -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 */
@@ -711,6 +712,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 */
@@ -764,7 +779,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(),