1
1
//! Physical and virtual addresses manipulation
2
2
3
- #[ cfg( feature = "step_trait" ) ]
4
3
use core:: convert:: TryFrom ;
5
4
use core:: fmt;
6
5
#[ cfg( feature = "step_trait" ) ]
@@ -11,7 +10,6 @@ use crate::structures::paging::page_table::PageTableLevel;
11
10
use crate :: structures:: paging:: { PageOffset , PageTableIndex } ;
12
11
use bit_field:: BitField ;
13
12
14
- #[ cfg( feature = "step_trait" ) ]
15
13
const ADDRESS_SPACE_SIZE : u64 = 0x1_0000_0000_0000 ;
16
14
17
15
/// A canonical 64-bit virtual memory address.
@@ -226,6 +224,42 @@ impl VirtAddr {
226
224
pub const fn page_table_index ( self , level : PageTableLevel ) -> PageTableIndex {
227
225
PageTableIndex :: new_truncate ( ( self . 0 >> 12 >> ( ( level as u8 - 1 ) * 9 ) ) as u16 )
228
226
}
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
+ }
229
263
}
230
264
231
265
impl fmt:: Debug for VirtAddr {
@@ -346,37 +380,11 @@ impl Sub<VirtAddr> for VirtAddr {
346
380
#[ cfg( feature = "step_trait" ) ]
347
381
impl Step for VirtAddr {
348
382
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)
357
384
}
358
385
359
386
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)
380
388
}
381
389
382
390
fn backward_checked ( start : Self , count : usize ) -> Option < Self > {
0 commit comments