On 2/26/25 11:39 AM, Florian Lugou wrote:
scontext size is 16 bits on RV32 and 32 bits on RV64, as recommended by
version 1.0 2025-02-21 of the debug specification.

When the Smstateen extension is implemented, accessibility to the
scontext CSR is controlled by bit 57 of the [mh]stateen0 CSRs.

Signed-off-by: Florian Lugou <[email protected]>
---

Can you please rebase these patches on top of the maintainer's tree:

https://github.com/alistair23/qemu/tree/riscv-to-apply.next

This patch will have a conflict on cpu_bits.h in that tree.


Looks good otherwise. Thanks,

Daniel


  target/riscv/cpu.h      |  1 +
  target/riscv/cpu_bits.h |  5 +++++
  target/riscv/csr.c      | 36 ++++++++++++++++++++++++++++++++++++
  target/riscv/debug.c    |  1 +
  4 files changed, 43 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 97713681cb..e47200f409 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -430,6 +430,7 @@ struct CPUArchState {
      target_ulong tdata2[RV_MAX_TRIGGERS];
      target_ulong tdata3[RV_MAX_TRIGGERS];
      target_ulong mcontext;
+    target_ulong scontext;
      struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
      struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
      QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index f97c48a394..add0bb9d0e 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -247,6 +247,9 @@
  #define CSR_SIEH            0x114
  #define CSR_SIPH            0x154
+/* Supervisor-Level Sdtrig CSRs (debug) */
+#define CSR_SCONTEXT        0x5a8
+
  /* Hpervisor CSRs */
  #define CSR_HSTATUS         0x600
  #define CSR_HEDELEG         0x602
@@ -959,4 +962,6 @@ typedef enum RISCVException {
  #define MCONTEXT64                         0x0000000000001FFFULL
  #define MCONTEXT32_HCONTEXT                0x0000007F
  #define MCONTEXT64_HCONTEXT                0x0000000000003FFFULL
+#define SCONTEXT32                         0x0000FFFF
+#define SCONTEXT64                         0x00000000FFFFFFFFULL
  #endif
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index afb7544f07..1c1ac8ed67 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3221,6 +3221,10 @@ static RISCVException write_mstateen0(CPURISCVState 
*env, int csrno,
          wr_mask |= SMSTATEEN0_P1P13;
      }
+ if (riscv_cpu_cfg(env)->debug) {
+        wr_mask |= SMSTATEEN0_HSCONTXT;
+    }
+
      if (riscv_cpu_cfg(env)->ext_smaia || riscv_cpu_cfg(env)->ext_smcsrind) {
          wr_mask |= SMSTATEEN0_SVSLCT;
      }
@@ -5053,6 +5057,35 @@ static RISCVException write_mcontext(CPURISCVState *env, 
int csrno,
      return RISCV_EXCP_NONE;
  }
+static RISCVException read_scontext(CPURISCVState *env, int csrno,
+                                    target_ulong *val)
+{
+    RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSCONTXT);
+    if (ret != RISCV_EXCP_NONE) {
+        return ret;
+    }
+
+    *val = env->scontext;
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_scontext(CPURISCVState *env, int csrno,
+                                     target_ulong val)
+{
+    bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
+
+    RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSCONTXT);
+    if (ret != RISCV_EXCP_NONE) {
+        return ret;
+    }
+
+    /* Spec suggest 16-bit for RV32 and 34-bit for RV64 */
+    target_ulong mask = rv32 ? SCONTEXT32 : SCONTEXT64;
+
+    env->scontext = val & mask;
+    return RISCV_EXCP_NONE;
+}
+
  static RISCVException read_mnscratch(CPURISCVState *env, int csrno,
                                       target_ulong *val)
  {
@@ -5705,6 +5738,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
      [CSR_SIEH]       = { "sieh",   aia_smode32, NULL, NULL, rmw_sieh },
      [CSR_SIPH]       = { "siph",   aia_smode32, NULL, NULL, rmw_siph },
+ /* Supervisor-Level Sdtrig CSRs (debug) */
+    [CSR_SCONTEXT]   = { "scontext", debug, read_scontext, write_scontext },
+
      [CSR_HSTATUS]     = { "hstatus",     hmode,   read_hstatus, write_hstatus,
                            .min_priv_ver = PRIV_VERSION_1_12_0                
},
      [CSR_HEDELEG]     = { "hedeleg",     hmode,   read_hedeleg, write_hedeleg,
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index f6241a80be..914a9ce0f8 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -1086,4 +1086,5 @@ void riscv_trigger_reset_hold(CPURISCVState *env)
      }
env->mcontext = 0;
+    env->scontext = 0;
  }


Reply via email to