diff options
author | Atish Patra <atish.patra@wdc.com> | 2022-06-20 16:15:52 -0700 |
---|---|---|
committer | Alistair Francis <alistair@alistair23.me> | 2022-07-03 10:03:20 +1000 |
commit | a5a92fd6ef038170231933c60cc2780f52b3a2e1 (patch) | |
tree | 9bc5c4429818ee21e9f8cbe4954f6d5b1a0b04e0 /target/riscv | |
parent | 562009e47c622298f82ee7557be9e15d5e50cee5 (diff) |
target/riscv: Implement PMU CSR predicate function for S-mode
Currently, the predicate function for PMU related CSRs only works if
virtualization is enabled. It also does not check mcounteren bits before
before cycle/minstret/hpmcounterx access.
Support supervisor mode access in the predicate function as well.
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Signed-off-by: Atish Patra <atish.patra@wdc.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Message-Id: <20220620231603.2547260-3-atishp@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target/riscv')
-rw-r--r-- | target/riscv/csr.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 46bd417cc1..58d07c511f 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -79,6 +79,57 @@ static RISCVException ctr(CPURISCVState *env, int csrno) return RISCV_EXCP_ILLEGAL_INST; } + if (env->priv == PRV_S) { + switch (csrno) { + case CSR_CYCLE: + if (!get_field(env->mcounteren, COUNTEREN_CY)) { + return RISCV_EXCP_ILLEGAL_INST; + } + break; + case CSR_TIME: + if (!get_field(env->mcounteren, COUNTEREN_TM)) { + return RISCV_EXCP_ILLEGAL_INST; + } + break; + case CSR_INSTRET: + if (!get_field(env->mcounteren, COUNTEREN_IR)) { + return RISCV_EXCP_ILLEGAL_INST; + } + break; + case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31: + ctr_index = csrno - CSR_CYCLE; + if (!get_field(env->mcounteren, 1 << ctr_index)) { + return RISCV_EXCP_ILLEGAL_INST; + } + break; + } + if (riscv_cpu_mxl(env) == MXL_RV32) { + switch (csrno) { + case CSR_CYCLEH: + if (!get_field(env->mcounteren, COUNTEREN_CY)) { + return RISCV_EXCP_ILLEGAL_INST; + } + break; + case CSR_TIMEH: + if (!get_field(env->mcounteren, COUNTEREN_TM)) { + return RISCV_EXCP_ILLEGAL_INST; + } + break; + case CSR_INSTRETH: + if (!get_field(env->mcounteren, COUNTEREN_IR)) { + return RISCV_EXCP_ILLEGAL_INST; + } + break; + case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H: + ctr_index = csrno - CSR_CYCLEH; + if (!get_field(env->mcounteren, 1 << ctr_index)) { + return RISCV_EXCP_ILLEGAL_INST; + } + break; + } + } + } + if (riscv_cpu_virt_enabled(env)) { switch (csrno) { case CSR_CYCLE: |