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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
use crate::{mask, VmMeta};
use core::{
    fmt,
    marker::PhantomData,
    ops::{Add, AddAssign, Range},
};

/// 页号。
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct PageNumber<Meta: VmMeta, S: Space>(usize, PhantomData<Meta>, PhantomData<S>);

/// 地址空间标记。
pub trait Space: Clone + Copy + PartialEq + Eq + PartialOrd + Ord + fmt::Debug {}

/// 物理地址空间。
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Physical;

/// 虚地址空间。
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Virtual;

impl Space for Physical {}
impl Space for Virtual {}

impl<Meta: VmMeta, S: Space> PageNumber<Meta, S> {
    /// 页号零。
    pub const ZERO: Self = Self::new(0);

    /// 最小页号。
    pub const MIN: Self = Self::ZERO;

    /// 新建一个页号。
    #[inline]
    pub const fn new(n: usize) -> Self {
        Self(n, PhantomData, PhantomData)
    }

    /// 获取页号值。
    #[inline]
    pub const fn val(self) -> usize {
        self.0
    }
}

impl<Meta: VmMeta, S: Space> Add<usize> for PageNumber<Meta, S> {
    type Output = Self;

    #[inline]
    fn add(self, rhs: usize) -> Self {
        Self::new(self.0.wrapping_add(rhs))
    }
}

impl<Meta: VmMeta, S: Space> AddAssign<usize> for PageNumber<Meta, S> {
    #[inline]
    fn add_assign(&mut self, rhs: usize) {
        self.0 = self.0.wrapping_add(rhs);
    }
}

/// 物理页号。
pub type PPN<Meta> = PageNumber<Meta, Physical>;

/// 虚拟页号。
pub type VPN<Meta> = PageNumber<Meta, Virtual>;

impl<Meta: VmMeta> PPN<Meta> {
    /// 无效的物理页号,作为 NULL 使用。
    ///
    /// 显然,物理页号不可能和 usize 一样长,所以可以这样操作。
    pub const INVALID: Self = Self::new(1 << (Meta::P_ADDR_BITS - Meta::PAGE_BITS));

    /// 最大物理页号。
    pub const MAX: Self = Self::new(Self::INVALID.val() - 1);
}

impl<Meta: VmMeta> fmt::Debug for PPN<Meta> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "PPN({:#x})", self.0)
    }
}

impl<Meta: VmMeta> VPN<Meta> {
    /// 最大虚拟页号。
    pub const MAX: Self = Self::new(mask(Meta::V_ADDR_BITS - Meta::PAGE_BITS));

    /// 虚页的起始地址。
    #[inline]
    pub const fn base(self) -> VAddr<Meta> {
        VAddr::new(self.0 << Meta::PAGE_BITS)
    }

    /// 虚页在 `level` 级页表中的位置。
    #[inline]
    pub fn index_in(self, level: usize) -> usize {
        (self.0 >> Self::bits_until(level)) & mask(Meta::LEVEL_BITS[level])
    }

    /// 包含这个虚页的 `level` 级页表起始地址。
    #[inline]
    pub fn floor(self, level: usize) -> Self {
        let bits = Self::bits_until(level);
        Self::new(self.0 & !mask(bits))
    }

    /// 不包含这个虚页的 `level` 级页表起始地址。
    #[inline]
    pub fn ceil(self, level: usize) -> usize {
        let bits = Self::bits_until(level);
        (self.0 + mask(bits)) >> bits
    }

    /// 包含这个虚页的 `level` 级页表容纳的虚页范围。
    #[inline]
    pub fn vaddr_range(self, level: usize) -> Range<VAddr<Meta>> {
        let base = self.base();
        base..base + Meta::bytes_in_page(level)
    }

    /// 虚页的对齐级别,使虚页在页表中序号为 0 的最高等级页表的级别。
    #[inline]
    pub fn align_level(self) -> usize {
        let mut n = self.0;
        for (i, bits) in Meta::LEVEL_BITS[..Meta::MAX_LEVEL].iter().rev().enumerate() {
            if n & mask(*bits) != 0 {
                return i;
            }
            n >>= bits;
        }
        Meta::MAX_LEVEL
    }

    /// `level` 级页表中页号的总位数。
    #[inline]
    fn bits_until(level: usize) -> usize {
        Meta::LEVEL_BITS[..level].iter().sum::<usize>()
    }
}

impl<Meta: VmMeta> fmt::Debug for VPN<Meta> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "VPN({:#x})", self.0)
    }
}

/// 一个可能无效的物理页号。
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct MaybeInvalidPPN<Meta: VmMeta>(PPN<Meta>);

impl<Meta: VmMeta> MaybeInvalidPPN<Meta> {
    /// 从一个物理页号新建。
    #[inline]
    pub const fn new(n: PPN<Meta>) -> Self {
        Self(n)
    }

    /// 新建一个无效物理页号。
    #[inline]
    pub const fn invalid() -> Self {
        Self(PPN::INVALID)
    }

    /// 取出物理页号。
    #[inline]
    pub const fn get(&self) -> Option<PPN<Meta>> {
        if self.0.val() > PPN::<Meta>::MAX.val() {
            None
        } else {
            Some(self.0)
        }
    }
}

/// 虚拟地址。
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct VAddr<Meta: VmMeta>(usize, PhantomData<Meta>);

impl<Meta: VmMeta> Add<usize> for VAddr<Meta> {
    type Output = Self;

    #[inline]
    fn add(self, rhs: usize) -> Self {
        Self::new(self.0.wrapping_add(rhs))
    }
}

impl<Meta: VmMeta> AddAssign<usize> for VAddr<Meta> {
    #[inline]
    fn add_assign(&mut self, rhs: usize) {
        self.0 = self.0.wrapping_add(rhs);
    }
}

impl<Meta: VmMeta> VAddr<Meta> {
    /// 将一个地址值转换为虚拟地址意味着允许虚存方案根据实际情况裁剪地址值。
    /// 超过虚址范围的地址会被裁剪。
    #[inline]
    pub const fn new(value: usize) -> Self {
        Self(value, PhantomData)
    }

    /// 将虚地址转化为任意指针。
    ///
    /// # Safety
    ///
    /// 调用者需要确保虚地址在当前地址空间中。
    #[inline]
    pub const unsafe fn as_ptr<T>(self) -> *const T {
        self.0 as _
    }

    /// 将虚地址转化为任意可变指针。
    ///
    /// # Safety
    ///
    /// 调用者需要确保虚地址在当前地址空间中。
    #[inline]
    pub unsafe fn as_mut_ptr<T>(self) -> *mut T {
        self.0 as _
    }

    /// 虚地址值。
    #[inline]
    pub const fn val(self) -> usize {
        self.0
    }

    /// 包括这个虚地址最后页的页号。
    #[inline]
    pub const fn floor(self) -> VPN<Meta> {
        VPN::new(self.0 >> Meta::PAGE_BITS)
    }

    /// 不包括这个虚地址的最前页的页号。
    #[inline]
    pub const fn ceil(self) -> VPN<Meta> {
        VPN::new((self.0 + mask(Meta::PAGE_BITS)) >> Meta::PAGE_BITS)
    }
}

impl<Meta: VmMeta> From<usize> for VAddr<Meta> {
    #[inline]
    fn from(value: usize) -> Self {
        Self::new(value)
    }
}

impl<Meta: VmMeta, T> From<&T> for VAddr<Meta> {
    #[inline]
    fn from(value: &T) -> Self {
        Self::new(value as *const _ as _)
    }
}

impl<Meta: VmMeta> fmt::Debug for VAddr<Meta> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "VAddr({:#x})", self.0)
    }
}

#[test]
fn test_index_in() {
    use crate::test_meta::Sv39;

    for i in 0..=Sv39::MAX_LEVEL {
        let vpn = VPN::<Sv39>::new(1 << (i * 9));
        for j in 0..=Sv39::MAX_LEVEL {
            assert_eq!(vpn.index_in(j), if i == j { 1 } else { 0 });
        }
    }
}

#[test]
fn test_align_level() {
    use crate::test_meta::Sv39;

    assert_eq!(VPN::<Sv39>::new(1).align_level(), 0);
    assert_eq!(VPN::<Sv39>::new(1 << 9).align_level(), 1);
    assert_eq!(VPN::<Sv39>::new(1 << 18).align_level(), 2);
    assert_eq!(VPN::<Sv39>::new(0).align_level(), 2);
}