From ca9c87d8533ca5b4ad7dd70b2876c924dfddd647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Sat, 11 Jan 2025 10:41:53 +0100 Subject: [PATCH] sys_regs: compute mstatus and sstatus SD bit on CSR read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SD bit is read-only and we don't have to store it anywhere, because its only purpose is to accelerate software after CSR reads. Dynamically add SD as the most significant bit in CSR reads * to avoid the need to increase mstatus width to bit(128) when implementing RV128, * to simplify support for dynamic XLEN, and * to make the code nicer. Signed-off-by: Radim Krčmář --- model/riscv_fdext_regs.sail | 1 - model/riscv_sys_control.sail | 2 -- model/riscv_sys_regs.sail | 51 +++++++++--------------------------- model/riscv_vext_regs.sail | 1 - 4 files changed, 13 insertions(+), 42 deletions(-) diff --git a/model/riscv_fdext_regs.sail b/model/riscv_fdext_regs.sail index 35dce2b68..02c5bba1e 100644 --- a/model/riscv_fdext_regs.sail +++ b/model/riscv_fdext_regs.sail @@ -88,7 +88,6 @@ register f31 : fregtype function dirty_fd_context() -> unit = { assert(sys_enable_fdext()); mstatus[FS] = extStatus_to_bits(Dirty); - mstatus = set_mstatus_SD(mstatus, 0b1); } function dirty_fd_context_if_present() -> unit = { diff --git a/model/riscv_sys_control.sail b/model/riscv_sys_control.sail index 5c75a2d66..bc49bb863 100644 --- a/model/riscv_sys_control.sail +++ b/model/riscv_sys_control.sail @@ -335,8 +335,6 @@ function init_sys() -> unit = { else 0b0; mstatus = [mstatus with - SD_64 = 0b0, - SD_32 = 0b0, /* SXL and UXL is only valid for 64-bit systems and in RV32 WPRI */ SXL = if xlen != 32 then misa[MXL] else 0b00, UXL = if xlen != 32 then misa[MXL] else 0b00, diff --git a/model/riscv_sys_regs.sail b/model/riscv_sys_regs.sail index a2562b945..2269c62c2 100644 --- a/model/riscv_sys_regs.sail +++ b/model/riscv_sys_regs.sail @@ -165,8 +165,6 @@ function have_privLevel(priv : priv_level) -> bool = } bitfield Mstatus : bits(64) = { - SD_64: 63, - //MDT : 42, //MPELP: 41, @@ -179,8 +177,6 @@ bitfield Mstatus : bits(64) = { SXL : 35 .. 34, UXL : 33 .. 32, - SD_32: 31, - //SDT : 24, //SPELP: 23, TSR : 22, @@ -210,15 +206,10 @@ function effectivePrivilege(t : AccessType(ext_access_type), m : Mstatus, priv : then privLevel_of_bits(m[MPP]) else priv -function get_mstatus_SD(m : Mstatus) -> bits(1) = { - if xlen == 32 then m[SD_32] - else m[SD_64] -} - -function set_mstatus_SD(m : Mstatus, v : bits(1)) -> Mstatus = { - if xlen == 32 - then [m with SD_32 = v] - else [m with SD_64 = v] +function status_dirty(s : Mstatus) -> bits(1) = { + bool_to_bits(extStatus_of_bits(s[FS]) == Dirty | + extStatus_of_bits(s[XS]) == Dirty | + extStatus_of_bits(s[VS]) == Dirty) } function legalize_mstatus(o : Mstatus, v : bits(64)) -> Mstatus = { @@ -229,7 +220,9 @@ function legalize_mstatus(o : Mstatus, v : bits(64)) -> Mstatus = { */ let v = Mk_Mstatus(v); - let o = [o with + [o with + /* SD is handled in CSR accessors */ + // MDT = v[MDT], // MPELP = v[MPELP], // MPV = v[MPV], @@ -263,16 +256,6 @@ function legalize_mstatus(o : Mstatus, v : bits(64)) -> Mstatus = { SPIE = v[SPIE], MIE = v[MIE], SIE = v[SIE], - ]; - - // Set dirty bit to OR of other status bits. - let dirty = extStatus_of_bits(o[FS]) == Dirty | - extStatus_of_bits(o[XS]) == Dirty | - extStatus_of_bits(o[VS]) == Dirty; - - [o with - SD_64 = if xlen == 64 then bool_to_bits(dirty) else o[SD_64], - SD_32 = if xlen == 32 then bool_to_bits(dirty) else o[SD_32], ] } @@ -281,11 +264,11 @@ mapping clause csr_name_map = 0x300 <-> "mstatus" function clause is_CSR_defined(0x300) = true // mstatus function clause is_CSR_defined(0x310) = xlen == 32 // mstatush -function clause read_CSR(0x300) = mstatus.bits[xlen - 1 .. 0] +function clause read_CSR(0x300) = status_dirty(mstatus) @ mstatus.bits[xlen - 2 .. 0] function clause read_CSR(0x310 if xlen == 32) = mstatus.bits[63 .. 32] -function clause write_CSR((0x300, value) if xlen == 64) = { mstatus = legalize_mstatus(mstatus, value); mstatus.bits } -function clause write_CSR((0x300, value) if xlen == 32) = { mstatus = legalize_mstatus(mstatus, mstatus.bits[63 .. 32] @ value); mstatus.bits[31 .. 0] } +function clause write_CSR((0x300, value) if xlen == 64) = { mstatus = legalize_mstatus(mstatus, value); status_dirty(mstatus) @ mstatus.bits[62 .. 0] } +function clause write_CSR((0x300, value) if xlen == 32) = { mstatus = legalize_mstatus(mstatus, mstatus.bits[63 .. 32] @ value); status_dirty(mstatus) @ mstatus.bits[30 .. 0] } function clause write_CSR((0x310, value) if xlen == 32) = { mstatus = legalize_mstatus(mstatus, value @ mstatus.bits[31 .. 0]); mstatus.bits[63 .. 32] } /* architecture and extension checks */ @@ -674,10 +657,9 @@ function clause read_CSR(0xF15) = mconfigptr /* sstatus reveals a subset of mstatus */ bitfield Sstatus : bits(64) = { - SD_64 : 63, + /* SD is handled in CSR accessors */ UXL : 33 .. 32, - SD_32 : 31, // SDT : 24, // SPELP : 23, MXR : 19, @@ -695,9 +677,7 @@ function lower_mstatus(m : Mstatus) -> Sstatus = { let s = Mk_Sstatus(zeros()); [s with - SD_64 = m[SD_64], UXL = m[UXL], - SD_32 = m[SD_32], //SDT = m[SDT], //SPELP = m[SPELP], MXR = m[MXR], @@ -712,12 +692,7 @@ function lower_mstatus(m : Mstatus) -> Sstatus = { } function lift_sstatus(m : Mstatus, s : Sstatus) -> Mstatus = { - let dirty = extStatus_of_bits(s[FS]) == Dirty | extStatus_of_bits(s[XS]) == Dirty | - extStatus_of_bits(s[VS]) == Dirty; - [m with - SD_64 = if xlen == 64 then bool_to_bits(dirty) else m[SD_64], - SD_32 = if xlen == 32 then bool_to_bits(dirty) else m[SD_32], UXL = s[UXL], //SDT = s[SDT], //SPELP = s[SPELP], @@ -738,8 +713,8 @@ function legalize_sstatus(m : Mstatus, v : xlenbits) -> Mstatus = { mapping clause csr_name_map = 0x100 <-> "sstatus" function clause is_CSR_defined(0x100) = extensionEnabled(Ext_S) // sstatus -function clause read_CSR(0x100) = lower_mstatus(mstatus).bits[xlen - 1 .. 0] -function clause write_CSR(0x100, value) = { mstatus = legalize_sstatus(mstatus, value); mstatus.bits[xlen - 1 .. 0] } +function clause read_CSR(0x100) = status_dirty(mstatus) @ lower_mstatus(mstatus).bits[xlen - 2 .. 0] +function clause write_CSR(0x100, value) = { mstatus = legalize_sstatus(mstatus, value); status_dirty(mstatus) @ mstatus.bits[xlen - 2 .. 0] } bitfield Sinterrupts : xlenbits = { diff --git a/model/riscv_vext_regs.sail b/model/riscv_vext_regs.sail index e98a87013..15823df43 100644 --- a/model/riscv_vext_regs.sail +++ b/model/riscv_vext_regs.sail @@ -79,7 +79,6 @@ mapping vreg_name = { function dirty_v_context() -> unit = { assert(sys_enable_vext()); mstatus[VS] = extStatus_to_bits(Dirty); - mstatus = set_mstatus_SD(mstatus, 0b1); } function rV (r : regno) -> vregtype = {