@@ -5,58 +5,49 @@ use x86_64::{
5
5
PhysAddr ,
6
6
} ;
7
7
8
- // Keep in sync with address_space_gib in layout.ld
8
+ // This is the number of GiB we will identity map.
9
9
const ADDRESS_SPACE_GIB : usize = 4 ;
10
10
11
- pub static MANAGER : AtomicRefCell < Manager > = AtomicRefCell :: new ( Manager ) ;
12
- pub struct Manager ;
13
-
14
- extern "C" {
15
- static mut pml4t: PageTable ;
16
- static mut pml3t: PageTable ;
17
- static mut pml2ts: [ PageTable ; ADDRESS_SPACE_GIB ] ;
18
- }
19
-
20
- struct Tables < ' a > {
21
- l4 : & ' a mut PageTable ,
22
- l3 : & ' a mut PageTable ,
23
- l2s : & ' a mut [ PageTable ] ,
11
+ pub static MANAGER : AtomicRefCell < Manager > = AtomicRefCell :: new ( Manager :: new ( ) ) ;
12
+ pub struct Manager {
13
+ l4 : PageTable ,
14
+ l3 : PageTable ,
15
+ l2s : [ PageTable ; ADDRESS_SPACE_GIB ] ,
24
16
}
25
17
26
18
impl Manager {
27
- fn tables ( & mut self ) -> Tables {
28
- Tables {
29
- l4 : unsafe { & mut pml4t } ,
30
- l3 : unsafe { & mut pml3t } ,
31
- l2s : unsafe { & mut pml2ts } ,
19
+ const fn new ( ) -> Self {
20
+ Manager {
21
+ l4 : PageTable :: new ( ) ,
22
+ l3 : PageTable :: new ( ) ,
23
+ l2s : [ PageTable :: new ( ) ; ADDRESS_SPACE_GIB ] ,
32
24
}
33
25
}
34
26
35
27
pub fn setup ( & mut self ) {
36
28
log ! ( "Setting up {} GiB identity mapping" , ADDRESS_SPACE_GIB ) ;
37
- let Tables { l4, l3, l2s } = self . tables ( ) ;
38
29
39
30
let pt_flags = PageTableFlags :: PRESENT | PageTableFlags :: WRITABLE ;
40
31
// Setup Identity map using L2 huge pages
41
32
let mut next_addr = PhysAddr :: new ( 0 ) ;
42
- for l2 in l2s. iter_mut ( ) {
33
+ for l2 in self . l2s . iter_mut ( ) {
43
34
for l2e in l2. iter_mut ( ) {
44
35
l2e. set_addr ( next_addr, pt_flags | PageTableFlags :: HUGE_PAGE ) ;
45
36
next_addr += Size2MiB :: SIZE ;
46
37
}
47
38
}
48
39
49
40
// Point L3 at L2s
50
- for ( i, l2) in l2s. iter ( ) . enumerate ( ) {
51
- l3[ i] . set_addr ( phys_addr ( l2) , pt_flags) ;
41
+ for ( i, l2) in self . l2s . iter ( ) . enumerate ( ) {
42
+ self . l3 [ i] . set_addr ( phys_addr ( l2) , pt_flags) ;
52
43
}
53
44
54
45
// Point L4 at L3
55
- l4[ 0 ] . set_addr ( phys_addr ( l3) , pt_flags) ;
46
+ self . l4 [ 0 ] . set_addr ( phys_addr ( & self . l3 ) , pt_flags) ;
56
47
57
48
// Point Cr3 at PML4
58
49
let cr3_flags = Cr3 :: read ( ) . 1 ;
59
- let pml4t_frame = PhysFrame :: from_start_address ( phys_addr ( l4) ) . unwrap ( ) ;
50
+ let pml4t_frame = PhysFrame :: from_start_address ( phys_addr ( & self . l4 ) ) . unwrap ( ) ;
60
51
unsafe { Cr3 :: write ( pml4t_frame, cr3_flags) } ;
61
52
log ! ( "Page tables setup" ) ;
62
53
}
0 commit comments