diff options
| author | Rajnesh Kanwal <rkanwal@rivosinc.com> | 2025-02-05 11:18:49 +0000 |
|---|---|---|
| committer | Alistair Francis <alistair.francis@wdc.com> | 2025-03-04 15:42:54 +1000 |
| commit | 9e69e760fdc34a9d13a8c434d6a9fada835a05ad (patch) | |
| tree | 0bccb6e7b933441c596749c12a319661c748a4b1 /target/riscv/op_helper.c | |
| parent | 4ff7a27adce4c880d2137788da0fc57d75ee80be (diff) | |
| download | focaccia-qemu-9e69e760fdc34a9d13a8c434d6a9fada835a05ad.tar.gz focaccia-qemu-9e69e760fdc34a9d13a8c434d6a9fada835a05ad.zip | |
target/riscv: Add CTR sctrclr instruction.
CTR extension adds a new instruction sctrclr to quickly clear the recorded entries buffer. Signed-off-by: Rajnesh Kanwal <rkanwal@rivosinc.com> Acked-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20250205-b4-ctr_upstream_v6-v6-5-439d8e06c8ef@rivosinc.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target/riscv/op_helper.c')
| -rw-r--r-- | target/riscv/op_helper.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index 5a99c47b12..f156bfab12 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -485,6 +485,35 @@ void helper_ctr_add_entry(CPURISCVState *env, target_ulong src, env->priv, env->virt_enabled); } +void helper_ctr_clear(CPURISCVState *env) +{ + /* + * It's safe to call smstateen_acc_ok() for umode access regardless of the + * state of bit 54 (CTR bit in case of m/hstateen) of sstateen. If the bit + * is zero, smstateen_acc_ok() will return the correct exception code and + * if it's one, smstateen_acc_ok() will return RISCV_EXCP_NONE. In that + * scenario the U-mode check below will handle that case. + */ + RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_CTR); + if (ret != RISCV_EXCP_NONE) { + riscv_raise_exception(env, ret, GETPC()); + } + + if (env->priv == PRV_U) { + /* + * One corner case is when sctrclr is executed from VU-mode and + * mstateen.CTR = 0, in which case we are supposed to raise + * RISCV_EXCP_ILLEGAL_INST. This case is already handled in + * smstateen_acc_ok(). + */ + uint32_t excep = env->virt_enabled ? RISCV_EXCP_VIRT_INSTRUCTION_FAULT : + RISCV_EXCP_ILLEGAL_INST; + riscv_raise_exception(env, excep, GETPC()); + } + + riscv_ctr_clear(env); +} + void helper_wfi(CPURISCVState *env) { CPUState *cs = env_cpu(env); |