Spike, a RISC-V ISA Simulator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

38 lines
1.2 KiB

require_extension('S');
reg_t prev_hstatus = STATE.hstatus->read();
if (STATE.v) {
if (STATE.prv == PRV_U || get_field(prev_hstatus, HSTATUS_VTSR))
require_novirt();
} else {
require_privilege(get_field(STATE.mstatus->read(), MSTATUS_TSR) ? PRV_M : PRV_S);
}
reg_t next_pc = p->get_state()->sepc->read();
set_pc_and_serialize(next_pc);
reg_t s = STATE.sstatus->read();
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);
bool prev_virt = STATE.v;
if (!STATE.v) {
if (p->extension_enabled('H')) {
prev_virt = get_field(prev_hstatus, HSTATUS_SPV);
reg_t new_hstatus = set_field(prev_hstatus, HSTATUS_SPV, 0);
STATE.hstatus->write(new_hstatus);
}
STATE.mstatus->write(set_field(STATE.mstatus->read(), MSTATUS_MPRV, 0));
}
if (ZICFILP_xLPE(prev_virt, prev_prv)) {
STATE.elp = static_cast<elp_t>(get_field(s, SSTATUS_SPELP));
}
s = set_field(s, SSTATUS_SPELP, elp_t::NO_LP_EXPECTED);
if (STATE.prv == PRV_S) {
s = set_field(s, SSTATUS_SDT, 0);
if (!STATE.v && prev_virt && prev_prv == PRV_U)
STATE.vsstatus->write(STATE.vsstatus->read() & ~SSTATUS_SDT);
}
STATE.sstatus->write(s);
p->set_privilege(prev_prv, prev_virt);