@@ -140,6 +140,16 @@ function clause write_CSR(0x301, value) = { misa = legalize_misa(misa, value); m
140
140
function clause currentlyEnabled(Ext_U) = hartSupports(Ext_U) & misa[U] == 0b1
141
141
function clause currentlyEnabled(Ext_S) = hartSupports(Ext_S) & misa[S] == 0b1
142
142
143
+ function clause currentlyEnabled(Ext_Svbare) = currentlyEnabled(Ext_S)
144
+ function clause currentlyEnabled(Ext_Sv32) = hartSupports(Ext_Sv32) & currentlyEnabled(Ext_S)
145
+ function clause currentlyEnabled(Ext_Sv39) = hartSupports(Ext_Sv39) & currentlyEnabled(Ext_S)
146
+ function clause currentlyEnabled(Ext_Sv48) = hartSupports(Ext_Sv48) & currentlyEnabled(Ext_S)
147
+ function clause currentlyEnabled(Ext_Sv57) = hartSupports(Ext_Sv57) & currentlyEnabled(Ext_S)
148
+
149
+ function virtual_memory_supported() -> bool = {
150
+ currentlyEnabled(Ext_Sv32) | currentlyEnabled(Ext_Sv39) | currentlyEnabled(Ext_Sv48) | currentlyEnabled(Ext_Sv57)
151
+ }
152
+
143
153
/*
144
154
* Illegal values legalized to least privileged mode supported.
145
155
* Note: the only valid combinations of supported modes are M, M+U, M+S+U.
@@ -235,7 +245,7 @@ function legalize_mstatus(o : Mstatus, v : bits(64)) -> Mstatus = {
235
245
TW = if currentlyEnabled(Ext_U) then v[TW] else 0b0,
236
246
TVM = if currentlyEnabled(Ext_S) then v[TVM] else 0b0,
237
247
MXR = if currentlyEnabled(Ext_S) then v[MXR] else 0b0,
238
- SUM = if currentlyEnabled(Ext_S ) then v[SUM] else 0b0, // TODO: Should also be disabled if satp.MODE is read-only 0
248
+ SUM = if virtual_memory_supported( ) then v[SUM] else 0b0,
239
249
MPRV = if currentlyEnabled(Ext_U) then v[MPRV] else 0b0,
240
250
/* We don't have any extension context yet. */
241
251
XS = extStatus_to_bits(Off),
@@ -851,13 +861,26 @@ function legalize_satp(
851
861
written_value : xlenbits,
852
862
) -> xlenbits = {
853
863
if xlen == 32 then {
854
- /* all 32-bit satp modes are valid */
855
- written_value
864
+ let s = Mk_Satp32(written_value);
865
+ match satpMode_of_bits(arch, 0b000 @ s[Mode]) {
866
+ None() => prev_value,
867
+ Some(Sv_mode) => match Sv_mode {
868
+ Bare if currentlyEnabled(Ext_Svbare) => s.bits,
869
+ Sv32 if currentlyEnabled(Ext_Sv32) => s.bits,
870
+ _ => prev_value,
871
+ }
872
+ }
856
873
} else if xlen == 64 then {
857
874
let s = Mk_Satp64(written_value);
858
875
match satpMode_of_bits(arch, s[Mode]) {
859
876
None() => prev_value,
860
- Some(_) => s.bits
877
+ Some(Sv_mode) => match Sv_mode {
878
+ Bare if currentlyEnabled(Ext_Svbare) => s.bits,
879
+ Sv39 if currentlyEnabled(Ext_Sv39) => s.bits,
880
+ Sv48 if currentlyEnabled(Ext_Sv48) => s.bits,
881
+ Sv57 if currentlyEnabled(Ext_Sv57) => s.bits,
882
+ _ => prev_value,
883
+ }
861
884
}
862
885
} else {
863
886
internal_error(__FILE__, __LINE__, "Unsupported xlen" ^ dec_str(xlen))
0 commit comments