[RFC PATCH 1/2] target/riscv: Add Sspesa extension and sample CSRs
Mayuresh Chitale <[email protected]>
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
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]> --- 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 */ }; -- 2.43.0