Re: [RFC PATCH 1/2] target/riscv: Add Sspesa extension and sample CSRs
Daniel Henrique Barboza <[email protected]>
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
On 8/17/2026 1:03 PM, Mayuresh Chitale wrote: > Add initial support for the Sspesa (Precise Event Sample Attribution) > extension from the RISC-V Performance Event Sampling specification. > > Added the 'sspesa' and ssplcofi CPU properties, and the shpmspc and > shpmsdata CSRs. > > Signed-off-by: Mayuresh Chitale <[email protected]> > --- Reviewed-by: Daniel Henrique Barboza <[email protected]> > target/riscv/cpu.c | 13 ++++++- > target/riscv/cpu.h | 4 +++ > target/riscv/cpu_bits.h | 7 ++++ > target/riscv/cpu_cfg_fields.h.inc | 2 ++ > target/riscv/tcg/csr.c | 59 +++++++++++++++++++++++++++++-- > 5 files changed, 82 insertions(+), 3 deletions(-) > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > index 5a82e6563b..f936cdeb68 100644 > --- a/target/riscv/cpu.c > +++ b/target/riscv/cpu.c > @@ -278,6 +278,8 @@ const RISCVIsaExtData isa_edata_arr[] = { > ISA_EXT_DATA_ENTRY(ssctr, PRIV_VERSION_1_12_0, ext_ssctr), > ISA_EXT_DATA_ENTRY(ssdbltrp, PRIV_VERSION_1_13_0, ext_ssdbltrp), > ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_13_0, ext_ssnpm), > + ISA_EXT_DATA_ENTRY(sspesa, PRIV_VERSION_1_12_0, ext_sspesa), > + ISA_EXT_DATA_ENTRY(ssplcofi, PRIV_VERSION_1_12_0, ext_ssplcofi), > ISA_EXT_DATA_ENTRY(sspm, PRIV_VERSION_1_13_0, ext_sspm), > ISA_INTERNAL_EXT_DATA_ENTRY(ssstateen, PRIV_VERSION_1_12_0, ext_ssstateen), > ISA_INTERNAL_EXT_DATA_ENTRY(ssstrict, PRIV_VERSION_1_12_0, has_priv_1_12), > @@ -2800,6 +2802,15 @@ static RISCVCPUImpliedExtsRule SSSTATEEN_IMPLIED = { > }, > }; > > +static RISCVCPUImpliedExtsRule SSPESA_IMPLIED = { > + .ext = CPU_CFG_OFFSET(ext_sspesa), > + .implied_multi_exts = { > + CPU_CFG_OFFSET(ext_ssplcofi), > + > + RISCV_IMPLIED_EXTS_RULE_END > + }, > +}; > + > static RISCVCPUImpliedExtsRule ZVFBFA_IMPLIED = { > .ext = CPU_CFG_OFFSET(ext_zvfbfa), > .implied_multi_exts = { > @@ -2829,7 +2840,7 @@ RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[] = { > &ZVKNC_IMPLIED, &ZVKNG_IMPLIED, &ZVKNHB_IMPLIED, > &ZVKS_IMPLIED, &ZVKSC_IMPLIED, &ZVKSG_IMPLIED, &SHA_IMPLIED, > &SSCFG_IMPLIED, &SUPM_IMPLIED, &SSPM_IMPLIED, &SMCTR_IMPLIED, > - &SSCTR_IMPLIED, &SSSTATEEN_IMPLIED, > + &SSCTR_IMPLIED, &SSSTATEEN_IMPLIED, &SSPESA_IMPLIED, > NULL > }; > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index c9dfa7daff..fe56a6afd1 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -470,6 +470,10 @@ struct CPUArchState { > uint64_t sscratch; > uint64_t mscratch; > > + /* Sspesa CSRs */ > + target_ulong shpmspc; > + target_ulong shpmsdata; > + > /* Sstc CSRs */ > uint64_t stimecmp; > > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h > index 3f146a43fe..d3afc9cada 100644 > --- a/target/riscv/cpu_bits.h > +++ b/target/riscv/cpu_bits.h > @@ -601,6 +601,13 @@ > > #define CSR_SCOUNTOVF 0xda0 > > + /* Temporary addresses for Sspesa (Precise Event Sample Attribution) CSRs. */ > +#define CSR_SHPMSPC 0x5d0 > +#define CSR_SHPMSDATA 0x5d1 > + > +/* shpmsdata fields */ > +#define SHPMSDATA_CNTRID 0x1f > + > /* Crypto Extension */ > #define CSR_SEED 0x015 > > diff --git a/target/riscv/cpu_cfg_fields.h.inc b/target/riscv/cpu_cfg_fields.h.inc > index 9eb47af0a7..05e0162b76 100644 > --- a/target/riscv/cpu_cfg_fields.h.inc > +++ b/target/riscv/cpu_cfg_fields.h.inc > @@ -110,6 +110,8 @@ BOOL_FIELD(ext_ssaia) > BOOL_FIELD(ext_smctr) > BOOL_FIELD(ext_ssctr) > BOOL_FIELD(ext_sscofpmf) > +BOOL_FIELD(ext_sspesa) > +BOOL_FIELD(ext_ssplcofi) > BOOL_FIELD(ext_smepmp) > BOOL_FIELD(ext_smrnmi) > BOOL_FIELD(ext_ssnpm) > diff --git a/target/riscv/tcg/csr.c b/target/riscv/tcg/csr.c > index eb823b16b5..ea49d28aae 100644 > --- a/target/riscv/tcg/csr.c > +++ b/target/riscv/tcg/csr.c > @@ -276,6 +276,28 @@ static RISCVException smcntrpmf(CPURISCVState *env, int csrno) > return RISCV_EXCP_NONE; > } > > +static RISCVException sspesa(CPURISCVState *env, int csrno) > +{ > + bool menvcfg_cde; > + > + if (!riscv_cpu_cfg(env)->ext_sspesa) { > + return RISCV_EXCP_ILLEGAL_INST; > + } > + > + if (env->priv == PRV_M) { > + return RISCV_EXCP_NONE; > + } > + > + menvcfg_cde = get_field(env->menvcfg, MENVCFG_CDE); > + /* Access to shpmspc/shpmsdata from VS-mode always causes a fault */ > + if (env->virt_enabled) { > + return menvcfg_cde ? RISCV_EXCP_VIRT_INSTRUCTION_FAULT : > + RISCV_EXCP_ILLEGAL_INST; > + } > + > + return menvcfg_cde ? RISCV_EXCP_NONE : RISCV_EXCP_ILLEGAL_INST; > +} > + > static RISCVException smcntrpmf_32(CPURISCVState *env, int csrno) > { > if (riscv_cpu_mxl(env) != MXL_RV32) { > @@ -1672,6 +1694,34 @@ static RISCVException read_scountovf(CPURISCVState *env, int csrno, > return RISCV_EXCP_NONE; > } > > +static RISCVException read_shpmspc(CPURISCVState *env, int csrno, > + target_ulong *val) > +{ > + *val = env->shpmspc; > + return RISCV_EXCP_NONE; > +} > + > +static RISCVException write_shpmspc(CPURISCVState *env, int csrno, > + target_ulong val, uintptr_t ra) > +{ > + env->shpmspc = val; > + return RISCV_EXCP_NONE; > +} > + > +static RISCVException read_shpmsdata(CPURISCVState *env, int csrno, > + target_ulong *val) > +{ > + *val = env->shpmsdata; > + return RISCV_EXCP_NONE; > +} > + > +static RISCVException write_shpmsdata(CPURISCVState *env, int csrno, > + target_ulong val, uintptr_t ra) > +{ > + env->shpmsdata = val; > + return RISCV_EXCP_NONE; > +} > + > static RISCVException read_time(CPURISCVState *env, int csrno, > target_ulong *val) > { > @@ -3220,7 +3270,7 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, > if (riscv_cpu_mxl(env) == MXL_RV64) { > mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) | > (cfg->ext_sstc ? MENVCFG_STCE : 0) | > - (cfg->ext_smcdeleg ? MENVCFG_CDE : 0) | > + ((cfg->ext_smcdeleg || cfg->ext_sspesa) ? MENVCFG_CDE : 0) | > (cfg->ext_svadu ? MENVCFG_ADUE : 0) | > (cfg->ext_ssdbltrp ? MENVCFG_DTE : 0); > > @@ -3272,7 +3322,7 @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno, > uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) | > (cfg->ext_sstc ? MENVCFG_STCE : 0) | > (cfg->ext_svadu ? MENVCFG_ADUE : 0) | > - (cfg->ext_smcdeleg ? MENVCFG_CDE : 0) | > + ((cfg->ext_smcdeleg || cfg->ext_sspesa) ? MENVCFG_CDE : 0) | > (cfg->ext_ssdbltrp ? MENVCFG_DTE : 0); > uint64_t valh = (uint64_t)val << 32; > bool stce_changed = false; > @@ -6771,6 +6821,11 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { > write_mhpmcounterh }, > [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf, > .min_priv_ver = PRIV_VERSION_1_12_0 }, > + [CSR_SHPMSPC] = { "shpmspc", sspesa, read_shpmspc, write_shpmspc, > + .min_priv_ver = PRIV_VERSION_1_12_0 }, > + [CSR_SHPMSDATA] = { "shpmsdata", sspesa, read_shpmsdata, > + write_shpmsdata, > + .min_priv_ver = PRIV_VERSION_1_12_0 }, > > #endif /* !CONFIG_USER_ONLY */ > };