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:
parent
562009e47c
commit
a5a92fd6ef
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user