summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/riscv.sail14
-rw-r--r--riscv/riscv_sys.sail40
2 files changed, 46 insertions, 8 deletions
diff --git a/riscv/riscv.sail b/riscv/riscv.sail
index 0dacf900..9b33a608 100644
--- a/riscv/riscv.sail
+++ b/riscv/riscv.sail
@@ -550,7 +550,7 @@ function writeCSR (csr : bits(12), value : xlenbits) -> unit =
0x302 => medeleg = legalize_medeleg(medeleg, value),
0x303 => mideleg = legalize_mideleg(mideleg, value),
0x304 => mie = legalize_mie(mie, value),
- 0x305 => mtvec = legalize_mtvec(mtvec, value),
+ 0x305 => mtvec = legalize_tvec(mtvec, value),
0x340 => mscratch = value,
0x341 => mepc = value,
0x342 => mcause->bits() = value,
@@ -558,14 +558,14 @@ function writeCSR (csr : bits(12), value : xlenbits) -> unit =
0x344 => mip = legalize_mip(mip, value),
/* supervisor mode */
- /* FIXME: need legalizers in many places */
- 0x100 => mstatus->bits() = value,
- 0x102 => sedeleg->bits() = value,
+ /* FIXME: need legalizers for interrupt regs and satp */
+ 0x100 => mstatus = legalize_sstatus(mstatus, value),
+ 0x102 => sedeleg = legalize_sedeleg(sedeleg, value),
0x103 => sideleg->bits() = value,
- 0x104 => mie->bits() = value,
- 0x105 => stvec->bits() = value,
+ 0x104 => sie->bits() = value,
+ 0x105 => stvec = legalize_tvec(stvec, value),
0x140 => sscratch = value,
- 0x141 => sepc = value,
+ 0x141 => sepc = value, // FIXME: alignment check/RVC
0x142 => scause->bits() = value,
0x143 => stval = value,
0x144 => mip->bits() = value,
diff --git a/riscv/riscv_sys.sail b/riscv/riscv_sys.sail
index f334003b..42240e6b 100644
--- a/riscv/riscv_sys.sail
+++ b/riscv/riscv_sys.sail
@@ -161,7 +161,7 @@ bitfield Mtvec : bits(64) = {
}
register mtvec : Mtvec /* Trap Vector */
-function legalize_mtvec(o : Mtvec, v : xlenbits) -> Mtvec = {
+function legalize_tvec(o : Mtvec, v : xlenbits) -> Mtvec = {
let v = Mk_Mtvec(v);
match (trapVectorMode_of_bits(v.Mode())) {
TV_Direct => v,
@@ -225,6 +225,40 @@ bitfield Sstatus : bits(64) = {
UIE : 0
}
/* This is a view, so there is no register defined. */
+function lower_mstatus(m : Mstatus) -> Sstatus = {
+ let s = Mk_Sstatus(EXTZ(0b0));
+ let s = update_SD(s, m.SD());
+ let s = update_UXL(s, m.UXL());
+ let s = update_MXR(s, m.MXR());
+ let s = update_SUM(s, m.SUM());
+ let s = update_XS(s, m.XS());
+ let s = update_FS(s, m.FS());
+ let s = update_SPP(s, m.SPP());
+ let s = update_SPIE(s, m.SPIE());
+ let s = update_UPIE(s, m.UPIE());
+ let s = update_SIE(s, m.SIE());
+ let s = update_UIE(s, m.UIE());
+ s
+}
+
+function lift_sstatus(m : Mstatus, s : Sstatus) -> Mstatus = {
+ let m = update_SD(m, s.SD());
+ let m = update_UXL(m, s.UXL());
+ let m = update_MXR(m, s.MXR());
+ let m = update_SUM(m, s.SUM());
+ let m = update_XS(m, s.XS());
+ let m = update_FS(m, s.FS());
+ let m = update_SPP(m, s.SPP());
+ let m = update_SPIE(m, s.SPIE());
+ let m = update_UPIE(m, s.UPIE());
+ let m = update_SIE(m, s.SIE());
+ let m = update_UIE(m, s.UIE());
+ m
+}
+
+function legalize_sstatus(m : Mstatus, v : xlenbits) -> Mstatus = {
+ lift_sstatus(m, Mk_Sstatus(v))
+}
bitfield Sedeleg : bits(64) = {
UEnvCall : 8,
@@ -239,6 +273,10 @@ bitfield Sedeleg : bits(64) = {
}
register sedeleg : Sedeleg
+function legalize_sedeleg(s : Sedeleg, v : xlenbits) -> Sedeleg = {
+ Mk_Sedeleg(EXTZ(v[8..0]))
+}
+
/* TODO: handle views for interrupt delegation */
register sideleg : Minterrupts
register sip : Minterrupts