kernel_vmem/
page_table.rs

1//! # Memory Page Table
2
3pub mod pd;
4pub mod pdpt;
5pub mod pml4;
6pub mod pt;
7
8use crate::addresses::VirtualAddress;
9use crate::page_table::pd::L2Index;
10use crate::page_table::pdpt::L3Index;
11use crate::page_table::pml4::L4Index;
12use crate::page_table::pt::L1Index;
13
14/// Hardware **Present** bit position shared across levels (bit 0).
15const PRESENT_BIT: u64 = 1 << 0;
16
17/// Hardware **Page Size** (PS) bit position shared across levels (bit 7).
18///
19/// - In non-leaf entries: PS **must be 0**.
20/// - In large leaf entries (L3 1 GiB / L2 2 MiB): PS **must be 1**.
21/// - In L1 4 KiB PTEs: bit 7 is **PAT** (not PS).
22const PS_BIT: u64 = 1 << 7;
23
24#[inline]
25#[must_use]
26pub const fn split_indices(va: VirtualAddress) -> (L4Index, L3Index, L2Index, L1Index) {
27    (
28        L4Index::from(va),
29        L3Index::from(va),
30        L2Index::from(va),
31        L1Index::from(va),
32    )
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    #[test]
40    fn indices_ok() {
41        let va = VirtualAddress::new(0xFFFF_8888_0123_4567);
42        let (i4, i3, i2, i1) = split_indices(va);
43        assert!(i4.as_usize() < 512);
44        assert!(i3.as_usize() < 512);
45        assert!(i2.as_usize() < 512);
46        assert!(i1.as_usize() < 512);
47    }
48}