All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements
@ 2018-06-18 18:40 Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 01/22] target/openrisc: Remove DISAS_JUMP & DISAS_TB_JUMP Richard Henderson
                   ` (23 more replies)
  0 siblings, 24 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

This is almost a grab-bag of little improvements to the port.

patches 1-3:
  Fix singlestepping for gdbstub.  This has apparently never
  worked, as the first commit has the same bug of not advancing
  the pc when stepping.

patches 4:
  Link more TBs.

patches 5-6:
  Exit the TB after l.mtspr insns.  In particular, storing to
  SR changes exception state so we want to return to the main
  loop to recognize any pending interrupts immediately.

patches 8-18:
  Reorganize TLB handling.  There is a fundamental bug that is
  fixed in patch 13.  However the bug has been hidden by extra
  TLB flushing elsewhere in the port.  I remove some unnecessary
  indirection that the port inherited from somewhere -- probably
  the MIPS port.  Finally, I present the QEMU TLB a unified view
  of the OpenRISC split I/D TLB.

patch 19:
  Split out disassembly from translation.

patch 20:
  Add qemu-or1k to qemu-binfmt-conf.sh.

patches 21-22:
  Implement signal handling for linux-user.

Richard Henderson (22):
  target/openrisc: Remove DISAS_JUMP & DISAS_TB_JUMP
  target/openrisc: Use exit_tb instead of CPU_INTERRUPT_EXITTB
  target/openrisc: Fix singlestep_enabled
  target/openrisc: Link more translation blocks
  target/openrisc: Split out is_user
  target/openrisc: Exit the TB after l.mtspr
  target/openrisc: Form the spr index from tcg
  target/openrisc: Merge tlb allocation into CPUOpenRISCState
  target/openrisc: Remove indirect function calls for mmu
  target/openrisc: Merge mmu_helper.c into mmu.c
  target/openrisc: Reduce tlb to a single dimension
  target/openrisc: Fix tlb flushing in mtspr
  target/openrisc: Fix cpu_mmu_index
  target/openrisc: Use identical sizes for ITLB and DTLB
  target/openrisc: Stub out handle_mmu_fault for softmmu
  target/openrisc: Log interrupts
  target/openrisc: Increase the TLB size
  target/openrisc: Reorg tlb lookup
  target/openrisc: Add print_insn_or1k
  target/openrisc: Add support in scripts/qemu-binfmt-conf.sh
  linux-user: Implement signals for openrisc
  linux-user: Fix struct sigaltstack for openrisc

 linux-user/openrisc/target_signal.h  |   2 +-
 linux-user/openrisc/target_syscall.h |  28 +--
 target/openrisc/cpu.h                |  61 +++---
 target/openrisc/helper.h             |   4 +-
 linux-user/openrisc/signal.c         | 212 ++++++++-----------
 linux-user/signal.c                  |   2 +-
 target/openrisc/cpu.c                |  17 +-
 target/openrisc/disas.c              | 170 +++++++++++++++
 target/openrisc/interrupt.c          |  36 +++-
 target/openrisc/interrupt_helper.c   |  35 +---
 target/openrisc/machine.c            |  44 +---
 target/openrisc/mmu.c                | 275 +++++++++---------------
 target/openrisc/mmu_helper.c         |  40 ----
 target/openrisc/sys_helper.c         |  85 ++++----
 target/openrisc/translate.c          | 298 ++++++++++-----------------
 scripts/qemu-binfmt-conf.sh          |  10 +-
 target/openrisc/Makefile.objs        |   5 +-
 17 files changed, 589 insertions(+), 735 deletions(-)
 create mode 100644 target/openrisc/disas.c
 delete mode 100644 target/openrisc/mmu_helper.c

-- 
2.17.1

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 01/22] target/openrisc: Remove DISAS_JUMP & DISAS_TB_JUMP
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 02/22] target/openrisc: Use exit_tb instead of CPU_INTERRUPT_EXITTB Richard Henderson
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

These values are unused.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/translate.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index d69f8d0422..2d7588a3eb 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -41,9 +41,7 @@
                   ## __VA_ARGS__)
 
 /* is_jmp field values */
-#define DISAS_JUMP    DISAS_TARGET_0 /* only pc was modified dynamically */
 #define DISAS_UPDATE  DISAS_TARGET_1 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
 
 typedef struct DisasContext {
     DisasContextBase base;
@@ -1467,8 +1465,6 @@ static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
             gen_goto_tb(dc, 0, dc->base.pc_next);
             break;
         case DISAS_NORETURN:
-        case DISAS_JUMP:
-        case DISAS_TB_JUMP:
             break;
         case DISAS_UPDATE:
             /* indicate that the hash table must be used
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 02/22] target/openrisc: Use exit_tb instead of CPU_INTERRUPT_EXITTB
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 01/22] target/openrisc: Remove DISAS_JUMP & DISAS_TB_JUMP Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 03/22] target/openrisc: Fix singlestep_enabled Richard Henderson
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

No need to use the interrupt mechanisms when we can
simply exit the tb directly.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/interrupt_helper.c | 3 +--
 target/openrisc/translate.c        | 6 +++---
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/target/openrisc/interrupt_helper.c b/target/openrisc/interrupt_helper.c
index 56620e0571..b865738f8b 100644
--- a/target/openrisc/interrupt_helper.c
+++ b/target/openrisc/interrupt_helper.c
@@ -26,7 +26,6 @@
 void HELPER(rfe)(CPUOpenRISCState *env)
 {
     OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
 #ifndef CONFIG_USER_ONLY
     int need_flush_tlb = (cpu->env.sr & (SR_SM | SR_IME | SR_DME)) ^
                          (cpu->env.esr & (SR_SM | SR_IME | SR_DME));
@@ -53,8 +52,8 @@ void HELPER(rfe)(CPUOpenRISCState *env)
     }
 
     if (need_flush_tlb) {
+        CPUState *cs = CPU(cpu);
         tlb_flush(cs);
     }
 #endif
-    cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
 }
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 2d7588a3eb..c7c1f40782 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -41,6 +41,7 @@
                   ## __VA_ARGS__)
 
 /* is_jmp field values */
+#define DISAS_EXIT    DISAS_TARGET_0  /* force exit to main loop */
 #define DISAS_UPDATE  DISAS_TARGET_1 /* cpu state was modified dynamically */
 
 typedef struct DisasContext {
@@ -1233,7 +1234,7 @@ static bool trans_l_rfe(DisasContext *dc, arg_l_rfe *a, uint32_t insn)
         gen_illegal_exception(dc);
     } else {
         gen_helper_rfe(cpu_env);
-        dc->base.is_jmp = DISAS_UPDATE;
+        dc->base.is_jmp = DISAS_EXIT;
     }
 #endif
     return true;
@@ -1467,8 +1468,7 @@ static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
         case DISAS_NORETURN:
             break;
         case DISAS_UPDATE:
-            /* indicate that the hash table must be used
-               to find the next TB */
+        case DISAS_EXIT:
             tcg_gen_exit_tb(NULL, 0);
             break;
         default:
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 03/22] target/openrisc: Fix singlestep_enabled
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 01/22] target/openrisc: Remove DISAS_JUMP & DISAS_TB_JUMP Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 02/22] target/openrisc: Use exit_tb instead of CPU_INTERRUPT_EXITTB Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 04/22] target/openrisc: Link more translation blocks Richard Henderson
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

We failed to store to cpu_pc before raising the exception,
which caused us to re-execute the same insn that we stepped.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/translate.c | 35 +++++++++++++++++------------------
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index c7c1f40782..5c0c9dee09 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -1449,31 +1449,30 @@ static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
 {
     DisasContext *dc = container_of(dcbase, DisasContext, base);
 
+    /* If we have already exited the TB, nothing following has effect.  */
+    if (dc->base.is_jmp == DISAS_NORETURN) {
+        return;
+    }
+
     if ((dc->tb_flags & TB_FLAGS_DFLAG ? 1 : 0) != (dc->delayed_branch != 0)) {
         tcg_gen_movi_i32(cpu_dflag, dc->delayed_branch != 0);
     }
 
     tcg_gen_movi_tl(cpu_ppc, dc->base.pc_next - 4);
-    if (dc->base.is_jmp == DISAS_NEXT) {
-        dc->base.is_jmp = DISAS_UPDATE;
-        tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
-    }
-    if (unlikely(dc->base.singlestep_enabled)) {
-        gen_exception(dc, EXCP_DEBUG);
-    } else {
-        switch (dc->base.is_jmp) {
-        case DISAS_TOO_MANY:
-            gen_goto_tb(dc, 0, dc->base.pc_next);
-            break;
-        case DISAS_NORETURN:
-            break;
-        case DISAS_UPDATE:
-        case DISAS_EXIT:
+    switch (dc->base.is_jmp) {
+    case DISAS_TOO_MANY:
+        gen_goto_tb(dc, 0, dc->base.pc_next);
+        break;
+    case DISAS_UPDATE:
+    case DISAS_EXIT:
+        if (unlikely(dc->base.singlestep_enabled)) {
+            gen_exception(dc, EXCP_DEBUG);
+        } else {
             tcg_gen_exit_tb(NULL, 0);
-            break;
-        default:
-            g_assert_not_reached();
         }
+        break;
+    default:
+        g_assert_not_reached();
     }
 }
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 04/22] target/openrisc: Link more translation blocks
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (2 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 03/22] target/openrisc: Fix singlestep_enabled Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 05/22] target/openrisc: Split out is_user Richard Henderson
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Track direct jumps via dc->jmp_pc_imm.  Use that in
preference to jmp_pc when possible.  Emit goto_tb in
that case, and lookup_and_goto_tb otherwise.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/translate.c | 82 +++++++++++++++++++++----------------
 1 file changed, 46 insertions(+), 36 deletions(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 5c0c9dee09..422f22d7f8 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -42,13 +42,16 @@
 
 /* is_jmp field values */
 #define DISAS_EXIT    DISAS_TARGET_0  /* force exit to main loop */
-#define DISAS_UPDATE  DISAS_TARGET_1 /* cpu state was modified dynamically */
+#define DISAS_JUMP    DISAS_TARGET_1  /* exit via jmp_pc/jmp_pc_imm */
 
 typedef struct DisasContext {
     DisasContextBase base;
     uint32_t mem_idx;
     uint32_t tb_flags;
     uint32_t delayed_branch;
+
+    /* If not -1, jmp_pc contains this value and so is a direct jump.  */
+    target_ulong jmp_pc_imm;
 } DisasContext;
 
 /* Include the auto-generated decoder.  */
@@ -164,34 +167,6 @@ static void check_ov64s(DisasContext *dc)
         }                               \
     } while (0)
 
-static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
-{
-    if (unlikely(dc->base.singlestep_enabled)) {
-        return false;
-    }
-
-#ifndef CONFIG_USER_ONLY
-    return (dc->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
-
-static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
-{
-    if (use_goto_tb(dc, dest)) {
-        tcg_gen_movi_tl(cpu_pc, dest);
-        tcg_gen_goto_tb(n);
-        tcg_gen_exit_tb(dc->base.tb, n);
-    } else {
-        tcg_gen_movi_tl(cpu_pc, dest);
-        if (dc->base.singlestep_enabled) {
-            gen_exception(dc, EXCP_DEBUG);
-        }
-        tcg_gen_exit_tb(NULL, 0);
-    }
-}
-
 static void gen_ove_cy(DisasContext *dc)
 {
     if (dc->tb_flags & SR_OVE) {
@@ -655,6 +630,7 @@ static bool trans_l_j(DisasContext *dc, arg_l_j *a, uint32_t insn)
 
     LOG_DIS("l.j %d\n", a->n);
     tcg_gen_movi_tl(jmp_pc, tmp_pc);
+    dc->jmp_pc_imm = tmp_pc;
     dc->delayed_branch = 2;
     return true;
 }
@@ -669,6 +645,7 @@ static bool trans_l_jal(DisasContext *dc, arg_l_jal *a, uint32_t insn)
     /* Optimize jal being used to load the PC for PIC.  */
     if (tmp_pc != ret_pc) {
         tcg_gen_movi_tl(jmp_pc, tmp_pc);
+        dc->jmp_pc_imm = tmp_pc;
         dc->delayed_branch = 2;
     }
     return true;
@@ -1381,6 +1358,8 @@ static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
     dc->mem_idx = cpu_mmu_index(env, false);
     dc->tb_flags = dc->base.tb->flags;
     dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0;
+    dc->jmp_pc_imm = -1;
+
     bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
     dc->base.max_insns = MIN(dc->base.max_insns, bound);
 }
@@ -1437,10 +1416,7 @@ static void openrisc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
     if (dc->delayed_branch) {
         dc->delayed_branch--;
         if (!dc->delayed_branch) {
-            tcg_gen_mov_tl(cpu_pc, jmp_pc);
-            tcg_gen_discard_tl(jmp_pc);
-            dc->base.is_jmp = DISAS_UPDATE;
-            return;
+            dc->base.is_jmp = DISAS_JUMP;
         }
     }
 }
@@ -1448,22 +1424,56 @@ static void openrisc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
 static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
 {
     DisasContext *dc = container_of(dcbase, DisasContext, base);
+    target_ulong jmp_dest;
 
     /* If we have already exited the TB, nothing following has effect.  */
     if (dc->base.is_jmp == DISAS_NORETURN) {
         return;
     }
 
+    /* Adjust the delayed branch state for the next TB.  */
     if ((dc->tb_flags & TB_FLAGS_DFLAG ? 1 : 0) != (dc->delayed_branch != 0)) {
         tcg_gen_movi_i32(cpu_dflag, dc->delayed_branch != 0);
     }
 
-    tcg_gen_movi_tl(cpu_ppc, dc->base.pc_next - 4);
+    /* For DISAS_TOO_MANY, jump to the next insn.  */
+    jmp_dest = dc->base.pc_next;
+    tcg_gen_movi_tl(cpu_ppc, jmp_dest - 4);
+
     switch (dc->base.is_jmp) {
+    case DISAS_JUMP:
+        jmp_dest = dc->jmp_pc_imm;
+        if (jmp_dest == -1) {
+            /* The jump destination is indirect/computed; use jmp_pc.  */
+            tcg_gen_mov_tl(cpu_pc, jmp_pc);
+            tcg_gen_discard_tl(jmp_pc);
+            if (unlikely(dc->base.singlestep_enabled)) {
+                gen_exception(dc, EXCP_DEBUG);
+            } else {
+                tcg_gen_lookup_and_goto_ptr();
+            }
+            break;
+        }
+        /* The jump destination is direct; use jmp_pc_imm.
+           However, we will have stored into jmp_pc as well;
+           we know now that it wasn't needed.  */
+        tcg_gen_discard_tl(jmp_pc);
+        /* fallthru */
+
     case DISAS_TOO_MANY:
-        gen_goto_tb(dc, 0, dc->base.pc_next);
+        if (unlikely(dc->base.singlestep_enabled)) {
+            tcg_gen_movi_tl(cpu_pc, jmp_dest);
+            gen_exception(dc, EXCP_DEBUG);
+        } else if ((dc->base.pc_first ^ jmp_dest) & TARGET_PAGE_MASK) {
+            tcg_gen_movi_tl(cpu_pc, jmp_dest);
+            tcg_gen_lookup_and_goto_ptr();
+        } else {
+            tcg_gen_goto_tb(0);
+            tcg_gen_movi_tl(cpu_pc, jmp_dest);
+            tcg_gen_exit_tb(dc->base.tb, 0);
+        }
         break;
-    case DISAS_UPDATE:
+
     case DISAS_EXIT:
         if (unlikely(dc->base.singlestep_enabled)) {
             gen_exception(dc, EXCP_DEBUG);
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 05/22] target/openrisc: Split out is_user
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (3 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 04/22] target/openrisc: Link more translation blocks Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 06/22] target/openrisc: Exit the TB after l.mtspr Richard Henderson
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

This allows us to limit the amount of ifdefs and isolate
the test for usermode.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/translate.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 422f22d7f8..16e69c75fa 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -54,6 +54,15 @@ typedef struct DisasContext {
     target_ulong jmp_pc_imm;
 } DisasContext;
 
+static inline bool is_user(DisasContext *dc)
+{
+#ifdef CONFIG_USER_ONLY
+    return true;
+#else
+    return dc->mem_idx == MMU_USER_IDX;
+#endif
+}
+
 /* Include the auto-generated decoder.  */
 #include "decode.inc.c"
 
@@ -914,17 +923,13 @@ static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a, uint32_t insn)
     LOG_DIS("l.mfspr r%d, r%d, %d\n", a->d, a->a, a->k);
     check_r0_write(a->d);
 
-#ifdef CONFIG_USER_ONLY
-    gen_illegal_exception(dc);
-#else
-    if (dc->mem_idx == MMU_USER_IDX) {
+    if (is_user(dc)) {
         gen_illegal_exception(dc);
     } else {
         TCGv_i32 ti = tcg_const_i32(a->k);
         gen_helper_mfspr(cpu_R[a->d], cpu_env, cpu_R[a->d], cpu_R[a->a], ti);
         tcg_temp_free_i32(ti);
     }
-#endif
     return true;
 }
 
@@ -932,17 +937,13 @@ static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a, uint32_t insn)
 {
     LOG_DIS("l.mtspr r%d, r%d, %d\n", a->a, a->b, a->k);
 
-#ifdef CONFIG_USER_ONLY
-    gen_illegal_exception(dc);
-#else
-    if (dc->mem_idx == MMU_USER_IDX) {
+    if (is_user(dc)) {
         gen_illegal_exception(dc);
     } else {
         TCGv_i32 ti = tcg_const_i32(a->k);
         gen_helper_mtspr(cpu_env, cpu_R[a->a], cpu_R[a->b], ti);
         tcg_temp_free_i32(ti);
     }
-#endif
     return true;
 }
 
@@ -1204,16 +1205,12 @@ static bool trans_l_rfe(DisasContext *dc, arg_l_rfe *a, uint32_t insn)
 {
     LOG_DIS("l.rfe\n");
 
-#ifdef CONFIG_USER_ONLY
-    gen_illegal_exception(dc);
-#else
-    if (dc->mem_idx == MMU_USER_IDX) {
+    if (is_user(dc)) {
         gen_illegal_exception(dc);
     } else {
         gen_helper_rfe(cpu_env);
         dc->base.is_jmp = DISAS_EXIT;
     }
-#endif
     return true;
 }
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 06/22] target/openrisc: Exit the TB after l.mtspr
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (4 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 05/22] target/openrisc: Split out is_user Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 07/22] target/openrisc: Form the spr index from tcg Richard Henderson
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

A store to SR changes interrupt state, which should return
to the main loop to recognize that state.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/translate.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 16e69c75fa..6a7eb4a3e8 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -940,9 +940,31 @@ static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a, uint32_t insn)
     if (is_user(dc)) {
         gen_illegal_exception(dc);
     } else {
-        TCGv_i32 ti = tcg_const_i32(a->k);
+        TCGv_i32 ti;
+
+        /* For SR, we will need to exit the TB to recognize the new
+         * exception state.  For NPC, in theory this counts as a branch
+         * (although the SPR only exists for use by an ICE).  Save all
+         * of the cpu state first, allowing it to be overwritten.
+         */
+        if (dc->tb_flags & TB_FLAGS_DFLAG) {
+            tcg_gen_movi_i32(cpu_dflag, 0);
+        }
+        tcg_gen_movi_tl(cpu_ppc, dc->base.pc_next);
+        tcg_gen_movi_tl(cpu_pc, dc->base.pc_next + 4);
+
+        ti = tcg_const_i32(a->k);
         gen_helper_mtspr(cpu_env, cpu_R[a->a], cpu_R[a->b], ti);
         tcg_temp_free_i32(ti);
+
+        /* For PPC, we want the value that was just written and not
+           the generic update that we'd get from DISAS_EXIT.  */
+        if (unlikely(dc->base.singlestep_enabled)) {
+            gen_exception(dc, EXCP_DEBUG);
+        } else {
+            tcg_gen_exit_tb(NULL, 0);
+        }
+        dc->base.is_jmp = DISAS_NORETURN;
     }
     return true;
 }
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 07/22] target/openrisc: Form the spr index from tcg
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (5 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 06/22] target/openrisc: Exit the TB after l.mtspr Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 08/22] target/openrisc: Merge tlb allocation into CPUOpenRISCState Richard Henderson
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Rather than pass base+offset to the helper, pass the full index.
In most cases the base is r0 and optimization yields a constant.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/helper.h     |  4 ++--
 target/openrisc/sys_helper.c |  9 +++------
 target/openrisc/translate.c  | 16 +++++++++-------
 3 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/target/openrisc/helper.h b/target/openrisc/helper.h
index e37dabc77a..9db9bf3963 100644
--- a/target/openrisc/helper.h
+++ b/target/openrisc/helper.h
@@ -56,5 +56,5 @@ FOP_CMP(le)
 DEF_HELPER_FLAGS_1(rfe, 0, void, env)
 
 /* sys */
-DEF_HELPER_FLAGS_4(mtspr, 0, void, env, tl, tl, tl)
-DEF_HELPER_FLAGS_4(mfspr, TCG_CALL_NO_WG, tl, env, tl, tl, tl)
+DEF_HELPER_FLAGS_3(mtspr, 0, void, env, tl, tl)
+DEF_HELPER_FLAGS_3(mfspr, TCG_CALL_NO_WG, tl, env, tl, tl)
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index b284064381..a8d287d6ef 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -27,13 +27,11 @@
 
 #define TO_SPR(group, number) (((group) << 11) + (number))
 
-void HELPER(mtspr)(CPUOpenRISCState *env,
-                   target_ulong ra, target_ulong rb, target_ulong offset)
+void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
 {
 #ifndef CONFIG_USER_ONLY
     OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
     CPUState *cs = CPU(cpu);
-    int spr = (ra | offset);
     int idx;
 
     switch (spr) {
@@ -201,13 +199,12 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
 #endif
 }
 
-target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
-                           target_ulong rd, target_ulong ra, uint32_t offset)
+target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
+                           target_ulong spr)
 {
 #ifndef CONFIG_USER_ONLY
     OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
     CPUState *cs = CPU(cpu);
-    int spr = (ra | offset);
     int idx;
 
     switch (spr) {
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 6a7eb4a3e8..f19f0d257b 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -926,9 +926,10 @@ static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a, uint32_t insn)
     if (is_user(dc)) {
         gen_illegal_exception(dc);
     } else {
-        TCGv_i32 ti = tcg_const_i32(a->k);
-        gen_helper_mfspr(cpu_R[a->d], cpu_env, cpu_R[a->d], cpu_R[a->a], ti);
-        tcg_temp_free_i32(ti);
+        TCGv spr = tcg_temp_new();
+        tcg_gen_ori_tl(spr, cpu_R[a->a], a->k);
+        gen_helper_mfspr(cpu_R[a->d], cpu_env, cpu_R[a->d], spr);
+        tcg_temp_free(spr);
     }
     return true;
 }
@@ -940,7 +941,7 @@ static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a, uint32_t insn)
     if (is_user(dc)) {
         gen_illegal_exception(dc);
     } else {
-        TCGv_i32 ti;
+        TCGv spr;
 
         /* For SR, we will need to exit the TB to recognize the new
          * exception state.  For NPC, in theory this counts as a branch
@@ -953,9 +954,10 @@ static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a, uint32_t insn)
         tcg_gen_movi_tl(cpu_ppc, dc->base.pc_next);
         tcg_gen_movi_tl(cpu_pc, dc->base.pc_next + 4);
 
-        ti = tcg_const_i32(a->k);
-        gen_helper_mtspr(cpu_env, cpu_R[a->a], cpu_R[a->b], ti);
-        tcg_temp_free_i32(ti);
+        spr = tcg_temp_new();
+        tcg_gen_ori_tl(spr, cpu_R[a->a], a->k);
+        gen_helper_mtspr(cpu_env, spr, cpu_R[a->b]);
+        tcg_temp_free(spr);
 
         /* For PPC, we want the value that was just written and not
            the generic update that we'd get from DISAS_EXIT.  */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 08/22] target/openrisc: Merge tlb allocation into CPUOpenRISCState
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (6 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 07/22] target/openrisc: Form the spr index from tcg Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 09/22] target/openrisc: Remove indirect function calls for mmu Richard Henderson
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

There is no reason to allocate this separately.  This was probably
copied from target/mips which makes the same mistake.

While doing so, move tlb into the clear-on-reset range.  While not
all of the TLB bits are guaranteed zero on reset, all of the valid
bits are cleared, and the rest of the bits are unspecified.
Therefore clearing the whole of the TLB is correct.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/cpu.h              |  6 ++++--
 target/openrisc/interrupt.c        |  4 ++--
 target/openrisc/interrupt_helper.c |  8 +++----
 target/openrisc/machine.c          | 15 ++++++-------
 target/openrisc/mmu.c              | 34 ++++++++++++++----------------
 target/openrisc/sys_helper.c       | 28 ++++++++++++------------
 6 files changed, 46 insertions(+), 49 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 35cab65f11..edc06be40e 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -301,6 +301,10 @@ typedef struct CPUOpenRISCState {
 
     uint32_t dflag;           /* In delay slot (boolean) */
 
+#ifndef CONFIG_USER_ONLY
+    CPUOpenRISCTLBContext tlb;
+#endif
+
     /* Fields up to this point are cleared by a CPU reset */
     struct {} end_reset_fields;
 
@@ -310,8 +314,6 @@ typedef struct CPUOpenRISCState {
     uint32_t cpucfgr;         /* CPU configure register */
 
 #ifndef CONFIG_USER_ONLY
-    CPUOpenRISCTLBContext * tlb;
-
     QEMUTimer *timer;
     uint32_t ttmr;          /* Timer tick mode register */
     int is_counting;
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index 3959671c59..8b8b14ace0 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -62,8 +62,8 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
     env->sr &= ~SR_TEE;
     env->pmr &= ~PMR_DME;
     env->pmr &= ~PMR_SME;
-    env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
-    env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
+    env->tlb.cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
+    env->tlb.cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
     env->lock_addr = -1;
 
     if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) {
diff --git a/target/openrisc/interrupt_helper.c b/target/openrisc/interrupt_helper.c
index b865738f8b..dc97b38704 100644
--- a/target/openrisc/interrupt_helper.c
+++ b/target/openrisc/interrupt_helper.c
@@ -36,18 +36,18 @@ void HELPER(rfe)(CPUOpenRISCState *env)
 
 #ifndef CONFIG_USER_ONLY
     if (cpu->env.sr & SR_DME) {
-        cpu->env.tlb->cpu_openrisc_map_address_data =
+        cpu->env.tlb.cpu_openrisc_map_address_data =
             &cpu_openrisc_get_phys_data;
     } else {
-        cpu->env.tlb->cpu_openrisc_map_address_data =
+        cpu->env.tlb.cpu_openrisc_map_address_data =
             &cpu_openrisc_get_phys_nommu;
     }
 
     if (cpu->env.sr & SR_IME) {
-        cpu->env.tlb->cpu_openrisc_map_address_code =
+        cpu->env.tlb.cpu_openrisc_map_address_code =
             &cpu_openrisc_get_phys_code;
     } else {
-        cpu->env.tlb->cpu_openrisc_map_address_code =
+        cpu->env.tlb.cpu_openrisc_map_address_code =
             &cpu_openrisc_get_phys_nommu;
     }
 
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index 0a793eb14d..c10d28b055 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -30,18 +30,18 @@ static int env_post_load(void *opaque, int version_id)
 
     /* Restore MMU handlers */
     if (env->sr & SR_DME) {
-        env->tlb->cpu_openrisc_map_address_data =
+        env->tlb.cpu_openrisc_map_address_data =
             &cpu_openrisc_get_phys_data;
     } else {
-        env->tlb->cpu_openrisc_map_address_data =
+        env->tlb.cpu_openrisc_map_address_data =
             &cpu_openrisc_get_phys_nommu;
     }
 
     if (env->sr & SR_IME) {
-        env->tlb->cpu_openrisc_map_address_code =
+        env->tlb.cpu_openrisc_map_address_code =
             &cpu_openrisc_get_phys_code;
     } else {
-        env->tlb->cpu_openrisc_map_address_code =
+        env->tlb.cpu_openrisc_map_address_code =
             &cpu_openrisc_get_phys_nommu;
     }
 
@@ -77,10 +77,6 @@ static const VMStateDescription vmstate_cpu_tlb = {
     }
 };
 
-#define VMSTATE_CPU_TLB(_f, _s)                             \
-    VMSTATE_STRUCT_POINTER(_f, _s, vmstate_cpu_tlb, CPUOpenRISCTLBContext)
-
-
 static int get_sr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
 {
     CPUOpenRISCState *env = opaque;
@@ -143,7 +139,8 @@ static const VMStateDescription vmstate_env = {
         VMSTATE_UINT32(fpcsr, CPUOpenRISCState),
         VMSTATE_UINT64(mac, CPUOpenRISCState),
 
-        VMSTATE_CPU_TLB(tlb, CPUOpenRISCState),
+        VMSTATE_STRUCT(tlb, CPUOpenRISCState, 1,
+                       vmstate_cpu_tlb, CPUOpenRISCTLBContext),
 
         VMSTATE_TIMER_PTR(timer, CPUOpenRISCState),
         VMSTATE_UINT32(ttmr, CPUOpenRISCState),
diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c
index 2bd782f89b..5665bb7cc9 100644
--- a/target/openrisc/mmu.c
+++ b/target/openrisc/mmu.c
@@ -46,19 +46,19 @@ int cpu_openrisc_get_phys_code(OpenRISCCPU *cpu,
     int idx = vpn & ITLB_MASK;
     int right = 0;
 
-    if ((cpu->env.tlb->itlb[0][idx].mr >> TARGET_PAGE_BITS) != vpn) {
+    if ((cpu->env.tlb.itlb[0][idx].mr >> TARGET_PAGE_BITS) != vpn) {
         return TLBRET_NOMATCH;
     }
-    if (!(cpu->env.tlb->itlb[0][idx].mr & 1)) {
+    if (!(cpu->env.tlb.itlb[0][idx].mr & 1)) {
         return TLBRET_INVALID;
     }
 
     if (cpu->env.sr & SR_SM) { /* supervisor mode */
-        if (cpu->env.tlb->itlb[0][idx].tr & SXE) {
+        if (cpu->env.tlb.itlb[0][idx].tr & SXE) {
             right |= PAGE_EXEC;
         }
     } else {
-        if (cpu->env.tlb->itlb[0][idx].tr & UXE) {
+        if (cpu->env.tlb.itlb[0][idx].tr & UXE) {
             right |= PAGE_EXEC;
         }
     }
@@ -67,7 +67,7 @@ int cpu_openrisc_get_phys_code(OpenRISCCPU *cpu,
         return TLBRET_BADADDR;
     }
 
-    *physical = (cpu->env.tlb->itlb[0][idx].tr & TARGET_PAGE_MASK) |
+    *physical = (cpu->env.tlb.itlb[0][idx].tr & TARGET_PAGE_MASK) |
                 (address & (TARGET_PAGE_SIZE-1));
     *prot = right;
     return TLBRET_MATCH;
@@ -81,25 +81,25 @@ int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,
     int idx = vpn & DTLB_MASK;
     int right = 0;
 
-    if ((cpu->env.tlb->dtlb[0][idx].mr >> TARGET_PAGE_BITS) != vpn) {
+    if ((cpu->env.tlb.dtlb[0][idx].mr >> TARGET_PAGE_BITS) != vpn) {
         return TLBRET_NOMATCH;
     }
-    if (!(cpu->env.tlb->dtlb[0][idx].mr & 1)) {
+    if (!(cpu->env.tlb.dtlb[0][idx].mr & 1)) {
         return TLBRET_INVALID;
     }
 
     if (cpu->env.sr & SR_SM) { /* supervisor mode */
-        if (cpu->env.tlb->dtlb[0][idx].tr & SRE) {
+        if (cpu->env.tlb.dtlb[0][idx].tr & SRE) {
             right |= PAGE_READ;
         }
-        if (cpu->env.tlb->dtlb[0][idx].tr & SWE) {
+        if (cpu->env.tlb.dtlb[0][idx].tr & SWE) {
             right |= PAGE_WRITE;
         }
     } else {
-        if (cpu->env.tlb->dtlb[0][idx].tr & URE) {
+        if (cpu->env.tlb.dtlb[0][idx].tr & URE) {
             right |= PAGE_READ;
         }
-        if (cpu->env.tlb->dtlb[0][idx].tr & UWE) {
+        if (cpu->env.tlb.dtlb[0][idx].tr & UWE) {
             right |= PAGE_WRITE;
         }
     }
@@ -111,7 +111,7 @@ int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,
         return TLBRET_BADADDR;
     }
 
-    *physical = (cpu->env.tlb->dtlb[0][idx].tr & TARGET_PAGE_MASK) |
+    *physical = (cpu->env.tlb.dtlb[0][idx].tr & TARGET_PAGE_MASK) |
                 (address & (TARGET_PAGE_SIZE-1));
     *prot = right;
     return TLBRET_MATCH;
@@ -126,10 +126,10 @@ static int cpu_openrisc_get_phys_addr(OpenRISCCPU *cpu,
 
     if (rw == MMU_INST_FETCH) {    /* ITLB */
        *physical = 0;
-        ret = cpu->env.tlb->cpu_openrisc_map_address_code(cpu, physical,
+        ret = cpu->env.tlb.cpu_openrisc_map_address_code(cpu, physical,
                                                           prot, address, rw);
     } else {          /* DTLB */
-        ret = cpu->env.tlb->cpu_openrisc_map_address_data(cpu, physical,
+        ret = cpu->env.tlb.cpu_openrisc_map_address_data(cpu, physical,
                                                           prot, address, rw);
     }
 
@@ -247,9 +247,7 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 
 void cpu_openrisc_mmu_init(OpenRISCCPU *cpu)
 {
-    cpu->env.tlb = g_malloc0(sizeof(CPUOpenRISCTLBContext));
-
-    cpu->env.tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
-    cpu->env.tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
+    cpu->env.tlb.cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
+    cpu->env.tlb.cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
 }
 #endif
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index a8d287d6ef..f26c688df6 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -61,18 +61,18 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
         }
         cpu_set_sr(env, rb);
         if (env->sr & SR_DME) {
-            env->tlb->cpu_openrisc_map_address_data =
+            env->tlb.cpu_openrisc_map_address_data =
                 &cpu_openrisc_get_phys_data;
         } else {
-            env->tlb->cpu_openrisc_map_address_data =
+            env->tlb.cpu_openrisc_map_address_data =
                 &cpu_openrisc_get_phys_nommu;
         }
 
         if (env->sr & SR_IME) {
-            env->tlb->cpu_openrisc_map_address_code =
+            env->tlb.cpu_openrisc_map_address_code =
                 &cpu_openrisc_get_phys_code;
         } else {
-            env->tlb->cpu_openrisc_map_address_code =
+            env->tlb.cpu_openrisc_map_address_code =
                 &cpu_openrisc_get_phys_nommu;
         }
         break;
@@ -100,14 +100,14 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
     case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
         idx = spr - TO_SPR(1, 512);
         if (!(rb & 1)) {
-            tlb_flush_page(cs, env->tlb->dtlb[0][idx].mr & TARGET_PAGE_MASK);
+            tlb_flush_page(cs, env->tlb.dtlb[0][idx].mr & TARGET_PAGE_MASK);
         }
-        env->tlb->dtlb[0][idx].mr = rb;
+        env->tlb.dtlb[0][idx].mr = rb;
         break;
 
     case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */
         idx = spr - TO_SPR(1, 640);
-        env->tlb->dtlb[0][idx].tr = rb;
+        env->tlb.dtlb[0][idx].tr = rb;
         break;
     case TO_SPR(1, 768) ... TO_SPR(1, 895):   /* DTLBW1MR 0-127 */
     case TO_SPR(1, 896) ... TO_SPR(1, 1023):  /* DTLBW1TR 0-127 */
@@ -119,14 +119,14 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
     case TO_SPR(2, 512) ... TO_SPR(2, 512+ITLB_SIZE-1):   /* ITLBW0MR 0-127 */
         idx = spr - TO_SPR(2, 512);
         if (!(rb & 1)) {
-            tlb_flush_page(cs, env->tlb->itlb[0][idx].mr & TARGET_PAGE_MASK);
+            tlb_flush_page(cs, env->tlb.itlb[0][idx].mr & TARGET_PAGE_MASK);
         }
-        env->tlb->itlb[0][idx].mr = rb;
+        env->tlb.itlb[0][idx].mr = rb;
         break;
 
     case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */
         idx = spr - TO_SPR(2, 640);
-        env->tlb->itlb[0][idx].tr = rb;
+        env->tlb.itlb[0][idx].tr = rb;
         break;
     case TO_SPR(2, 768) ... TO_SPR(2, 895):   /* ITLBW1MR 0-127 */
     case TO_SPR(2, 896) ... TO_SPR(2, 1023):  /* ITLBW1TR 0-127 */
@@ -258,11 +258,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
 
     case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
         idx = spr - TO_SPR(1, 512);
-        return env->tlb->dtlb[0][idx].mr;
+        return env->tlb.dtlb[0][idx].mr;
 
     case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */
         idx = spr - TO_SPR(1, 640);
-        return env->tlb->dtlb[0][idx].tr;
+        return env->tlb.dtlb[0][idx].tr;
 
     case TO_SPR(1, 768) ... TO_SPR(1, 895):   /* DTLBW1MR 0-127 */
     case TO_SPR(1, 896) ... TO_SPR(1, 1023):  /* DTLBW1TR 0-127 */
@@ -274,11 +274,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
 
     case TO_SPR(2, 512) ... TO_SPR(2, 512+ITLB_SIZE-1): /* ITLBW0MR 0-127 */
         idx = spr - TO_SPR(2, 512);
-        return env->tlb->itlb[0][idx].mr;
+        return env->tlb.itlb[0][idx].mr;
 
     case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */
         idx = spr - TO_SPR(2, 640);
-        return env->tlb->itlb[0][idx].tr;
+        return env->tlb.itlb[0][idx].tr;
 
     case TO_SPR(2, 768) ... TO_SPR(2, 895):   /* ITLBW1MR 0-127 */
     case TO_SPR(2, 896) ... TO_SPR(2, 1023):  /* ITLBW1TR 0-127 */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 09/22] target/openrisc: Remove indirect function calls for mmu
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (7 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 08/22] target/openrisc: Merge tlb allocation into CPUOpenRISCState Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 10/22] target/openrisc: Merge mmu_helper.c into mmu.c Richard Henderson
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

There is no reason to use an indirect branch instead
of simply testing the SR bits that control mmu state.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/cpu.h              | 11 -----
 target/openrisc/cpu.c              |  4 --
 target/openrisc/interrupt.c        |  2 -
 target/openrisc/interrupt_helper.c | 25 ++---------
 target/openrisc/machine.c          | 26 ------------
 target/openrisc/mmu.c              | 66 +++++++++++++-----------------
 target/openrisc/sys_helper.c       | 15 -------
 7 files changed, 31 insertions(+), 118 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index edc06be40e..13107058cb 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -378,17 +378,6 @@ void cpu_openrisc_count_update(OpenRISCCPU *cpu);
 void cpu_openrisc_timer_update(OpenRISCCPU *cpu);
 void cpu_openrisc_count_start(OpenRISCCPU *cpu);
 void cpu_openrisc_count_stop(OpenRISCCPU *cpu);
-
-void cpu_openrisc_mmu_init(OpenRISCCPU *cpu);
-int cpu_openrisc_get_phys_nommu(OpenRISCCPU *cpu,
-                                hwaddr *physical,
-                                int *prot, target_ulong address, int rw);
-int cpu_openrisc_get_phys_code(OpenRISCCPU *cpu,
-                               hwaddr *physical,
-                               int *prot, target_ulong address, int rw);
-int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,
-                               hwaddr *physical,
-                               int *prot, target_ulong address, int rw);
 #endif
 
 #define OPENRISC_CPU_TYPE_SUFFIX "-" TYPE_OPENRISC_CPU
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index a692a98ec0..4c166c6329 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -87,10 +87,6 @@ static void openrisc_cpu_initfn(Object *obj)
     OpenRISCCPU *cpu = OPENRISC_CPU(obj);
 
     cs->env_ptr = &cpu->env;
-
-#ifndef CONFIG_USER_ONLY
-    cpu_openrisc_mmu_init(cpu);
-#endif
 }
 
 /* CPU models */
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index 8b8b14ace0..d9cb363fea 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -62,8 +62,6 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
     env->sr &= ~SR_TEE;
     env->pmr &= ~PMR_DME;
     env->pmr &= ~PMR_SME;
-    env->tlb.cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
-    env->tlb.cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
     env->lock_addr = -1;
 
     if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) {
diff --git a/target/openrisc/interrupt_helper.c b/target/openrisc/interrupt_helper.c
index dc97b38704..a2e9003969 100644
--- a/target/openrisc/interrupt_helper.c
+++ b/target/openrisc/interrupt_helper.c
@@ -29,31 +29,12 @@ void HELPER(rfe)(CPUOpenRISCState *env)
 #ifndef CONFIG_USER_ONLY
     int need_flush_tlb = (cpu->env.sr & (SR_SM | SR_IME | SR_DME)) ^
                          (cpu->env.esr & (SR_SM | SR_IME | SR_DME));
-#endif
-    cpu->env.pc = cpu->env.epcr;
-    cpu_set_sr(&cpu->env, cpu->env.esr);
-    cpu->env.lock_addr = -1;
-
-#ifndef CONFIG_USER_ONLY
-    if (cpu->env.sr & SR_DME) {
-        cpu->env.tlb.cpu_openrisc_map_address_data =
-            &cpu_openrisc_get_phys_data;
-    } else {
-        cpu->env.tlb.cpu_openrisc_map_address_data =
-            &cpu_openrisc_get_phys_nommu;
-    }
-
-    if (cpu->env.sr & SR_IME) {
-        cpu->env.tlb.cpu_openrisc_map_address_code =
-            &cpu_openrisc_get_phys_code;
-    } else {
-        cpu->env.tlb.cpu_openrisc_map_address_code =
-            &cpu_openrisc_get_phys_nommu;
-    }
-
     if (need_flush_tlb) {
         CPUState *cs = CPU(cpu);
         tlb_flush(cs);
     }
 #endif
+    cpu->env.pc = cpu->env.epcr;
+    cpu->env.lock_addr = -1;
+    cpu_set_sr(&cpu->env, cpu->env.esr);
 }
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index c10d28b055..73e0abcfd7 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -24,31 +24,6 @@
 #include "hw/boards.h"
 #include "migration/cpu.h"
 
-static int env_post_load(void *opaque, int version_id)
-{
-    CPUOpenRISCState *env = opaque;
-
-    /* Restore MMU handlers */
-    if (env->sr & SR_DME) {
-        env->tlb.cpu_openrisc_map_address_data =
-            &cpu_openrisc_get_phys_data;
-    } else {
-        env->tlb.cpu_openrisc_map_address_data =
-            &cpu_openrisc_get_phys_nommu;
-    }
-
-    if (env->sr & SR_IME) {
-        env->tlb.cpu_openrisc_map_address_code =
-            &cpu_openrisc_get_phys_code;
-    } else {
-        env->tlb.cpu_openrisc_map_address_code =
-            &cpu_openrisc_get_phys_nommu;
-    }
-
-
-    return 0;
-}
-
 static const VMStateDescription vmstate_tlb_entry = {
     .name = "tlb_entry",
     .version_id = 1,
@@ -102,7 +77,6 @@ static const VMStateDescription vmstate_env = {
     .name = "env",
     .version_id = 6,
     .minimum_version_id = 6,
-    .post_load = env_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_UINTTL_2DARRAY(shadow_gpr, CPUOpenRISCState, 16, 32),
         VMSTATE_UINTTL(pc, CPUOpenRISCState),
diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c
index 5665bb7cc9..b2effaa6d7 100644
--- a/target/openrisc/mmu.c
+++ b/target/openrisc/mmu.c
@@ -29,18 +29,16 @@
 #endif
 
 #ifndef CONFIG_USER_ONLY
-int cpu_openrisc_get_phys_nommu(OpenRISCCPU *cpu,
-                                hwaddr *physical,
-                                int *prot, target_ulong address, int rw)
+static inline int get_phys_nommu(hwaddr *physical, int *prot,
+                                 target_ulong address)
 {
     *physical = address;
     *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
     return TLBRET_MATCH;
 }
 
-int cpu_openrisc_get_phys_code(OpenRISCCPU *cpu,
-                               hwaddr *physical,
-                               int *prot, target_ulong address, int rw)
+static int get_phys_code(OpenRISCCPU *cpu, hwaddr *physical, int *prot,
+                         target_ulong address, int rw, bool supervisor)
 {
     int vpn = address >> TARGET_PAGE_BITS;
     int idx = vpn & ITLB_MASK;
@@ -52,8 +50,7 @@ int cpu_openrisc_get_phys_code(OpenRISCCPU *cpu,
     if (!(cpu->env.tlb.itlb[0][idx].mr & 1)) {
         return TLBRET_INVALID;
     }
-
-    if (cpu->env.sr & SR_SM) { /* supervisor mode */
+    if (supervisor) {
         if (cpu->env.tlb.itlb[0][idx].tr & SXE) {
             right |= PAGE_EXEC;
         }
@@ -62,7 +59,6 @@ int cpu_openrisc_get_phys_code(OpenRISCCPU *cpu,
             right |= PAGE_EXEC;
         }
     }
-
     if ((rw & 2) && ((right & PAGE_EXEC) == 0)) {
         return TLBRET_BADADDR;
     }
@@ -73,9 +69,8 @@ int cpu_openrisc_get_phys_code(OpenRISCCPU *cpu,
     return TLBRET_MATCH;
 }
 
-int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,
-                               hwaddr *physical,
-                               int *prot, target_ulong address, int rw)
+static int get_phys_data(OpenRISCCPU *cpu, hwaddr *physical, int *prot,
+                         target_ulong address, int rw, bool supervisor)
 {
     int vpn = address >> TARGET_PAGE_BITS;
     int idx = vpn & DTLB_MASK;
@@ -87,8 +82,7 @@ int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,
     if (!(cpu->env.tlb.dtlb[0][idx].mr & 1)) {
         return TLBRET_INVALID;
     }
-
-    if (cpu->env.sr & SR_SM) { /* supervisor mode */
+    if (supervisor) {
         if (cpu->env.tlb.dtlb[0][idx].tr & SRE) {
             right |= PAGE_READ;
         }
@@ -117,20 +111,24 @@ int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,
     return TLBRET_MATCH;
 }
 
-static int cpu_openrisc_get_phys_addr(OpenRISCCPU *cpu,
-                                      hwaddr *physical,
-                                      int *prot, target_ulong address,
-                                      int rw)
+static int get_phys_addr(OpenRISCCPU *cpu, hwaddr *physical,
+                         int *prot, target_ulong address, int rw)
 {
-    int ret = TLBRET_MATCH;
+    bool supervisor = (cpu->env.sr & SR_SM) != 0;
+    int ret;
 
-    if (rw == MMU_INST_FETCH) {    /* ITLB */
-       *physical = 0;
-        ret = cpu->env.tlb.cpu_openrisc_map_address_code(cpu, physical,
-                                                          prot, address, rw);
-    } else {          /* DTLB */
-        ret = cpu->env.tlb.cpu_openrisc_map_address_data(cpu, physical,
-                                                          prot, address, rw);
+    /* Assume nommu results for a moment.  */
+    ret = get_phys_nommu(physical, prot, address);
+
+    /* Overwrite with TLB lookup if enabled.  */
+    if (rw == MMU_INST_FETCH) {
+        if (cpu->env.sr & SR_IME) {
+            ret = get_phys_code(cpu, physical, prot, address, rw, supervisor);
+        }
+    } else {
+        if (cpu->env.sr & SR_DME) {
+            ret = get_phys_data(cpu, physical, prot, address, rw, supervisor);
+        }
     }
 
     return ret;
@@ -186,8 +184,7 @@ int openrisc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
     hwaddr physical = 0;
     int prot = 0;
 
-    ret = cpu_openrisc_get_phys_addr(cpu, &physical, &prot,
-                                     address, rw);
+    ret = get_phys_addr(cpu, &physical, &prot, address, rw);
 
     if (ret == TLBRET_MATCH) {
         tlb_set_page(cs, address & TARGET_PAGE_MASK,
@@ -225,17 +222,16 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 
     /* Check memory for any kind of address, since during debug the
        gdb can ask for anything, check data tlb for address */
-    miss = cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr, 0);
+    miss = get_phys_addr(cpu, &phys_addr, &prot, addr, 0);
 
     /* Check instruction tlb */
     if (miss) {
-        miss = cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr,
-                                          MMU_INST_FETCH);
+        miss = get_phys_addr(cpu, &phys_addr, &prot, addr, MMU_INST_FETCH);
     }
 
     /* Last, fall back to a plain address */
     if (miss) {
-        miss = cpu_openrisc_get_phys_nommu(cpu, &phys_addr, &prot, addr, 0);
+        miss = get_phys_nommu(&phys_addr, &prot, addr);
     }
 
     if (miss) {
@@ -244,10 +240,4 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
         return phys_addr;
     }
 }
-
-void cpu_openrisc_mmu_init(OpenRISCCPU *cpu)
-{
-    cpu->env.tlb.cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
-    cpu->env.tlb.cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
-}
 #endif
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index f26c688df6..a1285894ad 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -60,21 +60,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
             tlb_flush(cs);
         }
         cpu_set_sr(env, rb);
-        if (env->sr & SR_DME) {
-            env->tlb.cpu_openrisc_map_address_data =
-                &cpu_openrisc_get_phys_data;
-        } else {
-            env->tlb.cpu_openrisc_map_address_data =
-                &cpu_openrisc_get_phys_nommu;
-        }
-
-        if (env->sr & SR_IME) {
-            env->tlb.cpu_openrisc_map_address_code =
-                &cpu_openrisc_get_phys_code;
-        } else {
-            env->tlb.cpu_openrisc_map_address_code =
-                &cpu_openrisc_get_phys_nommu;
-        }
         break;
 
     case TO_SPR(0, 18): /* PPC */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 10/22] target/openrisc: Merge mmu_helper.c into mmu.c
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (8 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 09/22] target/openrisc: Remove indirect function calls for mmu Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 11/22] target/openrisc: Reduce tlb to a single dimension Richard Henderson
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

With tlb_fill in mmu.c, we can simplify things further.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/mmu.c         | 11 ++++++++++
 target/openrisc/mmu_helper.c  | 40 -----------------------------------
 target/openrisc/Makefile.objs |  2 +-
 3 files changed, 12 insertions(+), 41 deletions(-)
 delete mode 100644 target/openrisc/mmu_helper.c

diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c
index b2effaa6d7..9b4b5cf04f 100644
--- a/target/openrisc/mmu.c
+++ b/target/openrisc/mmu.c
@@ -240,4 +240,15 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
         return phys_addr;
     }
 }
+
+void tlb_fill(CPUState *cs, target_ulong addr, int size,
+              MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
+{
+    int ret = openrisc_cpu_handle_mmu_fault(cs, addr, size,
+                                            access_type, mmu_idx);
+    if (ret) {
+        /* Raise Exception.  */
+        cpu_loop_exit_restore(cs, retaddr);
+    }
+}
 #endif
diff --git a/target/openrisc/mmu_helper.c b/target/openrisc/mmu_helper.c
deleted file mode 100644
index 97e1d17b5a..0000000000
--- a/target/openrisc/mmu_helper.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * OpenRISC MMU helper routines
- *
- * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
- *                         Zhizhou Zhang <etouzh@gmail.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
-
-#ifndef CONFIG_USER_ONLY
-
-void tlb_fill(CPUState *cs, target_ulong addr, int size,
-              MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
-{
-    int ret;
-
-    ret = openrisc_cpu_handle_mmu_fault(cs, addr, size, access_type, mmu_idx);
-
-    if (ret) {
-        /* Raise Exception.  */
-        cpu_loop_exit_restore(cs, retaddr);
-    }
-}
-#endif
diff --git a/target/openrisc/Makefile.objs b/target/openrisc/Makefile.objs
index 1b98a911ea..957ce02199 100644
--- a/target/openrisc/Makefile.objs
+++ b/target/openrisc/Makefile.objs
@@ -1,7 +1,7 @@
 obj-$(CONFIG_SOFTMMU) += machine.o
 obj-y += cpu.o exception.o interrupt.o mmu.o translate.o
 obj-y += exception_helper.o fpu_helper.o \
-         interrupt_helper.o mmu_helper.o sys_helper.o
+         interrupt_helper.o sys_helper.o
 obj-y += gdbstub.o
 
 DECODETREE = $(SRC_PATH)/scripts/decodetree.py
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 11/22] target/openrisc: Reduce tlb to a single dimension
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (9 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 10/22] target/openrisc: Merge mmu_helper.c into mmu.c Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 12/22] target/openrisc: Fix tlb flushing in mtspr Richard Henderson
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

While we had defines for *_WAYS, we didn't define more than 1.
Reduce the complexity by eliminating this unused dimension.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/cpu.h        |  6 ++----
 target/openrisc/machine.c    |  6 ++----
 target/openrisc/mmu.c        | 30 ++++++++++++++++--------------
 target/openrisc/sys_helper.c | 20 ++++++++++----------
 4 files changed, 30 insertions(+), 32 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 13107058cb..947ca00d8d 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -222,10 +222,8 @@ enum {
 
 /* TLB size */
 enum {
-    DTLB_WAYS = 1,
     DTLB_SIZE = 64,
     DTLB_MASK = (DTLB_SIZE-1),
-    ITLB_WAYS = 1,
     ITLB_SIZE = 64,
     ITLB_MASK = (ITLB_SIZE-1),
 };
@@ -256,8 +254,8 @@ typedef struct OpenRISCTLBEntry {
 
 #ifndef CONFIG_USER_ONLY
 typedef struct CPUOpenRISCTLBContext {
-    OpenRISCTLBEntry itlb[ITLB_WAYS][ITLB_SIZE];
-    OpenRISCTLBEntry dtlb[DTLB_WAYS][DTLB_SIZE];
+    OpenRISCTLBEntry itlb[ITLB_SIZE];
+    OpenRISCTLBEntry dtlb[DTLB_SIZE];
 
     int (*cpu_openrisc_map_address_code)(struct OpenRISCCPU *cpu,
                                          hwaddr *physical,
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index 73e0abcfd7..b795b56dc6 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -42,11 +42,9 @@ static const VMStateDescription vmstate_cpu_tlb = {
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .fields = (VMStateField[]) {
-        VMSTATE_STRUCT_2DARRAY(itlb, CPUOpenRISCTLBContext,
-                             ITLB_WAYS, ITLB_SIZE, 0,
+        VMSTATE_STRUCT_ARRAY(itlb, CPUOpenRISCTLBContext, ITLB_SIZE, 0,
                              vmstate_tlb_entry, OpenRISCTLBEntry),
-        VMSTATE_STRUCT_2DARRAY(dtlb, CPUOpenRISCTLBContext,
-                             DTLB_WAYS, DTLB_SIZE, 0,
+        VMSTATE_STRUCT_ARRAY(dtlb, CPUOpenRISCTLBContext, DTLB_SIZE, 0,
                              vmstate_tlb_entry, OpenRISCTLBEntry),
         VMSTATE_END_OF_LIST()
     }
diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c
index 9b4b5cf04f..856969a7f2 100644
--- a/target/openrisc/mmu.c
+++ b/target/openrisc/mmu.c
@@ -43,19 +43,21 @@ static int get_phys_code(OpenRISCCPU *cpu, hwaddr *physical, int *prot,
     int vpn = address >> TARGET_PAGE_BITS;
     int idx = vpn & ITLB_MASK;
     int right = 0;
+    uint32_t mr = cpu->env.tlb.itlb[idx].mr;
+    uint32_t tr = cpu->env.tlb.itlb[idx].tr;
 
-    if ((cpu->env.tlb.itlb[0][idx].mr >> TARGET_PAGE_BITS) != vpn) {
+    if ((mr >> TARGET_PAGE_BITS) != vpn) {
         return TLBRET_NOMATCH;
     }
-    if (!(cpu->env.tlb.itlb[0][idx].mr & 1)) {
+    if (!(mr & 1)) {
         return TLBRET_INVALID;
     }
     if (supervisor) {
-        if (cpu->env.tlb.itlb[0][idx].tr & SXE) {
+        if (tr & SXE) {
             right |= PAGE_EXEC;
         }
     } else {
-        if (cpu->env.tlb.itlb[0][idx].tr & UXE) {
+        if (tr & UXE) {
             right |= PAGE_EXEC;
         }
     }
@@ -63,8 +65,7 @@ static int get_phys_code(OpenRISCCPU *cpu, hwaddr *physical, int *prot,
         return TLBRET_BADADDR;
     }
 
-    *physical = (cpu->env.tlb.itlb[0][idx].tr & TARGET_PAGE_MASK) |
-                (address & (TARGET_PAGE_SIZE-1));
+    *physical = (tr & TARGET_PAGE_MASK) | (address & ~TARGET_PAGE_MASK);
     *prot = right;
     return TLBRET_MATCH;
 }
@@ -75,25 +76,27 @@ static int get_phys_data(OpenRISCCPU *cpu, hwaddr *physical, int *prot,
     int vpn = address >> TARGET_PAGE_BITS;
     int idx = vpn & DTLB_MASK;
     int right = 0;
+    uint32_t mr = cpu->env.tlb.dtlb[idx].mr;
+    uint32_t tr = cpu->env.tlb.dtlb[idx].tr;
 
-    if ((cpu->env.tlb.dtlb[0][idx].mr >> TARGET_PAGE_BITS) != vpn) {
+    if ((mr >> TARGET_PAGE_BITS) != vpn) {
         return TLBRET_NOMATCH;
     }
-    if (!(cpu->env.tlb.dtlb[0][idx].mr & 1)) {
+    if (!(mr & 1)) {
         return TLBRET_INVALID;
     }
     if (supervisor) {
-        if (cpu->env.tlb.dtlb[0][idx].tr & SRE) {
+        if (tr & SRE) {
             right |= PAGE_READ;
         }
-        if (cpu->env.tlb.dtlb[0][idx].tr & SWE) {
+        if (tr & SWE) {
             right |= PAGE_WRITE;
         }
     } else {
-        if (cpu->env.tlb.dtlb[0][idx].tr & URE) {
+        if (tr & URE) {
             right |= PAGE_READ;
         }
-        if (cpu->env.tlb.dtlb[0][idx].tr & UWE) {
+        if (tr & UWE) {
             right |= PAGE_WRITE;
         }
     }
@@ -105,8 +108,7 @@ static int get_phys_data(OpenRISCCPU *cpu, hwaddr *physical, int *prot,
         return TLBRET_BADADDR;
     }
 
-    *physical = (cpu->env.tlb.dtlb[0][idx].tr & TARGET_PAGE_MASK) |
-                (address & (TARGET_PAGE_SIZE-1));
+    *physical = (tr & TARGET_PAGE_MASK) | (address & ~TARGET_PAGE_MASK);
     *prot = right;
     return TLBRET_MATCH;
 }
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index a1285894ad..8ad7a7d898 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -85,14 +85,14 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
     case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
         idx = spr - TO_SPR(1, 512);
         if (!(rb & 1)) {
-            tlb_flush_page(cs, env->tlb.dtlb[0][idx].mr & TARGET_PAGE_MASK);
+            tlb_flush_page(cs, env->tlb.dtlb[idx].mr & TARGET_PAGE_MASK);
         }
-        env->tlb.dtlb[0][idx].mr = rb;
+        env->tlb.dtlb[idx].mr = rb;
         break;
 
     case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */
         idx = spr - TO_SPR(1, 640);
-        env->tlb.dtlb[0][idx].tr = rb;
+        env->tlb.dtlb[idx].tr = rb;
         break;
     case TO_SPR(1, 768) ... TO_SPR(1, 895):   /* DTLBW1MR 0-127 */
     case TO_SPR(1, 896) ... TO_SPR(1, 1023):  /* DTLBW1TR 0-127 */
@@ -104,14 +104,14 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
     case TO_SPR(2, 512) ... TO_SPR(2, 512+ITLB_SIZE-1):   /* ITLBW0MR 0-127 */
         idx = spr - TO_SPR(2, 512);
         if (!(rb & 1)) {
-            tlb_flush_page(cs, env->tlb.itlb[0][idx].mr & TARGET_PAGE_MASK);
+            tlb_flush_page(cs, env->tlb.itlb[idx].mr & TARGET_PAGE_MASK);
         }
-        env->tlb.itlb[0][idx].mr = rb;
+        env->tlb.itlb[idx].mr = rb;
         break;
 
     case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */
         idx = spr - TO_SPR(2, 640);
-        env->tlb.itlb[0][idx].tr = rb;
+        env->tlb.itlb[idx].tr = rb;
         break;
     case TO_SPR(2, 768) ... TO_SPR(2, 895):   /* ITLBW1MR 0-127 */
     case TO_SPR(2, 896) ... TO_SPR(2, 1023):  /* ITLBW1TR 0-127 */
@@ -243,11 +243,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
 
     case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
         idx = spr - TO_SPR(1, 512);
-        return env->tlb.dtlb[0][idx].mr;
+        return env->tlb.dtlb[idx].mr;
 
     case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */
         idx = spr - TO_SPR(1, 640);
-        return env->tlb.dtlb[0][idx].tr;
+        return env->tlb.dtlb[idx].tr;
 
     case TO_SPR(1, 768) ... TO_SPR(1, 895):   /* DTLBW1MR 0-127 */
     case TO_SPR(1, 896) ... TO_SPR(1, 1023):  /* DTLBW1TR 0-127 */
@@ -259,11 +259,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
 
     case TO_SPR(2, 512) ... TO_SPR(2, 512+ITLB_SIZE-1): /* ITLBW0MR 0-127 */
         idx = spr - TO_SPR(2, 512);
-        return env->tlb.itlb[0][idx].mr;
+        return env->tlb.itlb[idx].mr;
 
     case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */
         idx = spr - TO_SPR(2, 640);
-        return env->tlb.itlb[0][idx].tr;
+        return env->tlb.itlb[idx].tr;
 
     case TO_SPR(2, 768) ... TO_SPR(2, 895):   /* ITLBW1MR 0-127 */
     case TO_SPR(2, 896) ... TO_SPR(2, 1023):  /* ITLBW1TR 0-127 */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 12/22] target/openrisc: Fix tlb flushing in mtspr
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (10 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 11/22] target/openrisc: Reduce tlb to a single dimension Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-22  6:40   ` Stafford Horne
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 13/22] target/openrisc: Fix cpu_mmu_index Richard Henderson
                   ` (11 subsequent siblings)
  23 siblings, 1 reply; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

The previous code was confused, avoiding the flush of the old entry
if the new entry is invalid.  We need to flush the old page if the
old entry is valid and the new page if the new entry is valid.

This bug was masked by over-flushing elsewhere.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/sys_helper.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index 8ad7a7d898..e00aaa332e 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -32,6 +32,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
 #ifndef CONFIG_USER_ONLY
     OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
     CPUState *cs = CPU(cpu);
+    target_ulong mr;
     int idx;
 
     switch (spr) {
@@ -84,12 +85,15 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
 
     case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
         idx = spr - TO_SPR(1, 512);
-        if (!(rb & 1)) {
-            tlb_flush_page(cs, env->tlb.dtlb[idx].mr & TARGET_PAGE_MASK);
+        mr = env->tlb.dtlb[idx].mr;
+        if (mr & 1) {
+            tlb_flush_page(cs, mr & TARGET_PAGE_MASK);
+        }
+        if (rb & 1) {
+            tlb_flush_page(cs, rb & TARGET_PAGE_MASK);
         }
         env->tlb.dtlb[idx].mr = rb;
         break;
-
     case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */
         idx = spr - TO_SPR(1, 640);
         env->tlb.dtlb[idx].tr = rb;
@@ -101,14 +105,18 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
     case TO_SPR(1, 1280) ... TO_SPR(1, 1407): /* DTLBW3MR 0-127 */
     case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */
         break;
+
     case TO_SPR(2, 512) ... TO_SPR(2, 512+ITLB_SIZE-1):   /* ITLBW0MR 0-127 */
         idx = spr - TO_SPR(2, 512);
-        if (!(rb & 1)) {
-            tlb_flush_page(cs, env->tlb.itlb[idx].mr & TARGET_PAGE_MASK);
+        mr = env->tlb.itlb[idx].mr;
+        if (mr & 1) {
+            tlb_flush_page(cs, mr & TARGET_PAGE_MASK);
+        }
+        if (rb & 1) {
+            tlb_flush_page(cs, rb & TARGET_PAGE_MASK);
         }
         env->tlb.itlb[idx].mr = rb;
         break;
-
     case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */
         idx = spr - TO_SPR(2, 640);
         env->tlb.itlb[idx].tr = rb;
@@ -120,6 +128,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
     case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */
     case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
         break;
+
     case TO_SPR(5, 1):  /* MACLO */
         env->mac = deposit64(env->mac, 0, 32, rb);
         break;
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 13/22] target/openrisc: Fix cpu_mmu_index
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (11 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 12/22] target/openrisc: Fix tlb flushing in mtspr Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-24  3:44   ` Stafford Horne
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 14/22] target/openrisc: Use identical sizes for ITLB and DTLB Richard Henderson
                   ` (10 subsequent siblings)
  23 siblings, 1 reply; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

The code in cpu_mmu_index does not properly honor SR_DME.
This bug has workarounds elsewhere in that we flush the
tlb more often than necessary, on the state changes that
should be reflected in a change of mmu_index.

Fixing this means that we can respect the mmu_index that
is given to tlb_flush.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/cpu.h              | 23 +++++++++++++--------
 target/openrisc/interrupt.c        |  4 ----
 target/openrisc/interrupt_helper.c | 15 +++-----------
 target/openrisc/mmu.c              | 33 +++++++++++++++++++++++++++---
 target/openrisc/sys_helper.c       |  4 ----
 target/openrisc/translate.c        |  2 +-
 6 files changed, 49 insertions(+), 32 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 947ca00d8d..c48802ad8f 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -384,9 +384,12 @@ void cpu_openrisc_count_stop(OpenRISCCPU *cpu);
 
 #include "exec/cpu-all.h"
 
-#define TB_FLAGS_DFLAG 1
-#define TB_FLAGS_R0_0  2
+#define TB_FLAGS_SM    SR_SM
+#define TB_FLAGS_DME   SR_DME
+#define TB_FLAGS_IME   SR_IME
 #define TB_FLAGS_OVE   SR_OVE
+#define TB_FLAGS_DFLAG 2      /* reuse SR_TEE */
+#define TB_FLAGS_R0_0  4      /* reuse SR_IEE */
 
 static inline uint32_t cpu_get_gpr(const CPUOpenRISCState *env, int i)
 {
@@ -404,17 +407,21 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
 {
     *pc = env->pc;
     *cs_base = 0;
-    *flags = (env->dflag
-              | (cpu_get_gpr(env, 0) == 0 ? TB_FLAGS_R0_0 : 0)
-              | (env->sr & SR_OVE));
+    *flags = (env->dflag ? TB_FLAGS_DFLAG : 0)
+           | (cpu_get_gpr(env, 0) ? 0 : TB_FLAGS_R0_0)
+           | (env->sr & (SR_SM | SR_DME | SR_IME | SR_OVE));
 }
 
 static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch)
 {
-    if (!(env->sr & SR_IME)) {
-        return MMU_NOMMU_IDX;
+    int ret = MMU_NOMMU_IDX;  /* mmu is disabled */
+
+    if (env->sr & (ifetch ? SR_IME : SR_DME)) {
+        /* The mmu is enabled; test supervisor state.  */
+        ret = env->sr & SR_SM ? MMU_SUPERVISOR_IDX : MMU_USER_IDX;
     }
-    return (env->sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX;
+
+    return ret;
 }
 
 static inline uint32_t cpu_get_sr(const CPUOpenRISCState *env)
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index d9cb363fea..e28042856a 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -50,10 +50,6 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
         env->eear = env->pc;
     }
 
-    /* For machine-state changed between user-mode and supervisor mode,
-       we need flush TLB when we enter&exit EXCP.  */
-    tlb_flush(cs);
-
     env->esr = cpu_get_sr(env);
     env->sr &= ~SR_DME;
     env->sr &= ~SR_IME;
diff --git a/target/openrisc/interrupt_helper.c b/target/openrisc/interrupt_helper.c
index a2e9003969..9c5489f5f7 100644
--- a/target/openrisc/interrupt_helper.c
+++ b/target/openrisc/interrupt_helper.c
@@ -25,16 +25,7 @@
 
 void HELPER(rfe)(CPUOpenRISCState *env)
 {
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-#ifndef CONFIG_USER_ONLY
-    int need_flush_tlb = (cpu->env.sr & (SR_SM | SR_IME | SR_DME)) ^
-                         (cpu->env.esr & (SR_SM | SR_IME | SR_DME));
-    if (need_flush_tlb) {
-        CPUState *cs = CPU(cpu);
-        tlb_flush(cs);
-    }
-#endif
-    cpu->env.pc = cpu->env.epcr;
-    cpu->env.lock_addr = -1;
-    cpu_set_sr(&cpu->env, cpu->env.esr);
+    env->pc = env->epcr;
+    env->lock_addr = -1;
+    cpu_set_sr(env, env->esr);
 }
diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c
index 856969a7f2..b293b64e98 100644
--- a/target/openrisc/mmu.c
+++ b/target/openrisc/mmu.c
@@ -246,9 +246,36 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 void tlb_fill(CPUState *cs, target_ulong addr, int size,
               MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
 {
-    int ret = openrisc_cpu_handle_mmu_fault(cs, addr, size,
-                                            access_type, mmu_idx);
-    if (ret) {
+    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
+    int ret, prot = 0;
+    hwaddr physical = 0;
+
+    if (mmu_idx == MMU_NOMMU_IDX) {
+        ret = get_phys_nommu(&physical, &prot, addr);
+    } else {
+        bool super = mmu_idx == MMU_SUPERVISOR_IDX;
+        if (access_type == MMU_INST_FETCH) {
+            ret = get_phys_code(cpu, &physical, &prot, addr, 2, super);
+        } else {
+            ret = get_phys_data(cpu, &physical, &prot, addr,
+                                access_type == MMU_DATA_STORE, super);
+        }
+    }
+
+    if (ret == TLBRET_MATCH) {
+        tlb_set_page(cs, addr & TARGET_PAGE_MASK,
+                     physical & TARGET_PAGE_MASK, prot,
+                     mmu_idx, TARGET_PAGE_SIZE);
+    } else if (ret < 0) {
+        int rw;
+        if (access_type == MMU_INST_FETCH) {
+            rw = 2;
+        } else if (access_type == MMU_DATA_STORE) {
+            rw = 1;
+        } else {
+            rw = 0;
+        }
+        cpu_openrisc_raise_mmu_exception(cpu, addr, rw, ret);
         /* Raise Exception.  */
         cpu_loop_exit_restore(cs, retaddr);
     }
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index e00aaa332e..0a74c9522f 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -56,10 +56,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
         break;
 
     case TO_SPR(0, 17): /* SR */
-        if ((env->sr & (SR_IME | SR_DME | SR_SM)) ^
-            (rb & (SR_IME | SR_DME | SR_SM))) {
-            tlb_flush(cs);
-        }
         cpu_set_sr(env, rb);
         break;
 
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index f19f0d257b..60c6e19f4b 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -59,7 +59,7 @@ static inline bool is_user(DisasContext *dc)
 #ifdef CONFIG_USER_ONLY
     return true;
 #else
-    return dc->mem_idx == MMU_USER_IDX;
+    return !(dc->tb_flags & TB_FLAGS_SM);
 #endif
 }
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 14/22] target/openrisc: Use identical sizes for ITLB and DTLB
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (12 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 13/22] target/openrisc: Fix cpu_mmu_index Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 15/22] target/openrisc: Stub out handle_mmu_fault for softmmu Richard Henderson
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

The sizes are already the same, however, we can improve things
if they are identical by design.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/cpu.h        | 10 ++++------
 target/openrisc/machine.c    |  4 ++--
 target/openrisc/mmu.c        |  4 ++--
 target/openrisc/sys_helper.c | 16 ++++++++--------
 4 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index c48802ad8f..53abe965e8 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -222,10 +222,8 @@ enum {
 
 /* TLB size */
 enum {
-    DTLB_SIZE = 64,
-    DTLB_MASK = (DTLB_SIZE-1),
-    ITLB_SIZE = 64,
-    ITLB_MASK = (ITLB_SIZE-1),
+    TLB_SIZE = 64,
+    TLB_MASK = TLB_SIZE - 1,
 };
 
 /* TLB prot */
@@ -254,8 +252,8 @@ typedef struct OpenRISCTLBEntry {
 
 #ifndef CONFIG_USER_ONLY
 typedef struct CPUOpenRISCTLBContext {
-    OpenRISCTLBEntry itlb[ITLB_SIZE];
-    OpenRISCTLBEntry dtlb[DTLB_SIZE];
+    OpenRISCTLBEntry itlb[TLB_SIZE];
+    OpenRISCTLBEntry dtlb[TLB_SIZE];
 
     int (*cpu_openrisc_map_address_code)(struct OpenRISCCPU *cpu,
                                          hwaddr *physical,
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index b795b56dc6..3fc837b925 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -42,9 +42,9 @@ static const VMStateDescription vmstate_cpu_tlb = {
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .fields = (VMStateField[]) {
-        VMSTATE_STRUCT_ARRAY(itlb, CPUOpenRISCTLBContext, ITLB_SIZE, 0,
+        VMSTATE_STRUCT_ARRAY(itlb, CPUOpenRISCTLBContext, TLB_SIZE, 0,
                              vmstate_tlb_entry, OpenRISCTLBEntry),
-        VMSTATE_STRUCT_ARRAY(dtlb, CPUOpenRISCTLBContext, DTLB_SIZE, 0,
+        VMSTATE_STRUCT_ARRAY(dtlb, CPUOpenRISCTLBContext, TLB_SIZE, 0,
                              vmstate_tlb_entry, OpenRISCTLBEntry),
         VMSTATE_END_OF_LIST()
     }
diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c
index b293b64e98..a4613e9ae4 100644
--- a/target/openrisc/mmu.c
+++ b/target/openrisc/mmu.c
@@ -41,7 +41,7 @@ static int get_phys_code(OpenRISCCPU *cpu, hwaddr *physical, int *prot,
                          target_ulong address, int rw, bool supervisor)
 {
     int vpn = address >> TARGET_PAGE_BITS;
-    int idx = vpn & ITLB_MASK;
+    int idx = vpn & TLB_MASK;
     int right = 0;
     uint32_t mr = cpu->env.tlb.itlb[idx].mr;
     uint32_t tr = cpu->env.tlb.itlb[idx].tr;
@@ -74,7 +74,7 @@ static int get_phys_data(OpenRISCCPU *cpu, hwaddr *physical, int *prot,
                          target_ulong address, int rw, bool supervisor)
 {
     int vpn = address >> TARGET_PAGE_BITS;
-    int idx = vpn & DTLB_MASK;
+    int idx = vpn & TLB_MASK;
     int right = 0;
     uint32_t mr = cpu->env.tlb.dtlb[idx].mr;
     uint32_t tr = cpu->env.tlb.dtlb[idx].tr;
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index 0a74c9522f..7254aa9830 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -79,7 +79,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
         idx = (spr - 1024);
         env->shadow_gpr[idx / 32][idx % 32] = rb;
 
-    case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
+    case TO_SPR(1, 512) ... TO_SPR(1, 512 + TLB_SIZE - 1): /* DTLBW0MR 0-127 */
         idx = spr - TO_SPR(1, 512);
         mr = env->tlb.dtlb[idx].mr;
         if (mr & 1) {
@@ -90,7 +90,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
         }
         env->tlb.dtlb[idx].mr = rb;
         break;
-    case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */
+    case TO_SPR(1, 640) ... TO_SPR(1, 640 + TLB_SIZE - 1): /* DTLBW0TR 0-127 */
         idx = spr - TO_SPR(1, 640);
         env->tlb.dtlb[idx].tr = rb;
         break;
@@ -102,7 +102,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
     case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */
         break;
 
-    case TO_SPR(2, 512) ... TO_SPR(2, 512+ITLB_SIZE-1):   /* ITLBW0MR 0-127 */
+    case TO_SPR(2, 512) ... TO_SPR(2, 512 + TLB_SIZE - 1): /* ITLBW0MR 0-127 */
         idx = spr - TO_SPR(2, 512);
         mr = env->tlb.itlb[idx].mr;
         if (mr & 1) {
@@ -113,7 +113,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
         }
         env->tlb.itlb[idx].mr = rb;
         break;
-    case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */
+    case TO_SPR(2, 640) ... TO_SPR(2, 640 + TLB_SIZE - 1): /* ITLBW0TR 0-127 */
         idx = spr - TO_SPR(2, 640);
         env->tlb.itlb[idx].tr = rb;
         break;
@@ -246,11 +246,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
         idx = (spr - 1024);
         return env->shadow_gpr[idx / 32][idx % 32];
 
-    case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
+    case TO_SPR(1, 512) ... TO_SPR(1, 512 + TLB_SIZE - 1): /* DTLBW0MR 0-127 */
         idx = spr - TO_SPR(1, 512);
         return env->tlb.dtlb[idx].mr;
 
-    case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */
+    case TO_SPR(1, 640) ... TO_SPR(1, 640 + TLB_SIZE - 1): /* DTLBW0TR 0-127 */
         idx = spr - TO_SPR(1, 640);
         return env->tlb.dtlb[idx].tr;
 
@@ -262,11 +262,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
     case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */
         break;
 
-    case TO_SPR(2, 512) ... TO_SPR(2, 512+ITLB_SIZE-1): /* ITLBW0MR 0-127 */
+    case TO_SPR(2, 512) ... TO_SPR(2, 512 + TLB_SIZE - 1): /* ITLBW0MR 0-127 */
         idx = spr - TO_SPR(2, 512);
         return env->tlb.itlb[idx].mr;
 
-    case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */
+    case TO_SPR(2, 640) ... TO_SPR(2, 640 + TLB_SIZE - 1): /* ITLBW0TR 0-127 */
         idx = spr - TO_SPR(2, 640);
         return env->tlb.itlb[idx].tr;
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 15/22] target/openrisc: Stub out handle_mmu_fault for softmmu
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (13 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 14/22] target/openrisc: Use identical sizes for ITLB and DTLB Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 16/22] target/openrisc: Log interrupts Richard Henderson
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

This hook is only used by CONFIG_USER_ONLY.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/mmu.c | 35 +++++------------------------------
 1 file changed, 5 insertions(+), 30 deletions(-)

diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c
index a4613e9ae4..f4c0a3e217 100644
--- a/target/openrisc/mmu.c
+++ b/target/openrisc/mmu.c
@@ -177,42 +177,17 @@ static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu,
     cpu->env.lock_addr = -1;
 }
 
-#ifndef CONFIG_USER_ONLY
 int openrisc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
                                   int rw, int mmu_idx)
 {
+#ifdef CONFIG_USER_ONLY
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
-    int ret = 0;
-    hwaddr physical = 0;
-    int prot = 0;
-
-    ret = get_phys_addr(cpu, &physical, &prot, address, rw);
-
-    if (ret == TLBRET_MATCH) {
-        tlb_set_page(cs, address & TARGET_PAGE_MASK,
-                     physical & TARGET_PAGE_MASK, prot,
-                     mmu_idx, TARGET_PAGE_SIZE);
-        ret = 0;
-    } else if (ret < 0) {
-        cpu_openrisc_raise_mmu_exception(cpu, address, rw, ret);
-        ret = 1;
-    }
-
-    return ret;
-}
+    cpu_openrisc_raise_mmu_exception(cpu, address, rw, 0);
+    return 1;
 #else
-int openrisc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
-                                  int rw, int mmu_idx)
-{
-    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
-    int ret = 0;
-
-    cpu_openrisc_raise_mmu_exception(cpu, address, rw, ret);
-    ret = 1;
-
-    return ret;
-}
+    g_assert_not_reached();
 #endif
+}
 
 #ifndef CONFIG_USER_ONLY
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 16/22] target/openrisc: Log interrupts
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (14 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 15/22] target/openrisc: Stub out handle_mmu_fault for softmmu Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 17/22] target/openrisc: Increase the TLB size Richard Henderson
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/interrupt.c | 30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index e28042856a..138ad17f00 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -32,6 +32,7 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
 #ifndef CONFIG_USER_ONLY
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
     CPUOpenRISCState *env = &cpu->env;
+    int exception = cs->exception_index;
 
     env->epcr = env->pc;
     if (env->dflag) {
@@ -41,12 +42,12 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
     } else {
         env->sr &= ~SR_DSX;
     }
-    if (cs->exception_index == EXCP_SYSCALL) {
+    if (exception == EXCP_SYSCALL) {
         env->epcr += 4;
     }
     /* When we have an illegal instruction the error effective address
        shall be set to the illegal instruction address.  */
-    if (cs->exception_index == EXCP_ILLEGAL) {
+    if (exception == EXCP_ILLEGAL) {
         env->eear = env->pc;
     }
 
@@ -60,8 +61,27 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
     env->pmr &= ~PMR_SME;
     env->lock_addr = -1;
 
-    if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) {
-        hwaddr vect_pc = cs->exception_index << 8;
+    if (exception > 0 && exception < EXCP_NR) {
+        static const char * const int_name[EXCP_NR] = {
+            [EXCP_RESET]    = "RESET",
+            [EXCP_BUSERR]   = "BUSERR (bus error)",
+            [EXCP_DPF]      = "DFP (data protection fault)",
+            [EXCP_IPF]      = "IPF (code protection fault)",
+            [EXCP_TICK]     = "TICK (timer interrupt)",
+            [EXCP_ALIGN]    = "ALIGN",
+            [EXCP_ILLEGAL]  = "ILLEGAL",
+            [EXCP_INT]      = "INT (device interrupt)",
+            [EXCP_DTLBMISS] = "DTLBMISS (data tlb miss)",
+            [EXCP_ITLBMISS] = "ITLBMISS (code tlb miss)",
+            [EXCP_RANGE]    = "RANGE",
+            [EXCP_SYSCALL]  = "SYSCALL",
+            [EXCP_FPE]      = "FPE",
+            [EXCP_TRAP]     = "TRAP",
+        };
+
+        qemu_log_mask(CPU_LOG_INT, "INT: %s\n", int_name[exception]);
+
+        hwaddr vect_pc = exception << 8;
         if (env->cpucfgr & CPUCFGR_EVBARP) {
             vect_pc |= env->evbar;
         }
@@ -70,7 +90,7 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
         }
         env->pc = vect_pc;
     } else {
-        cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
+        cpu_abort(cs, "Unhandled exception 0x%x\n", exception);
     }
 #endif
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 17/22] target/openrisc: Increase the TLB size
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (15 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 16/22] target/openrisc: Log interrupts Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 18/22] target/openrisc: Reorg tlb lookup Richard Henderson
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

The architecture supports 128 TLB entries.  There is no reason
not to provide all of them.  In the process we need to fix a
bug that failed to parameterize the configuration register that
tells the operating system the number of entries.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
v2:
  - Change VMState version.
---
 target/openrisc/cpu.h     | 2 +-
 target/openrisc/cpu.c     | 6 ++++--
 target/openrisc/machine.c | 5 ++---
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 53abe965e8..8035654087 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -222,7 +222,7 @@ enum {
 
 /* TLB size */
 enum {
-    TLB_SIZE = 64,
+    TLB_SIZE = 128,
     TLB_MASK = TLB_SIZE - 1,
 };
 
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index 4c166c6329..677f02efa4 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -52,8 +52,10 @@ static void openrisc_cpu_reset(CPUState *s)
 
     cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP |
                    UPR_PMP;
-    cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2)) | (DMMUCFGR_NTS & (6 << 2));
-    cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2)) | (IMMUCFGR_NTS & (6 << 2));
+    cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2))
+                      | (DMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
+    cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2))
+                      | (IMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
 
 #ifndef CONFIG_USER_ONLY
     cpu->env.picmr = 0x00000000;
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index 3fc837b925..1eedbf3dbe 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -38,9 +38,8 @@ static const VMStateDescription vmstate_tlb_entry = {
 
 static const VMStateDescription vmstate_cpu_tlb = {
     .name = "cpu_tlb",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
+    .version_id = 2,
+    .minimum_version_id = 2,
     .fields = (VMStateField[]) {
         VMSTATE_STRUCT_ARRAY(itlb, CPUOpenRISCTLBContext, TLB_SIZE, 0,
                              vmstate_tlb_entry, OpenRISCTLBEntry),
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 18/22] target/openrisc: Reorg tlb lookup
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (16 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 17/22] target/openrisc: Increase the TLB size Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 19/22] target/openrisc: Add print_insn_or1k Richard Henderson
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

While openrisc has a split i/d tlb, qemu does not.  Perform a
lookup on both i & d tlbs in parallel and put the composite
rights into qemu's tlb.  This avoids ping-ponging the qemu tlb
between EXEC and READ.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/cpu.h |   8 --
 target/openrisc/mmu.c | 254 +++++++++++++++---------------------------
 2 files changed, 90 insertions(+), 172 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 8035654087..1efffa5269 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -237,14 +237,6 @@ enum {
     UXE = (1 << 7),
 };
 
-/* check if tlb available */
-enum {
-    TLBRET_INVALID = -3,
-    TLBRET_NOMATCH = -2,
-    TLBRET_BADADDR = -1,
-    TLBRET_MATCH = 0
-};
-
 typedef struct OpenRISCTLBEntry {
     uint32_t mr;
     uint32_t tr;
diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c
index f4c0a3e217..d3796ae41e 100644
--- a/target/openrisc/mmu.c
+++ b/target/openrisc/mmu.c
@@ -29,148 +29,78 @@
 #endif
 
 #ifndef CONFIG_USER_ONLY
-static inline int get_phys_nommu(hwaddr *physical, int *prot,
-                                 target_ulong address)
+static inline void get_phys_nommu(hwaddr *phys_addr, int *prot,
+                                  target_ulong address)
 {
-    *physical = address;
+    *phys_addr = address;
     *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
-    return TLBRET_MATCH;
 }
 
-static int get_phys_code(OpenRISCCPU *cpu, hwaddr *physical, int *prot,
-                         target_ulong address, int rw, bool supervisor)
+static int get_phys_mmu(OpenRISCCPU *cpu, hwaddr *phys_addr, int *prot,
+                        target_ulong addr, int need, bool super)
 {
-    int vpn = address >> TARGET_PAGE_BITS;
-    int idx = vpn & TLB_MASK;
-    int right = 0;
-    uint32_t mr = cpu->env.tlb.itlb[idx].mr;
-    uint32_t tr = cpu->env.tlb.itlb[idx].tr;
+    int idx = (addr >> TARGET_PAGE_BITS) & TLB_MASK;
+    uint32_t imr = cpu->env.tlb.itlb[idx].mr;
+    uint32_t itr = cpu->env.tlb.itlb[idx].tr;
+    uint32_t dmr = cpu->env.tlb.dtlb[idx].mr;
+    uint32_t dtr = cpu->env.tlb.dtlb[idx].tr;
+    int right, match, valid;
 
-    if ((mr >> TARGET_PAGE_BITS) != vpn) {
-        return TLBRET_NOMATCH;
-    }
-    if (!(mr & 1)) {
-        return TLBRET_INVALID;
-    }
-    if (supervisor) {
-        if (tr & SXE) {
-            right |= PAGE_EXEC;
-        }
-    } else {
-        if (tr & UXE) {
-            right |= PAGE_EXEC;
+    /* If the ITLB and DTLB indexes map to the same page, we want to
+       load all permissions all at once.  If the destination pages do
+       not match, zap the one we don't need.  */
+    if (unlikely((itr ^ dtr) & TARGET_PAGE_MASK)) {
+        if (need & PAGE_EXEC) {
+            dmr = dtr = 0;
+        } else {
+            imr = itr = 0;
         }
     }
-    if ((rw & 2) && ((right & PAGE_EXEC) == 0)) {
-        return TLBRET_BADADDR;
-    }
 
-    *physical = (tr & TARGET_PAGE_MASK) | (address & ~TARGET_PAGE_MASK);
+    /* Check if either of the entries matches the source address.  */
+    match  = (imr ^ addr) & TARGET_PAGE_MASK ? 0 : PAGE_EXEC;
+    match |= (dmr ^ addr) & TARGET_PAGE_MASK ? 0 : PAGE_READ | PAGE_WRITE;
+
+    /* Check if either of the entries is valid.  */
+    valid  = imr & 1 ? PAGE_EXEC : 0;
+    valid |= dmr & 1 ? PAGE_READ | PAGE_WRITE : 0;
+    valid &= match;
+
+    /* Collect the permissions from the entries.  */
+    right  = itr & (super ? SXE : UXE) ? PAGE_EXEC : 0;
+    right |= dtr & (super ? SRE : URE) ? PAGE_READ : 0;
+    right |= dtr & (super ? SWE : UWE) ? PAGE_WRITE : 0;
+    right &= valid;
+
+    /* Note that above we validated that itr and dtr match on page.
+       So oring them together changes nothing without having to
+       check which one we needed.  We also want to store to these
+       variables even on failure, as it avoids compiler warnings.  */
+    *phys_addr = ((itr | dtr) & TARGET_PAGE_MASK) | (addr & ~TARGET_PAGE_MASK);
     *prot = right;
-    return TLBRET_MATCH;
-}
 
-static int get_phys_data(OpenRISCCPU *cpu, hwaddr *physical, int *prot,
-                         target_ulong address, int rw, bool supervisor)
-{
-    int vpn = address >> TARGET_PAGE_BITS;
-    int idx = vpn & TLB_MASK;
-    int right = 0;
-    uint32_t mr = cpu->env.tlb.dtlb[idx].mr;
-    uint32_t tr = cpu->env.tlb.dtlb[idx].tr;
+    qemu_log_mask(CPU_LOG_MMU,
+                  "MMU lookup: need %d match %d valid %d right %d -> %s\n",
+                  need, match, valid, right, (need & right) ? "OK" : "FAIL");
 
-    if ((mr >> TARGET_PAGE_BITS) != vpn) {
-        return TLBRET_NOMATCH;
+    /* Check the collective permissions are present.  */
+    if (likely(need & right)) {
+        return 0;  /* success! */
     }
-    if (!(mr & 1)) {
-        return TLBRET_INVALID;
-    }
-    if (supervisor) {
-        if (tr & SRE) {
-            right |= PAGE_READ;
-        }
-        if (tr & SWE) {
-            right |= PAGE_WRITE;
-        }
+
+    /* Determine what kind of failure we have.  */
+    if (need & valid) {
+        return need & PAGE_EXEC ? EXCP_IPF : EXCP_DPF;
     } else {
-        if (tr & URE) {
-            right |= PAGE_READ;
-        }
-        if (tr & UWE) {
-            right |= PAGE_WRITE;
-        }
+        return need & PAGE_EXEC ? EXCP_ITLBMISS : EXCP_DTLBMISS;
     }
-
-    if (!(rw & 1) && ((right & PAGE_READ) == 0)) {
-        return TLBRET_BADADDR;
-    }
-    if ((rw & 1) && ((right & PAGE_WRITE) == 0)) {
-        return TLBRET_BADADDR;
-    }
-
-    *physical = (tr & TARGET_PAGE_MASK) | (address & ~TARGET_PAGE_MASK);
-    *prot = right;
-    return TLBRET_MATCH;
-}
-
-static int get_phys_addr(OpenRISCCPU *cpu, hwaddr *physical,
-                         int *prot, target_ulong address, int rw)
-{
-    bool supervisor = (cpu->env.sr & SR_SM) != 0;
-    int ret;
-
-    /* Assume nommu results for a moment.  */
-    ret = get_phys_nommu(physical, prot, address);
-
-    /* Overwrite with TLB lookup if enabled.  */
-    if (rw == MMU_INST_FETCH) {
-        if (cpu->env.sr & SR_IME) {
-            ret = get_phys_code(cpu, physical, prot, address, rw, supervisor);
-        }
-    } else {
-        if (cpu->env.sr & SR_DME) {
-            ret = get_phys_data(cpu, physical, prot, address, rw, supervisor);
-        }
-    }
-
-    return ret;
 }
 #endif
 
-static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu,
-                                             target_ulong address,
-                                             int rw, int tlb_error)
+static void raise_mmu_exception(OpenRISCCPU *cpu, target_ulong address,
+                                int exception)
 {
     CPUState *cs = CPU(cpu);
-    int exception = 0;
-
-    switch (tlb_error) {
-    default:
-        if (rw == 2) {
-            exception = EXCP_IPF;
-        } else {
-            exception = EXCP_DPF;
-        }
-        break;
-#ifndef CONFIG_USER_ONLY
-    case TLBRET_BADADDR:
-        if (rw == 2) {
-            exception = EXCP_IPF;
-        } else {
-            exception = EXCP_DPF;
-        }
-        break;
-    case TLBRET_INVALID:
-    case TLBRET_NOMATCH:
-        /* No TLB match for a mapped address */
-        if (rw == 2) {
-            exception = EXCP_ITLBMISS;
-        } else {
-            exception = EXCP_DTLBMISS;
-        }
-        break;
-#endif
-    }
 
     cs->exception_index = exception;
     cpu->env.eear = address;
@@ -182,7 +112,7 @@ int openrisc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
 {
 #ifdef CONFIG_USER_ONLY
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
-    cpu_openrisc_raise_mmu_exception(cpu, address, rw, 0);
+    raise_mmu_exception(cpu, address, EXCP_DPF);
     return 1;
 #else
     g_assert_not_reached();
@@ -193,27 +123,32 @@ int openrisc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 {
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
+    int prot, excp, sr = cpu->env.sr;
     hwaddr phys_addr;
-    int prot;
-    int miss;
 
-    /* Check memory for any kind of address, since during debug the
-       gdb can ask for anything, check data tlb for address */
-    miss = get_phys_addr(cpu, &phys_addr, &prot, addr, 0);
+    switch (sr & (SR_DME | SR_IME)) {
+    case SR_DME | SR_IME:
+        /* The mmu is definitely enabled.  */
+        excp = get_phys_mmu(cpu, &phys_addr, &prot, addr,
+                            PROT_EXEC | PROT_READ | PROT_WRITE,
+                            (sr & SR_SM) != 0);
+        return excp ? -1 : phys_addr;
 
-    /* Check instruction tlb */
-    if (miss) {
-        miss = get_phys_addr(cpu, &phys_addr, &prot, addr, MMU_INST_FETCH);
-    }
+    default:
+        /* The mmu is partially enabled, and we don't really have
+           a "real" access type.  Begin by trying the mmu, but if
+           that fails try again without.  */
+        excp = get_phys_mmu(cpu, &phys_addr, &prot, addr,
+                            PROT_EXEC | PROT_READ | PROT_WRITE,
+                            (sr & SR_SM) != 0);
+        if (!excp) {
+            return phys_addr;
+        }
+        /* fallthru */
 
-    /* Last, fall back to a plain address */
-    if (miss) {
-        miss = get_phys_nommu(&phys_addr, &prot, addr);
-    }
-
-    if (miss) {
-        return -1;
-    } else {
+    case 0:
+        /* The mmu is definitely disabled; lookups never fail.  */
+        get_phys_nommu(&phys_addr, &prot, addr);
         return phys_addr;
     }
 }
@@ -222,37 +157,28 @@ void tlb_fill(CPUState *cs, target_ulong addr, int size,
               MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
 {
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
-    int ret, prot = 0;
-    hwaddr physical = 0;
+    int prot, excp;
+    hwaddr phys_addr;
 
     if (mmu_idx == MMU_NOMMU_IDX) {
-        ret = get_phys_nommu(&physical, &prot, addr);
+        /* The mmu is disabled; lookups never fail.  */
+        get_phys_nommu(&phys_addr, &prot, addr);
+        excp = 0;
     } else {
         bool super = mmu_idx == MMU_SUPERVISOR_IDX;
-        if (access_type == MMU_INST_FETCH) {
-            ret = get_phys_code(cpu, &physical, &prot, addr, 2, super);
-        } else {
-            ret = get_phys_data(cpu, &physical, &prot, addr,
-                                access_type == MMU_DATA_STORE, super);
-        }
+        int need = (access_type == MMU_INST_FETCH ? PROT_EXEC
+                    : access_type == MMU_DATA_STORE ? PROT_WRITE
+                    : PROT_READ);
+        excp = get_phys_mmu(cpu, &phys_addr, &prot, addr, need, super);
     }
 
-    if (ret == TLBRET_MATCH) {
-        tlb_set_page(cs, addr & TARGET_PAGE_MASK,
-                     physical & TARGET_PAGE_MASK, prot,
-                     mmu_idx, TARGET_PAGE_SIZE);
-    } else if (ret < 0) {
-        int rw;
-        if (access_type == MMU_INST_FETCH) {
-            rw = 2;
-        } else if (access_type == MMU_DATA_STORE) {
-            rw = 1;
-        } else {
-            rw = 0;
-        }
-        cpu_openrisc_raise_mmu_exception(cpu, addr, rw, ret);
-        /* Raise Exception.  */
+    if (unlikely(excp)) {
+        raise_mmu_exception(cpu, addr, excp);
         cpu_loop_exit_restore(cs, retaddr);
     }
+
+    tlb_set_page(cs, addr & TARGET_PAGE_MASK,
+                 phys_addr & TARGET_PAGE_MASK, prot,
+                 mmu_idx, TARGET_PAGE_SIZE);
 }
 #endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 19/22] target/openrisc: Add print_insn_or1k
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (17 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 18/22] target/openrisc: Reorg tlb lookup Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-27 16:03   ` Philippe Mathieu-Daudé
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 20/22] target/openrisc: Add support in scripts/qemu-binfmt-conf.sh Richard Henderson
                   ` (4 subsequent siblings)
  23 siblings, 1 reply; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Rather than emit disassembly while translating, reuse the
generated decoder to build a separate disassembler.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/cpu.h         |   1 +
 target/openrisc/cpu.c         |   6 ++
 target/openrisc/disas.c       | 170 ++++++++++++++++++++++++++++++++++
 target/openrisc/translate.c   | 114 -----------------------
 target/openrisc/Makefile.objs |   3 +-
 5 files changed, 179 insertions(+), 115 deletions(-)
 create mode 100644 target/openrisc/disas.c

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 1efffa5269..f1b31bc24a 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -348,6 +348,7 @@ void openrisc_translate_init(void);
 int openrisc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size,
                                   int rw, int mmu_idx);
 int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc);
+int print_insn_or1k(bfd_vma addr, disassemble_info *info);
 
 #define cpu_list cpu_openrisc_list
 #define cpu_signal_handler cpu_openrisc_signal_handler
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index 677f02efa4..e01ce9ed1c 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -35,6 +35,11 @@ static bool openrisc_cpu_has_work(CPUState *cs)
                                     CPU_INTERRUPT_TIMER);
 }
 
+static void openrisc_disas_set_info(CPUState *cpu, disassemble_info *info)
+{
+    info->print_insn = print_insn_or1k;
+}
+
 /* CPUClass::reset() */
 static void openrisc_cpu_reset(CPUState *s)
 {
@@ -150,6 +155,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
 #endif
     cc->gdb_num_core_regs = 32 + 3;
     cc->tcg_initialize = openrisc_translate_init;
+    cc->disas_set_info = openrisc_disas_set_info;
 }
 
 /* Sort alphabetically by type name, except for "any". */
diff --git a/target/openrisc/disas.c b/target/openrisc/disas.c
new file mode 100644
index 0000000000..5acf4f4744
--- /dev/null
+++ b/target/openrisc/disas.c
@@ -0,0 +1,170 @@
+/*
+ * OpenRISC disassembler
+ *
+ * Copyright (c) 2018 Richard Henderson <rth@twiddle.net>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "disas/bfd.h"
+#include "qemu/bitops.h"
+#include "cpu.h"
+
+typedef disassemble_info DisasContext;
+
+/* Include the auto-generated decoder.  */
+#include "decode.inc.c"
+
+#define output(mnemonic, format, ...) \
+    info->fprintf_func(info->stream, "%-9s " format, \
+                       mnemonic, ##__VA_ARGS__)
+
+int print_insn_or1k(bfd_vma addr, disassemble_info *info)
+{
+    bfd_byte buffer[4];
+    uint32_t insn;
+    int status;
+
+    status = info->read_memory_func(addr, buffer, 4, info);
+    if (status != 0) {
+        info->memory_error_func(status, addr, info);
+        return -1;
+    }
+    insn = bfd_getb32(buffer);
+
+    if (!decode(info, insn)) {
+        output(".long", "%#08x", insn);
+    }
+    return 4;
+}
+
+#define INSN(opcode, format, ...) \
+static bool trans_l_##opcode(disassemble_info *info,    \
+    arg_l_##opcode *a, uint32_t insn)                   \
+{                                                       \
+    output("l." #opcode, format, ##__VA_ARGS__);        \
+    return true;                                        \
+}
+
+INSN(add,    "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(addc,   "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(sub,    "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(and,    "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(or,     "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(xor,    "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(sll,    "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(srl,    "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(sra,    "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(ror,    "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(exths,  "r%d, r%d", a->d, a->a)
+INSN(extbs,  "r%d, r%d", a->d, a->a)
+INSN(exthz,  "r%d, r%d", a->d, a->a)
+INSN(extbz,  "r%d, r%d", a->d, a->a)
+INSN(cmov,   "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(ff1,    "r%d, r%d", a->d, a->a)
+INSN(fl1,    "r%d, r%d", a->d, a->a)
+INSN(mul,    "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(mulu,   "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(div,    "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(divu,   "r%d, r%d, r%d", a->d, a->a, a->b)
+INSN(muld,   "r%d, r%d", a->a, a->b)
+INSN(muldu,  "r%d, r%d", a->a, a->b)
+INSN(j,      "%d", a->n)
+INSN(jal,    "%d", a->n)
+INSN(bf,     "%d", a->n)
+INSN(bnf,    "%d", a->n)
+INSN(jr,     "r%d", a->b)
+INSN(jalr,   "r%d", a->b)
+INSN(lwa,    "r%d, %d(r%d)", a->d, a->i, a->a)
+INSN(lwz,    "r%d, %d(r%d)", a->d, a->i, a->a)
+INSN(lws,    "r%d, %d(r%d)", a->d, a->i, a->a)
+INSN(lbz,    "r%d, %d(r%d)", a->d, a->i, a->a)
+INSN(lbs,    "r%d, %d(r%d)", a->d, a->i, a->a)
+INSN(lhz,    "r%d, %d(r%d)", a->d, a->i, a->a)
+INSN(lhs,    "r%d, %d(r%d)", a->d, a->i, a->a)
+INSN(swa,    "%d(r%d), r%d", a->i, a->a, a->b)
+INSN(sw,     "%d(r%d), r%d", a->i, a->a, a->b)
+INSN(sb,     "%d(r%d), r%d", a->i, a->a, a->b)
+INSN(sh,     "%d(r%d), r%d", a->i, a->a, a->b)
+INSN(nop,    "")
+INSN(addi,   "r%d, r%d, %d", a->d, a->a, a->i)
+INSN(addic,  "r%d, r%d, %d", a->d, a->a, a->i)
+INSN(muli,   "r%d, r%d, %d", a->d, a->a, a->i)
+INSN(maci,   "r%d, %d", a->a, a->i)
+INSN(andi,   "r%d, r%d, %d", a->d, a->a, a->k)
+INSN(ori,    "r%d, r%d, %d", a->d, a->a, a->k)
+INSN(xori,   "r%d, r%d, %d", a->d, a->a, a->i)
+INSN(mfspr,  "r%d, r%d, %d", a->d, a->a, a->k)
+INSN(mtspr,  "r%d, r%d, %d", a->a, a->b, a->k)
+INSN(mac,    "r%d, r%d", a->a, a->b)
+INSN(msb,    "r%d, r%d", a->a, a->b)
+INSN(macu,   "r%d, r%d", a->a, a->b)
+INSN(msbu,   "r%d, r%d", a->a, a->b)
+INSN(slli,   "r%d, r%d, %d", a->d, a->a, a->l)
+INSN(srli,   "r%d, r%d, %d", a->d, a->a, a->l)
+INSN(srai,   "r%d, r%d, %d", a->d, a->a, a->l)
+INSN(rori,   "r%d, r%d, %d", a->d, a->a, a->l)
+INSN(movhi,  "r%d, %d", a->d, a->k)
+INSN(macrc,  "r%d", a->d)
+INSN(sfeq,   "r%d, r%d", a->a, a->b)
+INSN(sfne,   "r%d, r%d", a->a, a->b)
+INSN(sfgtu,  "r%d, r%d", a->a, a->b)
+INSN(sfgeu,  "r%d, r%d", a->a, a->b)
+INSN(sfltu,  "r%d, r%d", a->a, a->b)
+INSN(sfleu,  "r%d, r%d", a->a, a->b)
+INSN(sfgts,  "r%d, r%d", a->a, a->b)
+INSN(sfges,  "r%d, r%d", a->a, a->b)
+INSN(sflts,  "r%d, r%d", a->a, a->b)
+INSN(sfles,  "r%d, r%d", a->a, a->b)
+INSN(sfeqi,  "r%d, %d", a->a, a->i)
+INSN(sfnei,  "r%d, %d", a->a, a->i)
+INSN(sfgtui, "r%d, %d", a->a, a->i)
+INSN(sfgeui, "r%d, %d", a->a, a->i)
+INSN(sfltui, "r%d, %d", a->a, a->i)
+INSN(sfleui, "r%d, %d", a->a, a->i)
+INSN(sfgtsi, "r%d, %d", a->a, a->i)
+INSN(sfgesi, "r%d, %d", a->a, a->i)
+INSN(sfltsi, "r%d, %d", a->a, a->i)
+INSN(sflesi, "r%d, %d", a->a, a->i)
+INSN(sys,    "%d", a->k)
+INSN(trap,   "%d", a->k)
+INSN(msync,  "")
+INSN(psync,  "")
+INSN(csync,  "")
+INSN(rfe,    "")
+
+#define FP_INSN(opcode, suffix, format, ...) \
+static bool trans_lf_##opcode##_##suffix(disassemble_info *info, \
+    arg_lf_##opcode##_##suffix *a, uint32_t insn)                \
+{                                                                \
+    output("lf." #opcode "." #suffix, format, ##__VA_ARGS__);    \
+    return true;                                                 \
+}
+
+FP_INSN(add, s,  "r%d, r%d, r%d", a->d, a->a, a->b)
+FP_INSN(sub, s,  "r%d, r%d, r%d", a->d, a->a, a->b)
+FP_INSN(mul, s,  "r%d, r%d, r%d", a->d, a->a, a->b)
+FP_INSN(div, s,  "r%d, r%d, r%d", a->d, a->a, a->b)
+FP_INSN(rem, s,  "r%d, r%d, r%d", a->d, a->a, a->b)
+FP_INSN(itof, s, "r%d, r%d", a->d, a->a)
+FP_INSN(ftoi, s, "r%d, r%d", a->d, a->a)
+FP_INSN(madd, s, "r%d, r%d, r%d", a->d, a->a, a->b)
+FP_INSN(sfeq, s, "r%d, r%d", a->a, a->b)
+FP_INSN(sfne, s, "r%d, r%d", a->a, a->b)
+FP_INSN(sfgt, s, "r%d, r%d", a->a, a->b)
+FP_INSN(sfge, s, "r%d, r%d", a->a, a->b)
+FP_INSN(sflt, s, "r%d, r%d", a->a, a->b)
+FP_INSN(sfle, s, "r%d, r%d", a->a, a->b)
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 60c6e19f4b..d0662f38c6 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -36,10 +36,6 @@
 #include "trace-tcg.h"
 #include "exec/log.h"
 
-#define LOG_DIS(str, ...) \
-    qemu_log_mask(CPU_LOG_TB_IN_ASM, "%08x: " str, dc->base.pc_next,    \
-                  ## __VA_ARGS__)
-
 /* is_jmp field values */
 #define DISAS_EXIT    DISAS_TARGET_0  /* force exit to main loop */
 #define DISAS_JUMP    DISAS_TARGET_1  /* exit via jmp_pc/jmp_pc_imm */
@@ -440,7 +436,6 @@ static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb)
 
 static bool trans_l_add(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("l.add r%d, r%d, r%d\n", a->d, a->a, a->b);
     check_r0_write(a->d);
     gen_add(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
@@ -448,7 +443,6 @@ static bool trans_l_add(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_addc(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("l.addc r%d, r%d, r%d\n", a->d, a->a, a->b);
     check_r0_write(a->d);
     gen_addc(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
@@ -456,7 +450,6 @@ static bool trans_l_addc(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_sub(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("l.sub r%d, r%d, r%d\n", a->d, a->a, a->b);
     check_r0_write(a->d);
     gen_sub(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
@@ -464,7 +457,6 @@ static bool trans_l_sub(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_and(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("l.and r%d, r%d, r%d\n", a->d, a->a, a->b);
     check_r0_write(a->d);
     tcg_gen_and_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
@@ -472,7 +464,6 @@ static bool trans_l_and(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_or(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("l.or r%d, r%d, r%d\n", a->d, a->a, a->b);
     check_r0_write(a->d);
     tcg_gen_or_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
@@ -480,7 +471,6 @@ static bool trans_l_or(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_xor(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("l.xor r%d, r%d, r%d\n", a->d, a->a, a->b);
     check_r0_write(a->d);
     tcg_gen_xor_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
@@ -488,7 +478,6 @@ static bool trans_l_xor(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_sll(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("l.sll r%d, r%d, r%d\n", a->d, a->a, a->b);
     check_r0_write(a->d);
     tcg_gen_shl_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
@@ -496,7 +485,6 @@ static bool trans_l_sll(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_srl(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("l.srl r%d, r%d, r%d\n", a->d, a->a, a->b);
     check_r0_write(a->d);
     tcg_gen_shr_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
@@ -504,7 +492,6 @@ static bool trans_l_srl(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_sra(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("l.sra r%d, r%d, r%d\n", a->d, a->a, a->b);
     check_r0_write(a->d);
     tcg_gen_sar_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
@@ -512,7 +499,6 @@ static bool trans_l_sra(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_ror(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("l.ror r%d, r%d, r%d\n", a->d, a->a, a->b);
     check_r0_write(a->d);
     tcg_gen_rotr_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
@@ -520,7 +506,6 @@ static bool trans_l_ror(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_exths(DisasContext *dc, arg_da *a, uint32_t insn)
 {
-    LOG_DIS("l.exths r%d, r%d\n", a->d, a->a);
     check_r0_write(a->d);
     tcg_gen_ext16s_tl(cpu_R[a->d], cpu_R[a->a]);
     return true;
@@ -528,7 +513,6 @@ static bool trans_l_exths(DisasContext *dc, arg_da *a, uint32_t insn)
 
 static bool trans_l_extbs(DisasContext *dc, arg_da *a, uint32_t insn)
 {
-    LOG_DIS("l.extbs r%d, r%d\n", a->d, a->a);
     check_r0_write(a->d);
     tcg_gen_ext8s_tl(cpu_R[a->d], cpu_R[a->a]);
     return true;
@@ -536,7 +520,6 @@ static bool trans_l_extbs(DisasContext *dc, arg_da *a, uint32_t insn)
 
 static bool trans_l_exthz(DisasContext *dc, arg_da *a, uint32_t insn)
 {
-    LOG_DIS("l.exthz r%d, r%d\n", a->d, a->a);
     check_r0_write(a->d);
     tcg_gen_ext16u_tl(cpu_R[a->d], cpu_R[a->a]);
     return true;
@@ -544,7 +527,6 @@ static bool trans_l_exthz(DisasContext *dc, arg_da *a, uint32_t insn)
 
 static bool trans_l_extbz(DisasContext *dc, arg_da *a, uint32_t insn)
 {
-    LOG_DIS("l.extbz r%d, r%d\n", a->d, a->a);
     check_r0_write(a->d);
     tcg_gen_ext8u_tl(cpu_R[a->d], cpu_R[a->a]);
     return true;
@@ -553,7 +535,6 @@ static bool trans_l_extbz(DisasContext *dc, arg_da *a, uint32_t insn)
 static bool trans_l_cmov(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
     TCGv zero;
-    LOG_DIS("l.cmov r%d, r%d, r%d\n", a->d, a->a, a->b);
 
     check_r0_write(a->d);
     zero = tcg_const_tl(0);
@@ -565,8 +546,6 @@ static bool trans_l_cmov(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_ff1(DisasContext *dc, arg_da *a, uint32_t insn)
 {
-    LOG_DIS("l.ff1 r%d, r%d\n", a->d, a->a);
-
     check_r0_write(a->d);
     tcg_gen_ctzi_tl(cpu_R[a->d], cpu_R[a->a], -1);
     tcg_gen_addi_tl(cpu_R[a->d], cpu_R[a->d], 1);
@@ -575,8 +554,6 @@ static bool trans_l_ff1(DisasContext *dc, arg_da *a, uint32_t insn)
 
 static bool trans_l_fl1(DisasContext *dc, arg_da *a, uint32_t insn)
 {
-    LOG_DIS("l.fl1 r%d, r%d\n", a->d, a->a);
-
     check_r0_write(a->d);
     tcg_gen_clzi_tl(cpu_R[a->d], cpu_R[a->a], TARGET_LONG_BITS);
     tcg_gen_subfi_tl(cpu_R[a->d], TARGET_LONG_BITS, cpu_R[a->d]);
@@ -585,8 +562,6 @@ static bool trans_l_fl1(DisasContext *dc, arg_da *a, uint32_t insn)
 
 static bool trans_l_mul(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("l.mul r%d, r%d, r%d\n", a->d, a->a, a->b);
-
     check_r0_write(a->d);
     gen_mul(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
@@ -594,8 +569,6 @@ static bool trans_l_mul(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_mulu(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("l.mulu r%d, r%d, r%d\n", a->d, a->a, a->b);
-
     check_r0_write(a->d);
     gen_mulu(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
@@ -603,8 +576,6 @@ static bool trans_l_mulu(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_div(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("l.div r%d, r%d, r%d\n", a->d, a->a, a->b);
-
     check_r0_write(a->d);
     gen_div(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
@@ -612,8 +583,6 @@ static bool trans_l_div(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_divu(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("l.divu r%d, r%d, r%d\n", a->d, a->a, a->b);
-
     check_r0_write(a->d);
     gen_divu(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
@@ -621,14 +590,12 @@ static bool trans_l_divu(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_l_muld(DisasContext *dc, arg_ab *a, uint32_t insn)
 {
-    LOG_DIS("l.muld r%d, r%d\n", a->a, a->b);
     gen_muld(dc, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_muldu(DisasContext *dc, arg_ab *a, uint32_t insn)
 {
-    LOG_DIS("l.muldu r%d, r%d\n", a->a, a->b);
     gen_muldu(dc, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
@@ -637,7 +604,6 @@ static bool trans_l_j(DisasContext *dc, arg_l_j *a, uint32_t insn)
 {
     target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
 
-    LOG_DIS("l.j %d\n", a->n);
     tcg_gen_movi_tl(jmp_pc, tmp_pc);
     dc->jmp_pc_imm = tmp_pc;
     dc->delayed_branch = 2;
@@ -649,7 +615,6 @@ static bool trans_l_jal(DisasContext *dc, arg_l_jal *a, uint32_t insn)
     target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
     target_ulong ret_pc = dc->base.pc_next + 8;
 
-    LOG_DIS("l.jal %d\n", a->n);
     tcg_gen_movi_tl(cpu_R[9], ret_pc);
     /* Optimize jal being used to load the PC for PIC.  */
     if (tmp_pc != ret_pc) {
@@ -677,21 +642,18 @@ static void do_bf(DisasContext *dc, arg_l_bf *a, TCGCond cond)
 
 static bool trans_l_bf(DisasContext *dc, arg_l_bf *a, uint32_t insn)
 {
-    LOG_DIS("l.bf %d\n", a->n);
     do_bf(dc, a, TCG_COND_NE);
     return true;
 }
 
 static bool trans_l_bnf(DisasContext *dc, arg_l_bf *a, uint32_t insn)
 {
-    LOG_DIS("l.bnf %d\n", a->n);
     do_bf(dc, a, TCG_COND_EQ);
     return true;
 }
 
 static bool trans_l_jr(DisasContext *dc, arg_l_jr *a, uint32_t insn)
 {
-    LOG_DIS("l.jr r%d\n", a->b);
     tcg_gen_mov_tl(jmp_pc, cpu_R[a->b]);
     dc->delayed_branch = 2;
     return true;
@@ -699,7 +661,6 @@ static bool trans_l_jr(DisasContext *dc, arg_l_jr *a, uint32_t insn)
 
 static bool trans_l_jalr(DisasContext *dc, arg_l_jalr *a, uint32_t insn)
 {
-    LOG_DIS("l.jalr r%d\n", a->b);
     tcg_gen_mov_tl(jmp_pc, cpu_R[a->b]);
     tcg_gen_movi_tl(cpu_R[9], dc->base.pc_next + 8);
     dc->delayed_branch = 2;
@@ -710,8 +671,6 @@ static bool trans_l_lwa(DisasContext *dc, arg_load *a, uint32_t insn)
 {
     TCGv ea;
 
-    LOG_DIS("l.lwa r%d, r%d, %d\n", a->d, a->a, a->i);
-
     check_r0_write(a->d);
     ea = tcg_temp_new();
     tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
@@ -735,42 +694,36 @@ static void do_load(DisasContext *dc, arg_load *a, TCGMemOp mop)
 
 static bool trans_l_lwz(DisasContext *dc, arg_load *a, uint32_t insn)
 {
-    LOG_DIS("l.lwz r%d, r%d, %d\n", a->d, a->a, a->i);
     do_load(dc, a, MO_TEUL);
     return true;
 }
 
 static bool trans_l_lws(DisasContext *dc, arg_load *a, uint32_t insn)
 {
-    LOG_DIS("l.lws r%d, r%d, %d\n", a->d, a->a, a->i);
     do_load(dc, a, MO_TESL);
     return true;
 }
 
 static bool trans_l_lbz(DisasContext *dc, arg_load *a, uint32_t insn)
 {
-    LOG_DIS("l.lbz r%d, r%d, %d\n", a->d, a->a, a->i);
     do_load(dc, a, MO_UB);
     return true;
 }
 
 static bool trans_l_lbs(DisasContext *dc, arg_load *a, uint32_t insn)
 {
-    LOG_DIS("l.lbs r%d, r%d, %d\n", a->d, a->a, a->i);
     do_load(dc, a, MO_SB);
     return true;
 }
 
 static bool trans_l_lhz(DisasContext *dc, arg_load *a, uint32_t insn)
 {
-    LOG_DIS("l.lhz r%d, r%d, %d\n", a->d, a->a, a->i);
     do_load(dc, a, MO_TEUW);
     return true;
 }
 
 static bool trans_l_lhs(DisasContext *dc, arg_load *a, uint32_t insn)
 {
-    LOG_DIS("l.lhs r%d, r%d, %d\n", a->d, a->a, a->i);
     do_load(dc, a, MO_TESW);
     return true;
 }
@@ -780,8 +733,6 @@ static bool trans_l_swa(DisasContext *dc, arg_store *a, uint32_t insn)
     TCGv ea, val;
     TCGLabel *lab_fail, *lab_done;
 
-    LOG_DIS("l.swa r%d, r%d, %d\n", a->a, a->b, a->i);
-
     ea = tcg_temp_new();
     tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
 
@@ -822,28 +773,24 @@ static void do_store(DisasContext *dc, arg_store *a, TCGMemOp mop)
 
 static bool trans_l_sw(DisasContext *dc, arg_store *a, uint32_t insn)
 {
-    LOG_DIS("l.sw r%d, r%d, %d\n", a->a, a->b, a->i);
     do_store(dc, a, MO_TEUL);
     return true;
 }
 
 static bool trans_l_sb(DisasContext *dc, arg_store *a, uint32_t insn)
 {
-    LOG_DIS("l.sb r%d, r%d, %d\n", a->a, a->b, a->i);
     do_store(dc, a, MO_UB);
     return true;
 }
 
 static bool trans_l_sh(DisasContext *dc, arg_store *a, uint32_t insn)
 {
-    LOG_DIS("l.sh r%d, r%d, %d\n", a->a, a->b, a->i);
     do_store(dc, a, MO_TEUW);
     return true;
 }
 
 static bool trans_l_nop(DisasContext *dc, arg_l_nop *a, uint32_t insn)
 {
-    LOG_DIS("l.nop %d\n", a->k);
     return true;
 }
 
@@ -851,7 +798,6 @@ static bool trans_l_addi(DisasContext *dc, arg_rri *a, uint32_t insn)
 {
     TCGv t0;
 
-    LOG_DIS("l.addi r%d, r%d, %d\n", a->d, a->a, a->i);
     check_r0_write(a->d);
     t0 = tcg_const_tl(a->i);
     gen_add(dc, cpu_R[a->d], cpu_R[a->a], t0);
@@ -863,7 +809,6 @@ static bool trans_l_addic(DisasContext *dc, arg_rri *a, uint32_t insn)
 {
     TCGv t0;
 
-    LOG_DIS("l.addic r%d, r%d, %d\n", a->d, a->a, a->i);
     check_r0_write(a->d);
     t0 = tcg_const_tl(a->i);
     gen_addc(dc, cpu_R[a->d], cpu_R[a->a], t0);
@@ -875,7 +820,6 @@ static bool trans_l_muli(DisasContext *dc, arg_rri *a, uint32_t insn)
 {
     TCGv t0;
 
-    LOG_DIS("l.muli r%d, r%d, %d\n", a->d, a->a, a->i);
     check_r0_write(a->d);
     t0 = tcg_const_tl(a->i);
     gen_mul(dc, cpu_R[a->d], cpu_R[a->a], t0);
@@ -887,7 +831,6 @@ static bool trans_l_maci(DisasContext *dc, arg_l_maci *a, uint32_t insn)
 {
     TCGv t0;
 
-    LOG_DIS("l.maci r%d, %d\n", a->a, a->i);
     t0 = tcg_const_tl(a->i);
     gen_mac(dc, cpu_R[a->a], t0);
     tcg_temp_free(t0);
@@ -896,7 +839,6 @@ static bool trans_l_maci(DisasContext *dc, arg_l_maci *a, uint32_t insn)
 
 static bool trans_l_andi(DisasContext *dc, arg_rrk *a, uint32_t insn)
 {
-    LOG_DIS("l.andi r%d, r%d, %d\n", a->d, a->a, a->k);
     check_r0_write(a->d);
     tcg_gen_andi_tl(cpu_R[a->d], cpu_R[a->a], a->k);
     return true;
@@ -904,7 +846,6 @@ static bool trans_l_andi(DisasContext *dc, arg_rrk *a, uint32_t insn)
 
 static bool trans_l_ori(DisasContext *dc, arg_rrk *a, uint32_t insn)
 {
-    LOG_DIS("l.ori r%d, r%d, %d\n", a->d, a->a, a->k);
     check_r0_write(a->d);
     tcg_gen_ori_tl(cpu_R[a->d], cpu_R[a->a], a->k);
     return true;
@@ -912,7 +853,6 @@ static bool trans_l_ori(DisasContext *dc, arg_rrk *a, uint32_t insn)
 
 static bool trans_l_xori(DisasContext *dc, arg_rri *a, uint32_t insn)
 {
-    LOG_DIS("l.xori r%d, r%d, %d\n", a->d, a->a, a->i);
     check_r0_write(a->d);
     tcg_gen_xori_tl(cpu_R[a->d], cpu_R[a->a], a->i);
     return true;
@@ -920,7 +860,6 @@ static bool trans_l_xori(DisasContext *dc, arg_rri *a, uint32_t insn)
 
 static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a, uint32_t insn)
 {
-    LOG_DIS("l.mfspr r%d, r%d, %d\n", a->d, a->a, a->k);
     check_r0_write(a->d);
 
     if (is_user(dc)) {
@@ -936,8 +875,6 @@ static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a, uint32_t insn)
 
 static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a, uint32_t insn)
 {
-    LOG_DIS("l.mtspr r%d, r%d, %d\n", a->a, a->b, a->k);
-
     if (is_user(dc)) {
         gen_illegal_exception(dc);
     } else {
@@ -973,35 +910,30 @@ static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a, uint32_t insn)
 
 static bool trans_l_mac(DisasContext *dc, arg_ab *a, uint32_t insn)
 {
-    LOG_DIS("l.mac r%d, r%d\n", a->a, a->b);
     gen_mac(dc, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_msb(DisasContext *dc, arg_ab *a, uint32_t insn)
 {
-    LOG_DIS("l.msb r%d, r%d\n", a->a, a->b);
     gen_msb(dc, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_macu(DisasContext *dc, arg_ab *a, uint32_t insn)
 {
-    LOG_DIS("l.mac r%d, r%d\n", a->a, a->b);
     gen_macu(dc, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_msbu(DisasContext *dc, arg_ab *a, uint32_t insn)
 {
-    LOG_DIS("l.msb r%d, r%d\n", a->a, a->b);
     gen_msbu(dc, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_slli(DisasContext *dc, arg_dal *a, uint32_t insn)
 {
-    LOG_DIS("l.slli r%d, r%d, %d\n", a->d, a->a, a->l);
     check_r0_write(a->d);
     tcg_gen_shli_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
     return true;
@@ -1009,7 +941,6 @@ static bool trans_l_slli(DisasContext *dc, arg_dal *a, uint32_t insn)
 
 static bool trans_l_srli(DisasContext *dc, arg_dal *a, uint32_t insn)
 {
-    LOG_DIS("l.srli r%d, r%d, %d\n", a->d, a->a, a->l);
     check_r0_write(a->d);
     tcg_gen_shri_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
     return true;
@@ -1017,7 +948,6 @@ static bool trans_l_srli(DisasContext *dc, arg_dal *a, uint32_t insn)
 
 static bool trans_l_srai(DisasContext *dc, arg_dal *a, uint32_t insn)
 {
-    LOG_DIS("l.srai r%d, r%d, %d\n", a->d, a->a, a->l);
     check_r0_write(a->d);
     tcg_gen_sari_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
     return true;
@@ -1025,7 +955,6 @@ static bool trans_l_srai(DisasContext *dc, arg_dal *a, uint32_t insn)
 
 static bool trans_l_rori(DisasContext *dc, arg_dal *a, uint32_t insn)
 {
-    LOG_DIS("l.rori r%d, r%d, %d\n", a->d, a->a, a->l);
     check_r0_write(a->d);
     tcg_gen_rotri_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
     return true;
@@ -1033,7 +962,6 @@ static bool trans_l_rori(DisasContext *dc, arg_dal *a, uint32_t insn)
 
 static bool trans_l_movhi(DisasContext *dc, arg_l_movhi *a, uint32_t insn)
 {
-    LOG_DIS("l.movhi r%d, %d\n", a->d, a->k);
     check_r0_write(a->d);
     tcg_gen_movi_tl(cpu_R[a->d], a->k << 16);
     return true;
@@ -1041,7 +969,6 @@ static bool trans_l_movhi(DisasContext *dc, arg_l_movhi *a, uint32_t insn)
 
 static bool trans_l_macrc(DisasContext *dc, arg_l_macrc *a, uint32_t insn)
 {
-    LOG_DIS("l.macrc r%d\n", a->d);
     check_r0_write(a->d);
     tcg_gen_trunc_i64_tl(cpu_R[a->d], cpu_mac);
     tcg_gen_movi_i64(cpu_mac, 0);
@@ -1050,147 +977,126 @@ static bool trans_l_macrc(DisasContext *dc, arg_l_macrc *a, uint32_t insn)
 
 static bool trans_l_sfeq(DisasContext *dc, arg_ab *a, TCGCond cond)
 {
-    LOG_DIS("l.sfeq r%d, r%d\n", a->a, a->b);
     tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_sfne(DisasContext *dc, arg_ab *a, TCGCond cond)
 {
-    LOG_DIS("l.sfne r%d, r%d\n", a->a, a->b);
     tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_sfgtu(DisasContext *dc, arg_ab *a, TCGCond cond)
 {
-    LOG_DIS("l.sfgtu r%d, r%d\n", a->a, a->b);
     tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_sfgeu(DisasContext *dc, arg_ab *a, TCGCond cond)
 {
-    LOG_DIS("l.sfgeu r%d, r%d\n", a->a, a->b);
     tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_sfltu(DisasContext *dc, arg_ab *a, TCGCond cond)
 {
-    LOG_DIS("l.sfltu r%d, r%d\n", a->a, a->b);
     tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_sfleu(DisasContext *dc, arg_ab *a, TCGCond cond)
 {
-    LOG_DIS("l.sfleu r%d, r%d\n", a->a, a->b);
     tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_sfgts(DisasContext *dc, arg_ab *a, TCGCond cond)
 {
-    LOG_DIS("l.sfgts r%d, r%d\n", a->a, a->b);
     tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_sfges(DisasContext *dc, arg_ab *a, TCGCond cond)
 {
-    LOG_DIS("l.sfges r%d, r%d\n", a->a, a->b);
     tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_sflts(DisasContext *dc, arg_ab *a, TCGCond cond)
 {
-    LOG_DIS("l.sflts r%d, r%d\n", a->a, a->b);
     tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_sfles(DisasContext *dc, arg_ab *a, TCGCond cond)
 {
-    LOG_DIS("l.sfles r%d, r%d\n", a->a, a->b);
     tcg_gen_setcond_tl(TCG_COND_LE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_sfeqi(DisasContext *dc, arg_ai *a, TCGCond cond)
 {
-    LOG_DIS("l.sfeqi r%d, %d\n", a->a, a->i);
     tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[a->a], a->i);
     return true;
 }
 
 static bool trans_l_sfnei(DisasContext *dc, arg_ai *a, TCGCond cond)
 {
-    LOG_DIS("l.sfnei r%d, %d\n", a->a, a->i);
     tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R[a->a], a->i);
     return true;
 }
 
 static bool trans_l_sfgtui(DisasContext *dc, arg_ai *a, TCGCond cond)
 {
-    LOG_DIS("l.sfgtui r%d, %d\n", a->a, a->i);
     tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[a->a], a->i);
     return true;
 }
 
 static bool trans_l_sfgeui(DisasContext *dc, arg_ai *a, TCGCond cond)
 {
-    LOG_DIS("l.sfgeui r%d, %d\n", a->a, a->i);
     tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[a->a], a->i);
     return true;
 }
 
 static bool trans_l_sfltui(DisasContext *dc, arg_ai *a, TCGCond cond)
 {
-    LOG_DIS("l.sfltui r%d, %d\n", a->a, a->i);
     tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[a->a], a->i);
     return true;
 }
 
 static bool trans_l_sfleui(DisasContext *dc, arg_ai *a, TCGCond cond)
 {
-    LOG_DIS("l.sfleui r%d, %d\n", a->a, a->i);
     tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[a->a], a->i);
     return true;
 }
 
 static bool trans_l_sfgtsi(DisasContext *dc, arg_ai *a, TCGCond cond)
 {
-    LOG_DIS("l.sfgtsi r%d, %d\n", a->a, a->i);
     tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R[a->a], a->i);
     return true;
 }
 
 static bool trans_l_sfgesi(DisasContext *dc, arg_ai *a, TCGCond cond)
 {
-    LOG_DIS("l.sfgesi r%d, %d\n", a->a, a->i);
     tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R[a->a], a->i);
     return true;
 }
 
 static bool trans_l_sfltsi(DisasContext *dc, arg_ai *a, TCGCond cond)
 {
-    LOG_DIS("l.sfltsi r%d, %d\n", a->a, a->i);
     tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R[a->a], a->i);
     return true;
 }
 
 static bool trans_l_sflesi(DisasContext *dc, arg_ai *a, TCGCond cond)
 {
-    LOG_DIS("l.sflesi r%d, %d\n", a->a, a->i);
     tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R[a->a], a->i);
     return true;
 }
 
 static bool trans_l_sys(DisasContext *dc, arg_l_sys *a, uint32_t insn)
 {
-    LOG_DIS("l.sys %d\n", a->k);
     tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
     gen_exception(dc, EXCP_SYSCALL);
     dc->base.is_jmp = DISAS_NORETURN;
@@ -1199,7 +1105,6 @@ static bool trans_l_sys(DisasContext *dc, arg_l_sys *a, uint32_t insn)
 
 static bool trans_l_trap(DisasContext *dc, arg_l_trap *a, uint32_t insn)
 {
-    LOG_DIS("l.trap %d\n", a->k);
     tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
     gen_exception(dc, EXCP_TRAP);
     dc->base.is_jmp = DISAS_NORETURN;
@@ -1208,27 +1113,22 @@ static bool trans_l_trap(DisasContext *dc, arg_l_trap *a, uint32_t insn)
 
 static bool trans_l_msync(DisasContext *dc, arg_l_msync *a, uint32_t insn)
 {
-    LOG_DIS("l.msync\n");
     tcg_gen_mb(TCG_MO_ALL);
     return true;
 }
 
 static bool trans_l_psync(DisasContext *dc, arg_l_psync *a, uint32_t insn)
 {
-    LOG_DIS("l.psync\n");
     return true;
 }
 
 static bool trans_l_csync(DisasContext *dc, arg_l_csync *a, uint32_t insn)
 {
-    LOG_DIS("l.csync\n");
     return true;
 }
 
 static bool trans_l_rfe(DisasContext *dc, arg_l_rfe *a, uint32_t insn)
 {
-    LOG_DIS("l.rfe\n");
-
     if (is_user(dc)) {
         gen_illegal_exception(dc);
     } else {
@@ -1271,56 +1171,48 @@ static void do_fpcmp(DisasContext *dc, arg_ab *a,
 
 static bool trans_lf_add_s(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("lf.add.s r%d, r%d, r%d\n", a->d, a->a, a->b);
     do_fp3(dc, a, gen_helper_float_add_s);
     return true;
 }
 
 static bool trans_lf_sub_s(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("lf.sub.s r%d, r%d, r%d\n", a->d, a->a, a->b);
     do_fp3(dc, a, gen_helper_float_sub_s);
     return true;
 }
 
 static bool trans_lf_mul_s(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("lf.mul.s r%d, r%d, r%d\n", a->d, a->a, a->b);
     do_fp3(dc, a, gen_helper_float_mul_s);
     return true;
 }
 
 static bool trans_lf_div_s(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("lf.div.s r%d, r%d, r%d\n", a->d, a->a, a->b);
     do_fp3(dc, a, gen_helper_float_div_s);
     return true;
 }
 
 static bool trans_lf_rem_s(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("lf.rem.s r%d, r%d, r%d\n", a->d, a->a, a->b);
     do_fp3(dc, a, gen_helper_float_rem_s);
     return true;
 }
 
 static bool trans_lf_itof_s(DisasContext *dc, arg_da *a, uint32_t insn)
 {
-    LOG_DIS("lf.itof.s r%d, r%d\n", a->d, a->a);
     do_fp2(dc, a, gen_helper_itofs);
     return true;
 }
 
 static bool trans_lf_ftoi_s(DisasContext *dc, arg_da *a, uint32_t insn)
 {
-    LOG_DIS("lf.ftoi.s r%d, r%d\n", a->d, a->a);
     do_fp2(dc, a, gen_helper_ftois);
     return true;
 }
 
 static bool trans_lf_madd_s(DisasContext *dc, arg_dab *a, uint32_t insn)
 {
-    LOG_DIS("lf.madd.s r%d, r%d, r%d\n", a->d, a->a, a->b);
     check_r0_write(a->d);
     gen_helper_float_madd_s(cpu_R[a->d], cpu_env, cpu_R[a->d],
                             cpu_R[a->a], cpu_R[a->b]);
@@ -1330,42 +1222,36 @@ static bool trans_lf_madd_s(DisasContext *dc, arg_dab *a, uint32_t insn)
 
 static bool trans_lf_sfeq_s(DisasContext *dc, arg_ab *a, uint32_t insn)
 {
-    LOG_DIS("lf.sfeq.s r%d, r%d\n", a->a, a->b);
     do_fpcmp(dc, a, gen_helper_float_eq_s, false, false);
     return true;
 }
 
 static bool trans_lf_sfne_s(DisasContext *dc, arg_ab *a, uint32_t insn)
 {
-    LOG_DIS("lf.sfne.s r%d, r%d\n", a->a, a->b);
     do_fpcmp(dc, a, gen_helper_float_eq_s, true, false);
     return true;
 }
 
 static bool trans_lf_sfgt_s(DisasContext *dc, arg_ab *a, uint32_t insn)
 {
-    LOG_DIS("lf.sfgt.s r%d, r%d\n", a->a, a->b);
     do_fpcmp(dc, a, gen_helper_float_lt_s, false, true);
     return true;
 }
 
 static bool trans_lf_sfge_s(DisasContext *dc, arg_ab *a, uint32_t insn)
 {
-    LOG_DIS("lf.sfge.s r%d, r%d\n", a->a, a->b);
     do_fpcmp(dc, a, gen_helper_float_le_s, false, true);
     return true;
 }
 
 static bool trans_lf_sflt_s(DisasContext *dc, arg_ab *a, uint32_t insn)
 {
-    LOG_DIS("lf.sflt.s r%d, r%d\n", a->a, a->b);
     do_fpcmp(dc, a, gen_helper_float_lt_s, false, false);
     return true;
 }
 
 static bool trans_lf_sfle_s(DisasContext *dc, arg_ab *a, uint32_t insn)
 {
-    LOG_DIS("lf.sfle.s r%d, r%d\n", a->a, a->b);
     do_fpcmp(dc, a, gen_helper_float_le_s, false, false);
     return true;
 }
diff --git a/target/openrisc/Makefile.objs b/target/openrisc/Makefile.objs
index 957ce02199..b5432f4684 100644
--- a/target/openrisc/Makefile.objs
+++ b/target/openrisc/Makefile.objs
@@ -1,5 +1,5 @@
 obj-$(CONFIG_SOFTMMU) += machine.o
-obj-y += cpu.o exception.o interrupt.o mmu.o translate.o
+obj-y += cpu.o exception.o interrupt.o mmu.o translate.o disas.o
 obj-y += exception_helper.o fpu_helper.o \
          interrupt_helper.o sys_helper.o
 obj-y += gdbstub.o
@@ -12,3 +12,4 @@ target/openrisc/decode.inc.c: \
 	  $(PYTHON) $(DECODETREE) -o $@ $<, "GEN", $(TARGET_DIR)$@)
 
 target/openrisc/translate.o: target/openrisc/decode.inc.c
+target/openrisc/disas.o: target/openrisc/decode.inc.c
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 20/22] target/openrisc: Add support in scripts/qemu-binfmt-conf.sh
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (18 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 19/22] target/openrisc: Add print_insn_or1k Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-27 19:02   ` Laurent Vivier
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 21/22] linux-user: Implement signals for openrisc Richard Henderson
                   ` (3 subsequent siblings)
  23 siblings, 1 reply; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 scripts/qemu-binfmt-conf.sh | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
index d7eefda0b8..a5cb96d79a 100755
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -1,10 +1,10 @@
 #!/bin/sh
-# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390/HPPA/Xtensa/microblaze
-# program execution by the kernel
+# Enable automatic program execution by the kernel.
 
 qemu_target_list="i386 i486 alpha arm armeb sparc32plus ppc ppc64 ppc64le m68k \
 mips mipsel mipsn32 mipsn32el mips64 mips64el \
-sh4 sh4eb s390x aarch64 aarch64_be hppa riscv32 riscv64 xtensa xtensaeb microblaze microblazeel"
+sh4 sh4eb s390x aarch64 aarch64_be hppa riscv32 riscv64 xtensa xtensaeb \
+microblaze microblazeel or1k"
 
 i386_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'
 i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
@@ -124,6 +124,10 @@ microblazeel_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\
 microblazeel_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
 microblazeel_family=microblazeel
 
+or1k_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x5c'
+or1k_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+or1k_family=or1k
+
 qemu_get_family() {
     cpu=${HOST_ARCH:-$(uname -m)}
     case "$cpu" in
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 21/22] linux-user: Implement signals for openrisc
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (19 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 20/22] target/openrisc: Add support in scripts/qemu-binfmt-conf.sh Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-27 19:43   ` Laurent Vivier
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 22/22] linux-user: Fix struct sigaltstack " Richard Henderson
                   ` (2 subsequent siblings)
  23 siblings, 1 reply; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

All of the existing code was boilerplate from elsewhere,
and would crash the guest upon the first signal.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
v2:
  Add a comment to the new definition of target_pt_regs.
  Install the signal mask into the ucontext.
---
 linux-user/openrisc/target_syscall.h |  28 +---
 linux-user/openrisc/signal.c         | 212 +++++++++++----------------
 linux-user/signal.c                  |   2 +-
 target/openrisc/cpu.c                |   1 +
 4 files changed, 95 insertions(+), 148 deletions(-)

diff --git a/linux-user/openrisc/target_syscall.h b/linux-user/openrisc/target_syscall.h
index 03104f80af..d586d2a018 100644
--- a/linux-user/openrisc/target_syscall.h
+++ b/linux-user/openrisc/target_syscall.h
@@ -1,27 +1,15 @@
 #ifndef OPENRISC_TARGET_SYSCALL_H
 #define OPENRISC_TARGET_SYSCALL_H
 
+/* Note that in linux/arch/openrisc/include/uapi/asm/ptrace.h,
+ * this is called user_regs_struct.  Given that this is what
+ * is used within struct sigcontext we need this definition.
+ * However, elfload.c wants this name.
+ */
 struct target_pt_regs {
-    union {
-        struct {
-            /* Named registers */
-            uint32_t sr;       /* Stored in place of r0 */
-            target_ulong sp;   /* r1 */
-        };
-        struct {
-            /* Old style */
-            target_ulong offset[2];
-            target_ulong gprs[30];
-        };
-        struct {
-            /* New style */
-            target_ulong gpr[32];
-        };
-    };
-    target_ulong pc;
-    target_ulong orig_gpr11;   /* For restarting system calls */
-    uint32_t syscallno;        /* Syscall number (used by strace) */
-    target_ulong dummy;     /* Cheap alignment fix */
+    abi_ulong gpr[32];
+    abi_ulong pc;
+    abi_ulong sr;
 };
 
 #define UNAME_MACHINE "openrisc"
diff --git a/linux-user/openrisc/signal.c b/linux-user/openrisc/signal.c
index 8be0b74001..ea083ef15e 100644
--- a/linux-user/openrisc/signal.c
+++ b/linux-user/openrisc/signal.c
@@ -21,125 +21,79 @@
 #include "signal-common.h"
 #include "linux-user/trace.h"
 
-struct target_sigcontext {
+typedef struct target_sigcontext {
     struct target_pt_regs regs;
     abi_ulong oldmask;
-    abi_ulong usp;
-};
+} target_sigcontext;
 
-struct target_ucontext {
+typedef struct target_ucontext {
     abi_ulong tuc_flags;
     abi_ulong tuc_link;
     target_stack_t tuc_stack;
-    struct target_sigcontext tuc_mcontext;
+    target_sigcontext tuc_mcontext;
     target_sigset_t tuc_sigmask;   /* mask last for extensibility */
-};
+} target_ucontext;
 
-struct target_rt_sigframe {
-    abi_ulong pinfo;
-    uint64_t puc;
+typedef struct target_rt_sigframe {
     struct target_siginfo info;
-    struct target_sigcontext sc;
-    struct target_ucontext uc;
-    unsigned char retcode[16];  /* trampoline code */
-};
+    target_ucontext uc;
+    uint32_t retcode[4];  /* trampoline code */
+} target_rt_sigframe;
 
-/* This is the asm-generic/ucontext.h version */
-#if 0
-static int restore_sigcontext(CPUOpenRISCState *regs,
-                              struct target_sigcontext *sc)
+static void restore_sigcontext(CPUOpenRISCState *env, target_sigcontext *sc)
 {
-    unsigned int err = 0;
-    unsigned long old_usp;
+    int i;
+    abi_ulong v;
 
-    /* Alwys make any pending restarted system call return -EINTR */
-    current_thread_info()->restart_block.fn = do_no_restart_syscall;
-
-    /* restore the regs from &sc->regs (same as sc, since regs is first)
-     * (sc is already checked for VERIFY_READ since the sigframe was
-     *  checked in sys_sigreturn previously)
-     */
-
-    if (copy_from_user(regs, &sc, sizeof(struct target_pt_regs))) {
-        goto badframe;
+    for (i = 0; i < 32; ++i) {
+        __get_user(v, &sc->regs.gpr[i]);
+        cpu_set_gpr(env, i, v);
     }
+    __get_user(env->pc, &sc->regs.pc);
 
-    /* make sure the U-flag is set so user-mode cannot fool us */
-
-    regs->sr &= ~SR_SM;
-
-    /* restore the old USP as it was before we stacked the sc etc.
-     * (we cannot just pop the sigcontext since we aligned the sp and
-     *  stuff after pushing it)
-     */
-
-    __get_user(old_usp, &sc->usp);
-    phx_signal("old_usp 0x%lx", old_usp);
-
-    __PHX__ REALLY           /* ??? */
-    wrusp(old_usp);
-    regs->gpr[1] = old_usp;
-
-    /* TODO: the other ports use regs->orig_XX to disable syscall checks
-     * after this completes, but we don't use that mechanism. maybe we can
-     * use it now ?
-     */
-
-    return err;
-
-badframe:
-    return 1;
+    /* Make sure the supervisor flag is clear.  */
+    __get_user(v, &sc->regs.sr);
+    cpu_set_sr(env, v & ~SR_SM);
 }
-#endif
 
 /* Set up a signal frame.  */
 
-static void setup_sigcontext(struct target_sigcontext *sc,
-                             CPUOpenRISCState *regs,
-                             unsigned long mask)
+static void setup_sigcontext(target_sigcontext *sc, CPUOpenRISCState *env)
 {
-    unsigned long usp = cpu_get_gpr(regs, 1);
+    int i;
 
-    /* copy the regs. they are first in sc so we can use sc directly */
+    for (i = 0; i < 32; ++i) {
+        __put_user(cpu_get_gpr(env, i), &sc->regs.gpr[i]);
+    }
 
-    /*copy_to_user(&sc, regs, sizeof(struct target_pt_regs));*/
-
-    /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
-       the signal handler. The frametype will be restored to its previous
-       value in restore_sigcontext. */
-    /*regs->frametype = CRIS_FRAME_NORMAL;*/
-
-    /* then some other stuff */
-    __put_user(mask, &sc->oldmask);
-    __put_user(usp, &sc->usp);
+    __put_user(env->pc, &sc->regs.pc);
+    __put_user(cpu_get_sr(env), &sc->regs.sr);
 }
 
-static inline unsigned long align_sigframe(unsigned long sp)
+static inline target_ulong align_sigframe(target_ulong sp)
 {
-    return sp & ~3UL;
+    return QEMU_ALIGN_DOWN(sp, 4);
 }
 
 static inline abi_ulong get_sigframe(struct target_sigaction *ka,
-                                     CPUOpenRISCState *regs,
+                                     CPUOpenRISCState *env,
                                      size_t frame_size)
 {
-    unsigned long sp = get_sp_from_cpustate(regs);
+    target_ulong sp = get_sp_from_cpustate(env);
     int onsigstack = on_sig_stack(sp);
 
-    /* redzone */
-    sp = target_sigsp(sp, ka);
-
+    /* Honor redzone now.  If we swap to signal stack, no need to waste
+     * the 128 bytes by subtracting afterward.
+     */
+    sp = target_sigsp(sp - 128, ka);
     sp = align_sigframe(sp - frame_size);
 
-    /*
-     * If we are on the alternate signal stack and would overflow it, don't.
+    /* If we are on the alternate signal stack and would overflow it, don't.
      * Return an always-bogus address instead so we will die with SIGSEGV.
      */
-
-    if (onsigstack && !likely(on_sig_stack(sp))) {
+    if (onsigstack && !on_sig_stack(sp)) {
         return -1L;
     }
-
     return sp;
 }
 
@@ -147,11 +101,9 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
                     target_siginfo_t *info,
                     target_sigset_t *set, CPUOpenRISCState *env)
 {
-    int err = 0;
     abi_ulong frame_addr;
-    unsigned long return_ip;
-    struct target_rt_sigframe *frame;
-    abi_ulong info_addr, uc_addr;
+    target_rt_sigframe *frame;
+    int i;
 
     frame_addr = get_sigframe(ka, env, sizeof(*frame));
     trace_user_setup_rt_frame(env, frame_addr);
@@ -159,47 +111,35 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
         goto give_sigsegv;
     }
 
-    info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
-    __put_user(info_addr, &frame->pinfo);
-    uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
-    __put_user(uc_addr, &frame->puc);
+    tswap_siginfo(&frame->info, info);
 
-    if (ka->sa_flags & SA_SIGINFO) {
-        tswap_siginfo(&frame->info, info);
-    }
-
-    /*err |= __clear_user(&frame->uc, offsetof(ucontext_t, uc_mcontext));*/
     __put_user(0, &frame->uc.tuc_flags);
     __put_user(0, &frame->uc.tuc_link);
+
     target_save_altstack(&frame->uc.tuc_stack, env);
-    setup_sigcontext(&frame->sc, env, set->sig[0]);
-
-    /*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
-
-    /* trampoline - the desired return ip is the retcode itself */
-    return_ip = (unsigned long)&frame->retcode;
-    /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
-    __put_user(0xa960, (short *)(frame->retcode + 0));
-    __put_user(TARGET_NR_rt_sigreturn, (short *)(frame->retcode + 2));
-    __put_user(0x20000001, (unsigned long *)(frame->retcode + 4));
-    __put_user(0x15000000, (unsigned long *)(frame->retcode + 8));
-
-    if (err) {
-        goto give_sigsegv;
+    setup_sigcontext(&frame->uc.tuc_mcontext, env);
+    for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
+        __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
     }
 
-    /* TODO what is the current->exec_domain stuff and invmap ? */
+    /* This is l.ori r11,r0,__NR_sigreturn; l.sys 1; l.nop; l.nop */
+    __put_user(0xa9600000 | TARGET_NR_rt_sigreturn, frame->retcode + 0);
+    __put_user(0x20000001, frame->retcode + 1);
+    __put_user(0x15000000, frame->retcode + 2);
+    __put_user(0x15000000, frame->retcode + 3);
 
     /* Set up registers for signal handler */
-    env->pc = (unsigned long)ka->_sa_handler; /* what we enter NOW */
-    cpu_set_gpr(env, 9, (unsigned long)return_ip);     /* what we enter LATER */
-    cpu_set_gpr(env, 3, (unsigned long)sig);           /* arg 1: signo */
-    cpu_set_gpr(env, 4, (unsigned long)&frame->info);  /* arg 2: (siginfo_t*) */
-    cpu_set_gpr(env, 5, (unsigned long)&frame->uc);    /* arg 3: ucontext */
-
-    /* actually move the usp to reflect the stacked frame */
-    cpu_set_gpr(env, 1, (unsigned long)frame);
+    cpu_set_gpr(env, 9, frame_addr + offsetof(target_rt_sigframe, retcode));
+    cpu_set_gpr(env, 3, sig);
+    cpu_set_gpr(env, 4, frame_addr + offsetof(target_rt_sigframe, info));
+    cpu_set_gpr(env, 5, frame_addr + offsetof(target_rt_sigframe, uc));
+    cpu_set_gpr(env, 1, frame_addr);
 
+    /* For debugging convenience, set ppc to the insn that faulted.  */
+    env->ppc = env->pc;
+    /* When setting the PC for the signal handler, exit delay slot.  */
+    env->pc = ka->_sa_handler;
+    env->dflag = 0;
     return;
 
 give_sigsegv:
@@ -207,16 +147,34 @@ give_sigsegv:
     force_sigsegv(sig);
 }
 
-long do_sigreturn(CPUOpenRISCState *env)
-{
-    trace_user_do_sigreturn(env, 0);
-    fprintf(stderr, "do_sigreturn: not implemented\n");
-    return -TARGET_ENOSYS;
-}
-
 long do_rt_sigreturn(CPUOpenRISCState *env)
 {
+    abi_ulong frame_addr = cpu_get_gpr(env, 1);
+    target_rt_sigframe *frame;
+    sigset_t set;
+
     trace_user_do_rt_sigreturn(env, 0);
-    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
-    return -TARGET_ENOSYS;
+    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
+        goto badframe;
+    }
+    if (frame_addr & 3) {
+        goto badframe;
+    }
+
+    target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
+    set_sigmask(&set);
+
+    restore_sigcontext(env, &frame->uc.tuc_mcontext);
+    if (do_sigaltstack(frame_addr + offsetof(target_rt_sigframe, uc.tuc_stack),
+                       0, frame_addr) == -EFAULT) {
+        goto badframe;
+    }
+
+    unlock_user_struct(frame, frame_addr, 0);
+    return cpu_get_gpr(env, 11);
+
+ badframe:
+    unlock_user_struct(frame, frame_addr, 0);
+    force_sig(TARGET_SIGSEGV);
+    return 0;
 }
diff --git a/linux-user/signal.c b/linux-user/signal.c
index be2815b45d..602b631b92 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -236,7 +236,7 @@ int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
     return 0;
 }
 
-#if !defined(TARGET_OPENRISC) && !defined(TARGET_NIOS2)
+#if !defined(TARGET_NIOS2)
 /* Just set the guest's signal mask to the specified value; the
  * caller is assumed to have called block_signals() already.
  */
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index e01ce9ed1c..fb7cb5c507 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -27,6 +27,7 @@ static void openrisc_cpu_set_pc(CPUState *cs, vaddr value)
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
 
     cpu->env.pc = value;
+    cpu->env.dflag = 0;
 }
 
 static bool openrisc_cpu_has_work(CPUState *cs)
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [Qemu-devel] [PATCH v2 22/22] linux-user: Fix struct sigaltstack for openrisc
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (20 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 21/22] linux-user: Implement signals for openrisc Richard Henderson
@ 2018-06-18 18:40 ` Richard Henderson
  2018-06-18 21:05 ` [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements no-reply
  2018-06-21 11:00 ` Stafford Horne
  23 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-18 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/openrisc/target_signal.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/openrisc/target_signal.h b/linux-user/openrisc/target_signal.h
index c352a8b333..8283eaf544 100644
--- a/linux-user/openrisc/target_signal.h
+++ b/linux-user/openrisc/target_signal.h
@@ -5,8 +5,8 @@
 
 typedef struct target_sigaltstack {
     abi_long ss_sp;
+    abi_int ss_flags;
     abi_ulong ss_size;
-    abi_long ss_flags;
 } target_stack_t;
 
 /* sigaltstack controls  */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (21 preceding siblings ...)
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 22/22] linux-user: Fix struct sigaltstack " Richard Henderson
@ 2018-06-18 21:05 ` no-reply
  2018-06-21 11:00 ` Stafford Horne
  23 siblings, 0 replies; 41+ messages in thread
From: no-reply @ 2018-06-18 21:05 UTC (permalink / raw)
  To: richard.henderson; +Cc: famz, qemu-devel, shorne

Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20180618184046.6270-1-richard.henderson@linaro.org
Subject: [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]               patchew/20180618184046.6270-1-richard.henderson@linaro.org -> patchew/20180618184046.6270-1-richard.henderson@linaro.org
Switched to a new branch 'test'
f9574c9bba linux-user: Fix struct sigaltstack for openrisc
91ab86225f linux-user: Implement signals for openrisc
4139e74dc2 target/openrisc: Add support in scripts/qemu-binfmt-conf.sh
dffec46c36 target/openrisc: Add print_insn_or1k
d9dbd91a5d target/openrisc: Reorg tlb lookup
0ff65e9bc4 target/openrisc: Increase the TLB size
5567f0d2ea target/openrisc: Log interrupts
39f84d361e target/openrisc: Stub out handle_mmu_fault for softmmu
37112b6a94 target/openrisc: Use identical sizes for ITLB and DTLB
1a90f52464 target/openrisc: Fix cpu_mmu_index
54c6a8bcc5 target/openrisc: Fix tlb flushing in mtspr
9227f6d3ec target/openrisc: Reduce tlb to a single dimension
ea72737e47 target/openrisc: Merge mmu_helper.c into mmu.c
36d2c19dd0 target/openrisc: Remove indirect function calls for mmu
ee17b32c4a target/openrisc: Merge tlb allocation into CPUOpenRISCState
1030584e57 target/openrisc: Form the spr index from tcg
7676d26926 target/openrisc: Exit the TB after l.mtspr
b69e1bc347 target/openrisc: Split out is_user
9a6db89505 target/openrisc: Link more translation blocks
ea9e529068 target/openrisc: Fix singlestep_enabled
0d545edd65 target/openrisc: Use exit_tb instead of CPU_INTERRUPT_EXITTB
19714e6653 target/openrisc: Remove DISAS_JUMP & DISAS_TB_JUMP

=== OUTPUT BEGIN ===
Checking PATCH 1/22: target/openrisc: Remove DISAS_JUMP & DISAS_TB_JUMP...
Checking PATCH 2/22: target/openrisc: Use exit_tb instead of CPU_INTERRUPT_EXITTB...
Checking PATCH 3/22: target/openrisc: Fix singlestep_enabled...
Checking PATCH 4/22: target/openrisc: Link more translation blocks...
Checking PATCH 5/22: target/openrisc: Split out is_user...
Checking PATCH 6/22: target/openrisc: Exit the TB after l.mtspr...
Checking PATCH 7/22: target/openrisc: Form the spr index from tcg...
Checking PATCH 8/22: target/openrisc: Merge tlb allocation into CPUOpenRISCState...
Checking PATCH 9/22: target/openrisc: Remove indirect function calls for mmu...
Checking PATCH 10/22: target/openrisc: Merge mmu_helper.c into mmu.c...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#49: 
deleted file mode 100644

total: 0 errors, 1 warnings, 23 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 11/22: target/openrisc: Reduce tlb to a single dimension...
Checking PATCH 12/22: target/openrisc: Fix tlb flushing in mtspr...
Checking PATCH 13/22: target/openrisc: Fix cpu_mmu_index...
Checking PATCH 14/22: target/openrisc: Use identical sizes for ITLB and DTLB...
Checking PATCH 15/22: target/openrisc: Stub out handle_mmu_fault for softmmu...
Checking PATCH 16/22: target/openrisc: Log interrupts...
Checking PATCH 17/22: target/openrisc: Increase the TLB size...
Checking PATCH 18/22: target/openrisc: Reorg tlb lookup...
Checking PATCH 19/22: target/openrisc: Add print_insn_or1k...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#65: 
new file mode 100644

ERROR: Macros with complex values should be enclosed in parenthesis
#100: FILE: target/openrisc/disas.c:31:
+#define output(mnemonic, format, ...) \
+    info->fprintf_func(info->stream, "%-9s " format, \
+                       mnemonic, ##__VA_ARGS__)

ERROR: spaces required around that '*' (ctx:WxV)
#125: FILE: target/openrisc/disas.c:56:
+    arg_l_##opcode *a, uint32_t insn)                   \
                    ^

ERROR: spaces required around that '*' (ctx:WxV)
#220: FILE: target/openrisc/disas.c:151:
+    arg_lf_##opcode##_##suffix *a, uint32_t insn)                \
                                ^

total: 3 errors, 1 warnings, 923 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 20/22: target/openrisc: Add support in scripts/qemu-binfmt-conf.sh...
WARNING: line over 80 characters
#31: FILE: scripts/qemu-binfmt-conf.sh:127:
+or1k_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x5c'

ERROR: line over 90 characters
#32: FILE: scripts/qemu-binfmt-conf.sh:128:
+or1k_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'

total: 1 errors, 1 warnings, 23 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 21/22: linux-user: Implement signals for openrisc...
Checking PATCH 22/22: linux-user: Fix struct sigaltstack for openrisc...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements
  2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
                   ` (22 preceding siblings ...)
  2018-06-18 21:05 ` [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements no-reply
@ 2018-06-21 11:00 ` Stafford Horne
  2018-06-21 11:25   ` Richard Henderson
  23 siblings, 1 reply; 41+ messages in thread
From: Stafford Horne @ 2018-06-21 11:00 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

On Mon, Jun 18, 2018 at 08:40:24AM -1000, Richard Henderson wrote:
> This is almost a grab-bag of little improvements to the port.
> 
> patches 1-3:
>   Fix singlestepping for gdbstub.  This has apparently never
>   worked, as the first commit has the same bug of not advancing
>   the pc when stepping.
> 
> patches 4:
>   Link more TBs.
> 
> patches 5-6:
>   Exit the TB after l.mtspr insns.  In particular, storing to
>   SR changes exception state so we want to return to the main
>   loop to recognize any pending interrupts immediately.
> 
> patches 8-18:
>   Reorganize TLB handling.  There is a fundamental bug that is
>   fixed in patch 13.  However the bug has been hidden by extra
>   TLB flushing elsewhere in the port.  I remove some unnecessary
>   indirection that the port inherited from somewhere -- probably
>   the MIPS port.  Finally, I present the QEMU TLB a unified view
>   of the OpenRISC split I/D TLB.
> 
> patch 19:
>   Split out disassembly from translation.
> 
> patch 20:
>   Add qemu-or1k to qemu-binfmt-conf.sh.
> 
> patches 21-22:
>   Implement signal handling for linux-user.

Hi Richard,

Thanks for these, I think there are a few white space issues throughout.  Do you
mind if I take these and clean them up (indent with space) and work on the DSX
and Interrupt issue I mentioned earlier?

I can submit all during the next merge window.

Let me know if you have other plans or you think they can go right away.

-Stafford

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements
  2018-06-21 11:00 ` Stafford Horne
@ 2018-06-21 11:25   ` Richard Henderson
  0 siblings, 0 replies; 41+ messages in thread
From: Richard Henderson @ 2018-06-21 11:25 UTC (permalink / raw)
  To: Stafford Horne; +Cc: qemu-devel

On 06/21/2018 01:00 AM, Stafford Horne wrote:
> Thanks for these, I think there are a few white space issues throughout.  Do you
> mind if I take these and clean them up (indent with space) and work on the DSX
> and Interrupt issue I mentioned earlier?
> 
> I can submit all during the next merge window.

That's fine with me.


r~

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 12/22] target/openrisc: Fix tlb flushing in mtspr
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 12/22] target/openrisc: Fix tlb flushing in mtspr Richard Henderson
@ 2018-06-22  6:40   ` Stafford Horne
  2018-06-24  3:10     ` Stafford Horne
  0 siblings, 1 reply; 41+ messages in thread
From: Stafford Horne @ 2018-06-22  6:40 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

On Mon, Jun 18, 2018 at 08:40:36AM -1000, Richard Henderson wrote:
> The previous code was confused, avoiding the flush of the old entry
> if the new entry is invalid.  We need to flush the old page if the
> old entry is valid and the new page if the new entry is valid.
> 
> This bug was masked by over-flushing elsewhere.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/openrisc/sys_helper.c | 21 +++++++++++++++------
>  1 file changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
> index 8ad7a7d898..e00aaa332e 100644
> --- a/target/openrisc/sys_helper.c
> +++ b/target/openrisc/sys_helper.c
> @@ -32,6 +32,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
>  #ifndef CONFIG_USER_ONLY
>      OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
>      CPUState *cs = CPU(cpu);
> +    target_ulong mr;
>      int idx;
>  
>      switch (spr) {
> @@ -84,12 +85,15 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
>  
>      case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
>          idx = spr - TO_SPR(1, 512);
> -        if (!(rb & 1)) {
> -            tlb_flush_page(cs, env->tlb.dtlb[idx].mr & TARGET_PAGE_MASK);
> +        mr = env->tlb.dtlb[idx].mr;
> +        if (mr & 1) {
> +            tlb_flush_page(cs, mr & TARGET_PAGE_MASK);
> +        }
> +        if (rb & 1) {
> +            tlb_flush_page(cs, rb & TARGET_PAGE_MASK);

Hi Richard,

On openrisc we write 0 to the TLB SPR to flush the old entry out of the TLB, I
don't see much documentation on this, but this is what is done in the kernel.
This patch is causing the linux kernel to not boot.

I thought flush is to get rid of the old mapping from the tlb, if we need to do
it for new mappings too should we do.  Why do we need to flush new mappings?

    /* flush old page if it was valid or we are invalidating */
    if ((mr & 1) || !(rb & 1)) {
	tlb_flush_page(cs, mr & TARGET_PAGE_MASK);
    }
    /* flush new page if its being entered into tlb */
    if (rb & 1) {
	tlb_flush_page(cs, rb & TARGET_PAGE_MASK);
    }

I didn't write the original code, but I think it was right as is.

>          }
>          env->tlb.dtlb[idx].mr = rb;
>          break;
> -
>      case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */
>          idx = spr - TO_SPR(1, 640);
>          env->tlb.dtlb[idx].tr = rb;
> @@ -101,14 +105,18 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
>      case TO_SPR(1, 1280) ... TO_SPR(1, 1407): /* DTLBW3MR 0-127 */
>      case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */
>          break;
> +
>      case TO_SPR(2, 512) ... TO_SPR(2, 512+ITLB_SIZE-1):   /* ITLBW0MR 0-127 */
>          idx = spr - TO_SPR(2, 512);
> -        if (!(rb & 1)) {
> -            tlb_flush_page(cs, env->tlb.itlb[idx].mr & TARGET_PAGE_MASK);
> +        mr = env->tlb.itlb[idx].mr;
> +        if (mr & 1) {
> +            tlb_flush_page(cs, mr & TARGET_PAGE_MASK);
> +        }
> +        if (rb & 1) {
> +            tlb_flush_page(cs, rb & TARGET_PAGE_MASK);
>          }

Likewise.

>          env->tlb.itlb[idx].mr = rb;
>          break;
> -
>      case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */
>          idx = spr - TO_SPR(2, 640);
>          env->tlb.itlb[idx].tr = rb;
> @@ -120,6 +128,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
>      case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */
>      case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
>          break;
> +
>      case TO_SPR(5, 1):  /* MACLO */
>          env->mac = deposit64(env->mac, 0, 32, rb);
>          break;
> -- 
> 2.17.1
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 12/22] target/openrisc: Fix tlb flushing in mtspr
  2018-06-22  6:40   ` Stafford Horne
@ 2018-06-24  3:10     ` Stafford Horne
  0 siblings, 0 replies; 41+ messages in thread
From: Stafford Horne @ 2018-06-24  3:10 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel qemu-devel, Stafford Horne

On Fri, Jun 22, 2018 at 3:40 PM Stafford Horne <shorne@gmail.com> wrote:
>
> On Mon, Jun 18, 2018 at 08:40:36AM -1000, Richard Henderson wrote:
> > The previous code was confused, avoiding the flush of the old entry
> > if the new entry is invalid.  We need to flush the old page if the
> > old entry is valid and the new page if the new entry is valid.
> >
> > This bug was masked by over-flushing elsewhere.
> >
> > Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> > ---
> >  target/openrisc/sys_helper.c | 21 +++++++++++++++------
> >  1 file changed, 15 insertions(+), 6 deletions(-)
> >
> > diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
> > index 8ad7a7d898..e00aaa332e 100644
> > --- a/target/openrisc/sys_helper.c
> > +++ b/target/openrisc/sys_helper.c
> > @@ -32,6 +32,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
> >  #ifndef CONFIG_USER_ONLY
> >      OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
> >      CPUState *cs = CPU(cpu);
> > +    target_ulong mr;
> >      int idx;
> >
> >      switch (spr) {
> > @@ -84,12 +85,15 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
> >
> >      case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
> >          idx = spr - TO_SPR(1, 512);
> > -        if (!(rb & 1)) {
> > -            tlb_flush_page(cs, env->tlb.dtlb[idx].mr & TARGET_PAGE_MASK);
> > +        mr = env->tlb.dtlb[idx].mr;
> > +        if (mr & 1) {
> > +            tlb_flush_page(cs, mr & TARGET_PAGE_MASK);
> > +        }
> > +        if (rb & 1) {
> > +            tlb_flush_page(cs, rb & TARGET_PAGE_MASK);
>
> Hi Richard,
>
> On openrisc we write 0 to the TLB SPR to flush the old entry out of the TLB, I
> don't see much documentation on this, but this is what is done in the kernel.
> This patch is causing the linux kernel to not boot.
>
> I thought flush is to get rid of the old mapping from the tlb, if we need to do
> it for new mappings too should we do.  Why do we need to flush new mappings?
>
>     /* flush old page if it was valid or we are invalidating */
>     if ((mr & 1) || !(rb & 1)) {
>         tlb_flush_page(cs, mr & TARGET_PAGE_MASK);
>     }
>     /* flush new page if its being entered into tlb */
>     if (rb & 1) {
>         tlb_flush_page(cs, rb & TARGET_PAGE_MASK);
>     }
>
> I didn't write the original code, but I think it was right as is.
>

Ignore this for now your code makes more sense, maybe we don't need to
flush the new page though?  This is causing a failure but something
more interesting is failing with the next patch "target/openrisc: Fix
cpu_mmu_index".

-Stafford

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/22] target/openrisc: Fix cpu_mmu_index
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 13/22] target/openrisc: Fix cpu_mmu_index Richard Henderson
@ 2018-06-24  3:44   ` Stafford Horne
  2018-06-26 22:07     ` Stafford Horne
  0 siblings, 1 reply; 41+ messages in thread
From: Stafford Horne @ 2018-06-24  3:44 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel qemu-devel, Stafford Horne

On Tue, Jun 19, 2018 at 3:41 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The code in cpu_mmu_index does not properly honor SR_DME.
> This bug has workarounds elsewhere in that we flush the
> tlb more often than necessary, on the state changes that
> should be reflected in a change of mmu_index.
>
> Fixing this means that we can respect the mmu_index that
> is given to tlb_flush.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/openrisc/cpu.h              | 23 +++++++++++++--------
>  target/openrisc/interrupt.c        |  4 ----
>  target/openrisc/interrupt_helper.c | 15 +++-----------
>  target/openrisc/mmu.c              | 33 +++++++++++++++++++++++++++---
>  target/openrisc/sys_helper.c       |  4 ----
>  target/openrisc/translate.c        |  2 +-
>  6 files changed, 49 insertions(+), 32 deletions(-)


Hello,

I am trying to test these patches running a linux kernel.

For some reason this is causing a strange failure with SMP but not
single core, I see an OpenRISC target pointer is making its way into
the tb_jmp_cache.  I don't think this is right and I am trying to
figure out why this happens and why this patch triggers it.

When bisecting to this commit I get:

[New Thread 0x7fffe9f11700 (LWP 4210)]

[    0.000000] Compiled-in FDT at (ptrval)
[    0.000000] Linux version
4.18.0-rc1-simple-smp-00006-gd5d0782e3db9-dirty
(shorne@lianli.shorne-pla.net) (gcc version 9.0.0 20180426
(experimental) (GCC)) #1013 SMP Sat Jun 23 17:11:42 JST 2018
[    0.000000] CPU: OpenRISC-0 (revision 0) @20 MHz
[    0.000000] -- dcache disabled
[    0.000000] -- icache disabled
[    0.000000] -- dmmu:   64 entries, 1 way(s)
[    0.000000] -- immu:   64 entries, 1 way(s)
[    0.000000] -- additional features:
[    0.000000] -- power management
[    0.000000] -- PIC
[    0.000000] -- timer
[    0.000000] setup_memory: Memory: 0x0-0x2000000
[    0.000000] Setting up paging and PTEs.
[    0.000000] map_ram: Memory: 0x0-0x2000000
[    0.000000] itlb_miss_handler (ptrval)
[    0.000000] dtlb_miss_handler (ptrval)
[    0.000000] OpenRISC Linux -- http://openrisc.io
[    0.000000] percpu: Embedded 6 pages/cpu @(ptrval) s18880 r8192 d22080 u49152
[    0.000000] Built 1 zonelists, mobility grouping off.  Total pages: 4080
[    0.000000] Kernel command line: earlycon
[    0.000000] earlycon: ns16550a0 at MMIO 0x90000000 (options '115200')
[    0.000000] bootconsole [ns16550a0] enabled
[    0.000000] Dentry cache hash table entries: 4096 (order: 1, 16384 bytes)
[    0.000000] Inode-cache hash table entries: 2048 (order: 0, 8192 bytes)
[    0.000000] Sorting __ex_table...
[    0.000000] Memory: 22336K/32768K available (3309K kernel code, 96K
rwdata, 736K rodata, 5898K init, 91K bss, 10432K reserved, 0K
cma-reserved)
[    0.000000] mem_init_done ...........................................
[    0.000000] Hierarchical RCU implementation.
[    0.000000] NR_IRQS: 32, nr_irqs: 32, preallocated irqs: 0
[    0.000000] clocksource: openrisc_timer: mask: 0xffffffff
max_cycles: 0xffffffff, max_idle_ns: 95563022313 ns
[    0.000000] 40.00 BogoMIPS (lpj=200000)
[    0.000000] pid_max: default: 32768 minimum: 301
[    0.000000] Mount-cache hash table entries: 2048 (order: 0, 8192 bytes)
[    0.000000] Mountpoint-cache hash table entries: 2048 (order: 0, 8192 bytes)


(gdb) bt
#0  0x00005555556d3e59 in tb_lookup__cpu_state (cf_mask=0,
flags=<synthetic pointer>, cs_base=<synthetic pointer>, pc=<synthetic
pointer>, cpu=0x555555f81300)
    at /home/shorne/work/openrisc/qemu/include/exec/tb-lookup.h:31
#1  0x00005555556d3e59 in tb_find (cf_mask=0, tb_exit=0,
last_tb=0x7fffe223ff00 <code_gen_buffer+2358995>, cpu=0x555555f81300)
at /home/shorne/work/openrisc/qemu/accel/tcg/cpu-exec.c:390
#2  0x00005555556d3e59 in cpu_exec (cpu=cpu@entry=0x555555f81300) at
/home/shorne/work/openrisc/qemu/accel/tcg/cpu-exec.c:735
#3  0x00005555556a0d2b in tcg_cpu_exec (cpu=cpu@entry=0x555555f81300)
at /home/shorne/work/openrisc/qemu/cpus.c:1362
#4  0x00005555556a238e in qemu_tcg_rr_cpu_thread_fn (arg=<optimized
out>) at /home/shorne/work/openrisc/qemu/cpus.c:1461
#5  0x0000555555886005 in qemu_thread_start (args=0x555555f93ef0) at
/home/shorne/work/openrisc/qemu/util/qemu-thread-posix.c:507
#6  0x00007ffff2a18564 in start_thread () at /lib64/libpthread.so.0
#7  0x00007ffff274c31f in clone () at /lib64/libc.so.6
(gdb) l
26          uint32_t hash;
27
28          cpu_get_tb_cpu_state(env, pc, cs_base, flags);
29          hash = tb_jmp_cache_hash_func(*pc);
30          tb = atomic_rcu_read(&cpu->tb_jmp_cache[hash]);
31          if (likely(tb &&
32                     tb->pc == *pc &&
33                     tb->cs_base == *cs_base &&
34                     tb->flags == *flags &&
35                     tb->trace_vcpu_dstate == *cpu->trace_dstate &&
(gdb) p tb
$1 = (TranslationBlock *) 0xc03c90a8


To reproduce I am running qemu with:
  qemu-system-or1k -cpu or1200 -M or1k-sim -kernel
or1k-linux-4.18-rc1-smp -serial stdio -nographic -monitor none -smp
cpus=2 -m 128

Kernel (need to gunzip):
  SMP - http://shorne.noip.me/downloads/or1k-linux-4.18-rc1-smp.gz
  Single - http://shorne.noip.me/downloads/or1k-linux-4.18-rc1.gz

I will continue to investigate, I just figured out SMP triggers it so
maybe that will uncover something more.

Sorry, if this mail gets clobbered I am using the gmail web interface.

-Stafford

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/22] target/openrisc: Fix cpu_mmu_index
  2018-06-24  3:44   ` Stafford Horne
@ 2018-06-26 22:07     ` Stafford Horne
  2018-06-26 22:26       ` Richard Henderson
  0 siblings, 1 reply; 41+ messages in thread
From: Stafford Horne @ 2018-06-26 22:07 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel qemu-devel

Hello,

I think I found out something.

in: target/openrisc/sys_helper.c:92

When we write to `env->tlb.dtlb[idx].tr`  in helper_mtspr():
  93          case TO_SPR(1, 640) ... TO_SPR(1, 640 + TLB_SIZE - 1):
/* DTLBW0TR 0-127 */
  94              idx = spr - TO_SPR(1, 640);
  95              env->tlb.dtlb[idx].tr = rb;


Somehow we are overlapping with `cpu->tb_jmp_cache`,  these are both
pointing to the same spot in memory.

(gdb) p &cs->tb_jmp_cache[3014]
$9 = (struct TranslationBlock **) 0x55555608b300
(gdb) p &env->tlb.dtlb[idx].tr
$10 = (uint32_t *) 0x55555608b304


I can't see why yet, but it should be something simple.  Still looking.

-Stafford
On Sun, Jun 24, 2018 at 12:44 PM Stafford Horne <shorne@gmail.com> wrote:
>
> On Tue, Jun 19, 2018 at 3:41 AM Richard Henderson
> <richard.henderson@linaro.org> wrote:
> >
> > The code in cpu_mmu_index does not properly honor SR_DME.
> > This bug has workarounds elsewhere in that we flush the
> > tlb more often than necessary, on the state changes that
> > should be reflected in a change of mmu_index.
> >
> > Fixing this means that we can respect the mmu_index that
> > is given to tlb_flush.
> >
> > Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> > ---
> >  target/openrisc/cpu.h              | 23 +++++++++++++--------
> >  target/openrisc/interrupt.c        |  4 ----
> >  target/openrisc/interrupt_helper.c | 15 +++-----------
> >  target/openrisc/mmu.c              | 33 +++++++++++++++++++++++++++---
> >  target/openrisc/sys_helper.c       |  4 ----
> >  target/openrisc/translate.c        |  2 +-
> >  6 files changed, 49 insertions(+), 32 deletions(-)
>
>
> Hello,
>
> I am trying to test these patches running a linux kernel.
>
> For some reason this is causing a strange failure with SMP but not
> single core, I see an OpenRISC target pointer is making its way into
> the tb_jmp_cache.  I don't think this is right and I am trying to
> figure out why this happens and why this patch triggers it.
>
> When bisecting to this commit I get:
>
> [New Thread 0x7fffe9f11700 (LWP 4210)]
>
> [    0.000000] Compiled-in FDT at (ptrval)
> [    0.000000] Linux version
> 4.18.0-rc1-simple-smp-00006-gd5d0782e3db9-dirty
> (shorne@lianli.shorne-pla.net) (gcc version 9.0.0 20180426
> (experimental) (GCC)) #1013 SMP Sat Jun 23 17:11:42 JST 2018
> [    0.000000] CPU: OpenRISC-0 (revision 0) @20 MHz
> [    0.000000] -- dcache disabled
> [    0.000000] -- icache disabled
> [    0.000000] -- dmmu:   64 entries, 1 way(s)
> [    0.000000] -- immu:   64 entries, 1 way(s)
> [    0.000000] -- additional features:
> [    0.000000] -- power management
> [    0.000000] -- PIC
> [    0.000000] -- timer
> [    0.000000] setup_memory: Memory: 0x0-0x2000000
> [    0.000000] Setting up paging and PTEs.
> [    0.000000] map_ram: Memory: 0x0-0x2000000
> [    0.000000] itlb_miss_handler (ptrval)
> [    0.000000] dtlb_miss_handler (ptrval)
> [    0.000000] OpenRISC Linux -- http://openrisc.io
> [    0.000000] percpu: Embedded 6 pages/cpu @(ptrval) s18880 r8192 d22080 u49152
> [    0.000000] Built 1 zonelists, mobility grouping off.  Total pages: 4080
> [    0.000000] Kernel command line: earlycon
> [    0.000000] earlycon: ns16550a0 at MMIO 0x90000000 (options '115200')
> [    0.000000] bootconsole [ns16550a0] enabled
> [    0.000000] Dentry cache hash table entries: 4096 (order: 1, 16384 bytes)
> [    0.000000] Inode-cache hash table entries: 2048 (order: 0, 8192 bytes)
> [    0.000000] Sorting __ex_table...
> [    0.000000] Memory: 22336K/32768K available (3309K kernel code, 96K
> rwdata, 736K rodata, 5898K init, 91K bss, 10432K reserved, 0K
> cma-reserved)
> [    0.000000] mem_init_done ...........................................
> [    0.000000] Hierarchical RCU implementation.
> [    0.000000] NR_IRQS: 32, nr_irqs: 32, preallocated irqs: 0
> [    0.000000] clocksource: openrisc_timer: mask: 0xffffffff
> max_cycles: 0xffffffff, max_idle_ns: 95563022313 ns
> [    0.000000] 40.00 BogoMIPS (lpj=200000)
> [    0.000000] pid_max: default: 32768 minimum: 301
> [    0.000000] Mount-cache hash table entries: 2048 (order: 0, 8192 bytes)
> [    0.000000] Mountpoint-cache hash table entries: 2048 (order: 0, 8192 bytes)
>
>
> (gdb) bt
> #0  0x00005555556d3e59 in tb_lookup__cpu_state (cf_mask=0,
> flags=<synthetic pointer>, cs_base=<synthetic pointer>, pc=<synthetic
> pointer>, cpu=0x555555f81300)
>     at /home/shorne/work/openrisc/qemu/include/exec/tb-lookup.h:31
> #1  0x00005555556d3e59 in tb_find (cf_mask=0, tb_exit=0,
> last_tb=0x7fffe223ff00 <code_gen_buffer+2358995>, cpu=0x555555f81300)
> at /home/shorne/work/openrisc/qemu/accel/tcg/cpu-exec.c:390
> #2  0x00005555556d3e59 in cpu_exec (cpu=cpu@entry=0x555555f81300) at
> /home/shorne/work/openrisc/qemu/accel/tcg/cpu-exec.c:735
> #3  0x00005555556a0d2b in tcg_cpu_exec (cpu=cpu@entry=0x555555f81300)
> at /home/shorne/work/openrisc/qemu/cpus.c:1362
> #4  0x00005555556a238e in qemu_tcg_rr_cpu_thread_fn (arg=<optimized
> out>) at /home/shorne/work/openrisc/qemu/cpus.c:1461
> #5  0x0000555555886005 in qemu_thread_start (args=0x555555f93ef0) at
> /home/shorne/work/openrisc/qemu/util/qemu-thread-posix.c:507
> #6  0x00007ffff2a18564 in start_thread () at /lib64/libpthread.so.0
> #7  0x00007ffff274c31f in clone () at /lib64/libc.so.6
> (gdb) l
> 26          uint32_t hash;
> 27
> 28          cpu_get_tb_cpu_state(env, pc, cs_base, flags);
> 29          hash = tb_jmp_cache_hash_func(*pc);
> 30          tb = atomic_rcu_read(&cpu->tb_jmp_cache[hash]);
> 31          if (likely(tb &&
> 32                     tb->pc == *pc &&
> 33                     tb->cs_base == *cs_base &&
> 34                     tb->flags == *flags &&
> 35                     tb->trace_vcpu_dstate == *cpu->trace_dstate &&
> (gdb) p tb
> $1 = (TranslationBlock *) 0xc03c90a8
>
>
> To reproduce I am running qemu with:
>   qemu-system-or1k -cpu or1200 -M or1k-sim -kernel
> or1k-linux-4.18-rc1-smp -serial stdio -nographic -monitor none -smp
> cpus=2 -m 128
>
> Kernel (need to gunzip):
>   SMP - http://shorne.noip.me/downloads/or1k-linux-4.18-rc1-smp.gz
>   Single - http://shorne.noip.me/downloads/or1k-linux-4.18-rc1.gz
>
> I will continue to investigate, I just figured out SMP triggers it so
> maybe that will uncover something more.
>
> Sorry, if this mail gets clobbered I am using the gmail web interface.
>
> -Stafford

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/22] target/openrisc: Fix cpu_mmu_index
  2018-06-26 22:07     ` Stafford Horne
@ 2018-06-26 22:26       ` Richard Henderson
  2018-06-27 12:59         ` Stafford Horne
  0 siblings, 1 reply; 41+ messages in thread
From: Richard Henderson @ 2018-06-26 22:26 UTC (permalink / raw)
  To: Stafford Horne; +Cc: qemu-devel qemu-devel

On 06/26/2018 03:07 PM, Stafford Horne wrote:
> Hello,
> 
> I think I found out something.
> 
> in: target/openrisc/sys_helper.c:92
> 
> When we write to `env->tlb.dtlb[idx].tr`  in helper_mtspr():
>   93          case TO_SPR(1, 640) ... TO_SPR(1, 640 + TLB_SIZE - 1):
> /* DTLBW0TR 0-127 */
>   94              idx = spr - TO_SPR(1, 640);
>   95              env->tlb.dtlb[idx].tr = rb;
> 
> 
> Somehow we are overlapping with `cpu->tb_jmp_cache`,  these are both
> pointing to the same spot in memory.
> 
> (gdb) p &cs->tb_jmp_cache[3014]
> $9 = (struct TranslationBlock **) 0x55555608b300
> (gdb) p &env->tlb.dtlb[idx].tr
> $10 = (uint32_t *) 0x55555608b304

That is definitely weird.  How about

(gdb) p openrisc_env_get_cpu(env)
$1 = xxxx
(gdb) p &$1->parent_obj
(gdb) p &$1->env
(gdb) p cs->env_ptr

There should be 4096 entries in tb_jmp_cache, so there should
be no way that overlaps.  I can only imagine either CS or ENV
is incorrect somehow.  How that would be, I don't know...


r~

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/22] target/openrisc: Fix cpu_mmu_index
  2018-06-26 22:26       ` Richard Henderson
@ 2018-06-27 12:59         ` Stafford Horne
  2018-06-27 13:50           ` Richard Henderson
  0 siblings, 1 reply; 41+ messages in thread
From: Stafford Horne @ 2018-06-27 12:59 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel qemu-devel

On Tue, Jun 26, 2018 at 03:26:01PM -0700, Richard Henderson wrote:
> On 06/26/2018 03:07 PM, Stafford Horne wrote:
> > Hello,
> > 
> > I think I found out something.
> > 
> > in: target/openrisc/sys_helper.c:92
> > 
> > When we write to `env->tlb.dtlb[idx].tr`  in helper_mtspr():
> >   93          case TO_SPR(1, 640) ... TO_SPR(1, 640 + TLB_SIZE - 1):
> > /* DTLBW0TR 0-127 */
> >   94              idx = spr - TO_SPR(1, 640);
> >   95              env->tlb.dtlb[idx].tr = rb;
> > 
> > 
> > Somehow we are overlapping with `cpu->tb_jmp_cache`,  these are both
> > pointing to the same spot in memory.
> > 
> > (gdb) p &cs->tb_jmp_cache[3014]
> > $9 = (struct TranslationBlock **) 0x55555608b300
> > (gdb) p &env->tlb.dtlb[idx].tr
> > $10 = (uint32_t *) 0x55555608b304
> 
> That is definitely weird.  How about
> 
> (gdb) p openrisc_env_get_cpu(env)
> $1 = xxxx
> (gdb) p &$1->parent_obj
> (gdb) p &$1->env
> (gdb) p cs->env_ptr
> 
> There should be 4096 entries in tb_jmp_cache, so there should
> be no way that overlaps.  I can only imagine either CS or ENV
> is incorrect somehow.  How that would be, I don't know...

Nothing looks strange there... but this does... :)

(gdb) p &cs->tb_jmp_cache[3014]
$56 = (struct TranslationBlock **) 0x55555606c570
(gdb) p &env->tlb.dtlb[idx].tr
$57 = (uint32_t *) 0x55555606c574
(gdb) p &env->tlb.dtlb[idx].mr
$58 = (uint32_t *) 0x55555606c570
(gdb) p idx
$59 = -1502

The index is negative... this patch should fix that.

@@ -78,6 +78,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr,
target_ulong rb)
     case TO_SPR(0, 1024) ... TO_SPR(0, 1024 + (16 * 32)): /* Shadow GPRs */
         idx = (spr - 1024);
         env->shadow_gpr[idx / 32][idx % 32] = rb;
+        break;
 
     case TO_SPR(1, 512) ... TO_SPR(1, 512 + TLB_SIZE - 1): /* DTLBW0MR 0-127 */
         idx = spr - TO_SPR(1, 512);

-Stafford

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/22] target/openrisc: Fix cpu_mmu_index
  2018-06-27 12:59         ` Stafford Horne
@ 2018-06-27 13:50           ` Richard Henderson
  2018-06-27 23:08             ` Stafford Horne
  0 siblings, 1 reply; 41+ messages in thread
From: Richard Henderson @ 2018-06-27 13:50 UTC (permalink / raw)
  To: Stafford Horne; +Cc: qemu-devel qemu-devel

On 06/27/2018 05:59 AM, Stafford Horne wrote:
> The index is negative... this patch should fix that.
> 
> @@ -78,6 +78,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr,
> target_ulong rb)
>      case TO_SPR(0, 1024) ... TO_SPR(0, 1024 + (16 * 32)): /* Shadow GPRs */
>          idx = (spr - 1024);
>          env->shadow_gpr[idx / 32][idx % 32] = rb;
> +        break;
>  
>      case TO_SPR(1, 512) ... TO_SPR(1, 512 + TLB_SIZE - 1): /* DTLBW0MR 0-127 */

OMG.  That's embarrasing...


r~

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 19/22] target/openrisc: Add print_insn_or1k
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 19/22] target/openrisc: Add print_insn_or1k Richard Henderson
@ 2018-06-27 16:03   ` Philippe Mathieu-Daudé
  2018-06-27 16:15     ` Richard Henderson
  0 siblings, 1 reply; 41+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-06-27 16:03 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, shorne

On 06/18/2018 03:40 PM, Richard Henderson wrote:
> Rather than emit disassembly while translating, reuse the
> generated decoder to build a separate disassembler.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/openrisc/cpu.h         |   1 +
>  target/openrisc/cpu.c         |   6 ++
>  target/openrisc/disas.c       | 170 ++++++++++++++++++++++++++++++++++
>  target/openrisc/translate.c   | 114 -----------------------
>  target/openrisc/Makefile.objs |   3 +-
>  5 files changed, 179 insertions(+), 115 deletions(-)
>  create mode 100644 target/openrisc/disas.c
> 
> diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
> index 1efffa5269..f1b31bc24a 100644
> --- a/target/openrisc/cpu.h
> +++ b/target/openrisc/cpu.h
> @@ -348,6 +348,7 @@ void openrisc_translate_init(void);
>  int openrisc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size,
>                                    int rw, int mmu_idx);
>  int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc);
> +int print_insn_or1k(bfd_vma addr, disassemble_info *info);
>  
>  #define cpu_list cpu_openrisc_list
>  #define cpu_signal_handler cpu_openrisc_signal_handler
> diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
> index 677f02efa4..e01ce9ed1c 100644
> --- a/target/openrisc/cpu.c
> +++ b/target/openrisc/cpu.c
> @@ -35,6 +35,11 @@ static bool openrisc_cpu_has_work(CPUState *cs)
>                                      CPU_INTERRUPT_TIMER);
>  }
>  
> +static void openrisc_disas_set_info(CPUState *cpu, disassemble_info *info)
> +{
> +    info->print_insn = print_insn_or1k;
> +}
> +
>  /* CPUClass::reset() */
>  static void openrisc_cpu_reset(CPUState *s)
>  {
> @@ -150,6 +155,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
>  #endif
>      cc->gdb_num_core_regs = 32 + 3;
>      cc->tcg_initialize = openrisc_translate_init;
> +    cc->disas_set_info = openrisc_disas_set_info;
>  }
>  
>  /* Sort alphabetically by type name, except for "any". */
> diff --git a/target/openrisc/disas.c b/target/openrisc/disas.c
> new file mode 100644
> index 0000000000..5acf4f4744
> --- /dev/null
> +++ b/target/openrisc/disas.c
> @@ -0,0 +1,170 @@
> +/*
> + * OpenRISC disassembler
> + *
> + * Copyright (c) 2018 Richard Henderson <rth@twiddle.net>
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu-common.h"
> +#include "disas/bfd.h"
> +#include "qemu/bitops.h"
> +#include "cpu.h"
> +
> +typedef disassemble_info DisasContext;
> +
> +/* Include the auto-generated decoder.  */
> +#include "decode.inc.c"
> +
> +#define output(mnemonic, format, ...) \
> +    info->fprintf_func(info->stream, "%-9s " format, \
> +                       mnemonic, ##__VA_ARGS__)
> +
> +int print_insn_or1k(bfd_vma addr, disassemble_info *info)
> +{
> +    bfd_byte buffer[4];
> +    uint32_t insn;
> +    int status;
> +
> +    status = info->read_memory_func(addr, buffer, 4, info);
> +    if (status != 0) {
> +        info->memory_error_func(status, addr, info);
> +        return -1;
> +    }
> +    insn = bfd_getb32(buffer);
> +
> +    if (!decode(info, insn)) {
> +        output(".long", "%#08x", insn);
> +    }
> +    return 4;
> +}
> +
> +#define INSN(opcode, format, ...) \
> +static bool trans_l_##opcode(disassemble_info *info,    \
> +    arg_l_##opcode *a, uint32_t insn)                   \
> +{                                                       \
> +    output("l." #opcode, format, ##__VA_ARGS__);        \
> +    return true;                                        \
> +}
> +
> +INSN(add,    "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(addc,   "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(sub,    "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(and,    "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(or,     "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(xor,    "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(sll,    "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(srl,    "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(sra,    "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(ror,    "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(exths,  "r%d, r%d", a->d, a->a)
> +INSN(extbs,  "r%d, r%d", a->d, a->a)
> +INSN(exthz,  "r%d, r%d", a->d, a->a)
> +INSN(extbz,  "r%d, r%d", a->d, a->a)
> +INSN(cmov,   "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(ff1,    "r%d, r%d", a->d, a->a)
> +INSN(fl1,    "r%d, r%d", a->d, a->a)
> +INSN(mul,    "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(mulu,   "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(div,    "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(divu,   "r%d, r%d, r%d", a->d, a->a, a->b)
> +INSN(muld,   "r%d, r%d", a->a, a->b)
> +INSN(muldu,  "r%d, r%d", a->a, a->b)
> +INSN(j,      "%d", a->n)
> +INSN(jal,    "%d", a->n)
> +INSN(bf,     "%d", a->n)
> +INSN(bnf,    "%d", a->n)
> +INSN(jr,     "r%d", a->b)
> +INSN(jalr,   "r%d", a->b)

> +INSN(lwa,    "r%d, %d(r%d)", a->d, a->i, a->a)
> +INSN(lwz,    "r%d, %d(r%d)", a->d, a->i, a->a)
> +INSN(lws,    "r%d, %d(r%d)", a->d, a->i, a->a)
> +INSN(lbz,    "r%d, %d(r%d)", a->d, a->i, a->a)
> +INSN(lbs,    "r%d, %d(r%d)", a->d, a->i, a->a)
> +INSN(lhz,    "r%d, %d(r%d)", a->d, a->i, a->a)
> +INSN(lhs,    "r%d, %d(r%d)", a->d, a->i, a->a)
> +INSN(swa,    "%d(r%d), r%d", a->i, a->a, a->b)
> +INSN(sw,     "%d(r%d), r%d", a->i, a->a, a->b)
> +INSN(sb,     "%d(r%d), r%d", a->i, a->a, a->b)
> +INSN(sh,     "%d(r%d), r%d", a->i, a->a, a->b)

You updated to use the offset(reg) notation, ok.

> +INSN(nop,    "")

The nop previously displayed 'k', I suppose a left-over from sys/trap.

> +INSN(addi,   "r%d, r%d, %d", a->d, a->a, a->i)
> +INSN(addic,  "r%d, r%d, %d", a->d, a->a, a->i)
> +INSN(muli,   "r%d, r%d, %d", a->d, a->a, a->i)
> +INSN(maci,   "r%d, %d", a->a, a->i)
> +INSN(andi,   "r%d, r%d, %d", a->d, a->a, a->k)
> +INSN(ori,    "r%d, r%d, %d", a->d, a->a, a->k)
> +INSN(xori,   "r%d, r%d, %d", a->d, a->a, a->i)
> +INSN(mfspr,  "r%d, r%d, %d", a->d, a->a, a->k)
> +INSN(mtspr,  "r%d, r%d, %d", a->a, a->b, a->k)
> +INSN(mac,    "r%d, r%d", a->a, a->b)
> +INSN(msb,    "r%d, r%d", a->a, a->b)
> +INSN(macu,   "r%d, r%d", a->a, a->b)
> +INSN(msbu,   "r%d, r%d", a->a, a->b)
> +INSN(slli,   "r%d, r%d, %d", a->d, a->a, a->l)
> +INSN(srli,   "r%d, r%d, %d", a->d, a->a, a->l)
> +INSN(srai,   "r%d, r%d, %d", a->d, a->a, a->l)
> +INSN(rori,   "r%d, r%d, %d", a->d, a->a, a->l)
> +INSN(movhi,  "r%d, %d", a->d, a->k)
> +INSN(macrc,  "r%d", a->d)
> +INSN(sfeq,   "r%d, r%d", a->a, a->b)
> +INSN(sfne,   "r%d, r%d", a->a, a->b)
> +INSN(sfgtu,  "r%d, r%d", a->a, a->b)
> +INSN(sfgeu,  "r%d, r%d", a->a, a->b)
> +INSN(sfltu,  "r%d, r%d", a->a, a->b)
> +INSN(sfleu,  "r%d, r%d", a->a, a->b)
> +INSN(sfgts,  "r%d, r%d", a->a, a->b)
> +INSN(sfges,  "r%d, r%d", a->a, a->b)
> +INSN(sflts,  "r%d, r%d", a->a, a->b)
> +INSN(sfles,  "r%d, r%d", a->a, a->b)
> +INSN(sfeqi,  "r%d, %d", a->a, a->i)
> +INSN(sfnei,  "r%d, %d", a->a, a->i)
> +INSN(sfgtui, "r%d, %d", a->a, a->i)
> +INSN(sfgeui, "r%d, %d", a->a, a->i)
> +INSN(sfltui, "r%d, %d", a->a, a->i)
> +INSN(sfleui, "r%d, %d", a->a, a->i)
> +INSN(sfgtsi, "r%d, %d", a->a, a->i)
> +INSN(sfgesi, "r%d, %d", a->a, a->i)
> +INSN(sfltsi, "r%d, %d", a->a, a->i)
> +INSN(sflesi, "r%d, %d", a->a, a->i)
> +INSN(sys,    "%d", a->k)
> +INSN(trap,   "%d", a->k)
> +INSN(msync,  "")
> +INSN(psync,  "")
> +INSN(csync,  "")
> +INSN(rfe,    "")
> +
> +#define FP_INSN(opcode, suffix, format, ...) \
> +static bool trans_lf_##opcode##_##suffix(disassemble_info *info, \
> +    arg_lf_##opcode##_##suffix *a, uint32_t insn)                \
> +{                                                                \
> +    output("lf." #opcode "." #suffix, format, ##__VA_ARGS__);    \
> +    return true;                                                 \
> +}
> +
> +FP_INSN(add, s,  "r%d, r%d, r%d", a->d, a->a, a->b)
> +FP_INSN(sub, s,  "r%d, r%d, r%d", a->d, a->a, a->b)
> +FP_INSN(mul, s,  "r%d, r%d, r%d", a->d, a->a, a->b)
> +FP_INSN(div, s,  "r%d, r%d, r%d", a->d, a->a, a->b)
> +FP_INSN(rem, s,  "r%d, r%d, r%d", a->d, a->a, a->b)
> +FP_INSN(itof, s, "r%d, r%d", a->d, a->a)
> +FP_INSN(ftoi, s, "r%d, r%d", a->d, a->a)
> +FP_INSN(madd, s, "r%d, r%d, r%d", a->d, a->a, a->b)
> +FP_INSN(sfeq, s, "r%d, r%d", a->a, a->b)
> +FP_INSN(sfne, s, "r%d, r%d", a->a, a->b)
> +FP_INSN(sfgt, s, "r%d, r%d", a->a, a->b)
> +FP_INSN(sfge, s, "r%d, r%d", a->a, a->b)
> +FP_INSN(sflt, s, "r%d, r%d", a->a, a->b)
> +FP_INSN(sfle, s, "r%d, r%d", a->a, a->b)
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
> index 60c6e19f4b..d0662f38c6 100644
> --- a/target/openrisc/translate.c
> +++ b/target/openrisc/translate.c
> @@ -36,10 +36,6 @@
>  #include "trace-tcg.h"
>  #include "exec/log.h"
>  
> -#define LOG_DIS(str, ...) \
> -    qemu_log_mask(CPU_LOG_TB_IN_ASM, "%08x: " str, dc->base.pc_next,    \
> -                  ## __VA_ARGS__)
> -
>  /* is_jmp field values */
>  #define DISAS_EXIT    DISAS_TARGET_0  /* force exit to main loop */
>  #define DISAS_JUMP    DISAS_TARGET_1  /* exit via jmp_pc/jmp_pc_imm */
> @@ -440,7 +436,6 @@ static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb)
>  
>  static bool trans_l_add(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.add r%d, r%d, r%d\n", a->d, a->a, a->b);
>      check_r0_write(a->d);
>      gen_add(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
>      return true;
> @@ -448,7 +443,6 @@ static bool trans_l_add(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_addc(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.addc r%d, r%d, r%d\n", a->d, a->a, a->b);
>      check_r0_write(a->d);
>      gen_addc(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
>      return true;
> @@ -456,7 +450,6 @@ static bool trans_l_addc(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_sub(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.sub r%d, r%d, r%d\n", a->d, a->a, a->b);
>      check_r0_write(a->d);
>      gen_sub(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
>      return true;
> @@ -464,7 +457,6 @@ static bool trans_l_sub(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_and(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.and r%d, r%d, r%d\n", a->d, a->a, a->b);
>      check_r0_write(a->d);
>      tcg_gen_and_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
>      return true;
> @@ -472,7 +464,6 @@ static bool trans_l_and(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_or(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.or r%d, r%d, r%d\n", a->d, a->a, a->b);
>      check_r0_write(a->d);
>      tcg_gen_or_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
>      return true;
> @@ -480,7 +471,6 @@ static bool trans_l_or(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_xor(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.xor r%d, r%d, r%d\n", a->d, a->a, a->b);
>      check_r0_write(a->d);
>      tcg_gen_xor_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
>      return true;
> @@ -488,7 +478,6 @@ static bool trans_l_xor(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_sll(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.sll r%d, r%d, r%d\n", a->d, a->a, a->b);
>      check_r0_write(a->d);
>      tcg_gen_shl_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
>      return true;
> @@ -496,7 +485,6 @@ static bool trans_l_sll(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_srl(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.srl r%d, r%d, r%d\n", a->d, a->a, a->b);
>      check_r0_write(a->d);
>      tcg_gen_shr_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
>      return true;
> @@ -504,7 +492,6 @@ static bool trans_l_srl(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_sra(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.sra r%d, r%d, r%d\n", a->d, a->a, a->b);
>      check_r0_write(a->d);
>      tcg_gen_sar_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
>      return true;
> @@ -512,7 +499,6 @@ static bool trans_l_sra(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_ror(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.ror r%d, r%d, r%d\n", a->d, a->a, a->b);
>      check_r0_write(a->d);
>      tcg_gen_rotr_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
>      return true;
> @@ -520,7 +506,6 @@ static bool trans_l_ror(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_exths(DisasContext *dc, arg_da *a, uint32_t insn)
>  {
> -    LOG_DIS("l.exths r%d, r%d\n", a->d, a->a);
>      check_r0_write(a->d);
>      tcg_gen_ext16s_tl(cpu_R[a->d], cpu_R[a->a]);
>      return true;
> @@ -528,7 +513,6 @@ static bool trans_l_exths(DisasContext *dc, arg_da *a, uint32_t insn)
>  
>  static bool trans_l_extbs(DisasContext *dc, arg_da *a, uint32_t insn)
>  {
> -    LOG_DIS("l.extbs r%d, r%d\n", a->d, a->a);
>      check_r0_write(a->d);
>      tcg_gen_ext8s_tl(cpu_R[a->d], cpu_R[a->a]);
>      return true;
> @@ -536,7 +520,6 @@ static bool trans_l_extbs(DisasContext *dc, arg_da *a, uint32_t insn)
>  
>  static bool trans_l_exthz(DisasContext *dc, arg_da *a, uint32_t insn)
>  {
> -    LOG_DIS("l.exthz r%d, r%d\n", a->d, a->a);
>      check_r0_write(a->d);
>      tcg_gen_ext16u_tl(cpu_R[a->d], cpu_R[a->a]);
>      return true;
> @@ -544,7 +527,6 @@ static bool trans_l_exthz(DisasContext *dc, arg_da *a, uint32_t insn)
>  
>  static bool trans_l_extbz(DisasContext *dc, arg_da *a, uint32_t insn)
>  {
> -    LOG_DIS("l.extbz r%d, r%d\n", a->d, a->a);
>      check_r0_write(a->d);
>      tcg_gen_ext8u_tl(cpu_R[a->d], cpu_R[a->a]);
>      return true;
> @@ -553,7 +535,6 @@ static bool trans_l_extbz(DisasContext *dc, arg_da *a, uint32_t insn)
>  static bool trans_l_cmov(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
>      TCGv zero;
> -    LOG_DIS("l.cmov r%d, r%d, r%d\n", a->d, a->a, a->b);
>  
>      check_r0_write(a->d);
>      zero = tcg_const_tl(0);
> @@ -565,8 +546,6 @@ static bool trans_l_cmov(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_ff1(DisasContext *dc, arg_da *a, uint32_t insn)
>  {
> -    LOG_DIS("l.ff1 r%d, r%d\n", a->d, a->a);
> -
>      check_r0_write(a->d);
>      tcg_gen_ctzi_tl(cpu_R[a->d], cpu_R[a->a], -1);
>      tcg_gen_addi_tl(cpu_R[a->d], cpu_R[a->d], 1);
> @@ -575,8 +554,6 @@ static bool trans_l_ff1(DisasContext *dc, arg_da *a, uint32_t insn)
>  
>  static bool trans_l_fl1(DisasContext *dc, arg_da *a, uint32_t insn)
>  {
> -    LOG_DIS("l.fl1 r%d, r%d\n", a->d, a->a);
> -
>      check_r0_write(a->d);
>      tcg_gen_clzi_tl(cpu_R[a->d], cpu_R[a->a], TARGET_LONG_BITS);
>      tcg_gen_subfi_tl(cpu_R[a->d], TARGET_LONG_BITS, cpu_R[a->d]);
> @@ -585,8 +562,6 @@ static bool trans_l_fl1(DisasContext *dc, arg_da *a, uint32_t insn)
>  
>  static bool trans_l_mul(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.mul r%d, r%d, r%d\n", a->d, a->a, a->b);
> -
>      check_r0_write(a->d);
>      gen_mul(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
>      return true;
> @@ -594,8 +569,6 @@ static bool trans_l_mul(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_mulu(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.mulu r%d, r%d, r%d\n", a->d, a->a, a->b);
> -
>      check_r0_write(a->d);
>      gen_mulu(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
>      return true;
> @@ -603,8 +576,6 @@ static bool trans_l_mulu(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_div(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.div r%d, r%d, r%d\n", a->d, a->a, a->b);
> -
>      check_r0_write(a->d);
>      gen_div(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
>      return true;
> @@ -612,8 +583,6 @@ static bool trans_l_div(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_divu(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.divu r%d, r%d, r%d\n", a->d, a->a, a->b);
> -
>      check_r0_write(a->d);
>      gen_divu(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
>      return true;
> @@ -621,14 +590,12 @@ static bool trans_l_divu(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_l_muld(DisasContext *dc, arg_ab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.muld r%d, r%d\n", a->a, a->b);
>      gen_muld(dc, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_muldu(DisasContext *dc, arg_ab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.muldu r%d, r%d\n", a->a, a->b);
>      gen_muldu(dc, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
> @@ -637,7 +604,6 @@ static bool trans_l_j(DisasContext *dc, arg_l_j *a, uint32_t insn)
>  {
>      target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
>  
> -    LOG_DIS("l.j %d\n", a->n);
>      tcg_gen_movi_tl(jmp_pc, tmp_pc);
>      dc->jmp_pc_imm = tmp_pc;
>      dc->delayed_branch = 2;
> @@ -649,7 +615,6 @@ static bool trans_l_jal(DisasContext *dc, arg_l_jal *a, uint32_t insn)
>      target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
>      target_ulong ret_pc = dc->base.pc_next + 8;
>  
> -    LOG_DIS("l.jal %d\n", a->n);
>      tcg_gen_movi_tl(cpu_R[9], ret_pc);
>      /* Optimize jal being used to load the PC for PIC.  */
>      if (tmp_pc != ret_pc) {
> @@ -677,21 +642,18 @@ static void do_bf(DisasContext *dc, arg_l_bf *a, TCGCond cond)
>  
>  static bool trans_l_bf(DisasContext *dc, arg_l_bf *a, uint32_t insn)
>  {
> -    LOG_DIS("l.bf %d\n", a->n);
>      do_bf(dc, a, TCG_COND_NE);
>      return true;
>  }
>  
>  static bool trans_l_bnf(DisasContext *dc, arg_l_bf *a, uint32_t insn)
>  {
> -    LOG_DIS("l.bnf %d\n", a->n);
>      do_bf(dc, a, TCG_COND_EQ);
>      return true;
>  }
>  
>  static bool trans_l_jr(DisasContext *dc, arg_l_jr *a, uint32_t insn)
>  {
> -    LOG_DIS("l.jr r%d\n", a->b);
>      tcg_gen_mov_tl(jmp_pc, cpu_R[a->b]);
>      dc->delayed_branch = 2;
>      return true;
> @@ -699,7 +661,6 @@ static bool trans_l_jr(DisasContext *dc, arg_l_jr *a, uint32_t insn)
>  
>  static bool trans_l_jalr(DisasContext *dc, arg_l_jalr *a, uint32_t insn)
>  {
> -    LOG_DIS("l.jalr r%d\n", a->b);
>      tcg_gen_mov_tl(jmp_pc, cpu_R[a->b]);
>      tcg_gen_movi_tl(cpu_R[9], dc->base.pc_next + 8);
>      dc->delayed_branch = 2;
> @@ -710,8 +671,6 @@ static bool trans_l_lwa(DisasContext *dc, arg_load *a, uint32_t insn)
>  {
>      TCGv ea;
>  
> -    LOG_DIS("l.lwa r%d, r%d, %d\n", a->d, a->a, a->i);
> -
>      check_r0_write(a->d);
>      ea = tcg_temp_new();
>      tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
> @@ -735,42 +694,36 @@ static void do_load(DisasContext *dc, arg_load *a, TCGMemOp mop)
>  
>  static bool trans_l_lwz(DisasContext *dc, arg_load *a, uint32_t insn)
>  {
> -    LOG_DIS("l.lwz r%d, r%d, %d\n", a->d, a->a, a->i);
>      do_load(dc, a, MO_TEUL);
>      return true;
>  }
>  
>  static bool trans_l_lws(DisasContext *dc, arg_load *a, uint32_t insn)
>  {
> -    LOG_DIS("l.lws r%d, r%d, %d\n", a->d, a->a, a->i);
>      do_load(dc, a, MO_TESL);
>      return true;
>  }
>  
>  static bool trans_l_lbz(DisasContext *dc, arg_load *a, uint32_t insn)
>  {
> -    LOG_DIS("l.lbz r%d, r%d, %d\n", a->d, a->a, a->i);
>      do_load(dc, a, MO_UB);
>      return true;
>  }
>  
>  static bool trans_l_lbs(DisasContext *dc, arg_load *a, uint32_t insn)
>  {
> -    LOG_DIS("l.lbs r%d, r%d, %d\n", a->d, a->a, a->i);
>      do_load(dc, a, MO_SB);
>      return true;
>  }
>  
>  static bool trans_l_lhz(DisasContext *dc, arg_load *a, uint32_t insn)
>  {
> -    LOG_DIS("l.lhz r%d, r%d, %d\n", a->d, a->a, a->i);
>      do_load(dc, a, MO_TEUW);
>      return true;
>  }
>  
>  static bool trans_l_lhs(DisasContext *dc, arg_load *a, uint32_t insn)
>  {
> -    LOG_DIS("l.lhs r%d, r%d, %d\n", a->d, a->a, a->i);
>      do_load(dc, a, MO_TESW);
>      return true;
>  }
> @@ -780,8 +733,6 @@ static bool trans_l_swa(DisasContext *dc, arg_store *a, uint32_t insn)
>      TCGv ea, val;
>      TCGLabel *lab_fail, *lab_done;
>  
> -    LOG_DIS("l.swa r%d, r%d, %d\n", a->a, a->b, a->i);
> -
>      ea = tcg_temp_new();
>      tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
>  
> @@ -822,28 +773,24 @@ static void do_store(DisasContext *dc, arg_store *a, TCGMemOp mop)
>  
>  static bool trans_l_sw(DisasContext *dc, arg_store *a, uint32_t insn)
>  {
> -    LOG_DIS("l.sw r%d, r%d, %d\n", a->a, a->b, a->i);
>      do_store(dc, a, MO_TEUL);
>      return true;
>  }
>  
>  static bool trans_l_sb(DisasContext *dc, arg_store *a, uint32_t insn)
>  {
> -    LOG_DIS("l.sb r%d, r%d, %d\n", a->a, a->b, a->i);
>      do_store(dc, a, MO_UB);
>      return true;
>  }
>  
>  static bool trans_l_sh(DisasContext *dc, arg_store *a, uint32_t insn)
>  {
> -    LOG_DIS("l.sh r%d, r%d, %d\n", a->a, a->b, a->i);
>      do_store(dc, a, MO_TEUW);
>      return true;
>  }
>  
>  static bool trans_l_nop(DisasContext *dc, arg_l_nop *a, uint32_t insn)
>  {
> -    LOG_DIS("l.nop %d\n", a->k);
>      return true;
>  }
>  
> @@ -851,7 +798,6 @@ static bool trans_l_addi(DisasContext *dc, arg_rri *a, uint32_t insn)
>  {
>      TCGv t0;
>  
> -    LOG_DIS("l.addi r%d, r%d, %d\n", a->d, a->a, a->i);
>      check_r0_write(a->d);
>      t0 = tcg_const_tl(a->i);
>      gen_add(dc, cpu_R[a->d], cpu_R[a->a], t0);
> @@ -863,7 +809,6 @@ static bool trans_l_addic(DisasContext *dc, arg_rri *a, uint32_t insn)
>  {
>      TCGv t0;
>  
> -    LOG_DIS("l.addic r%d, r%d, %d\n", a->d, a->a, a->i);
>      check_r0_write(a->d);
>      t0 = tcg_const_tl(a->i);
>      gen_addc(dc, cpu_R[a->d], cpu_R[a->a], t0);
> @@ -875,7 +820,6 @@ static bool trans_l_muli(DisasContext *dc, arg_rri *a, uint32_t insn)
>  {
>      TCGv t0;
>  
> -    LOG_DIS("l.muli r%d, r%d, %d\n", a->d, a->a, a->i);
>      check_r0_write(a->d);
>      t0 = tcg_const_tl(a->i);
>      gen_mul(dc, cpu_R[a->d], cpu_R[a->a], t0);
> @@ -887,7 +831,6 @@ static bool trans_l_maci(DisasContext *dc, arg_l_maci *a, uint32_t insn)
>  {
>      TCGv t0;
>  
> -    LOG_DIS("l.maci r%d, %d\n", a->a, a->i);
>      t0 = tcg_const_tl(a->i);
>      gen_mac(dc, cpu_R[a->a], t0);
>      tcg_temp_free(t0);
> @@ -896,7 +839,6 @@ static bool trans_l_maci(DisasContext *dc, arg_l_maci *a, uint32_t insn)
>  
>  static bool trans_l_andi(DisasContext *dc, arg_rrk *a, uint32_t insn)
>  {
> -    LOG_DIS("l.andi r%d, r%d, %d\n", a->d, a->a, a->k);
>      check_r0_write(a->d);
>      tcg_gen_andi_tl(cpu_R[a->d], cpu_R[a->a], a->k);
>      return true;
> @@ -904,7 +846,6 @@ static bool trans_l_andi(DisasContext *dc, arg_rrk *a, uint32_t insn)
>  
>  static bool trans_l_ori(DisasContext *dc, arg_rrk *a, uint32_t insn)
>  {
> -    LOG_DIS("l.ori r%d, r%d, %d\n", a->d, a->a, a->k);
>      check_r0_write(a->d);
>      tcg_gen_ori_tl(cpu_R[a->d], cpu_R[a->a], a->k);
>      return true;
> @@ -912,7 +853,6 @@ static bool trans_l_ori(DisasContext *dc, arg_rrk *a, uint32_t insn)
>  
>  static bool trans_l_xori(DisasContext *dc, arg_rri *a, uint32_t insn)
>  {
> -    LOG_DIS("l.xori r%d, r%d, %d\n", a->d, a->a, a->i);
>      check_r0_write(a->d);
>      tcg_gen_xori_tl(cpu_R[a->d], cpu_R[a->a], a->i);
>      return true;
> @@ -920,7 +860,6 @@ static bool trans_l_xori(DisasContext *dc, arg_rri *a, uint32_t insn)
>  
>  static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a, uint32_t insn)
>  {
> -    LOG_DIS("l.mfspr r%d, r%d, %d\n", a->d, a->a, a->k);
>      check_r0_write(a->d);
>  
>      if (is_user(dc)) {
> @@ -936,8 +875,6 @@ static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a, uint32_t insn)
>  
>  static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a, uint32_t insn)
>  {
> -    LOG_DIS("l.mtspr r%d, r%d, %d\n", a->a, a->b, a->k);
> -
>      if (is_user(dc)) {
>          gen_illegal_exception(dc);
>      } else {
> @@ -973,35 +910,30 @@ static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a, uint32_t insn)
>  
>  static bool trans_l_mac(DisasContext *dc, arg_ab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.mac r%d, r%d\n", a->a, a->b);
>      gen_mac(dc, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_msb(DisasContext *dc, arg_ab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.msb r%d, r%d\n", a->a, a->b);
>      gen_msb(dc, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_macu(DisasContext *dc, arg_ab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.mac r%d, r%d\n", a->a, a->b);
>      gen_macu(dc, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_msbu(DisasContext *dc, arg_ab *a, uint32_t insn)
>  {
> -    LOG_DIS("l.msb r%d, r%d\n", a->a, a->b);
>      gen_msbu(dc, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_slli(DisasContext *dc, arg_dal *a, uint32_t insn)
>  {
> -    LOG_DIS("l.slli r%d, r%d, %d\n", a->d, a->a, a->l);
>      check_r0_write(a->d);
>      tcg_gen_shli_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
>      return true;
> @@ -1009,7 +941,6 @@ static bool trans_l_slli(DisasContext *dc, arg_dal *a, uint32_t insn)
>  
>  static bool trans_l_srli(DisasContext *dc, arg_dal *a, uint32_t insn)
>  {
> -    LOG_DIS("l.srli r%d, r%d, %d\n", a->d, a->a, a->l);
>      check_r0_write(a->d);
>      tcg_gen_shri_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
>      return true;
> @@ -1017,7 +948,6 @@ static bool trans_l_srli(DisasContext *dc, arg_dal *a, uint32_t insn)
>  
>  static bool trans_l_srai(DisasContext *dc, arg_dal *a, uint32_t insn)
>  {
> -    LOG_DIS("l.srai r%d, r%d, %d\n", a->d, a->a, a->l);
>      check_r0_write(a->d);
>      tcg_gen_sari_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
>      return true;
> @@ -1025,7 +955,6 @@ static bool trans_l_srai(DisasContext *dc, arg_dal *a, uint32_t insn)
>  
>  static bool trans_l_rori(DisasContext *dc, arg_dal *a, uint32_t insn)
>  {
> -    LOG_DIS("l.rori r%d, r%d, %d\n", a->d, a->a, a->l);
>      check_r0_write(a->d);
>      tcg_gen_rotri_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
>      return true;
> @@ -1033,7 +962,6 @@ static bool trans_l_rori(DisasContext *dc, arg_dal *a, uint32_t insn)
>  
>  static bool trans_l_movhi(DisasContext *dc, arg_l_movhi *a, uint32_t insn)
>  {
> -    LOG_DIS("l.movhi r%d, %d\n", a->d, a->k);
>      check_r0_write(a->d);
>      tcg_gen_movi_tl(cpu_R[a->d], a->k << 16);
>      return true;
> @@ -1041,7 +969,6 @@ static bool trans_l_movhi(DisasContext *dc, arg_l_movhi *a, uint32_t insn)
>  
>  static bool trans_l_macrc(DisasContext *dc, arg_l_macrc *a, uint32_t insn)
>  {
> -    LOG_DIS("l.macrc r%d\n", a->d);
>      check_r0_write(a->d);
>      tcg_gen_trunc_i64_tl(cpu_R[a->d], cpu_mac);
>      tcg_gen_movi_i64(cpu_mac, 0);
> @@ -1050,147 +977,126 @@ static bool trans_l_macrc(DisasContext *dc, arg_l_macrc *a, uint32_t insn)
>  
>  static bool trans_l_sfeq(DisasContext *dc, arg_ab *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfeq r%d, r%d\n", a->a, a->b);
>      tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_sfne(DisasContext *dc, arg_ab *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfne r%d, r%d\n", a->a, a->b);
>      tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_sfgtu(DisasContext *dc, arg_ab *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfgtu r%d, r%d\n", a->a, a->b);
>      tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_sfgeu(DisasContext *dc, arg_ab *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfgeu r%d, r%d\n", a->a, a->b);
>      tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_sfltu(DisasContext *dc, arg_ab *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfltu r%d, r%d\n", a->a, a->b);
>      tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_sfleu(DisasContext *dc, arg_ab *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfleu r%d, r%d\n", a->a, a->b);
>      tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_sfgts(DisasContext *dc, arg_ab *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfgts r%d, r%d\n", a->a, a->b);
>      tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_sfges(DisasContext *dc, arg_ab *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfges r%d, r%d\n", a->a, a->b);
>      tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_sflts(DisasContext *dc, arg_ab *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sflts r%d, r%d\n", a->a, a->b);
>      tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_sfles(DisasContext *dc, arg_ab *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfles r%d, r%d\n", a->a, a->b);
>      tcg_gen_setcond_tl(TCG_COND_LE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
>      return true;
>  }
>  
>  static bool trans_l_sfeqi(DisasContext *dc, arg_ai *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfeqi r%d, %d\n", a->a, a->i);
>      tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[a->a], a->i);
>      return true;
>  }
>  
>  static bool trans_l_sfnei(DisasContext *dc, arg_ai *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfnei r%d, %d\n", a->a, a->i);
>      tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R[a->a], a->i);
>      return true;
>  }
>  
>  static bool trans_l_sfgtui(DisasContext *dc, arg_ai *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfgtui r%d, %d\n", a->a, a->i);
>      tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[a->a], a->i);
>      return true;
>  }
>  
>  static bool trans_l_sfgeui(DisasContext *dc, arg_ai *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfgeui r%d, %d\n", a->a, a->i);
>      tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[a->a], a->i);
>      return true;
>  }
>  
>  static bool trans_l_sfltui(DisasContext *dc, arg_ai *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfltui r%d, %d\n", a->a, a->i);
>      tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[a->a], a->i);
>      return true;
>  }
>  
>  static bool trans_l_sfleui(DisasContext *dc, arg_ai *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfleui r%d, %d\n", a->a, a->i);
>      tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[a->a], a->i);
>      return true;
>  }
>  
>  static bool trans_l_sfgtsi(DisasContext *dc, arg_ai *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfgtsi r%d, %d\n", a->a, a->i);
>      tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R[a->a], a->i);
>      return true;
>  }
>  
>  static bool trans_l_sfgesi(DisasContext *dc, arg_ai *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfgesi r%d, %d\n", a->a, a->i);
>      tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R[a->a], a->i);
>      return true;
>  }
>  
>  static bool trans_l_sfltsi(DisasContext *dc, arg_ai *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sfltsi r%d, %d\n", a->a, a->i);
>      tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R[a->a], a->i);
>      return true;
>  }
>  
>  static bool trans_l_sflesi(DisasContext *dc, arg_ai *a, TCGCond cond)
>  {
> -    LOG_DIS("l.sflesi r%d, %d\n", a->a, a->i);
>      tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R[a->a], a->i);
>      return true;
>  }
>  
>  static bool trans_l_sys(DisasContext *dc, arg_l_sys *a, uint32_t insn)
>  {
> -    LOG_DIS("l.sys %d\n", a->k);
>      tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
>      gen_exception(dc, EXCP_SYSCALL);
>      dc->base.is_jmp = DISAS_NORETURN;
> @@ -1199,7 +1105,6 @@ static bool trans_l_sys(DisasContext *dc, arg_l_sys *a, uint32_t insn)
>  
>  static bool trans_l_trap(DisasContext *dc, arg_l_trap *a, uint32_t insn)
>  {
> -    LOG_DIS("l.trap %d\n", a->k);
>      tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
>      gen_exception(dc, EXCP_TRAP);
>      dc->base.is_jmp = DISAS_NORETURN;
> @@ -1208,27 +1113,22 @@ static bool trans_l_trap(DisasContext *dc, arg_l_trap *a, uint32_t insn)
>  
>  static bool trans_l_msync(DisasContext *dc, arg_l_msync *a, uint32_t insn)
>  {
> -    LOG_DIS("l.msync\n");
>      tcg_gen_mb(TCG_MO_ALL);
>      return true;
>  }
>  
>  static bool trans_l_psync(DisasContext *dc, arg_l_psync *a, uint32_t insn)
>  {
> -    LOG_DIS("l.psync\n");
>      return true;
>  }
>  
>  static bool trans_l_csync(DisasContext *dc, arg_l_csync *a, uint32_t insn)
>  {
> -    LOG_DIS("l.csync\n");
>      return true;
>  }
>  
>  static bool trans_l_rfe(DisasContext *dc, arg_l_rfe *a, uint32_t insn)
>  {
> -    LOG_DIS("l.rfe\n");
> -
>      if (is_user(dc)) {
>          gen_illegal_exception(dc);
>      } else {
> @@ -1271,56 +1171,48 @@ static void do_fpcmp(DisasContext *dc, arg_ab *a,
>  
>  static bool trans_lf_add_s(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("lf.add.s r%d, r%d, r%d\n", a->d, a->a, a->b);
>      do_fp3(dc, a, gen_helper_float_add_s);
>      return true;
>  }
>  
>  static bool trans_lf_sub_s(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("lf.sub.s r%d, r%d, r%d\n", a->d, a->a, a->b);
>      do_fp3(dc, a, gen_helper_float_sub_s);
>      return true;
>  }
>  
>  static bool trans_lf_mul_s(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("lf.mul.s r%d, r%d, r%d\n", a->d, a->a, a->b);
>      do_fp3(dc, a, gen_helper_float_mul_s);
>      return true;
>  }
>  
>  static bool trans_lf_div_s(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("lf.div.s r%d, r%d, r%d\n", a->d, a->a, a->b);
>      do_fp3(dc, a, gen_helper_float_div_s);
>      return true;
>  }
>  
>  static bool trans_lf_rem_s(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("lf.rem.s r%d, r%d, r%d\n", a->d, a->a, a->b);
>      do_fp3(dc, a, gen_helper_float_rem_s);
>      return true;
>  }
>  
>  static bool trans_lf_itof_s(DisasContext *dc, arg_da *a, uint32_t insn)
>  {
> -    LOG_DIS("lf.itof.s r%d, r%d\n", a->d, a->a);
>      do_fp2(dc, a, gen_helper_itofs);
>      return true;
>  }
>  
>  static bool trans_lf_ftoi_s(DisasContext *dc, arg_da *a, uint32_t insn)
>  {
> -    LOG_DIS("lf.ftoi.s r%d, r%d\n", a->d, a->a);
>      do_fp2(dc, a, gen_helper_ftois);
>      return true;
>  }
>  
>  static bool trans_lf_madd_s(DisasContext *dc, arg_dab *a, uint32_t insn)
>  {
> -    LOG_DIS("lf.madd.s r%d, r%d, r%d\n", a->d, a->a, a->b);
>      check_r0_write(a->d);
>      gen_helper_float_madd_s(cpu_R[a->d], cpu_env, cpu_R[a->d],
>                              cpu_R[a->a], cpu_R[a->b]);
> @@ -1330,42 +1222,36 @@ static bool trans_lf_madd_s(DisasContext *dc, arg_dab *a, uint32_t insn)
>  
>  static bool trans_lf_sfeq_s(DisasContext *dc, arg_ab *a, uint32_t insn)
>  {
> -    LOG_DIS("lf.sfeq.s r%d, r%d\n", a->a, a->b);
>      do_fpcmp(dc, a, gen_helper_float_eq_s, false, false);
>      return true;
>  }
>  
>  static bool trans_lf_sfne_s(DisasContext *dc, arg_ab *a, uint32_t insn)
>  {
> -    LOG_DIS("lf.sfne.s r%d, r%d\n", a->a, a->b);
>      do_fpcmp(dc, a, gen_helper_float_eq_s, true, false);
>      return true;
>  }
>  
>  static bool trans_lf_sfgt_s(DisasContext *dc, arg_ab *a, uint32_t insn)
>  {
> -    LOG_DIS("lf.sfgt.s r%d, r%d\n", a->a, a->b);
>      do_fpcmp(dc, a, gen_helper_float_lt_s, false, true);
>      return true;
>  }
>  
>  static bool trans_lf_sfge_s(DisasContext *dc, arg_ab *a, uint32_t insn)
>  {
> -    LOG_DIS("lf.sfge.s r%d, r%d\n", a->a, a->b);
>      do_fpcmp(dc, a, gen_helper_float_le_s, false, true);
>      return true;
>  }
>  
>  static bool trans_lf_sflt_s(DisasContext *dc, arg_ab *a, uint32_t insn)
>  {
> -    LOG_DIS("lf.sflt.s r%d, r%d\n", a->a, a->b);
>      do_fpcmp(dc, a, gen_helper_float_lt_s, false, false);
>      return true;
>  }
>  
>  static bool trans_lf_sfle_s(DisasContext *dc, arg_ab *a, uint32_t insn)
>  {
> -    LOG_DIS("lf.sfle.s r%d, r%d\n", a->a, a->b);
>      do_fpcmp(dc, a, gen_helper_float_le_s, false, false);
>      return true;
>  }
> diff --git a/target/openrisc/Makefile.objs b/target/openrisc/Makefile.objs
> index 957ce02199..b5432f4684 100644
> --- a/target/openrisc/Makefile.objs
> +++ b/target/openrisc/Makefile.objs
> @@ -1,5 +1,5 @@
>  obj-$(CONFIG_SOFTMMU) += machine.o
> -obj-y += cpu.o exception.o interrupt.o mmu.o translate.o
> +obj-y += cpu.o exception.o interrupt.o mmu.o translate.o disas.o
>  obj-y += exception_helper.o fpu_helper.o \
>           interrupt_helper.o sys_helper.o
>  obj-y += gdbstub.o
> @@ -12,3 +12,4 @@ target/openrisc/decode.inc.c: \
>  	  $(PYTHON) $(DECODETREE) -o $@ $<, "GEN", $(TARGET_DIR)$@)
>  
>  target/openrisc/translate.o: target/openrisc/decode.inc.c
> +target/openrisc/disas.o: target/openrisc/decode.inc.c
> 

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 19/22] target/openrisc: Add print_insn_or1k
  2018-06-27 16:03   ` Philippe Mathieu-Daudé
@ 2018-06-27 16:15     ` Richard Henderson
  2018-06-27 23:17       ` Stafford Horne
  0 siblings, 1 reply; 41+ messages in thread
From: Richard Henderson @ 2018-06-27 16:15 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé; +Cc: qemu-devel, shorne

On 06/27/2018 09:03 AM, Philippe Mathieu-Daudé wrote:
>> +INSN(lwa,    "r%d, %d(r%d)", a->d, a->i, a->a)
>> +INSN(lwz,    "r%d, %d(r%d)", a->d, a->i, a->a)
>> +INSN(lws,    "r%d, %d(r%d)", a->d, a->i, a->a)
>> +INSN(lbz,    "r%d, %d(r%d)", a->d, a->i, a->a)
>> +INSN(lbs,    "r%d, %d(r%d)", a->d, a->i, a->a)
>> +INSN(lhz,    "r%d, %d(r%d)", a->d, a->i, a->a)
>> +INSN(lhs,    "r%d, %d(r%d)", a->d, a->i, a->a)
>> +INSN(swa,    "%d(r%d), r%d", a->i, a->a, a->b)
>> +INSN(sw,     "%d(r%d), r%d", a->i, a->a, a->b)
>> +INSN(sb,     "%d(r%d), r%d", a->i, a->a, a->b)
>> +INSN(sh,     "%d(r%d), r%d", a->i, a->a, a->b)
> 
> You updated to use the offset(reg) notation, ok.

Yes, failure to match the usual format was confusing.

>> +INSN(nop,    "")
> 
> The nop previously displayed 'k', I suppose a left-over from sys/trap.

Yes, real nop has no argument.


r~

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 20/22] target/openrisc: Add support in scripts/qemu-binfmt-conf.sh
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 20/22] target/openrisc: Add support in scripts/qemu-binfmt-conf.sh Richard Henderson
@ 2018-06-27 19:02   ` Laurent Vivier
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Vivier @ 2018-06-27 19:02 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: shorne

Le 18/06/2018 à 20:40, Richard Henderson a écrit :
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  scripts/qemu-binfmt-conf.sh | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)

Reviewed-by: Laurent Vivier <laurent@vivier.eu>

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 21/22] linux-user: Implement signals for openrisc
  2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 21/22] linux-user: Implement signals for openrisc Richard Henderson
@ 2018-06-27 19:43   ` Laurent Vivier
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Vivier @ 2018-06-27 19:43 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: shorne

Le 18/06/2018 à 20:40, Richard Henderson a écrit :
> All of the existing code was boilerplate from elsewhere,
> and would crash the guest upon the first signal.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> 
> ---
> v2:
>   Add a comment to the new definition of target_pt_regs.
>   Install the signal mask into the ucontext.
> ---
>  linux-user/openrisc/target_syscall.h |  28 +---
>  linux-user/openrisc/signal.c         | 212 +++++++++++----------------
>  linux-user/signal.c                  |   2 +-
>  target/openrisc/cpu.c                |   1 +
>  4 files changed, 95 insertions(+), 148 deletions(-)
> 
...
> diff --git a/linux-user/openrisc/signal.c b/linux-user/openrisc/signal.c
> index 8be0b74001..ea083ef15e 100644
> --- a/linux-user/openrisc/signal.c
> +++ b/linux-user/openrisc/signal.c
...
>  static inline abi_ulong get_sigframe(struct target_sigaction *ka,
> -                                     CPUOpenRISCState *regs,
> +                                     CPUOpenRISCState *env,
>                                       size_t frame_size)
>  {
> -    unsigned long sp = get_sp_from_cpustate(regs);
> +    target_ulong sp = get_sp_from_cpustate(env);
>      int onsigstack = on_sig_stack(sp);
>  
> -    /* redzone */
> -    sp = target_sigsp(sp, ka);
> -
> +    /* Honor redzone now.  If we swap to signal stack, no need to waste
> +     * the 128 bytes by subtracting afterward.
> +     */
> +    sp = target_sigsp(sp - 128, ka);
>      sp = align_sigframe(sp - frame_size);
>  
> -    /*
> -     * If we are on the alternate signal stack and would overflow it, don't.
> +    /* If we are on the alternate signal stack and would overflow it, don't.
>       * Return an always-bogus address instead so we will die with SIGSEGV.
>       */
> -
> -    if (onsigstack && !likely(on_sig_stack(sp))) {
> +    if (onsigstack && !on_sig_stack(sp)) {
>          return -1L;
>      }

This part has been removed from the kernel since:

    8e2beafa2f7f openrisc: Use sigsp()

and we use target_sigsp().

> -
>      return sp;
>  }
>  
> @@ -147,11 +101,9 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
>                      target_siginfo_t *info,
>                      target_sigset_t *set, CPUOpenRISCState *env)
>  {
> -    int err = 0;
>      abi_ulong frame_addr;
> -    unsigned long return_ip;
> -    struct target_rt_sigframe *frame;
> -    abi_ulong info_addr, uc_addr;
> +    target_rt_sigframe *frame;
> +    int i;
>  
>      frame_addr = get_sigframe(ka, env, sizeof(*frame));
>      trace_user_setup_rt_frame(env, frame_addr);
> @@ -159,47 +111,35 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
>          goto give_sigsegv;
>      }
>  
> -    info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
> -    __put_user(info_addr, &frame->pinfo);
> -    uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
> -    __put_user(uc_addr, &frame->puc);
> +    tswap_siginfo(&frame->info, info);
>  
> -    if (ka->sa_flags & SA_SIGINFO) {
> -        tswap_siginfo(&frame->info, info);
> -    }

According to your answer to my comment of the v1, you should keep this.
Did you change your mind?

...
>  long do_rt_sigreturn(CPUOpenRISCState *env)
>  {
> +    abi_ulong frame_addr = cpu_get_gpr(env, 1);

You should use get_sp_from_cpustate(env)

Thanks,
Laurent

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/22] target/openrisc: Fix cpu_mmu_index
  2018-06-27 13:50           ` Richard Henderson
@ 2018-06-27 23:08             ` Stafford Horne
  2018-06-28  1:36               ` Richard Henderson
  0 siblings, 1 reply; 41+ messages in thread
From: Stafford Horne @ 2018-06-27 23:08 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel qemu-devel

On Wed, Jun 27, 2018 at 06:50:18AM -0700, Richard Henderson wrote:
> On 06/27/2018 05:59 AM, Stafford Horne wrote:
> > The index is negative... this patch should fix that.
> > 
> > @@ -78,6 +78,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr,
> > target_ulong rb)
> >      case TO_SPR(0, 1024) ... TO_SPR(0, 1024 + (16 * 32)): /* Shadow GPRs */
> >          idx = (spr - 1024);
> >          env->shadow_gpr[idx / 32][idx % 32] = rb;
> > +        break;
> >  
> >      case TO_SPR(1, 512) ... TO_SPR(1, 512 + TLB_SIZE - 1): /* DTLBW0MR 0-127 */
> 
> OMG.  That's embarrasing...

Yes, I thought so too, it's my bug.  I am little surprised it didn't cause
issues before.

I am still getting failures on SMP, this time the kernel is jumping to some
unknown address, maybe an itlb issue, I will continue to debug.  Bisecting it is
exposing some other issues (the mmu handlers were not getting init'd during one
point in time).

-Stafford

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 19/22] target/openrisc: Add print_insn_or1k
  2018-06-27 16:15     ` Richard Henderson
@ 2018-06-27 23:17       ` Stafford Horne
  0 siblings, 0 replies; 41+ messages in thread
From: Stafford Horne @ 2018-06-27 23:17 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Philippe Mathieu-Daudé, qemu-devel

On Wed, Jun 27, 2018 at 09:15:09AM -0700, Richard Henderson wrote:
> On 06/27/2018 09:03 AM, Philippe Mathieu-Daudé wrote:
> >> +INSN(nop,    "")
> > 
> > The nop previously displayed 'k', I suppose a left-over from sys/trap.
> 
> Yes, real nop has no argument.

Just for some history here, in case others are interested.  The nop in openrisc
does have an argument, but it is not used in real hardware.  It is a
hack/shortcut used by the old simulator to trigger debugging operations.  Its
used a lot in a few tests and even in the kernel, but I dont think we want to
carry it in QEMU.  I am happy to get rid of it.

 https://github.com/openrisc/or1ksim/blob/f75787f390cbd543b8ae49a2670ff338d6e9326a/cpu/or32/insnset.c#L766-L825

Also in: cpu/or1k/spr-defs.h

    #define NOP_NOP          0x0000      /* Normal nop instruction */
    #define NOP_EXIT         0x0001      /* End of simulation */
    #define NOP_REPORT       0x0002      /* Simple report */
    /*#define NOP_PRINTF       0x0003       Simprintf instruction (obsolete)*/
    #define NOP_PUTC         0x0004      /* JPB: Simputc instruction */
    #define NOP_CNT_RESET    0x0005	     /* Reset statistics counters */
    ...

-Stafford

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/22] target/openrisc: Fix cpu_mmu_index
  2018-06-27 23:08             ` Stafford Horne
@ 2018-06-28  1:36               ` Richard Henderson
  2018-06-28 21:27                 ` Stafford Horne
  0 siblings, 1 reply; 41+ messages in thread
From: Richard Henderson @ 2018-06-28  1:36 UTC (permalink / raw)
  To: Stafford Horne; +Cc: qemu-devel qemu-devel

On 06/27/2018 04:08 PM, Stafford Horne wrote:
> I am still getting failures on SMP, this time the kernel is jumping to some
> unknown address, maybe an itlb issue, I will continue to debug.  Bisecting it is
> exposing some other issues (the mmu handlers were not getting init'd during one
> point in time).

Fixed, I think.  I traced it down to the l.mtspr rewrite.


r~

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/22] target/openrisc: Fix cpu_mmu_index
  2018-06-28  1:36               ` Richard Henderson
@ 2018-06-28 21:27                 ` Stafford Horne
  0 siblings, 0 replies; 41+ messages in thread
From: Stafford Horne @ 2018-06-28 21:27 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel qemu-devel

On Wed, Jun 27, 2018 at 06:36:20PM -0700, Richard Henderson wrote:
> On 06/27/2018 04:08 PM, Stafford Horne wrote:
> > I am still getting failures on SMP, this time the kernel is jumping to some
> > unknown address, maybe an itlb issue, I will continue to debug.  Bisecting it is
> > exposing some other issues (the mmu handlers were not getting init'd during one
> > point in time).
> 
> Fixed, I think.  I traced it down to the l.mtspr rewrite.

Thanks, the new series works for me.

-Stafford

^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2018-06-28 21:27 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-18 18:40 [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 01/22] target/openrisc: Remove DISAS_JUMP & DISAS_TB_JUMP Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 02/22] target/openrisc: Use exit_tb instead of CPU_INTERRUPT_EXITTB Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 03/22] target/openrisc: Fix singlestep_enabled Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 04/22] target/openrisc: Link more translation blocks Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 05/22] target/openrisc: Split out is_user Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 06/22] target/openrisc: Exit the TB after l.mtspr Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 07/22] target/openrisc: Form the spr index from tcg Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 08/22] target/openrisc: Merge tlb allocation into CPUOpenRISCState Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 09/22] target/openrisc: Remove indirect function calls for mmu Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 10/22] target/openrisc: Merge mmu_helper.c into mmu.c Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 11/22] target/openrisc: Reduce tlb to a single dimension Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 12/22] target/openrisc: Fix tlb flushing in mtspr Richard Henderson
2018-06-22  6:40   ` Stafford Horne
2018-06-24  3:10     ` Stafford Horne
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 13/22] target/openrisc: Fix cpu_mmu_index Richard Henderson
2018-06-24  3:44   ` Stafford Horne
2018-06-26 22:07     ` Stafford Horne
2018-06-26 22:26       ` Richard Henderson
2018-06-27 12:59         ` Stafford Horne
2018-06-27 13:50           ` Richard Henderson
2018-06-27 23:08             ` Stafford Horne
2018-06-28  1:36               ` Richard Henderson
2018-06-28 21:27                 ` Stafford Horne
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 14/22] target/openrisc: Use identical sizes for ITLB and DTLB Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 15/22] target/openrisc: Stub out handle_mmu_fault for softmmu Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 16/22] target/openrisc: Log interrupts Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 17/22] target/openrisc: Increase the TLB size Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 18/22] target/openrisc: Reorg tlb lookup Richard Henderson
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 19/22] target/openrisc: Add print_insn_or1k Richard Henderson
2018-06-27 16:03   ` Philippe Mathieu-Daudé
2018-06-27 16:15     ` Richard Henderson
2018-06-27 23:17       ` Stafford Horne
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 20/22] target/openrisc: Add support in scripts/qemu-binfmt-conf.sh Richard Henderson
2018-06-27 19:02   ` Laurent Vivier
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 21/22] linux-user: Implement signals for openrisc Richard Henderson
2018-06-27 19:43   ` Laurent Vivier
2018-06-18 18:40 ` [Qemu-devel] [PATCH v2 22/22] linux-user: Fix struct sigaltstack " Richard Henderson
2018-06-18 21:05 ` [Qemu-devel] [PATCH v2 00/22] target/openrisc improvements no-reply
2018-06-21 11:00 ` Stafford Horne
2018-06-21 11:25   ` Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.