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