diff options
author | Michael Clark <mjc@sifive.com> | 2019-01-14 23:58:08 +0000 |
---|---|---|
committer | Palmer Dabbelt <palmer@sifive.com> | 2019-02-11 15:56:21 -0800 |
commit | 7f2b5ff125d518a7fff9f6a4c633e3063fd75ec3 (patch) | |
tree | b66e36ce977606f1045348ca8b3b4c0871a64e4d /target/riscv/csr.c | |
parent | 533b8f8877d4e3e8bf2b57e633a84afe27c14429 (diff) |
RISC-V: Implement mstatus.TSR/TW/TVM
This adds the necessary minimum to support S-mode
virtualization for priv ISA >= v1.10
Signed-off-by: Michael Clark <mjc@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Co-authored-by: Matthew Suozzo <msuozzo@google.com>
Co-authored-by: Michael Clark <mjc@sifive.com>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
Diffstat (limited to 'target/riscv/csr.c')
-rw-r--r-- | target/riscv/csr.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 5714147689..390d3a9a56 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -305,7 +305,8 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) } mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE | MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM | - MSTATUS_MPP | MSTATUS_MXR; + MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR | + MSTATUS_TW; } /* silenty discard mstatus.mpp writes for unsupported modes */ @@ -642,7 +643,11 @@ static int read_satp(CPURISCVState *env, int csrno, target_ulong *val) if (!riscv_feature(env, RISCV_FEATURE_MMU)) { *val = 0; } else if (env->priv_ver >= PRIV_VERSION_1_10_0) { - *val = env->satp; + if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) { + return -1; + } else { + *val = env->satp; + } } else { *val = env->sptbr; } @@ -663,8 +668,12 @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val) validate_vm(env, get_field(val, SATP_MODE)) && ((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN))) { - tlb_flush(CPU(riscv_env_get_cpu(env))); - env->satp = val; + if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) { + return -1; + } else { + tlb_flush(CPU(riscv_env_get_cpu(env))); + env->satp = val; + } } return 0; } |