Skip to content

Commit

Permalink
RISC-V: Use [ms]counteren CSRs when priv ISA >= v1.10
Browse files Browse the repository at this point in the history
Privileged ISA v1.9.1 defines mscounteren and mucounteren:

* mscounteren contains a mask of counters available to S-mode
* mucounteren contains a mask of counters available to U-mode

Privileged ISA v1.10 defines mcounteren and scounteren:

* mcounteren contains a mask of counters available to S-mode
* scounteren contains a mask of counters available to U-mode

mcounteren and scounteren CSR registers were implemented
however they were not honoured for counter accesses when
the privilege ISA was >= v1.10. This fix solves the issue
by coalescing the counter enable registers. In addition
the code now  generates illegal instruction exceptions
for accesses to the counter enabled registers depending
on the privileged ISA version.

- Coalesce mscounteren and mcounteren into one variable
- Coalesce mucounteren and scounteren into one variable
- Makes mcounteren and scounteren CSR accesses generate
  illegal instructions when the privileged ISA <= v1.9.1
- Makes mscounteren and mucounteren CSR accesses generate
  illegal instructions when the privileged ISA >= v1.10

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
  • Loading branch information
Michael Clark committed May 5, 2018
1 parent e216590 commit 8c59f5c
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 18 deletions.
6 changes: 2 additions & 4 deletions target/riscv/cpu.h
Expand Up @@ -151,10 +151,8 @@ struct CPURISCVState {
target_ulong mcause;
target_ulong mtval; /* since: priv-1.10.0 */

uint32_t mucounteren;
uint32_t mscounteren;
target_ulong scounteren; /* since: priv-1.10.0 */
target_ulong mcounteren; /* since: priv-1.10.0 */
target_ulong scounteren;
target_ulong mcounteren;

target_ulong sscratch;
target_ulong mscratch;
Expand Down
62 changes: 48 additions & 14 deletions target/riscv/op_helper.c
Expand Up @@ -225,11 +225,19 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write,
qemu_log_mask(LOG_UNIMP, "CSR_MCYCLEH: write not implemented");
goto do_illegal;
case CSR_MUCOUNTEREN:
env->mucounteren = val_to_write;
break;
if (env->priv_ver <= PRIV_VERSION_1_09_1) {
env->scounteren = val_to_write;
break;
} else {
goto do_illegal;
}
case CSR_MSCOUNTEREN:
env->mscounteren = val_to_write;
break;
if (env->priv_ver <= PRIV_VERSION_1_09_1) {
env->mcounteren = val_to_write;
break;
} else {
goto do_illegal;
}
case CSR_SSTATUS: {
target_ulong ms = env->mstatus;
target_ulong mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UIE
Expand Down Expand Up @@ -286,8 +294,12 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write,
env->stvec = val_to_write >> 2 << 2;
break;
case CSR_SCOUNTEREN:
env->scounteren = val_to_write;
break;
if (env->priv_ver >= PRIV_VERSION_1_10_0) {
env->scounteren = val_to_write;
break;
} else {
goto do_illegal;
}
case CSR_SSCRATCH:
env->sscratch = val_to_write;
break;
Expand All @@ -308,8 +320,12 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write,
env->mtvec = val_to_write >> 2 << 2;
break;
case CSR_MCOUNTEREN:
env->mcounteren = val_to_write;
break;
if (env->priv_ver >= PRIV_VERSION_1_10_0) {
env->mcounteren = val_to_write;
break;
} else {
goto do_illegal;
}
case CSR_MSCRATCH:
env->mscratch = val_to_write;
break;
Expand Down Expand Up @@ -347,6 +363,8 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write,
case CSR_PMPADDR15:
pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val_to_write);
break;
#endif
#if !defined(CONFIG_USER_ONLY)
do_illegal:
#endif
default:
Expand All @@ -362,8 +380,8 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write,
target_ulong csr_read_helper(CPURISCVState *env, target_ulong csrno)
{
#ifndef CONFIG_USER_ONLY
target_ulong ctr_en = env->priv == PRV_U ? env->mucounteren :
env->priv == PRV_S ? env->mscounteren : -1U;
target_ulong ctr_en = env->priv == PRV_U ? env->scounteren :
env->priv == PRV_S ? env->mcounteren : -1U;
#else
target_ulong ctr_en = -1;
#endif
Expand Down Expand Up @@ -438,9 +456,17 @@ target_ulong csr_read_helper(CPURISCVState *env, target_ulong csrno)
#endif
break;
case CSR_MUCOUNTEREN:
return env->mucounteren;
if (env->priv_ver <= PRIV_VERSION_1_09_1) {
return env->scounteren;
} else {
break; /* illegal instruction */
}
case CSR_MSCOUNTEREN:
return env->mscounteren;
if (env->priv_ver <= PRIV_VERSION_1_09_1) {
return env->mcounteren;
} else {
break; /* illegal instruction */
}
case CSR_SSTATUS: {
target_ulong mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UIE
| SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS
Expand All @@ -465,7 +491,11 @@ target_ulong csr_read_helper(CPURISCVState *env, target_ulong csrno)
case CSR_STVEC:
return env->stvec;
case CSR_SCOUNTEREN:
return env->scounteren;
if (env->priv_ver >= PRIV_VERSION_1_10_0) {
return env->scounteren;
} else {
break; /* illegal instruction */
}
case CSR_SCAUSE:
return env->scause;
case CSR_SATP: /* CSR_SPTBR */
Expand Down Expand Up @@ -510,7 +540,11 @@ target_ulong csr_read_helper(CPURISCVState *env, target_ulong csrno)
case CSR_MTVEC:
return env->mtvec;
case CSR_MCOUNTEREN:
return env->mcounteren;
if (env->priv_ver >= PRIV_VERSION_1_10_0) {
return env->mcounteren;
} else {
break; /* illegal instruction */
}
case CSR_MEDELEG:
return env->medeleg;
case CSR_MIDELEG:
Expand Down

0 comments on commit 8c59f5c

Please sign in to comment.