@@ -138,6 +138,16 @@ function sys_enable_supervisor() -> bool = true
138138function clause currentlyEnabled (Ext_U ) = misa [U ] == 0b1
139139function clause currentlyEnabled (Ext_S ) = misa [S ] == 0b1
140140
141+ function clause currentlyEnabled (Ext_Svbare ) = currentlyEnabled (Ext_S )
142+ function clause currentlyEnabled (Ext_Sv32 ) = currentlyEnabled (Ext_S ) & (xlen == 32 ) & hartSupports (Ext_Sv32 )
143+ function clause currentlyEnabled (Ext_Sv39 ) = currentlyEnabled (Ext_S ) & (xlen == 64 ) & hartSupports (Ext_Sv39 )
144+ function clause currentlyEnabled (Ext_Sv48 ) = currentlyEnabled (Ext_S ) & (xlen == 64 ) & hartSupports (Ext_Sv48 )
145+ function clause currentlyEnabled (Ext_Sv57 ) = currentlyEnabled (Ext_S ) & (xlen == 64 ) & hartSupports (Ext_Sv57 )
146+
147+ function virtual_memory_supported () -> bool = {
148+ currentlyEnabled (Ext_Sv32 ) | currentlyEnabled (Ext_Sv39 ) | currentlyEnabled (Ext_Sv48 ) | currentlyEnabled (Ext_Sv57 )
149+ }
150+
141151/*
142152 * Illegal values legalized to least privileged mode supported.
143153 * Note: the only valid combinations of supported modes are M, M+U, M+S+U.
@@ -233,7 +243,7 @@ function legalize_mstatus(o : Mstatus, v : bits(64)) -> Mstatus = {
233243 TW = if currentlyEnabled (Ext_U ) then v [TW ] else 0b0 ,
234244 TVM = if currentlyEnabled (Ext_S ) then v [TVM ] else 0b0 ,
235245 MXR = if currentlyEnabled (Ext_S ) then v [MXR ] else 0b0 ,
236- SUM = if currentlyEnabled ( Ext_S ) then v [SUM ] else 0b0 , // TODO: Should also be disabled if satp.MODE is read-only 0
246+ SUM = if virtual_memory_supported ( ) then v [SUM ] else 0b0 ,
237247 MPRV = if currentlyEnabled (Ext_U ) then v [MPRV ] else 0b0 ,
238248 /* We don't have any extension context yet. */
239249 XS = extStatus_to_bits (Off ),
@@ -876,13 +886,26 @@ function legalize_satp(
876886 written_value : xlenbits ,
877887) -> xlenbits = {
878888 if xlen == 32 then {
879- /* all 32-bit satp modes are valid */
880- written_value
889+ let s = Mk_Satp32 (written_value );
890+ match satpMode_of_bits (arch , 0b000 @ s [Mode ]) {
891+ None () => prev_value ,
892+ Some (Sv_mode ) => match Sv_mode {
893+ Bare if currentlyEnabled (Ext_Svbare ) => s . bits ,
894+ Sv32 if currentlyEnabled (Ext_Sv32 ) => s . bits ,
895+ _ => prev_value ,
896+ }
897+ }
881898 } else if xlen == 64 then {
882899 let s = Mk_Satp64 (written_value );
883900 match satpMode_of_bits (arch , s [Mode ]) {
884901 None () => prev_value ,
885- Some (_ ) => s . bits
902+ Some (Sv_mode ) => match Sv_mode {
903+ Bare if currentlyEnabled (Ext_Svbare ) => s . bits ,
904+ Sv39 if currentlyEnabled (Ext_Sv39 ) => s . bits ,
905+ Sv48 if currentlyEnabled (Ext_Sv48 ) => s . bits ,
906+ Sv57 if currentlyEnabled (Ext_Sv57 ) => s . bits ,
907+ _ => prev_value ,
908+ }
886909 }
887910 } else {
888911 internal_error (__FILE__, __LINE__, "Unsupported xlen" ^ dec_str (xlen ))
0 commit comments