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;
|
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)) {
|
if (riscv_cpu_virt_enabled(env)) {
|
||||||
switch (csrno) {
|
switch (csrno) {
|
||||||
case CSR_CYCLE:
|
case CSR_CYCLE:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user