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>
This commit is contained in:
Atish Patra 2022-06-20 16:15:52 -07:00 committed by Alistair Francis
parent 562009e47c
commit a5a92fd6ef

View File

@ -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: