From: Atish Patra Date: Mon, 20 Jun 2022 23:15:52 +0000 (-0700) Subject: target/riscv: Implement PMU CSR predicate function for S-mode X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=a5a92fd6ef038170231933c60cc2780f52b3a2e1;p=qemu.git 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 Reviewed-by: Bin Meng Signed-off-by: Atish Patra Signed-off-by: Atish Patra Message-Id: <20220620231603.2547260-3-atishp@rivosinc.com> Signed-off-by: Alistair Francis --- 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: