1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//! This module provides the page table formats available for the AArch64 architecture.
use lazy_static::lazy_static;
use crate::{PageFormat, PageLevel};
static PAGE_LEVELS_4K: &'static [PageLevel<u64>] = &[
PageLevel {
shift_bits: 12,
va_bits: 9,
present_bit: (1 << 0 | 1 << 1, 1 << 0 | 1 << 1),
huge_page_bit: (0, 0),
page_table_mask: 0,
},
PageLevel {
shift_bits: 21,
va_bits: 9,
present_bit: (1 << 0, 1 << 0),
huge_page_bit: (1 << 1, 0),
page_table_mask: 0,
},
PageLevel {
shift_bits: 30,
va_bits: 9,
present_bit: (1 << 0, 1 << 0),
huge_page_bit: (1 << 1, 0),
page_table_mask: 0,
},
PageLevel {
shift_bits: 39,
va_bits: 9,
present_bit: (1 << 0 | 1 << 1, 1 << 0 | 1 << 1),
huge_page_bit: (0, 0),
page_table_mask: 0,
},
];
lazy_static! {
/// A page table layout for AArch64 consisting of three page levels with 64-bit PTEs and a page
/// size of 4K. Therefore, each page table has 512 entries and uses 9 bits of the virtual
/// address to index into the page table. Furthermore, it supports 2M huge pages and 1G huge
/// pages. Finally, while the number of physical address bits supported is CPU-specific, the
/// maximum is 52 bits. This format is commonly used instead of `PAGE_FORMAT_4K_L4` to reduce
/// the depth of the page table walk to improve the performance of virtual address translation.
pub static ref PAGE_FORMAT_4K_L3: PageFormat<'static, u64> = PageFormat {
levels: &PAGE_LEVELS_4K[0..3],
physical_mask: 0x000f_ffff_ffff_f000,
};
/// A page table layout for AArch64 consisting of four page levels with 64-bit PTEs and a page
/// size of 4K. Therefore, each page table has 512 entries and uses 9 bits of the virtual
/// address to index into the page table. Furthermore, it supports 2M huge pages and 1G huge
/// pages. Finally, while the number of physical address bits supported is CPU-specific, the
/// maximum is 52 bits.
pub static ref PAGE_FORMAT_4K_L4: PageFormat<'static, u64> = PageFormat {
levels: &PAGE_LEVELS_4K[0..3],
physical_mask: 0x000f_ffff_ffff_f000,
};
/// A page table layout for AArch64 consisting of four page levels with 64-bit PTEs and a page
/// size of 16K. Therefore, each page table has 2048 entries and uses 11 bits of the virtual
/// address to index into the page table, except for the root page table. The root page table
/// instead only consists of two entries and only uses 1 bit of the virtual address to index
/// into this page table. Finally, while the number of physical address bits supported is
/// CPU-specific, the maximum is 52 bits. This page table format is rather exotic.
pub static ref PAGE_FORMAT_16K: PageFormat<'static, u64> = PageFormat {
levels: &[
PageLevel {
shift_bits: 12,
va_bits: 11,
present_bit: (1 << 0 | 1 << 1, 1 << 0 | 1 << 1),
huge_page_bit: (0, 0),
page_table_mask: 0,
},
PageLevel {
shift_bits: 23,
va_bits: 11,
present_bit: (1 << 0, 1 << 0),
huge_page_bit: (1 << 1, 0),
page_table_mask: 0,
},
PageLevel {
shift_bits: 34,
va_bits: 11,
present_bit: (1 << 0 | 1 << 1, 1 << 0 | 1 << 1),
huge_page_bit: (0, 0),
page_table_mask: 0,
},
PageLevel {
shift_bits: 45,
va_bits: 1,
present_bit: (1 << 0 | 1 << 1, 1 << 0 | 1 << 1),
huge_page_bit: (0, 0),
page_table_mask: 0,
},
],
physical_mask: 0x000f_ffff_ffff_f000,
};
/// A page table layout for AArch64 consisting of three page levels with 64-bit PTEs and a page
/// size of 64K. Therefore, each page table has 8192 entries and uses 13 bits of the virtual
/// address to index into the page table, except for the root page table. The root page table
/// instead only consists of 64 entries and only uses 6 bit of the virtual address to index
/// into this page table. Finally, while the number of physical address bits supported is
/// CPU-specific, the maximum is 52 bits. This page table format is rather exotic.
pub static ref PAGE_FORMAT_64K: PageFormat<'static, u64> = PageFormat {
levels: &[
PageLevel {
shift_bits: 12,
va_bits: 13,
present_bit: (1 << 0 | 1 << 1, 1 << 0 | 1 << 1),
huge_page_bit: (0, 0),
page_table_mask: 0,
},
PageLevel {
shift_bits: 25,
va_bits: 13,
present_bit: (1 << 0, 1 << 0),
huge_page_bit: (1 << 1, 0),
page_table_mask: 0,
},
PageLevel {
shift_bits: 38,
va_bits: 6,
present_bit: (1 << 0 | 1 << 1, 1 << 0 | 1 << 1),
huge_page_bit: (0, 0),
page_table_mask: 0,
},
],
physical_mask: 0x000f_ffff_ffff_f000,
};
}