Skip to content

Commit 29044d0

Browse files
committed
Add Smdbltrp
1 parent 5caf7f1 commit 29044d0

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

riscv/csrs.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,10 @@ bool mstatus_csr_t::unlogged_write(const reg_t val) noexcept {
511511

512512
const reg_t requested_mpp = proc->legalize_privilege(get_field(val, MSTATUS_MPP));
513513
const reg_t adjusted_val = set_field(val, MSTATUS_MPP, requested_mpp);
514-
const reg_t new_mstatus = (read() & ~mask) | (adjusted_val & mask);
514+
reg_t new_mstatus = (read() & ~mask) | (adjusted_val & mask);
515+
if (new_mstatus & MSTATUS_MDT) {
516+
new_mstatus = new_mstatus & ~MSTATUS_MIE;
517+
}
515518
maybe_flush_tlb(new_mstatus);
516519
this->val = adjust_sd(new_mstatus);
517520
return true;

riscv/insns/mret.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@ if (ZICFILP_xLPE(prev_virt, prev_prv)) {
1313
STATE.elp = static_cast<elp_t>(get_field(s, MSTATUS_MPELP));
1414
}
1515
s = set_field(s, MSTATUS_MPELP, elp_t::NO_LP_EXPECTED);
16+
17+
s = set_field(s, MSTATUS_MDT, 0);
18+
if (prev_prv == PRV_U || prev_virt) {
19+
s = set_field(s, MSTATUS_SDT, 0);
20+
}
21+
if (prev_virt && prev_prv == PRV_U) {
22+
reg_t vs = STATE.vsstatus->read();
23+
vs = set_field(vs, SSTATUS_SDT, 0);
24+
STATE.vsstatus->write(vs);
25+
}
26+
1627
STATE.mstatus->write(s);
1728
if (STATE.mstatush) STATE.mstatush->write(s >> 32); // log mstatush change
1829
STATE.tcontrol->write((STATE.tcontrol->read() & CSR_TCONTROL_MPTE) ? (CSR_TCONTROL_MPTE | CSR_TCONTROL_MTE) : 0);

riscv/insns/sret.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,21 @@ if (!STATE.v) {
2626
if (ZICFILP_xLPE(prev_virt, prev_prv)) {
2727
STATE.elp = static_cast<elp_t>(get_field(s, SSTATUS_SPELP));
2828
}
29+
30+
if (STATE.prv == PRV_M) {
31+
reg_t m = STATE.mstatus->read();
32+
m = set_field(m, MSTATUS_MDT, 0);
33+
if (prev_prv == PRV_U || prev_virt) {
34+
s = set_field(s, MSTATUS_SDT, 0);
35+
}
36+
STATE.mstatus->write(m);
37+
if (prev_virt && prev_prv == PRV_U) {
38+
reg_t vs = STATE.vsstatus->read();
39+
vs = set_field(vs, SSTATUS_SDT, 0);
40+
STATE.vsstatus->write(vs);
41+
}
42+
}
43+
2944
s = set_field(s, SSTATUS_SPELP, elp_t::NO_LP_EXPECTED);
3045
STATE.sstatus->write(s);
3146
p->set_privilege(prev_prv, prev_virt);

0 commit comments

Comments
 (0)