Skip to content

Commit

Permalink
sys_regs: compute mstatus and sstatus SD bit on CSR read
Browse files Browse the repository at this point in the history
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ář <rkrcmar@ventanamicro.com>
  • Loading branch information
radimkrcmar committed Jan 28, 2025
1 parent ddd0c7f commit ca9c87d
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 42 deletions.
1 change: 0 additions & 1 deletion model/riscv_fdext_regs.sail
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
2 changes: 0 additions & 2 deletions model/riscv_sys_control.sail
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
51 changes: 13 additions & 38 deletions model/riscv_sys_regs.sail
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,6 @@ function have_privLevel(priv : priv_level) -> bool =
}

bitfield Mstatus : bits(64) = {
SD_64: 63,

//MDT : 42,
//MPELP: 41,

Expand All @@ -179,8 +177,6 @@ bitfield Mstatus : bits(64) = {
SXL : 35 .. 34,
UXL : 33 .. 32,

SD_32: 31,

//SDT : 24,
//SPELP: 23,
TSR : 22,
Expand Down Expand Up @@ -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 = {
Expand All @@ -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],
Expand Down Expand Up @@ -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],
]
}

Expand All @@ -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 */
Expand Down Expand Up @@ -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,
Expand All @@ -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],
Expand All @@ -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],
Expand All @@ -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 = {
Expand Down
1 change: 0 additions & 1 deletion model/riscv_vext_regs.sail
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down

0 comments on commit ca9c87d

Please sign in to comment.