diff options
Diffstat (limited to 'riscv/insns/sret.h')
-rw-r--r-- | riscv/insns/sret.h | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/riscv/insns/sret.h b/riscv/insns/sret.h index be837a3..bc063e6 100644 --- a/riscv/insns/sret.h +++ b/riscv/insns/sret.h @@ -1,10 +1,17 @@ require_extension('S'); require_privilege(get_field(STATE.mstatus, MSTATUS_TSR) ? PRV_M : PRV_S); -set_pc_and_serialize(p->get_state()->sepc); +if (STATE.v && get_field(STATE.hstatus, HSTATUS_VTSR)) + require_novirt(); +reg_t next_pc = (STATE.v) ? p->get_state()->vsepc : p->get_state()->sepc; +set_pc_and_serialize(next_pc); reg_t s = STATE.mstatus; reg_t prev_prv = get_field(s, MSTATUS_SPP); s = set_field(s, MSTATUS_SIE, get_field(s, MSTATUS_SPIE)); s = set_field(s, MSTATUS_SPIE, 1); s = set_field(s, MSTATUS_SPP, PRV_U); -p->set_privilege(prev_prv); p->set_csr(CSR_MSTATUS, s); +p->set_privilege(prev_prv); +if (!STATE.v) { + reg_t prev_virt = get_field(STATE.hstatus, HSTATUS_SPV); + p->set_virt(prev_virt); +} |