summaryrefslogtreecommitdiffstats
path: root/target/riscv
diff options
context:
space:
mode:
authorAlistair Francis2019-06-18 03:31:08 +0200
committerPalmer Dabbelt2019-06-25 12:05:40 +0200
commit747a43e818dc36bd50ef98c2b11a7c31ceb810fa (patch)
tree13fea576f05a1532b2fdf82824a5791f36431b1c /target/riscv
parenttarget/riscv: Add the privledge spec version 1.11.0 (diff)
downloadqemu-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>
Diffstat (limited to 'target/riscv')
-rw-r--r--target/riscv/cpu_bits.h1
-rw-r--r--target/riscv/csr.c17
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;