page_table/
addr.rs

1use crate::{mask, VmMeta};
2use core::{
3    fmt,
4    marker::PhantomData,
5    ops::{Add, AddAssign, Range},
6};
7
8/// 页号。
9#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10#[repr(transparent)]
11pub struct PageNumber<Meta: VmMeta, S: Space>(usize, PhantomData<Meta>, PhantomData<S>);
12
13/// 地址空间标记。
14pub trait Space: Clone + Copy + PartialEq + Eq + PartialOrd + Ord + fmt::Debug {}
15
16/// 物理地址空间。
17#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
18pub struct Physical;
19
20/// 虚地址空间。
21#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
22pub struct Virtual;
23
24impl Space for Physical {}
25impl Space for Virtual {}
26
27impl<Meta: VmMeta, S: Space> PageNumber<Meta, S> {
28    /// 页号零。
29    pub const ZERO: Self = Self::new(0);
30
31    /// 最小页号。
32    pub const MIN: Self = Self::ZERO;
33
34    /// 新建一个页号。
35    #[inline]
36    pub const fn new(n: usize) -> Self {
37        Self(n, PhantomData, PhantomData)
38    }
39
40    /// 获取页号值。
41    #[inline]
42    pub const fn val(self) -> usize {
43        self.0
44    }
45}
46
47impl<Meta: VmMeta, S: Space> Add<usize> for PageNumber<Meta, S> {
48    type Output = Self;
49
50    #[inline]
51    fn add(self, rhs: usize) -> Self {
52        Self::new(self.0.wrapping_add(rhs))
53    }
54}
55
56impl<Meta: VmMeta, S: Space> AddAssign<usize> for PageNumber<Meta, S> {
57    #[inline]
58    fn add_assign(&mut self, rhs: usize) {
59        self.0 = self.0.wrapping_add(rhs);
60    }
61}
62
63/// 物理页号。
64pub type PPN<Meta> = PageNumber<Meta, Physical>;
65
66/// 虚拟页号。
67pub type VPN<Meta> = PageNumber<Meta, Virtual>;
68
69impl<Meta: VmMeta> PPN<Meta> {
70    /// 无效的物理页号,作为 NULL 使用。
71    ///
72    /// 显然,物理页号不可能和 usize 一样长,所以可以这样操作。
73    pub const INVALID: Self = Self::new(1 << (Meta::P_ADDR_BITS - Meta::PAGE_BITS));
74
75    /// 最大物理页号。
76    pub const MAX: Self = Self::new(Self::INVALID.val() - 1);
77}
78
79impl<Meta: VmMeta> fmt::Debug for PPN<Meta> {
80    #[inline]
81    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82        write!(f, "PPN({:#x})", self.0)
83    }
84}
85
86impl<Meta: VmMeta> VPN<Meta> {
87    /// 最大虚拟页号。
88    pub const MAX: Self = Self::new(mask(Meta::V_ADDR_BITS - Meta::PAGE_BITS));
89
90    /// 虚页的起始地址。
91    #[inline]
92    pub const fn base(self) -> VAddr<Meta> {
93        VAddr::new(self.0 << Meta::PAGE_BITS)
94    }
95
96    /// 虚页在 `level` 级页表中的位置。
97    #[inline]
98    pub fn index_in(self, level: usize) -> usize {
99        (self.0 >> Self::bits_until(level)) & mask(Meta::LEVEL_BITS[level])
100    }
101
102    /// 包含这个虚页的 `level` 级页表起始地址。
103    #[inline]
104    pub fn floor(self, level: usize) -> Self {
105        let bits = Self::bits_until(level);
106        Self::new(self.0 & !mask(bits))
107    }
108
109    /// 不包含这个虚页的 `level` 级页表起始地址。
110    #[inline]
111    pub fn ceil(self, level: usize) -> usize {
112        let bits = Self::bits_until(level);
113        (self.0 + mask(bits)) >> bits
114    }
115
116    /// 包含这个虚页的 `level` 级页表容纳的虚页范围。
117    #[inline]
118    pub fn vaddr_range(self, level: usize) -> Range<VAddr<Meta>> {
119        let base = self.base();
120        base..base + Meta::bytes_in_page(level)
121    }
122
123    /// 虚页的对齐级别,使虚页在页表中序号为 0 的最高等级页表的级别。
124    #[inline]
125    pub fn align_level(self) -> usize {
126        let mut n = self.0;
127        for (i, bits) in Meta::LEVEL_BITS[..Meta::MAX_LEVEL].iter().rev().enumerate() {
128            if n & mask(*bits) != 0 {
129                return i;
130            }
131            n >>= bits;
132        }
133        Meta::MAX_LEVEL
134    }
135
136    /// `level` 级页表中页号的总位数。
137    #[inline]
138    fn bits_until(level: usize) -> usize {
139        Meta::LEVEL_BITS[..level].iter().sum::<usize>()
140    }
141}
142
143impl<Meta: VmMeta> fmt::Debug for VPN<Meta> {
144    #[inline]
145    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146        write!(f, "VPN({:#x})", self.0)
147    }
148}
149
150/// 一个可能无效的物理页号。
151#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
152#[repr(transparent)]
153pub struct MaybeInvalidPPN<Meta: VmMeta>(PPN<Meta>);
154
155impl<Meta: VmMeta> MaybeInvalidPPN<Meta> {
156    /// 从一个物理页号新建。
157    #[inline]
158    pub const fn new(n: PPN<Meta>) -> Self {
159        Self(n)
160    }
161
162    /// 新建一个无效物理页号。
163    #[inline]
164    pub const fn invalid() -> Self {
165        Self(PPN::INVALID)
166    }
167
168    /// 取出物理页号。
169    #[inline]
170    pub const fn get(&self) -> Option<PPN<Meta>> {
171        if self.0.val() > PPN::<Meta>::MAX.val() {
172            None
173        } else {
174            Some(self.0)
175        }
176    }
177}
178
179/// 虚拟地址。
180#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
181#[repr(transparent)]
182pub struct VAddr<Meta: VmMeta>(usize, PhantomData<Meta>);
183
184impl<Meta: VmMeta> Add<usize> for VAddr<Meta> {
185    type Output = Self;
186
187    #[inline]
188    fn add(self, rhs: usize) -> Self {
189        Self::new(self.0.wrapping_add(rhs))
190    }
191}
192
193impl<Meta: VmMeta> AddAssign<usize> for VAddr<Meta> {
194    #[inline]
195    fn add_assign(&mut self, rhs: usize) {
196        self.0 = self.0.wrapping_add(rhs);
197    }
198}
199
200impl<Meta: VmMeta> VAddr<Meta> {
201    const IGNORED_MASK: usize = mask(Meta::V_ADDR_BITS - 1);
202
203    /// 将一个地址值转换为虚拟地址意味着允许虚存方案根据实际情况裁剪地址值。
204    /// 超过虚址范围的地址会被裁剪。
205    #[inline]
206    pub const fn new(value: usize) -> Self {
207        Self(value & mask(Meta::V_ADDR_BITS), PhantomData)
208    }
209
210    /// 虚地址值。
211    #[inline]
212    pub const fn val(self) -> usize {
213        if self.0 <= Self::IGNORED_MASK {
214            self.0
215        } else {
216            self.0 | !Self::IGNORED_MASK
217        }
218    }
219
220    /// 将虚地址转化为任意指针。
221    ///
222    /// # Safety
223    ///
224    /// 调用者需要确保虚地址在当前地址空间中。
225    #[inline]
226    pub const unsafe fn as_ptr<T>(self) -> *const T {
227        self.val() as _
228    }
229
230    /// 将虚地址转化为任意可变指针。
231    ///
232    /// # Safety
233    ///
234    /// 调用者需要确保虚地址在当前地址空间中。
235    #[inline]
236    pub unsafe fn as_mut_ptr<T>(self) -> *mut T {
237        self.val() as _
238    }
239
240    /// 包括这个虚地址最后页的页号。
241    #[inline]
242    pub const fn floor(self) -> VPN<Meta> {
243        VPN::new(self.0 >> Meta::PAGE_BITS)
244    }
245
246    /// 不包括这个虚地址的最前页的页号。
247    #[inline]
248    pub const fn ceil(self) -> VPN<Meta> {
249        VPN::new((self.0 + mask(Meta::PAGE_BITS)) >> Meta::PAGE_BITS)
250    }
251
252    /// 页内偏移。
253    #[inline]
254    pub const fn offset(self) -> usize {
255        self.0 & mask(Meta::PAGE_BITS)
256    }
257}
258
259impl<Meta: VmMeta> From<usize> for VAddr<Meta> {
260    #[inline]
261    fn from(value: usize) -> Self {
262        Self::new(value)
263    }
264}
265
266impl<Meta: VmMeta, T> From<&T> for VAddr<Meta> {
267    #[inline]
268    fn from(value: &T) -> Self {
269        Self::new(value as *const _ as _)
270    }
271}
272
273impl<Meta: VmMeta> fmt::Debug for VAddr<Meta> {
274    #[inline]
275    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
276        write!(f, "VAddr({:#x})", self.0)
277    }
278}
279
280#[test]
281fn test_index_in() {
282    use crate::test_meta::Sv39;
283
284    for i in 0..=Sv39::MAX_LEVEL {
285        let vpn = VPN::<Sv39>::new(1 << (i * 9));
286        for j in 0..=Sv39::MAX_LEVEL {
287            assert_eq!(vpn.index_in(j), if i == j { 1 } else { 0 });
288        }
289    }
290}
291
292#[test]
293fn test_align_level() {
294    use crate::test_meta::Sv39;
295
296    assert_eq!(VPN::<Sv39>::new(1).align_level(), 0);
297    assert_eq!(VPN::<Sv39>::new(1 << 9).align_level(), 1);
298    assert_eq!(VPN::<Sv39>::new(1 << 18).align_level(), 2);
299    assert_eq!(VPN::<Sv39>::new(0).align_level(), 2);
300}