[PATCH v2 1/2] target/riscv: Add scontext CSR handling

Florian Lugou posted 2 patches 11 months, 1 week ago
Maintainers: Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <dbarboza@ventanamicro.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
[PATCH v2 1/2] target/riscv: Add scontext CSR handling
Posted by Florian Lugou 11 months, 1 week ago
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 <florian.lugou@provenrun.com>
---
 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 616c3bdc1c..102e8285a6 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -440,6 +440,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 a30317c617..e8997f3153 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -258,6 +258,9 @@
 /* VS-Level Control transfer records CSRs */
 #define CSR_VSCTRCTL        0x24e
 
+/* Supervisor-Level Sdtrig CSRs (debug) */
+#define CSR_SCONTEXT        0x5a8
+
 /* Hpervisor CSRs */
 #define CSR_HSTATUS         0x600
 #define CSR_HEDELEG         0x602
@@ -1103,4 +1106,6 @@ typedef enum CTRType {
 #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 0ebcca4597..37b38f24a6 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3393,6 +3393,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;
     }
@@ -5321,6 +5325,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)
 {
@@ -5973,6 +6006,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 9db4048523..072593ab12 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -1088,4 +1088,5 @@ void riscv_trigger_reset_hold(CPURISCVState *env)
     }
 
     env->mcontext = 0;
+    env->scontext = 0;
 }
-- 
2.43.0
Re: [PATCH v2 1/2] target/riscv: Add scontext CSR handling
Posted by Alistair Francis 11 months, 1 week ago
On Mon, Mar 3, 2025 at 7:39 PM Florian Lugou
<florian.lugou@provenrun.com> 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.

Section 5.7.8 indicates the register is XLEN bits wide, with data
being 32-bits wide for both RV32 and RV64.

Alistair

>
> 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 <florian.lugou@provenrun.com>
> ---
>  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 616c3bdc1c..102e8285a6 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -440,6 +440,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 a30317c617..e8997f3153 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -258,6 +258,9 @@
>  /* VS-Level Control transfer records CSRs */
>  #define CSR_VSCTRCTL        0x24e
>
> +/* Supervisor-Level Sdtrig CSRs (debug) */
> +#define CSR_SCONTEXT        0x5a8
> +
>  /* Hpervisor CSRs */
>  #define CSR_HSTATUS         0x600
>  #define CSR_HEDELEG         0x602
> @@ -1103,4 +1106,6 @@ typedef enum CTRType {
>  #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 0ebcca4597..37b38f24a6 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -3393,6 +3393,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;
>      }
> @@ -5321,6 +5325,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)
>  {
> @@ -5973,6 +6006,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 9db4048523..072593ab12 100644
> --- a/target/riscv/debug.c
> +++ b/target/riscv/debug.c
> @@ -1088,4 +1088,5 @@ void riscv_trigger_reset_hold(CPURISCVState *env)
>      }
>
>      env->mcontext = 0;
> +    env->scontext = 0;
>  }
> --
> 2.43.0
>
>
Re: [PATCH v2 1/2] target/riscv: Add scontext CSR handling
Posted by Alistair Francis 11 months, 1 week ago
On Thu, Mar 6, 2025 at 3:48 PM Alistair Francis <alistair23@gmail.com> wrote:
>
> On Mon, Mar 3, 2025 at 7:39 PM Florian Lugou
> <florian.lugou@provenrun.com> 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.
>
> Section 5.7.8 indicates the register is XLEN bits wide, with data
> being 32-bits wide for both RV32 and RV64.

Note that QEMU supports the ratified 0.13 debug spec [1] (plus
mcontrol6), where scontext.data is XLEN bits wide, so that's what will
need to be done here.

If you want to support the new debug spec that's also fine, but we
need a way to expose that to users and ensure the spec is supported.

1: https://github.com/riscv/riscv-debug-spec/releases/tag/task_group_vote

Alistair

>
> Alistair
>
> >
> > 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 <florian.lugou@provenrun.com>
> > ---
> >  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 616c3bdc1c..102e8285a6 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -440,6 +440,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 a30317c617..e8997f3153 100644
> > --- a/target/riscv/cpu_bits.h
> > +++ b/target/riscv/cpu_bits.h
> > @@ -258,6 +258,9 @@
> >  /* VS-Level Control transfer records CSRs */
> >  #define CSR_VSCTRCTL        0x24e
> >
> > +/* Supervisor-Level Sdtrig CSRs (debug) */
> > +#define CSR_SCONTEXT        0x5a8
> > +
> >  /* Hpervisor CSRs */
> >  #define CSR_HSTATUS         0x600
> >  #define CSR_HEDELEG         0x602
> > @@ -1103,4 +1106,6 @@ typedef enum CTRType {
> >  #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 0ebcca4597..37b38f24a6 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -3393,6 +3393,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;
> >      }
> > @@ -5321,6 +5325,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)
> >  {
> > @@ -5973,6 +6006,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 9db4048523..072593ab12 100644
> > --- a/target/riscv/debug.c
> > +++ b/target/riscv/debug.c
> > @@ -1088,4 +1088,5 @@ void riscv_trigger_reset_hold(CPURISCVState *env)
> >      }
> >
> >      env->mcontext = 0;
> > +    env->scontext = 0;
> >  }
> > --
> > 2.43.0
> >
> >