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