1mod fmt;
2mod pos;
3mod visit;
4
5use crate::{Pte, VmMeta, VPN};
6use core::{
7 ops::{Index, IndexMut, Range},
8 ptr::NonNull,
9};
10use visit::{walk_inner, walk_inner_mut};
11
12pub use fmt::PageTableFormatter;
13pub use pos::Pos;
14pub use visit::{Decorator, Update, Visitor};
15
16pub struct PageTable<Meta: VmMeta> {
20 mem: &'static mut [Pte<Meta>],
21 base: VPN<Meta>,
22 level: usize,
23}
24
25impl<Meta: VmMeta> PageTable<Meta> {
26 #[inline]
32 pub unsafe fn from_raw_parts(ptr: NonNull<Pte<Meta>>, base: VPN<Meta>, level: usize) -> Self {
33 Self {
34 mem: core::slice::from_raw_parts_mut(ptr.as_ptr(), 1 << Meta::LEVEL_BITS[level]),
36 base: base.floor(level),
37 level,
38 }
39 }
40
41 #[inline]
47 pub unsafe fn from_root(root: NonNull<Pte<Meta>>) -> Self {
48 Self::from_raw_parts(root, VPN::ZERO, Meta::MAX_LEVEL)
49 }
50
51 #[inline]
53 pub const fn as_ptr(&self) -> *const Pte<Meta> {
54 self.mem.as_ptr()
55 }
56
57 #[inline]
59 pub const fn level(&self) -> usize {
60 self.level
61 }
62
63 #[inline]
65 pub fn range(&self) -> Range<VPN<Meta>> {
66 self.base..self.base + Meta::pages_in_table(self.level)
67 }
68
69 #[inline]
71 pub fn walk(&self, mut target: Pos<Meta>, visitor: &mut impl Visitor<Meta>) {
72 walk_inner(self, visitor, &mut target);
73 }
74
75 #[inline]
77 pub fn walk_mut(&mut self, mut target: Pos<Meta>, visitor: &mut impl Decorator<Meta>) {
78 walk_inner_mut(self, visitor, &mut target);
79 }
80}
81
82impl<Meta: VmMeta> Index<usize> for PageTable<Meta> {
83 type Output = Pte<Meta>;
84
85 #[inline]
86 fn index(&self, index: usize) -> &Self::Output {
87 &self.mem[index]
88 }
89}
90
91impl<Meta: VmMeta> IndexMut<usize> for PageTable<Meta> {
92 #[inline]
93 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
94 &mut self.mem[index]
95 }
96}