11//! Physical and virtual addresses manipulation
22
3- #[ cfg( feature = "step_trait" ) ]
43use core:: convert:: TryFrom ;
54use core:: fmt;
65#[ cfg( feature = "step_trait" ) ]
@@ -11,7 +10,6 @@ use crate::structures::paging::page_table::PageTableLevel;
1110use crate :: structures:: paging:: { PageOffset , PageTableIndex } ;
1211use bit_field:: BitField ;
1312
14- #[ cfg( feature = "step_trait" ) ]
1513const ADDRESS_SPACE_SIZE : u64 = 0x1_0000_0000_0000 ;
1614
1715/// A canonical 64-bit virtual memory address.
@@ -226,6 +224,42 @@ impl VirtAddr {
226224 pub const fn page_table_index ( self , level : PageTableLevel ) -> PageTableIndex {
227225 PageTableIndex :: new_truncate ( ( self . 0 >> 12 >> ( ( level as u8 - 1 ) * 9 ) ) as u16 )
228226 }
227+
228+ // FIXME: Move this into the `Step` impl, once `Step` is stabilized.
229+ pub ( crate ) fn steps_between_impl ( start : & Self , end : & Self ) -> Option < usize > {
230+ let mut steps = end. 0 . checked_sub ( start. 0 ) ?;
231+
232+ // Check if we jumped the gap.
233+ if end. 0 . get_bit ( 47 ) && !start. 0 . get_bit ( 47 ) {
234+ steps = steps. checked_sub ( 0xffff_0000_0000_0000 ) . unwrap ( ) ;
235+ }
236+
237+ usize:: try_from ( steps) . ok ( )
238+ }
239+
240+ // FIXME: Move this into the `Step` impl, once `Step` is stabilized.
241+ pub ( crate ) fn forward_checked_impl ( start : Self , count : usize ) -> Option < Self > {
242+ let offset = u64:: try_from ( count) . ok ( ) ?;
243+ if offset > ADDRESS_SPACE_SIZE {
244+ return None ;
245+ }
246+
247+ let mut addr = start. 0 . checked_add ( offset) ?;
248+
249+ match addr. get_bits ( 47 ..) {
250+ 0x1 => {
251+ // Jump the gap by sign extending the 47th bit.
252+ addr. set_bits ( 47 .., 0x1ffff ) ;
253+ }
254+ 0x2 => {
255+ // Address overflow
256+ return None ;
257+ }
258+ _ => { }
259+ }
260+
261+ Some ( Self :: new ( addr) )
262+ }
229263}
230264
231265impl fmt:: Debug for VirtAddr {
@@ -346,37 +380,11 @@ impl Sub<VirtAddr> for VirtAddr {
346380#[ cfg( feature = "step_trait" ) ]
347381impl Step for VirtAddr {
348382 fn steps_between ( start : & Self , end : & Self ) -> Option < usize > {
349- let mut steps = end. 0 . checked_sub ( start. 0 ) ?;
350-
351- // Check if we jumped the gap.
352- if end. 0 . get_bit ( 47 ) && !start. 0 . get_bit ( 47 ) {
353- steps = steps. checked_sub ( 0xffff_0000_0000_0000 ) . unwrap ( ) ;
354- }
355-
356- usize:: try_from ( steps) . ok ( )
383+ Self :: steps_between_impl ( start, end)
357384 }
358385
359386 fn forward_checked ( start : Self , count : usize ) -> Option < Self > {
360- let offset = u64:: try_from ( count) . ok ( ) ?;
361- if offset > ADDRESS_SPACE_SIZE {
362- return None ;
363- }
364-
365- let mut addr = start. 0 . checked_add ( offset) ?;
366-
367- match addr. get_bits ( 47 ..) {
368- 0x1 => {
369- // Jump the gap by sign extending the 47th bit.
370- addr. set_bits ( 47 .., 0x1ffff ) ;
371- }
372- 0x2 => {
373- // Address overflow
374- return None ;
375- }
376- _ => { }
377- }
378-
379- Some ( Self :: new ( addr) )
387+ Self :: forward_checked_impl ( start, count)
380388 }
381389
382390 fn backward_checked ( start : Self , count : usize ) -> Option < Self > {
0 commit comments