aboutsummaryrefslogtreecommitdiff
path: root/riscv/insns
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2023-03-16 17:14:24 -0700
committerAndrew Waterman <andrew@sifive.com>2023-03-20 09:39:37 -0700
commita5fdc4efbf9f79a890fe5d1c144880548b011d90 (patch)
tree6304d37738f4a0659deb4f87a9839fd9ff26a7b0 /riscv/insns
parent43c87e5ccc7904d3b782f66dc3bc361a3f8a1da7 (diff)
downloadriscv-isa-sim-a5fdc4efbf9f79a890fe5d1c144880548b011d90.zip
riscv-isa-sim-a5fdc4efbf9f79a890fe5d1c144880548b011d90.tar.gz
riscv-isa-sim-a5fdc4efbf9f79a890fe5d1c144880548b011d90.tar.bz2
Implement Smrnmi extension
We don't model any sources of RNMI, so this is mostly vestigial.
Diffstat (limited to 'riscv/insns')
-rw-r--r--riscv/insns/mnret.h15
1 files changed, 15 insertions, 0 deletions
diff --git a/riscv/insns/mnret.h b/riscv/insns/mnret.h
new file mode 100644
index 0000000..bc69510
--- /dev/null
+++ b/riscv/insns/mnret.h
@@ -0,0 +1,15 @@
+require_extension(EXT_SMRNMI);
+require_privilege(PRV_M);
+set_pc_and_serialize(p->get_state()->mnepc->read());
+reg_t s = STATE.mnstatus->read();
+reg_t prev_prv = get_field(s, MNSTATUS_MNPP);
+reg_t prev_virt = get_field(s, MNSTATUS_MNPV);
+if (prev_prv != PRV_M) {
+ reg_t mstatus = STATE.mstatus->read();
+ mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
+ STATE.mstatus->write(mstatus);
+}
+s = set_field(s, MNSTATUS_NMIE, 1);
+STATE.mnstatus->write(s);
+p->set_privilege(prev_prv);
+p->set_virt(prev_virt);