mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 17:53:56 -06:00
RISC-V: Add misa runtime write support
This patch adds support for writing misa. misa is validated based on rules in the ISA specification. 'E' is mutually exclusive with all other extensions. 'D' depends on 'F' so 'D' bit is dropped if 'F' is not present. A conservative approach to consistency is taken by flushing the translation cache on misa writes. misa_mask is added to the CPU struct to store the original set of extensions. Signed-off-by: Michael Clark <mjc@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Palmer Dabbelt <palmer@sifive.com> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
This commit is contained in:
parent
d77c3401e6
commit
f18637cd61
4 changed files with 68 additions and 3 deletions
|
@ -332,6 +332,58 @@ static int read_misa(CPURISCVState *env, int csrno, target_ulong *val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int write_misa(CPURISCVState *env, int csrno, target_ulong val)
|
||||
{
|
||||
if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
|
||||
/* drop write to misa */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 'I' or 'E' must be present */
|
||||
if (!(val & (RVI | RVE))) {
|
||||
/* It is not, drop write to misa */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 'E' excludes all other extensions */
|
||||
if (val & RVE) {
|
||||
/* when we support 'E' we can do "val = RVE;" however
|
||||
* for now we just drop writes if 'E' is present.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Mask extensions that are not supported by this hart */
|
||||
val &= env->misa_mask;
|
||||
|
||||
/* Mask extensions that are not supported by QEMU */
|
||||
val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
|
||||
|
||||
/* 'D' depends on 'F', so clear 'D' if 'F' is not present */
|
||||
if ((val & RVD) && !(val & RVF)) {
|
||||
val &= ~RVD;
|
||||
}
|
||||
|
||||
/* Suppress 'C' if next instruction is not aligned
|
||||
* TODO: this should check next_pc
|
||||
*/
|
||||
if ((val & RVC) && (GETPC() & ~3) != 0) {
|
||||
val &= ~RVC;
|
||||
}
|
||||
|
||||
/* misa.MXL writes are not supported by QEMU */
|
||||
val = (env->misa & MISA_MXL) | (val & ~MISA_MXL);
|
||||
|
||||
/* flush translation cache */
|
||||
if (val != env->misa) {
|
||||
tb_flush(CPU(riscv_env_get_cpu(env)));
|
||||
}
|
||||
|
||||
env->misa = val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_medeleg(CPURISCVState *env, int csrno, target_ulong *val)
|
||||
{
|
||||
*val = env->medeleg;
|
||||
|
@ -810,7 +862,7 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
|
|||
|
||||
/* Machine Trap Setup */
|
||||
[CSR_MSTATUS] = { any, read_mstatus, write_mstatus },
|
||||
[CSR_MISA] = { any, read_misa },
|
||||
[CSR_MISA] = { any, read_misa, write_misa },
|
||||
[CSR_MIDELEG] = { any, read_mideleg, write_mideleg },
|
||||
[CSR_MEDELEG] = { any, read_medeleg, write_medeleg },
|
||||
[CSR_MIE] = { any, read_mie, write_mie },
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue