3
3
use core:: fmt;
4
4
use core:: ops:: { Add , AddAssign , Sub , SubAssign } ;
5
5
6
+ use crate :: structures:: paging:: page_table:: PageTableLevel ;
6
7
use crate :: structures:: paging:: { PageOffset , PageTableIndex } ;
7
8
use bit_field:: BitField ;
8
9
@@ -16,7 +17,7 @@ use bit_field::BitField;
16
17
/// On `x86_64`, only the 48 lower bits of a virtual address can be used. The top 16 bits need
17
18
/// to be copies of bit 47, i.e. the most significant bit. Addresses that fulfil this criterium
18
19
/// are called “canonical”. This type guarantees that it always represents a canonical address.
19
- #[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord ) ]
20
+ #[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
20
21
#[ repr( transparent) ]
21
22
pub struct VirtAddr ( u64 ) ;
22
23
@@ -29,7 +30,7 @@ pub struct VirtAddr(u64);
29
30
///
30
31
/// On `x86_64`, only the 52 lower bits of a physical address can be used. The top 12 bits need
31
32
/// to be zero. This type guarantees that it always represents a valid physical address.
32
- #[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord ) ]
33
+ #[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
33
34
#[ repr( transparent) ]
34
35
pub struct PhysAddr ( u64 ) ;
35
36
@@ -198,6 +199,12 @@ impl VirtAddr {
198
199
pub const fn p4_index ( self ) -> PageTableIndex {
199
200
PageTableIndex :: new_truncate ( ( self . 0 >> 12 >> 9 >> 9 >> 9 ) as u16 )
200
201
}
202
+
203
+ /// Returns the 9-bit level page table index.
204
+ #[ inline]
205
+ pub const fn page_table_index ( self , level : PageTableLevel ) -> PageTableIndex {
206
+ PageTableIndex :: new_truncate ( ( self . 0 >> 12 >> ( ( level as u8 - 1 ) * 9 ) ) as u16 )
207
+ }
201
208
}
202
209
203
210
impl fmt:: Debug for VirtAddr {
@@ -537,7 +544,7 @@ impl Sub<PhysAddr> for PhysAddr {
537
544
/// feature, the panic message will be "index out of bounds".
538
545
#[ inline]
539
546
pub const fn align_down ( addr : u64 , align : u64 ) -> u64 {
540
- const_assert ! ( align. is_power_of_two( ) , "`align` must be a power of two" ) ;
547
+ assert ! ( align. is_power_of_two( ) , "`align` must be a power of two" ) ;
541
548
addr & !( align - 1 )
542
549
}
543
550
@@ -549,7 +556,7 @@ pub const fn align_down(addr: u64, align: u64) -> u64 {
549
556
/// feature, the panic message will be "index out of bounds".
550
557
#[ inline]
551
558
pub const fn align_up ( addr : u64 , align : u64 ) -> u64 {
552
- const_assert ! ( align. is_power_of_two( ) , "`align` must be a power of two" ) ;
559
+ assert ! ( align. is_power_of_two( ) , "`align` must be a power of two" ) ;
553
560
let align_mask = align - 1 ;
554
561
if addr & align_mask == 0 {
555
562
addr // already aligned
0 commit comments