target/riscv: fix csr check for cycle{h}, instret{h}, time{h}, hpmcounter3-31{h}

- modify check for mcounteren to work in all less-privilege mode
- modify check for scounteren to work only when S mode is enabled
- distinguish the exception type raised by check for scounteren between U
and VU mode

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20220817083756.12471-1-liweiwei@iscas.ac.cn>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Weiwei Li 2022-08-17 16:37:56 +08:00 committed by Alistair Francis
parent 513eb437ae
commit a412829406
1 changed files with 9 additions and 4 deletions

View File

@ -98,17 +98,22 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
skip_ext_pmu_check:
if (((env->priv == PRV_S) && (!get_field(env->mcounteren, ctr_mask))) ||
((env->priv == PRV_U) && (!get_field(env->scounteren, ctr_mask)))) {
if (env->priv < PRV_M && !get_field(env->mcounteren, ctr_mask)) {
return RISCV_EXCP_ILLEGAL_INST;
}
if (riscv_cpu_virt_enabled(env)) {
if (!get_field(env->hcounteren, ctr_mask) &&
get_field(env->mcounteren, ctr_mask)) {
if (!get_field(env->hcounteren, ctr_mask) ||
(env->priv == PRV_U && !get_field(env->scounteren, ctr_mask))) {
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
}
if (riscv_has_ext(env, RVS) && env->priv == PRV_U &&
!get_field(env->scounteren, ctr_mask)) {
return RISCV_EXCP_ILLEGAL_INST;
}
#endif
return RISCV_EXCP_NONE;
}