diff options
author | Alistair Francis | 2019-06-18 03:31:08 +0200 |
---|---|---|
committer | Palmer Dabbelt | 2019-06-25 12:05:40 +0200 |
commit | 747a43e818dc36bd50ef98c2b11a7c31ceb810fa (patch) | |
tree | 13fea576f05a1532b2fdf82824a5791f36431b1c | |
parent | target/riscv: Add the privledge spec version 1.11.0 (diff) | |
download | qemu-747a43e818dc36bd50ef98c2b11a7c31ceb810fa.tar.gz qemu-747a43e818dc36bd50ef98c2b11a7c31ceb810fa.tar.xz qemu-747a43e818dc36bd50ef98c2b11a7c31ceb810fa.zip |
target/riscv: Add the mcountinhibit CSR
1.11 defines mcountinhibit, which has the same numeric CSR value as
mucounteren from 1.09.1 but has different semantics. This patch enables
the CSR for 1.11-based targets, which is trivial to implement because
the counters in QEMU never tick (legal according to the spec).
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
[Palmer: Fix counter access semantics, change commit message to indicate
the behavior is fully emulated.]
Reviewed-by: Palmer Dabbelt <palmer@sifive.com>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
-rw-r--r-- | target/riscv/cpu_bits.h | 1 | ||||
-rw-r--r-- | target/riscv/csr.c | 17 |
2 files changed, 16 insertions, 2 deletions
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 47450a3cdb..11f971ad5d 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -136,6 +136,7 @@ #define CSR_MCOUNTEREN 0x306 /* Legacy Counter Setup (priv v1.9.1) */ +/* Update to #define CSR_MCOUNTINHIBIT 0x320 for 1.11.0 */ #define CSR_MUCOUNTEREN 0x320 #define CSR_MSCOUNTEREN 0x321 #define CSR_MHCOUNTEREN 0x322 diff --git a/target/riscv/csr.c b/target/riscv/csr.c index c67d29e206..448162e484 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -56,6 +56,15 @@ static int fs(CPURISCVState *env, int csrno) static int ctr(CPURISCVState *env, int csrno) { #if !defined(CONFIG_USER_ONLY) + /* + * The counters are always enabled on newer priv specs, as the CSR has + * changed from controlling that the counters can be read to controlling + * that the counters increment. + */ + if (env->priv_ver > PRIV_VERSION_1_09_1) { + return 0; + } + uint32_t ctr_en = ~0u; if (env->priv < PRV_M) { @@ -461,18 +470,22 @@ static int write_mcounteren(CPURISCVState *env, int csrno, target_ulong val) return 0; } +/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */ static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val) { - if (env->priv_ver > PRIV_VERSION_1_09_1) { + if (env->priv_ver > PRIV_VERSION_1_09_1 + && env->priv_ver < PRIV_VERSION_1_11_0) { return -1; } *val = env->mcounteren; return 0; } +/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */ static int write_mscounteren(CPURISCVState *env, int csrno, target_ulong val) { - if (env->priv_ver > PRIV_VERSION_1_09_1) { + if (env->priv_ver > PRIV_VERSION_1_09_1 + && env->priv_ver < PRIV_VERSION_1_11_0) { return -1; } env->mcounteren = val; |