page_table/table/
pos.rs

1use crate::{VmMeta, VPN};
2use core::fmt;
3
4/// `Meta` 方案中页表上的一个位置。
5#[derive(Clone, Copy)]
6pub struct Pos<Meta: VmMeta> {
7    /// 目标页表项包含的一个虚页号。
8    pub vpn: VPN<Meta>,
9    /// 目标页表项的级别。
10    pub level: usize,
11}
12
13impl<Meta: VmMeta> Pos<Meta> {
14    /// 新建目标。
15    #[inline]
16    pub const fn new(vpn: VPN<Meta>, level: usize) -> Self {
17        Self { vpn, level }
18    }
19
20    /// 结束遍历。
21    #[inline]
22    pub const fn stop() -> Self {
23        Self {
24            vpn: VPN::ZERO,
25            level: Meta::MAX_LEVEL + 1,
26        }
27    }
28
29    /// 向前移动一页。
30    #[inline]
31    pub fn prev(self) -> Self {
32        let delta = match self.level {
33            0 => 1,
34            n => Meta::pages_in_table(n - 1),
35        };
36        match self.vpn.val().checked_sub(delta) {
37            Some(vpn) => Self {
38                vpn: VPN::new(vpn),
39                ..self
40            },
41            None => panic!("prev: vpn overflow"),
42        }
43    }
44
45    /// 向后移动一页。
46    #[inline]
47    pub fn next(self) -> Self {
48        let delta = match self.level {
49            0 => 1,
50            n => Meta::pages_in_table(n - 1),
51        };
52        match self.vpn.val().checked_add(delta) {
53            Some(vpn) => Self {
54                vpn: VPN::new(vpn),
55                ..self
56            },
57            None => panic!("next: vpn overflow"),
58        }
59    }
60
61    /// 向上移动一页。
62    #[inline]
63    pub fn up(self) -> Self {
64        match self.level.checked_add(1) {
65            Some(level) => Self { level, ..self },
66            None => panic!("up: level overflow"),
67        }
68    }
69
70    /// 向下移动一页。
71    #[inline]
72    pub fn down(self) -> Self {
73        match self.level.checked_sub(1) {
74            Some(level) => Self { level, ..self },
75            None => panic!("down: level overflow"),
76        }
77    }
78}
79
80impl<Meta: VmMeta> fmt::Debug for Pos<Meta> {
81    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82        write!(
83            f,
84            "Pos {{ vpn = {:#x}, level = {:#x} }}",
85            self.vpn.val(),
86            self.level
87        )
88    }
89}