summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrashanth Mundkur2018-04-13 14:22:34 -0700
committerPrashanth Mundkur2018-04-13 14:27:34 -0700
commit5ebb68fc5cb0583730cb5b4b0c4c28d5f72636c5 (patch)
treef47f6c0bbd9e89145d59956a29cfd8b3109e4ad6
parent33fa6f5cf6f3ffbcfbd5549ed9e330db85f5947c (diff)
Define legalizers for writes to M-mode CSRs, and hook these writes to use them.
-rw-r--r--riscv/riscv.sail14
-rw-r--r--riscv/riscv_sys.sail69
2 files changed, 72 insertions, 11 deletions
diff --git a/riscv/riscv.sail b/riscv/riscv.sail
index 0747d077..0dacf900 100644
--- a/riscv/riscv.sail
+++ b/riscv/riscv.sail
@@ -544,21 +544,21 @@ function readCSR csr: bits(12) -> xlenbits =
}
function writeCSR (csr : bits(12), value : xlenbits) -> unit =
- /* FIXME: need legalizers in many places */
match csr {
/* machine mode */
- 0x300 => mstatus->bits() = value,
- 0x302 => medeleg->bits() = value,
- 0x303 => mideleg->bits() = value,
- 0x304 => mie->bits() = value,
- 0x305 => mtvec->bits() = value,
+ 0x300 => mstatus = legalize_mstatus(mstatus, value),
+ 0x302 => medeleg = legalize_medeleg(medeleg, value),
+ 0x303 => mideleg = legalize_mideleg(mideleg, value),
+ 0x304 => mie = legalize_mie(mie, value),
+ 0x305 => mtvec = legalize_mtvec(mtvec, value),
0x340 => mscratch = value,
0x341 => mepc = value,
0x342 => mcause->bits() = value,
0x343 => mtval = value,
- 0x344 => mip->bits() = value,
+ 0x344 => mip = legalize_mip(mip, value),
/* supervisor mode */
+ /* FIXME: need legalizers in many places */
0x100 => mstatus->bits() = value,
0x102 => sedeleg->bits() = value,
0x103 => sideleg->bits() = value,
diff --git a/riscv/riscv_sys.sail b/riscv/riscv_sys.sail
index b3ded01e..f334003b 100644
--- a/riscv/riscv_sys.sail
+++ b/riscv/riscv_sys.sail
@@ -34,6 +34,10 @@ bitfield Misa : bits(64) = {
}
register misa : Misa
+function legalize_misa(m : Misa, v : xlenbits) -> Misa =
+ /* Ignore all writes for now. */
+ m
+
bitfield Mstatus : bits(64) = {
SD : 63,
@@ -63,6 +67,21 @@ bitfield Mstatus : bits(64) = {
}
register mstatus : Mstatus
+function legalize_mstatus(o : Mstatus, v : xlenbits) -> Mstatus = {
+ let m : Mstatus = Mk_Mstatus(v);
+ /* We don't have any extension context yet. */
+ let m = update_XS(m, extStatus_to_bits(Off));
+ let m = update_SD(m, extStatus_of_bits(m.FS()) == Dirty
+ | extStatus_of_bits(m.XS()) == Dirty);
+ /* For now, we don't allow SXL and UXL to be changed, for Spike compatibility. */
+ let m = update_SXL(m, o.SXL());
+ let m = update_UXL(m, o.UXL());
+ /* Hardwired to zero in the absence of 'N'. */
+ let m = update_UPIE(m, false);
+ let m = update_UIE(m, false);
+ m
+}
+
/* interrupt registers */
bitfield Minterrupts : bits(64) = {
@@ -83,6 +102,32 @@ register mip : Minterrupts /* Pending */
register mie : Minterrupts /* Enabled */
register mideleg : Minterrupts /* Delegation to S-mode */
+function legalize_mip(o : Minterrupts, v : xlenbits) -> Minterrupts = {
+ /* The only writable bits are the S-mode bits, and with the 'N'
+ * extension, the U-mode bits. */
+ let v = Mk_Minterrupts(v);
+ let m = update_SEI(o, v.SEI());
+ let m = update_STI(m, v.STI());
+ let m = update_SSI(m, v.SSI());
+ m
+}
+
+function legalize_mie(o : Minterrupts, v : xlenbits) -> Minterrupts = {
+ let v = Mk_Minterrupts(v);
+ let m = update_MEI(o, v.MEI());
+ let m = update_MTI(m, v.MTI());
+ let m = update_MSI(m, v.MSI());
+ let m = update_SEI(m, v.SEI());
+ let m = update_STI(m, v.STI());
+ let m = update_SSI(m, v.SSI());
+ /* The U-mode bits will be modified if we have the 'N' extension. */
+ m
+}
+
+function legalize_mideleg(o : Minterrupts, v : xlenbits) -> Minterrupts = {
+ Mk_Minterrupts(v)
+}
+
/* exception registers */
bitfield Medeleg : bits(64) = {
@@ -103,11 +148,12 @@ bitfield Medeleg : bits(64) = {
}
register medeleg : Medeleg /* Delegation to S-mode */
-bitfield Mcause : bits(64) = {
- IsInterrupt : 63,
- Cause : 62 .. 0
+function legalize_medeleg(o : Medeleg, v : xlenbits) -> Medeleg = {
+ let m = Mk_Medeleg(v);
+ /* M-EnvCalls delegation is not supported */
+ let m = update_MEnvCall(m, false);
+ m
}
-register mcause : Mcause
bitfield Mtvec : bits(64) = {
Base : 63 .. 2,
@@ -115,6 +161,21 @@ bitfield Mtvec : bits(64) = {
}
register mtvec : Mtvec /* Trap Vector */
+function legalize_mtvec(o : Mtvec, v : xlenbits) -> Mtvec = {
+ let v = Mk_Mtvec(v);
+ match (trapVectorMode_of_bits(v.Mode())) {
+ TV_Direct => v,
+ TV_Vector => v,
+ _ => update_Mode(v, o.Mode())
+ }
+}
+
+bitfield Mcause : bits(64) = {
+ IsInterrupt : 63,
+ Cause : 62 .. 0
+}
+register mcause : Mcause
+
/* Interpreting the trap-vector address */
function tvec_addr(m : Mtvec, c : Mcause) -> option(xlenbits) = {
let base : xlenbits = m.Base() @ 0b00;