qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: marex@denx.de, amir.gonnen@neuroblade.ai
Subject: [PATCH for-7.1 v6 41/51] target/nios2: Introduce shadow register sets
Date: Wed, 16 Mar 2022 22:05:28 -0700	[thread overview]
Message-ID: <20220317050538.924111-42-richard.henderson@linaro.org> (raw)
In-Reply-To: <20220317050538.924111-1-richard.henderson@linaro.org>

Do not actually enable them so far, but add all of the
plumbing to address them.  Do not enable them for user-only.

Add an env->regs pointer that handles the indirection to
the current register set.  The naming of the pointer hides
the difference between old and new, user-only and sysemu.

From the notes on wrprs, which states that r0 must be initialized
before use in shadow register sets, infer that R_ZERO is *not*
hardwired to zero in shadow register sets.  Adjust load_gpr and
dest_gpr to reflect this.  At the same time we might as well
special case crs == 0 to avoid the indirection through env->regs
during translation as well.  Given that this is intended to be
the most common case for non-interrupt handlers.

Init env->regs at reset.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/nios2/cpu.h       | 24 +++++++++++++++++
 target/nios2/cpu.c       |  4 ++-
 target/nios2/translate.c | 58 +++++++++++++++++++++++++++++++---------
 3 files changed, 72 insertions(+), 14 deletions(-)

diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index d5255e9e76..e32bebe9b7 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -60,6 +60,11 @@ struct Nios2CPUClass {
 #define NUM_GP_REGS 32
 #define NUM_CR_REGS 32
 
+#ifndef CONFIG_USER_ONLY
+/* 63 shadow register sets; index 0 is the primary register set. */
+#define NUM_REG_SETS 64
+#endif
+
 /* General purpose register aliases */
 enum {
     R_ZERO   = 0,
@@ -178,7 +183,13 @@ FIELD(CR_TLBMISC, EE, 24, 1)
 #define EXCP_MPUD     17
 
 struct CPUArchState {
+#ifdef CONFIG_USER_ONLY
     uint32_t regs[NUM_GP_REGS];
+#else
+    uint32_t shadow_regs[NUM_REG_SETS][NUM_GP_REGS];
+    /* Pointer into shadow_regs for the current register set. */
+    uint32_t *regs;
+#endif
     uint32_t ctrl[NUM_CR_REGS];
     uint32_t pc;
 
@@ -229,6 +240,14 @@ static inline bool nios2_cr_reserved(const ControlRegState *s)
     return (s->writable | s->readonly) == 0;
 }
 
+static inline void nios2_update_crs(CPUNios2State *env)
+{
+#ifndef CONFIG_USER_ONLY
+    unsigned crs = FIELD_EX32(env->ctrl[CR_STATUS], CR_STATUS, CRS);
+    env->regs = env->shadow_regs[crs];
+#endif
+}
+
 void nios2_tcg_init(void);
 void nios2_cpu_do_interrupt(CPUState *cs);
 void dump_mmu(CPUNios2State *env);
@@ -271,12 +290,17 @@ typedef Nios2CPU ArchCPU;
 
 #include "exec/cpu-all.h"
 
+FIELD(TBFLAGS, CRS0, 0, 1)  /* Set if CRS == 0. */
+FIELD(TBFLAGS, U, 1, 1)     /* Overlaps CR_STATUS_U */
+
 static inline void cpu_get_tb_cpu_state(CPUNios2State *env, target_ulong *pc,
                                         target_ulong *cs_base, uint32_t *flags)
 {
     *pc = env->pc;
     *cs_base = 0;
     *flags = env->ctrl[CR_STATUS] & CR_STATUS_U;
+    *flags |= (env->ctrl[CR_STATUS] & R_CR_STATUS_CRS_MASK
+               ? 0 : R_TBFLAGS_CRS0_MASK);
 }
 
 #endif /* NIOS2_CPU_H */
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index 07306efc35..7545abc68e 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -53,15 +53,17 @@ static void nios2_cpu_reset(DeviceState *dev)
 
     ncc->parent_reset(dev);
 
-    memset(env->regs, 0, sizeof(env->regs));
     memset(env->ctrl, 0, sizeof(env->ctrl));
     env->pc = cpu->reset_addr;
 
 #if defined(CONFIG_USER_ONLY)
     /* Start in user mode with interrupts enabled. */
     env->ctrl[CR_STATUS] = CR_STATUS_RSIE | CR_STATUS_U | CR_STATUS_PIE;
+    memset(env->regs, 0, sizeof(env->regs));
 #else
     env->ctrl[CR_STATUS] = CR_STATUS_RSIE;
+    nios2_update_crs(env);
+    memset(env->shadow_regs, 0, sizeof(env->shadow_regs));
 #endif
 }
 
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 1e784c8a37..525df7b023 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -100,12 +100,16 @@ typedef struct DisasContext {
     DisasContextBase  base;
     target_ulong      pc;
     int               mem_idx;
+    bool              crs0;
     TCGv              sink;
     const ControlRegState *cr_state;
 } DisasContext;
 
 static TCGv cpu_R[NUM_GP_REGS];
 static TCGv cpu_pc;
+#ifndef CONFIG_USER_ONLY
+static TCGv cpu_crs_R[NUM_GP_REGS];
+#endif
 
 typedef struct Nios2Instruction {
     void     (*handler)(DisasContext *dc, uint32_t code, uint32_t flags);
@@ -127,22 +131,36 @@ static uint8_t get_opxcode(uint32_t code)
 static TCGv load_gpr(DisasContext *dc, unsigned reg)
 {
     assert(reg < NUM_GP_REGS);
-    if (unlikely(reg == R_ZERO)) {
-        return tcg_constant_tl(0);
+    if (dc->crs0) {
+        if (unlikely(reg == R_ZERO)) {
+            return tcg_constant_tl(0);
+        }
+        return cpu_R[reg];
     }
-    return cpu_R[reg];
+#ifdef CONFIG_USER_ONLY
+    g_assert_not_reached();
+#else
+    return cpu_crs_R[reg];
+#endif
 }
 
 static TCGv dest_gpr(DisasContext *dc, unsigned reg)
 {
     assert(reg < NUM_GP_REGS);
-    if (unlikely(reg == R_ZERO)) {
-        if (dc->sink == NULL) {
-            dc->sink = tcg_temp_new();
+    if (dc->crs0) {
+        if (unlikely(reg == R_ZERO)) {
+            if (dc->sink == NULL) {
+                dc->sink = tcg_temp_new();
+            }
+            return dc->sink;
         }
-        return dc->sink;
+        return cpu_R[reg];
     }
-    return cpu_R[reg];
+#ifdef CONFIG_USER_ONLY
+    g_assert_not_reached();
+#else
+    return cpu_crs_R[reg];
+#endif
 }
 
 static void t_gen_helper_raise_exception(DisasContext *dc,
@@ -198,7 +216,7 @@ static void gen_excp(DisasContext *dc, uint32_t code, uint32_t flags)
 
 static bool gen_check_supervisor(DisasContext *dc)
 {
-    if (dc->base.tb->flags & CR_STATUS_U) {
+    if (dc->base.tb->flags & R_TBFLAGS_U_MASK) {
         /* CPU in user mode, privileged instruction called, stop. */
         t_gen_helper_raise_exception(dc, EXCP_SUPERI);
         return false;
@@ -794,6 +812,7 @@ static void nios2_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
 
     dc->mem_idx = cpu_mmu_index(env, false);
     dc->cr_state = cpu->cr_state;
+    dc->crs0 = FIELD_EX32(dc->base.tb->flags, TBFLAGS, CRS0);
 
     /* Bound the number of insns to execute to those left on the page.  */
     page_insns = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
@@ -927,13 +946,26 @@ void nios2_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 
 void nios2_tcg_init(void)
 {
-    int i;
+#ifndef CONFIG_USER_ONLY
+    TCGv_ptr crs = tcg_global_mem_new_ptr(cpu_env,
+                                          offsetof(CPUNios2State, regs), "crs");
 
-    for (i = 0; i < NUM_GP_REGS; i++) {
-        cpu_R[i] = tcg_global_mem_new(cpu_env,
-                                      offsetof(CPUNios2State, regs[i]),
+    for (int i = 0; i < NUM_GP_REGS; i++) {
+        cpu_crs_R[i] = tcg_global_mem_new(crs, 4 * i, gr_regnames[i]);
+    }
+
+#define offsetof_regs0(N)  offsetof(CPUNios2State, shadow_regs[0][N])
+#else
+#define offsetof_regs0(N)  offsetof(CPUNios2State, regs[N])
+#endif
+
+    for (int i = 0; i < NUM_GP_REGS; i++) {
+        cpu_R[i] = tcg_global_mem_new(cpu_env, offsetof_regs0(i),
                                       gr_regnames[i]);
     }
+
+#undef offsetof_regs0
+
     cpu_pc = tcg_global_mem_new(cpu_env,
                                 offsetof(CPUNios2State, pc), "pc");
 }
-- 
2.25.1



  parent reply	other threads:[~2022-03-17  5:37 UTC|newest]

Thread overview: 80+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-17  5:04 [PATCH for-7.1 v6 00/51] target/nios2: Shadow register set, EIC and VIC Richard Henderson
2022-03-17  5:04 ` [PATCH for-7.1 v6 01/51] tcg: Fix indirect lowering vs TCG_OPF_COND_BRANCH Richard Henderson
2022-03-17 13:38   ` Peter Maydell
2022-03-17  5:04 ` [PATCH for-7.1 v6 02/51] target/nios2: Check supervisor on eret Richard Henderson
2022-03-17  5:04 ` [PATCH for-7.1 v6 03/51] target/nios2: Stop generating code if gen_check_supervisor fails Richard Henderson
2022-03-17  5:04 ` [PATCH for-7.1 v6 04/51] target/nios2: Add NUM_GP_REGS and NUM_CP_REGS Richard Henderson
2022-03-17  5:04 ` [PATCH for-7.1 v6 05/51] target/nios2: Split PC out of env->regs[] Richard Henderson
2022-03-17  5:04 ` [PATCH for-7.1 v6 06/51] target/nios2: Split out helper for eret instruction Richard Henderson
2022-03-17  5:04 ` [PATCH for-7.1 v6 07/51] target/nios2: Fix BRET instruction Richard Henderson
2022-03-17  5:04 ` [PATCH for-7.1 v6 08/51] target/nios2: Do not create TCGv for control registers Richard Henderson
2022-03-17  5:04 ` [PATCH for-7.1 v6 09/51] linux-user/nios2: Only initialize SP and PC in target_cpu_copy_regs Richard Henderson
2022-03-17  5:04 ` [PATCH for-7.1 v6 10/51] target/nios2: Remove cpu_interrupts_enabled Richard Henderson
2022-03-17  5:04 ` [PATCH for-7.1 v6 11/51] target/nios2: Split control registers away from general registers Richard Henderson
2022-03-17  5:04 ` [PATCH for-7.1 v6 12/51] target/nios2: Clean up nios2_cpu_dump_state Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 13/51] target/nios2: Use hw/registerfields.h for CR_STATUS fields Richard Henderson
2022-03-17 15:13   ` Peter Maydell
2022-03-17  5:05 ` [PATCH for-7.1 v6 14/51] target/nios2: Use hw/registerfields.h for CR_EXCEPTION fields Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 15/51] target/nios2: Use hw/registerfields.h for CR_TLBADDR fields Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 16/51] target/nios2: Use hw/registerfields.h for CR_TLBACC fields Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 17/51] target/nios2: Rename CR_TLBMISC_WR to CR_TLBMISC_WE Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 18/51] target/nios2: Use hw/registerfields.h for CR_TLBMISC fields Richard Henderson
2022-03-17 15:15   ` Peter Maydell
2022-03-17  5:05 ` [PATCH for-7.1 v6 19/51] target/nios2: Move R_FOO and CR_BAR into enumerations Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 20/51] target/nios2: Create EXCP_SEMIHOST for semi-hosting Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 21/51] target/nios2: Clean up nios2_cpu_do_interrupt Richard Henderson
2022-03-17 15:24   ` Peter Maydell
2022-03-17  5:05 ` [PATCH for-7.1 v6 22/51] target/nios2: Hoist CPU_LOG_INT logging Richard Henderson
2022-03-17 15:25   ` Peter Maydell
2022-03-17  5:05 ` [PATCH for-7.1 v6 23/51] target/nios2: Handle EXCP_UNALIGN and EXCP_UALIGND Richard Henderson
2022-03-17 15:27   ` Peter Maydell
2022-03-17 16:47     ` Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 24/51] target/nios2: Cleanup set of CR_EXCEPTION for do_interrupt Richard Henderson
2022-03-17 15:28   ` Peter Maydell
2022-03-17  5:05 ` [PATCH for-7.1 v6 25/51] target/nios2: Clean up handling of tlbmisc in do_exception Richard Henderson
2022-03-17 15:41   ` Peter Maydell
2022-03-17 17:01     ` Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 26/51] target/nios2: Prevent writes to read-only or reserved control fields Richard Henderson
2022-03-17 15:49   ` Peter Maydell
2022-03-17 17:16     ` Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 27/51] target/nios2: Implement cpuid Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 28/51] target/nios2: Implement CR_STATUS.RSIE Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 29/51] target/nios2: Remove CPU_INTERRUPT_NMI Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 30/51] target/nios2: Support division error exception Richard Henderson
2022-03-17 15:52   ` Peter Maydell
2022-03-17  5:05 ` [PATCH for-7.1 v6 31/51] target/nios2: Use tcg_constant_tl Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 32/51] target/nios2: Introduce dest_gpr Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 33/51] target/nios2: Drop CR_STATUS_EH from tb->flags Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 34/51] target/nios2: Enable unaligned traps for system mode Richard Henderson
2022-03-17 16:06   ` Peter Maydell
2022-03-17  5:05 ` [PATCH for-7.1 v6 35/51] target/nios2: Create gen_jumpr Richard Henderson
2022-03-17 16:24   ` Peter Maydell
2022-03-17  5:05 ` [PATCH for-7.1 v6 36/51] target/nios2: Hoist set of is_jmp into gen_goto_tb Richard Henderson
2022-03-17 16:25   ` Peter Maydell
2022-03-17  5:05 ` [PATCH for-7.1 v6 37/51] target/nios2: Use gen_goto_tb for DISAS_TOO_MANY Richard Henderson
2022-03-17 16:28   ` Peter Maydell
2022-03-17  5:05 ` [PATCH for-7.1 v6 38/51] target/nios2: Use tcg_gen_lookup_and_goto_ptr Richard Henderson
2022-03-17 16:29   ` Peter Maydell
2022-03-17  5:05 ` [PATCH for-7.1 v6 39/51] target/nios2: Implement Misaligned destination exception Richard Henderson
2022-03-17 16:37   ` Peter Maydell
2022-03-17 17:41     ` Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 40/51] linux-user/nios2: Handle various SIGILL exceptions Richard Henderson
2022-03-17 16:38   ` Peter Maydell
2022-03-17  5:05 ` Richard Henderson [this message]
2022-03-17 18:33   ` [PATCH for-7.1 v6 41/51] target/nios2: Introduce shadow register sets Peter Maydell
2022-03-17 19:31     ` Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 42/51] target/nios2: Implement rdprs, wrprs Richard Henderson
2022-03-17 18:47   ` Peter Maydell
2022-03-17  5:05 ` [PATCH for-7.1 v6 43/51] target/nios2: Update helper_eret for shadow registers Richard Henderson
2022-03-17 18:53   ` Peter Maydell
2022-03-17  5:05 ` [PATCH for-7.1 v6 44/51] target/nios2: Implement EIC interrupt processing Richard Henderson
2022-03-17 19:11   ` Peter Maydell
2022-03-17 19:54     ` Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 45/51] hw/intc: Vectored Interrupt Controller (VIC) Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 46/51] hw/nios2: Introduce Nios2MachineState Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 47/51] hw/nios2: Move memory regions into Nios2Machine Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 48/51] hw/nios2: Machine with a Vectored Interrupt Controller Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 49/51] tests/tcg: Expose AR to test build environment if needed Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 50/51] test/tcg/nios2: Add semihosting multiarch tests Richard Henderson
2022-03-17  5:05 ` [PATCH for-7.1 v6 51/51] tests/tcg/nios2: Add test-shadow-1 Richard Henderson
2022-03-22 12:17 ` [PATCH for-7.1 v6 00/51] target/nios2: Shadow register set, EIC and VIC Amir Gonnen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220317050538.924111-42-richard.henderson@linaro.org \
    --to=richard.henderson@linaro.org \
    --cc=amir.gonnen@neuroblade.ai \
    --cc=marex@denx.de \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).