diff options
| author | Prashanth Mundkur | 2018-04-13 14:22:34 -0700 |
|---|---|---|
| committer | Prashanth Mundkur | 2018-04-13 14:27:34 -0700 |
| commit | 5ebb68fc5cb0583730cb5b4b0c4c28d5f72636c5 (patch) | |
| tree | f47f6c0bbd9e89145d59956a29cfd8b3109e4ad6 | |
| parent | 33fa6f5cf6f3ffbcfbd5549ed9e330db85f5947c (diff) | |
Define legalizers for writes to M-mode CSRs, and hook these writes to use them.
| -rw-r--r-- | riscv/riscv.sail | 14 | ||||
| -rw-r--r-- | riscv/riscv_sys.sail | 69 |
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; |
