@@ -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) = currentlyEnabled(Ext_S) & hartSupports(Ext_Sv32)
145
+ function clause currentlyEnabled(Ext_Sv39) = currentlyEnabled(Ext_S) & hartSupports(Ext_Sv39)
146
+ function clause currentlyEnabled(Ext_Sv48) = currentlyEnabled(Ext_S) & hartSupports(Ext_Sv48)
147
+ function clause currentlyEnabled(Ext_Sv57) = currentlyEnabled(Ext_S) & hartSupports(Ext_Sv57)
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),
@@ -855,13 +865,26 @@ function legalize_satp(
855
865
written_value : xlenbits,
856
866
) -> xlenbits = {
857
867
if xlen == 32 then {
858
- /* all 32-bit satp modes are valid */
859
- written_value
868
+ let s = Mk_Satp32(written_value);
869
+ match satpMode_of_bits(arch, 0b000 @ s[Mode]) {
870
+ None() => prev_value,
871
+ Some(Sv_mode) => match Sv_mode {
872
+ Bare if currentlyEnabled(Ext_Svbare) => s.bits,
873
+ Sv32 if currentlyEnabled(Ext_Sv32) => s.bits,
874
+ _ => prev_value,
875
+ }
876
+ }
860
877
} else if xlen == 64 then {
861
878
let s = Mk_Satp64(written_value);
862
879
match satpMode_of_bits(arch, s[Mode]) {
863
880
None() => prev_value,
864
- Some(_) => s.bits
881
+ Some(Sv_mode) => match Sv_mode {
882
+ Bare if currentlyEnabled(Ext_Svbare) => s.bits,
883
+ Sv39 if currentlyEnabled(Ext_Sv39) => s.bits,
884
+ Sv48 if currentlyEnabled(Ext_Sv48) => s.bits,
885
+ Sv57 if currentlyEnabled(Ext_Sv57) => s.bits,
886
+ _ => prev_value,
887
+ }
865
888
}
866
889
} else {
867
890
internal_error(__FILE__, __LINE__, "Unsupported xlen" ^ dec_str(xlen))
0 commit comments