Reviewed-by: Jay Chang <jay,[email protected]>

Thanks

On Thu, Mar 19, 2026 at 3:45 AM luisccc <[email protected]> wrote:

> Signed-off-by: Luis Cunha <[email protected]>
> ---
>  target/riscv/cpu_bits.h           |  4 ++
>  target/riscv/cpu_cfg_fields.h.inc |  1 +
>  target/riscv/csr.c                | 67 +++++++++++++++++++++++++++++++
>  target/riscv/spmp.c               |  6 ++-
>  4 files changed, 77 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index 36f7c1e873..0a8cfedc5d 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -255,6 +255,10 @@
>  #define CSR_SCTRSTATUS      0x14f
>  #define CSR_SCTRDEPTH       0x15f
>
> +/* S-mode Physical Memory Protection (SPMP) */
> +#define CSR_SPMPEN          0x183
> +#define CSR_SPMPENH         0x193
> +
>  /* VS-Level Control transfer records CSRs */
>  #define CSR_VSCTRCTL        0x24e
>
> diff --git a/target/riscv/cpu_cfg_fields.h.inc
> b/target/riscv/cpu_cfg_fields.h.inc
> index 772cc176d0..88edac21ca 100644
> --- a/target/riscv/cpu_cfg_fields.h.inc
> +++ b/target/riscv/cpu_cfg_fields.h.inc
> @@ -120,6 +120,7 @@ BOOL_FIELD(rvv_ma_all_1s)
>  BOOL_FIELD(rvv_vl_half_avl)
>  BOOL_FIELD(rvv_vsetvl_x0_vill)
>  BOOL_FIELD(ext_smpmpdeleg)
> +BOOL_FIELD(ext_sspmpen)
>  /* Named features  */
>  BOOL_FIELD(ext_svade)
>  BOOL_FIELD(ext_zic64b)
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 4b9fa11540..a11d7e6704 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -769,6 +769,16 @@ static RISCVException spmp(CPURISCVState *env, int
> csrno)
>      return smode(env, csrno);
>  }
>
> +static RISCVException sspmpen(CPURISCVState *env, int csrno)
> +{
> +    if (!riscv_cpu_cfg(env)->ext_sspmpen) {
> +        return RISCV_EXCP_ILLEGAL_INST;
> +    }
> +
> +    /* SSPMPEN can only exist, if spmp exists */
> +    return spmp(env, csrno);
> +}
> +
>  static RISCVException have_mseccfg(CPURISCVState *env, int csrno)
>  {
>      if (riscv_cpu_cfg(env)->ext_smepmp) {
> @@ -5389,6 +5399,61 @@ static RISCVException rmw_mpmpdeleg(CPURISCVState
> *env, int csrno,
>      return RISCV_EXCP_NONE;
>  }
>
> +static RISCVException rmw_spmpen64(CPURISCVState *env, int csrno,
> +                                    uint64_t *ret_val,
> +                                    uint64_t new_val, uint64_t wr_mask)
> +{
> +    uint64_t new_spmpen = (env->spmp_state.spmpen & ~wr_mask) |
> +                            (new_val & wr_mask);
> +
> +    if (env->spmp_state.num_deleg_rules == 0) {
> +        if (ret_val) {
> +            *ret_val = 0;
> +        }
> +
> +        return RISCV_EXCP_NONE;
> +    }
> +
> +    if (ret_val) {
> +        *ret_val = env->spmp_state.spmpen;
> +    }
> +
> +    sspmpen_csr_write(env, new_spmpen);
> +
> +    return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException rmw_spmpen(CPURISCVState *env, int csrno,
> +                                  target_ulong *ret_val,
> +                                  target_ulong new_val, target_ulong
> wr_mask)
> +{
> +    uint64_t rval = 0;
> +    RISCVException ret;
> +    ret = rmw_spmpen64(env, csrno, &rval, new_val, wr_mask);
> +    if (ret_val) {
> +        *ret_val = rval;
> +    }
> +
> +    return ret;
> +}
> +
> +static RISCVException rmw_spmpenh(CPURISCVState *env, int csrno,
> +                                   target_ulong *ret_val,
> +                                   target_ulong new_val,
> +                                   target_ulong wr_mask)
> +{
> +    uint64_t rval = 0;
> +    RISCVException ret;
> +
> +    ret = rmw_spmpen64(env, csrno, &rval,
> +        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
> +    if (ret_val) {
> +        *ret_val = rval >> 32;
> +    }
> +
> +    return ret;
> +}
> +
>  static RISCVException read_tselect(CPURISCVState *env, int csrno,
>                                     target_ulong *val)
>  {
> @@ -6388,6 +6453,8 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>
>      /* S-mode Physical Memory Protection */
>      [CSR_MPMPDELEG]   = { "mpmpdeleg", spmp, NULL, NULL, rmw_mpmpdeleg },
> +    [CSR_SPMPEN]  = { "spmpen", sspmpen, NULL, NULL, rmw_spmpen },
> +    [CSR_SPMPENH] = { "spmpenh", sspmpen, NULL, NULL, rmw_spmpenh },
>
>      /* Debug CSRs */
>      [CSR_TSELECT]   =  { "tselect",  debug, read_tselect,  write_tselect
> },
> diff --git a/target/riscv/spmp.c b/target/riscv/spmp.c
> index 85c5259b33..1615c207df 100644
> --- a/target/riscv/spmp.c
> +++ b/target/riscv/spmp.c
> @@ -147,7 +147,11 @@ static uint8_t spmp_is_in_range(CPURISCVState *env,
> int spmp_index,
>
>  static bool spmp_get_spmpen_bit(CPURISCVState *env, int index)
>  {
> -    return true;
> +    if (!riscv_cpu_cfg(env)->ext_sspmpen) {
> +        return true;
> +    }
> +
> +    return (env->spmp_state.spmpen >> index) & 0x1;
>  }
>
>  /*
> --
> 2.43.0
>
>
>

Reply via email to