[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v4 3/7] target/riscv: Add support for Control Transfer Records ex
From: |
Rajnesh Kanwal |
Subject: |
[PATCH v4 3/7] target/riscv: Add support for Control Transfer Records extension CSRs. |
Date: |
Wed, 4 Dec 2024 17:56:41 +0500 |
This commit adds support for [m|s|vs]ctrcontrol, sctrstatus and
sctrdepth CSRs handling.
Signed-off-by: Rajnesh Kanwal <rkanwal@rivosinc.com>
---
target/riscv/cpu.h | 5 ++
target/riscv/cpu_cfg.h | 2 +
target/riscv/csr.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 151 insertions(+)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index
903268626374474306f0e0259f37128326b354d4..da14ac2f874b81d3f01bc31b0064d020f2dbdf61
100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -305,6 +305,11 @@ struct CPUArchState {
target_ulong mcause;
target_ulong mtval; /* since: priv-1.10.0 */
+ uint64_t mctrctl;
+ uint32_t sctrdepth;
+ uint32_t sctrstatus;
+ uint64_t vsctrctl;
+
/* Machine and Supervisor interrupt priorities */
uint8_t miprio[64];
uint8_t siprio[64];
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index
ae2b019703fe4849eb7f264b4d90743d4c013b86..e365a368d71a695b1b99c3b6ae330347143d3422
100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -130,6 +130,8 @@ struct RISCVCPUConfig {
bool ext_zvfhmin;
bool ext_smaia;
bool ext_ssaia;
+ bool ext_smctr;
+ bool ext_ssctr;
bool ext_sscofpmf;
bool ext_smepmp;
bool rvv_ta_all_1s;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index
31ea8b8ec20db5a5af23e829757cccaafc02e2da..7e03065d3dcd8713e2cadae3017ed355c9f9bf10
100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -651,6 +651,48 @@ static RISCVException pointer_masking(CPURISCVState *env,
int csrno)
return RISCV_EXCP_ILLEGAL_INST;
}
+/*
+ * M-mode:
+ * Without ext_smctr raise illegal inst excep.
+ * Otherwise everything is accessible to m-mode.
+ *
+ * S-mode:
+ * Without ext_ssctr or mstateen.ctr raise illegal inst excep.
+ * Otherwise everything other than mctrctl is accessible.
+ *
+ * VS-mode:
+ * Without ext_ssctr or mstateen.ctr raise illegal inst excep.
+ * Without hstateen.ctr raise virtual illegal inst excep.
+ * Otherwise allow sctrctl (vsctrctl), sctrstatus, 0x200-0x2ff entry range.
+ * Always raise illegal instruction exception for sctrdepth.
+ */
+static RISCVException ctr_mmode(CPURISCVState *env, int csrno)
+{
+ /* Check if smctr-ext is present */
+ if (riscv_cpu_cfg(env)->ext_smctr) {
+ return RISCV_EXCP_NONE;
+ }
+
+ return RISCV_EXCP_ILLEGAL_INST;
+}
+
+static RISCVException ctr_smode(CPURISCVState *env, int csrno)
+{
+ const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
+
+ if (!cfg->ext_smctr && !cfg->ext_ssctr) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_CTR);
+ if (ret == RISCV_EXCP_NONE && csrno == CSR_SCTRDEPTH &&
+ env->virt_enabled) {
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ }
+
+ return ret;
+}
+
static RISCVException aia_hmode(CPURISCVState *env, int csrno)
{
int ret;
@@ -3160,6 +3202,10 @@ static RISCVException write_mstateen0(CPURISCVState
*env, int csrno,
wr_mask |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC);
}
+ if (riscv_cpu_cfg(env)->ext_ssctr) {
+ wr_mask |= SMSTATEEN0_CTR;
+ }
+
return write_mstateen(env, csrno, wr_mask, new_val);
}
@@ -3199,6 +3245,10 @@ static RISCVException write_mstateen0h(CPURISCVState
*env, int csrno,
wr_mask |= SMSTATEEN0_P1P13;
}
+ if (riscv_cpu_cfg(env)->ext_ssctr) {
+ wr_mask |= SMSTATEEN0_CTR;
+ }
+
return write_mstateenh(env, csrno, wr_mask, new_val);
}
@@ -3253,6 +3303,10 @@ static RISCVException write_hstateen0(CPURISCVState
*env, int csrno,
wr_mask |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC);
}
+ if (riscv_cpu_cfg(env)->ext_ssctr) {
+ wr_mask |= SMSTATEEN0_CTR;
+ }
+
return write_hstateen(env, csrno, wr_mask, new_val);
}
@@ -3292,6 +3346,10 @@ static RISCVException write_hstateen0h(CPURISCVState
*env, int csrno,
{
uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+ if (riscv_cpu_cfg(env)->ext_ssctr) {
+ wr_mask |= SMSTATEEN0_CTR;
+ }
+
return write_hstateenh(env, csrno, wr_mask, new_val);
}
@@ -4005,6 +4063,86 @@ static RISCVException write_satp(CPURISCVState *env, int
csrno,
return RISCV_EXCP_NONE;
}
+static RISCVException rmw_sctrdepth(CPURISCVState *env, int csrno,
+ target_ulong *ret_val,
+ target_ulong new_val, target_ulong wr_mask)
+{
+ uint64_t mask = wr_mask & SCTRDEPTH_MASK;
+
+ if (ret_val) {
+ *ret_val = env->sctrdepth;
+ }
+
+ env->sctrdepth = (env->sctrdepth & ~mask) | (new_val & mask);
+
+ /* Correct depth. */
+ if (mask) {
+ uint64_t depth = get_field(env->sctrdepth, SCTRDEPTH_MASK);
+
+ if (depth > SCTRDEPTH_MAX) {
+ depth = SCTRDEPTH_MAX;
+ env->sctrdepth = set_field(env->sctrdepth, SCTRDEPTH_MASK, depth);
+ }
+
+ /* Update sctrstatus.WRPTR with a legal value */
+ depth = 16 << depth;
+ env->sctrstatus =
+ env->sctrstatus & (~SCTRSTATUS_WRPTR_MASK | (depth - 1));
+ }
+
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException rmw_sctrstatus(CPURISCVState *env, int csrno,
+ target_ulong *ret_val,
+ target_ulong new_val, target_ulong
wr_mask)
+{
+ uint32_t depth = 16 << get_field(env->sctrdepth, SCTRDEPTH_MASK);
+ uint32_t mask = wr_mask & SCTRSTATUS_MASK;
+
+ if (ret_val) {
+ *ret_val = env->sctrstatus;
+ }
+
+ env->sctrstatus = (env->sctrstatus & ~mask) | (new_val & mask);
+
+ /* Update sctrstatus.WRPTR with a legal value */
+ env->sctrstatus = env->sctrstatus & (~SCTRSTATUS_WRPTR_MASK | (depth - 1));
+
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException rmw_xctrctl(CPURISCVState *env, int csrno,
+ target_ulong *ret_val,
+ target_ulong new_val, target_ulong wr_mask)
+{
+ uint64_t csr_mask, mask = wr_mask;
+ uint64_t *ctl_ptr = &env->mctrctl;
+
+ if (csrno == CSR_MCTRCTL) {
+ csr_mask = MCTRCTL_MASK;
+ } else if (csrno == CSR_SCTRCTL && !env->virt_enabled) {
+ csr_mask = SCTRCTL_MASK;
+ } else {
+ /*
+ * This is for csrno == CSR_SCTRCTL and env->virt_enabled == true
+ * or csrno == CSR_VSCTRCTL.
+ */
+ csr_mask = VSCTRCTL_MASK;
+ ctl_ptr = &env->vsctrctl;
+ }
+
+ mask &= csr_mask;
+
+ if (ret_val) {
+ *ret_val = *ctl_ptr & csr_mask;
+ }
+
+ *ctl_ptr = (*ctl_ptr & ~mask) | (new_val & mask);
+
+ return RISCV_EXCP_NONE;
+}
+
static RISCVException read_vstopi(CPURISCVState *env, int csrno,
target_ulong *val)
{
@@ -5984,6 +6122,12 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
[CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase,
write_spmbase },
+ [CSR_MCTRCTL] = { "mctrctl", ctr_mmode, NULL, NULL, rmw_xctrctl
},
+ [CSR_SCTRCTL] = { "sctrctl", ctr_smode, NULL, NULL, rmw_xctrctl
},
+ [CSR_VSCTRCTL] = { "vsctrctl", ctr_smode, NULL, NULL, rmw_xctrctl
},
+ [CSR_SCTRDEPTH] = { "sctrdepth", ctr_smode, NULL, NULL, rmw_sctrdepth
},
+ [CSR_SCTRSTATUS] = { "sctrstatus", ctr_smode, NULL, NULL, rmw_sctrstatus
},
+
/* Performance Counters */
[CSR_HPMCOUNTER3] = { "hpmcounter3", ctr, read_hpmcounter },
[CSR_HPMCOUNTER4] = { "hpmcounter4", ctr, read_hpmcounter },
--
2.34.1
- [PATCH v4 0/7] target/riscv: Add support for Control Transfer Records Ext., Rajnesh Kanwal, 2024/12/04
- [PATCH v4 1/7] target/riscv: Remove obsolete sfence.vm instruction, Rajnesh Kanwal, 2024/12/04
- [PATCH v4 2/7] target/riscv: Add Control Transfer Records CSR definitions., Rajnesh Kanwal, 2024/12/04
- [PATCH v4 3/7] target/riscv: Add support for Control Transfer Records extension CSRs.,
Rajnesh Kanwal <=
- [PATCH v4 5/7] target/riscv: Add CTR sctrclr instruction., Rajnesh Kanwal, 2024/12/04
- [PATCH v4 6/7] target/riscv: Add support to access ctrsource, ctrtarget, ctrdata regs., Rajnesh Kanwal, 2024/12/04
- [PATCH v4 7/7] target/riscv: machine: Add Control Transfer Record state description, Rajnesh Kanwal, 2024/12/04
- [PATCH v4 4/7] target/riscv: Add support to record CTR entries., Rajnesh Kanwal, 2024/12/04