@@ -149,3 +149,77 @@ pub unsafe fn try_set(mode: Mode, asid: usize, ppn: usize) -> Result<()> {
149149 _try_write ( bits)
150150 }
151151}
152+
153+ #[ cfg( test) ]
154+ mod tests {
155+ use super :: * ;
156+
157+ #[ cfg( target_pointer_width = "32" ) ]
158+ const ASID_START : usize = 22 ;
159+ #[ cfg( target_pointer_width = "64" ) ]
160+ const ASID_START : usize = 44 ;
161+ #[ cfg( target_pointer_width = "32" ) ]
162+ const MODE_START : usize = 31 ;
163+ #[ cfg( target_pointer_width = "64" ) ]
164+ const MODE_START : usize = 60 ;
165+
166+ #[ cfg( target_pointer_width = "32" ) ]
167+ const MODES : [ Mode ; 2 ] = [ Mode :: Bare , Mode :: Sv32 ] ;
168+ #[ cfg( target_pointer_width = "64" ) ]
169+ const MODES : [ Mode ; 5 ] = [ Mode :: Bare , Mode :: Sv39 , Mode :: Sv48 , Mode :: Sv57 , Mode :: Sv64 ] ;
170+
171+ #[ test]
172+ fn test_satp ( ) {
173+ let new_mode = Mode :: new ( ) ;
174+
175+ ( 1 ..=usize:: BITS )
176+ . map ( |r| ( ( 1u128 << r) - 1 ) as usize )
177+ . for_each ( |raw| {
178+ let mut satp = Satp :: from_bits ( raw) ;
179+
180+ let exp_ppn = raw & ( ( 1usize << ASID_START ) - 1 ) ;
181+ let exp_asid = ( raw & ( ( 1usize << MODE_START ) - 1 ) ) >> ASID_START ;
182+
183+ assert_eq ! ( satp. ppn( ) , exp_ppn) ;
184+
185+ satp. set_ppn ( 0 ) ;
186+ assert_eq ! ( satp. ppn( ) , 0 ) ;
187+
188+ satp. set_ppn ( exp_ppn) ;
189+ assert_eq ! ( satp. ppn( ) , exp_ppn) ;
190+
191+ assert_eq ! ( satp. asid( ) , exp_asid) ;
192+
193+ satp. set_asid ( 0 ) ;
194+ assert_eq ! ( satp. asid( ) , 0 ) ;
195+
196+ satp. set_asid ( exp_asid) ;
197+ assert_eq ! ( satp. asid( ) , exp_asid) ;
198+
199+ match Mode :: from_usize ( raw >> 60 ) {
200+ Ok ( exp_mode) => {
201+ assert_eq ! ( satp. try_mode( ) , Ok ( exp_mode) ) ;
202+ assert_eq ! ( satp. mode( ) , exp_mode) ;
203+
204+ satp. set_mode ( new_mode) ;
205+
206+ assert_eq ! ( satp. try_mode( ) , Ok ( new_mode) ) ;
207+ assert_eq ! ( satp. mode( ) , new_mode) ;
208+
209+ satp. set_mode ( exp_mode) ;
210+
211+ assert_eq ! ( satp. try_mode( ) , Ok ( exp_mode) ) ;
212+ assert_eq ! ( satp. mode( ) , exp_mode) ;
213+ }
214+ Err ( exp_err) => {
215+ assert_eq ! ( satp. try_mode( ) , Err ( exp_err) ) ;
216+ }
217+ }
218+ } ) ;
219+
220+ let mut satp = Satp :: from_bits ( 0 ) ;
221+ MODES
222+ . into_iter ( )
223+ . for_each ( |mode| test_csr_field ! ( satp, mode: mode) ) ;
224+ }
225+ }
0 commit comments