Signed-off-by: Alistair Francis <alistair.fran...@wdc.com> --- target/riscv/cpu_bits.h | 5 +++-- target/riscv/cpu_helper.c | 20 ++++++++++++++++---- target/riscv/csr.c | 6 +++--- 3 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index bb4ee3fc35..028e268faa 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -364,10 +364,10 @@ #define MSTATUS_TW 0x20000000 /* since: priv-1.10 */ #define MSTATUS_TSR 0x40000000 /* since: priv-1.10 */ #if defined(TARGET_RISCV64) -#define MSTATUS_MTL 0x4000000000ULL +#define MSTATUS_GVA 0x4000000000ULL #define MSTATUS_MPV 0x8000000000ULL #elif defined(TARGET_RISCV32) -#define MSTATUS_MTL 0x00000040 +#define MSTATUS_GVA 0x00000040 #define MSTATUS_MPV 0x00000080 #endif @@ -429,6 +429,7 @@ #define HSTATUS_VTVM 0x00100000 #define HSTATUS_VTSR 0x00400000 #define HSTATUS_HU 0x00000200 +#define HSTATUS_GVA 0x00000040 #define HSTATUS32_WPRI 0xFF8FF87E #define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 2ac599505f..93df7a896d 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -914,6 +914,15 @@ void riscv_cpu_do_interrupt(CPUState *cs) if (riscv_has_ext(env, RVH)) { target_ulong hdeleg = async ? env->hideleg : env->hedeleg; + if (riscv_cpu_virt_enabled(env) && tval) { + /* + * If we are writing a guest virtual address to stval, set + * this to 1. If we are trapping to VS we will set this to 0 + * later. + */ + env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 1); + } + if (riscv_cpu_virt_enabled(env) && ((hdeleg >> cause) & 1) && !force_hs_execp) { /* @@ -924,6 +933,7 @@ void riscv_cpu_do_interrupt(CPUState *cs) cause == IRQ_VS_EXT) cause = cause - 1; /* Trap to VS mode */ + env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 0); } else if (riscv_cpu_virt_enabled(env)) { /* Trap into HS mode, from virt */ riscv_cpu_swap_hypervisor_regs(env); @@ -973,13 +983,15 @@ void riscv_cpu_do_interrupt(CPUState *cs) #ifdef TARGET_RISCV32 env->mstatush = set_field(env->mstatush, MSTATUS_MPV, riscv_cpu_virt_enabled(env)); - env->mstatush = set_field(env->mstatush, MSTATUS_MTL, - riscv_cpu_force_hs_excep_enabled(env)); + if (riscv_cpu_virt_enabled(env) && tval) { + env->mstatush = set_field(env->mstatush, MSTATUS_GVA, 1); + } #else env->mstatus = set_field(env->mstatus, MSTATUS_MPV, riscv_cpu_virt_enabled(env)); - env->mstatus = set_field(env->mstatus, MSTATUS_MTL, - riscv_cpu_force_hs_excep_enabled(env)); + if (riscv_cpu_virt_enabled(env) && tval) { + env->mstatus = set_field(env->mstatus, MSTATUS_GVA, 1); + } #endif mtval2 = env->guest_phys_fault_addr; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 88cf0ff600..6b6080592a 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -380,10 +380,10 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) MSTATUS_TW; #if defined(TARGET_RISCV64) /* - * RV32: MPV and MTL are not in mstatus. The current plan is to + * RV32: MPV and GVA are not in mstatus. The current plan is to * add them to mstatush. For now, we just don't support it. */ - mask |= MSTATUS_MTL | MSTATUS_MPV; + mask |= MSTATUS_MPV | MSTATUS_GVA; #endif } @@ -410,7 +410,7 @@ static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val) tlb_flush(env_cpu(env)); } - val &= MSTATUS_MPV | MSTATUS_MTL; + val &= MSTATUS_MPV | MSTATUS_GVA; env->mstatush = val; -- 2.26.2