RISC-V: Use [ms]counteren CSRs when priv ISA >= v1.10

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>
This commit is contained in:
Michael Clark 2018-04-09 11:33:05 +12:00
parent e216590570
commit 8c59f5c1b5
No known key found for this signature in database
GPG Key ID: 6BF1D7B357EF3E4F
2 changed files with 50 additions and 18 deletions

View File

@ -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;

View File

@ -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
@ -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;
@ -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;
@ -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:
@ -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
@ -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
@ -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 */
@ -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: