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
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
>
>
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
> >
> >
© 2016 - 2026 Red Hat, Inc.