target/riscv: Convert MSTATUS MTL to GVA

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 9308432988946de550a68524ed76e4b8683f10e2.1597259519.git.alistair.francis@wdc.com
Message-Id: <9308432988946de550a68524ed76e4b8683f10e2.1597259519.git.alistair.francis@wdc.com>
This commit is contained in:
Alistair Francis 2020-08-12 12:13:27 -07:00
parent e2eb5ca8f6
commit 9034e90ad9
3 changed files with 26 additions and 9 deletions

View file

@ -379,10 +379,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
@ -444,6 +444,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

View file

@ -901,6 +901,19 @@ 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) ||
riscv_cpu_two_stage_lookup(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);
} else {
/* For other HS-mode traps, we set this to 0. */
env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 0);
}
if (riscv_cpu_virt_enabled(env) && ((hdeleg >> cause) & 1) &&
!force_hs_execp) {
/*
@ -911,6 +924,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);
@ -959,13 +973,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;

View file

@ -403,10 +403,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
mstatus = (mstatus & ~mask) | (val & mask);
@ -432,7 +432,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;