aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChih-Min Chao <chihmin.chao@sifive.com>2021-04-16 01:17:26 -0700
committerChih-Min Chao <chihmin.chao@sifive.com>2021-06-02 20:15:06 -0700
commit327084128246e5cf562293cfe82d2570a6d5629e (patch)
tree7f7f7b9f276eae79597bf4adbef147fb18b55bc6
parentbf4b1e09ed8e7a11ecff9891b12ce5d7f3375722 (diff)
downloadspike-327084128246e5cf562293cfe82d2570a6d5629e.zip
spike-327084128246e5cf562293cfe82d2570a6d5629e.tar.gz
spike-327084128246e5cf562293cfe82d2570a6d5629e.tar.bz2
pmp: mstatus.mprv should be clear if mpp is not M-mode
After the privilege draft-20191120-569d071, the section 3.1.6.3 says "An MRET or SRET instruction that changes the privilege mode to a mode less privileged than M also sets MPRV=0. Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
-rw-r--r--riscv/insns/mret.h2
-rw-r--r--riscv/insns/sret.h2
2 files changed, 4 insertions, 0 deletions
diff --git a/riscv/insns/mret.h b/riscv/insns/mret.h
index cedfc72..fd1d3a9 100644
--- a/riscv/insns/mret.h
+++ b/riscv/insns/mret.h
@@ -3,6 +3,8 @@ set_pc_and_serialize(p->get_state()->mepc);
reg_t s = STATE.mstatus;
reg_t prev_prv = get_field(s, MSTATUS_MPP);
reg_t prev_virt = get_field(s, MSTATUS_MPV);
+if (prev_prv != PRV_M)
+ s = set_field(s, MSTATUS_MPRV, 0);
s = set_field(s, MSTATUS_MIE, get_field(s, MSTATUS_MPIE));
s = set_field(s, MSTATUS_MPIE, 1);
s = set_field(s, MSTATUS_MPP, PRV_U);
diff --git a/riscv/insns/sret.h b/riscv/insns/sret.h
index 315f4f0..b940acd 100644
--- a/riscv/insns/sret.h
+++ b/riscv/insns/sret.h
@@ -9,6 +9,8 @@ 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);
+if (prev_prv != PRV_M)
+ s = set_field(s, MSTATUS_MPRV, 0);
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);