All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] target/riscv: Support scontext-based trigger matching
@ 2025-02-26 14:39 Florian Lugou
  2025-02-26 14:39 ` [PATCH 1/2] target/riscv: Add scontext CSR handling Florian Lugou
  2025-02-26 14:39 ` [PATCH 2/2] target/riscv: Support matching scontext in Sdtrig's textra CSRs Florian Lugou
  0 siblings, 2 replies; 4+ messages in thread
From: Florian Lugou @ 2025-02-26 14:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: Florian Lugou, Palmer Dabbelt, Alistair Francis, Bin Meng,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, qemu-riscv

Hi,

These 2 patches allow scontext-based trigger matching as specified by the Sdtrig
extension. Patch 1 allows access to the scontext CSR and patch 2 enforces
scontext matching as specified by the textra CSRs.

Florian Lugou (2):
  target/riscv: Add scontext CSR handling
  target/riscv: Support matching scontext in Sdtrig's textra CSRs

 target/riscv/cpu.h      |  1 +
 target/riscv/cpu_bits.h |  5 +++
 target/riscv/csr.c      | 36 +++++++++++++++++++
 target/riscv/debug.c    | 76 +++++++++++++++++++++++++++++------------
 target/riscv/debug.h    |  3 ++
 5 files changed, 100 insertions(+), 21 deletions(-)

-- 
2.43.0



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

* [PATCH 1/2] target/riscv: Add scontext CSR handling
  2025-02-26 14:39 [PATCH 0/2] target/riscv: Support scontext-based trigger matching Florian Lugou
@ 2025-02-26 14:39 ` Florian Lugou
  2025-02-28 11:15   ` Daniel Henrique Barboza
  2025-02-26 14:39 ` [PATCH 2/2] target/riscv: Support matching scontext in Sdtrig's textra CSRs Florian Lugou
  1 sibling, 1 reply; 4+ messages in thread
From: Florian Lugou @ 2025-02-26 14:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: Florian Lugou, Palmer Dabbelt, Alistair Francis, Bin Meng,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, qemu-riscv

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 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;
 }
-- 
2.43.0



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

* [PATCH 2/2] target/riscv: Support matching scontext in Sdtrig's textra CSRs
  2025-02-26 14:39 [PATCH 0/2] target/riscv: Support scontext-based trigger matching Florian Lugou
  2025-02-26 14:39 ` [PATCH 1/2] target/riscv: Add scontext CSR handling Florian Lugou
@ 2025-02-26 14:39 ` Florian Lugou
  1 sibling, 0 replies; 4+ messages in thread
From: Florian Lugou @ 2025-02-26 14:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: Florian Lugou, Palmer Dabbelt, Alistair Francis, Bin Meng,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, qemu-riscv

Support setting textra32.sselect or textra64.sselect to 1 (scontext).
The trigger will only match if the content of scontext matches the value
in svalue, after it is masked as configured in sbytemask.

Signed-off-by: Florian Lugou <florian.lugou@provenrun.com>
---
 target/riscv/debug.c | 75 +++++++++++++++++++++++++++++++-------------
 target/riscv/debug.h |  3 ++
 2 files changed, 57 insertions(+), 21 deletions(-)

diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 914a9ce0f8..ac9752d30e 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -219,8 +219,8 @@ static inline void warn_always_zero_bit(target_ulong val, target_ulong mask,
 
 static target_ulong textra_validate(CPURISCVState *env, target_ulong tdata3)
 {
-    target_ulong mhvalue, mhselect;
-    target_ulong mhselect_new;
+    target_ulong mhvalue, mhselect, sbytemask, svalue, sselect;
+    target_ulong mhselect_new, sselect_new;
     target_ulong textra;
     const uint32_t mhselect_no_rvh[8] = { 0, 0, 0, 0, 4, 4, 4, 4 };
 
@@ -228,25 +228,17 @@ static target_ulong textra_validate(CPURISCVState *env, target_ulong tdata3)
     case MXL_RV32:
         mhvalue  = get_field(tdata3, TEXTRA32_MHVALUE);
         mhselect = get_field(tdata3, TEXTRA32_MHSELECT);
-        /* Validate unimplemented (always zero) bits */
-        warn_always_zero_bit(tdata3, (target_ulong)TEXTRA32_SBYTEMASK,
-                             "sbytemask");
-        warn_always_zero_bit(tdata3, (target_ulong)TEXTRA32_SVALUE,
-                             "svalue");
-        warn_always_zero_bit(tdata3, (target_ulong)TEXTRA32_SSELECT,
-                             "sselect");
+        sbytemask  = get_field(tdata3, TEXTRA32_SBYTEMASK);
+        svalue  = get_field(tdata3, TEXTRA32_SVALUE);
+        sselect = get_field(tdata3, TEXTRA32_SSELECT);
         break;
     case MXL_RV64:
     case MXL_RV128:
         mhvalue  = get_field(tdata3, TEXTRA64_MHVALUE);
         mhselect = get_field(tdata3, TEXTRA64_MHSELECT);
-        /* Validate unimplemented (always zero) bits */
-        warn_always_zero_bit(tdata3, (target_ulong)TEXTRA64_SBYTEMASK,
-                             "sbytemask");
-        warn_always_zero_bit(tdata3, (target_ulong)TEXTRA64_SVALUE,
-                             "svalue");
-        warn_always_zero_bit(tdata3, (target_ulong)TEXTRA64_SSELECT,
-                             "sselect");
+        sbytemask  = get_field(tdata3, TEXTRA64_SBYTEMASK);
+        svalue  = get_field(tdata3, TEXTRA64_SVALUE);
+        sselect = get_field(tdata3, TEXTRA64_SSELECT);
         break;
     default:
         g_assert_not_reached();
@@ -258,17 +250,34 @@ static target_ulong textra_validate(CPURISCVState *env, target_ulong tdata3)
         qemu_log_mask(LOG_UNIMP, "mhselect only supports 0 or 4 for now\n");
     }
 
+    /* Validate sselect. */
+    switch (sselect) {
+    case SSELECT_IGNORE:
+    case SSELECT_SCONTEXT:
+        sselect_new = sselect;
+        break;
+    default:
+        sselect_new = 0;
+        qemu_log_mask(LOG_UNIMP, "sselect only supports 0 or 1 for now\n");
+    }
+
     /* Write legal values into textra */
     textra = 0;
     switch (riscv_cpu_mxl(env)) {
     case MXL_RV32:
-        textra = set_field(textra, TEXTRA32_MHVALUE,  mhvalue);
-        textra = set_field(textra, TEXTRA32_MHSELECT, mhselect_new);
+        textra = set_field(textra, TEXTRA32_MHVALUE,   mhvalue);
+        textra = set_field(textra, TEXTRA32_MHSELECT,  mhselect_new);
+        textra = set_field(textra, TEXTRA32_SBYTEMASK, sbytemask);
+        textra = set_field(textra, TEXTRA32_SVALUE,    svalue);
+        textra = set_field(textra, TEXTRA32_SSELECT,   sselect_new);
         break;
     case MXL_RV64:
     case MXL_RV128:
-        textra = set_field(textra, TEXTRA64_MHVALUE,  mhvalue);
-        textra = set_field(textra, TEXTRA64_MHSELECT, mhselect_new);
+        textra = set_field(textra, TEXTRA64_MHVALUE,   mhvalue);
+        textra = set_field(textra, TEXTRA64_MHSELECT,  mhselect_new);
+        textra = set_field(textra, TEXTRA64_SBYTEMASK, sbytemask);
+        textra = set_field(textra, TEXTRA64_SVALUE,    svalue);
+        textra = set_field(textra, TEXTRA64_SSELECT,   sselect_new);
         break;
     default:
         g_assert_not_reached();
@@ -368,7 +377,7 @@ static bool trigger_textra_match(CPURISCVState *env, trigger_type_t type,
                                  int trigger_index)
 {
     target_ulong textra = env->tdata3[trigger_index];
-    target_ulong mhvalue, mhselect;
+    target_ulong mhvalue, mhselect, sbytemask, svalue, sselect;
 
     if (type < TRIGGER_TYPE_AD_MATCH || type > TRIGGER_TYPE_AD_MATCH6) {
         /* textra checking is only applicable when type is 2, 3, 4, 5, or 6 */
@@ -379,11 +388,17 @@ static bool trigger_textra_match(CPURISCVState *env, trigger_type_t type,
     case MXL_RV32:
         mhvalue  = get_field(textra, TEXTRA32_MHVALUE);
         mhselect = get_field(textra, TEXTRA32_MHSELECT);
+        sbytemask = get_field(textra, TEXTRA32_SBYTEMASK);
+        svalue = get_field(textra, TEXTRA32_SVALUE);
+        sselect = get_field(textra, TEXTRA32_SSELECT);
         break;
     case MXL_RV64:
     case MXL_RV128:
         mhvalue  = get_field(textra, TEXTRA64_MHVALUE);
         mhselect = get_field(textra, TEXTRA64_MHSELECT);
+        sbytemask  = get_field(textra, TEXTRA64_SBYTEMASK);
+        svalue  = get_field(textra, TEXTRA64_SVALUE);
+        sselect = get_field(textra, TEXTRA64_SSELECT);
         break;
     default:
         g_assert_not_reached();
@@ -403,6 +418,24 @@ static bool trigger_textra_match(CPURISCVState *env, trigger_type_t type,
         break;
     }
 
+    target_ulong svalue_mask = ((sbytemask & 1) * 0xFF) |
+        ((sbytemask & 2) * 0x7F80) | ((sbytemask & 4) * 0x3FC000) |
+        ((sbytemask & 8) * 0x1FE00000);
+
+    /* Check svalue and sselect. */
+    switch (sselect) {
+    case SSELECT_IGNORE:
+        break;
+    case SSELECT_SCONTEXT:
+        /* Match if the low bits of scontext equal svalue. */
+        if ((svalue & svalue_mask) != (env->scontext & svalue_mask)) {
+            return false;
+        }
+        break;
+    default:
+        break;
+    }
+
     return true;
 }
 
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
index f76b8f944a..16b66441ca 100644
--- a/target/riscv/debug.h
+++ b/target/riscv/debug.h
@@ -134,6 +134,9 @@ enum {
 #define MHSELECT_IGNORE       0
 #define MHSELECT_MCONTEXT     4
 
+#define SSELECT_IGNORE        0
+#define SSELECT_SCONTEXT      1
+
 bool tdata_available(CPURISCVState *env, int tdata_index);
 
 target_ulong tselect_csr_read(CPURISCVState *env);
-- 
2.43.0



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

* Re: [PATCH 1/2] target/riscv: Add scontext CSR handling
  2025-02-26 14:39 ` [PATCH 1/2] target/riscv: Add scontext CSR handling Florian Lugou
@ 2025-02-28 11:15   ` Daniel Henrique Barboza
  0 siblings, 0 replies; 4+ messages in thread
From: Daniel Henrique Barboza @ 2025-02-28 11:15 UTC (permalink / raw)
  To: Florian Lugou, qemu-devel
  Cc: Palmer Dabbelt, Alistair Francis, Bin Meng, Weiwei Li, Liu Zhiwei,
	qemu-riscv



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 <florian.lugou@provenrun.com>
> ---

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;
>   }



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

end of thread, other threads:[~2025-02-28 11:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-26 14:39 [PATCH 0/2] target/riscv: Support scontext-based trigger matching Florian Lugou
2025-02-26 14:39 ` [PATCH 1/2] target/riscv: Add scontext CSR handling Florian Lugou
2025-02-28 11:15   ` Daniel Henrique Barboza
2025-02-26 14:39 ` [PATCH 2/2] target/riscv: Support matching scontext in Sdtrig's textra CSRs Florian Lugou

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.