xref: /DragonOS/kernel/src/mm/allocator/page_frame.rs (revision d46c6d27941a26de14f55a2bbf956219bcc70871)
1 use core::{
2     intrinsics::unlikely,
3     ops::{Add, AddAssign, Mul, Sub, SubAssign},
4 };
5 
6 use crate::{
7     arch::{mm::LockedFrameAllocator, MMArch},
8     mm::{MemoryManagementArch, PhysAddr, VirtAddr},
9 };
10 
11 /// @brief 物理页帧的表示
12 #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
13 pub struct PhysPageFrame {
14     /// 物理页页号
15     number: usize,
16 }
17 
18 #[allow(dead_code)]
19 impl PhysPageFrame {
20     pub fn new(paddr: PhysAddr) -> Self {
21         return Self {
22             number: paddr.data() / MMArch::PAGE_SIZE,
23         };
24     }
25 
26     /// 从物理页号创建PhysPageFrame结构体
27     pub fn from_ppn(ppn: usize) -> Self {
28         return Self { number: ppn };
29     }
30 
31     /// 获取当前页对应的物理页号
32     pub fn ppn(&self) -> usize {
33         return self.number;
34     }
35 
36     /// @brief 获取当前页对应的物理地址
37     pub fn phys_address(&self) -> PhysAddr {
38         return PhysAddr::new(self.number * MMArch::PAGE_SIZE);
39     }
40 
41     pub fn next_by(&self, n: usize) -> Self {
42         return Self {
43             number: self.number + n,
44         };
45     }
46 
47     pub fn next(&self) -> Self {
48         return self.next_by(1);
49     }
50 
51     /// 构造物理页帧的迭代器,范围为[start, end)
52     pub fn iter_range(start: Self, end: Self) -> PhysPageFrameIter {
53         return PhysPageFrameIter::new(start, end);
54     }
55 }
56 
57 /// @brief 物理页帧的迭代器
58 #[derive(Debug)]
59 pub struct PhysPageFrameIter {
60     current: PhysPageFrame,
61     /// 结束的物理页帧(不包含)
62     end: PhysPageFrame,
63 }
64 
65 impl PhysPageFrameIter {
66     pub fn new(start: PhysPageFrame, end: PhysPageFrame) -> Self {
67         return Self {
68             current: start,
69             end,
70         };
71     }
72 }
73 
74 impl Iterator for PhysPageFrameIter {
75     type Item = PhysPageFrame;
76 
77     fn next(&mut self) -> Option<Self::Item> {
78         if unlikely(self.current == self.end) {
79             return None;
80         }
81         let current = self.current.next();
82         return Some(current);
83     }
84 }
85 
86 /// 虚拟页帧的表示
87 #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
88 pub struct VirtPageFrame {
89     /// 虚拟页页号
90     number: usize,
91 }
92 
93 impl VirtPageFrame {
94     pub fn new(vaddr: VirtAddr) -> Self {
95         return Self {
96             number: vaddr.data() / MMArch::PAGE_SIZE,
97         };
98     }
99 
100     /// 从虚拟页号创建PhysPageFrame结构体
101     #[allow(dead_code)]
102     pub fn from_vpn(vpn: usize) -> Self {
103         return Self { number: vpn };
104     }
105 
106     /// 获取当前虚拟页对应的虚拟地址
107     pub fn virt_address(&self) -> VirtAddr {
108         return VirtAddr::new(self.number * MMArch::PAGE_SIZE);
109     }
110 
111     pub fn next_by(&self, n: usize) -> Self {
112         return Self {
113             number: self.number + n,
114         };
115     }
116 
117     pub fn next(&self) -> Self {
118         return self.next_by(1);
119     }
120 
121     /// 构造虚拟页帧的迭代器,范围为[start, end)
122     pub fn iter_range(start: Self, end: Self) -> VirtPageFrameIter {
123         return VirtPageFrameIter {
124             current: start,
125             end,
126         };
127     }
128 
129     pub fn add(&self, n: PageFrameCount) -> Self {
130         return Self {
131             number: self.number + n.data(),
132         };
133     }
134 }
135 
136 /// 虚拟页帧的迭代器
137 #[derive(Debug)]
138 pub struct VirtPageFrameIter {
139     current: VirtPageFrame,
140     /// 结束的虚拟页帧(不包含)
141     end: VirtPageFrame,
142 }
143 
144 impl VirtPageFrameIter {
145     /// @brief 构造虚拟页帧的迭代器,范围为[start, end)
146     pub fn new(start: VirtPageFrame, end: VirtPageFrame) -> Self {
147         return Self {
148             current: start,
149             end,
150         };
151     }
152 }
153 
154 impl Iterator for VirtPageFrameIter {
155     type Item = VirtPageFrame;
156 
157     fn next(&mut self) -> Option<Self::Item> {
158         if unlikely(self.current == self.end) {
159             return None;
160         }
161         let current: VirtPageFrame = self.current;
162         self.current = self.current.next_by(1);
163         return Some(current);
164     }
165 }
166 
167 /// 页帧使用的数量
168 #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
169 #[repr(transparent)]
170 pub struct PageFrameCount(usize);
171 
172 impl PageFrameCount {
173     // @brief 初始化PageFrameCount
174     pub const fn new(count: usize) -> Self {
175         return Self(count);
176     }
177     // @brief 获取页帧数量
178     pub fn data(&self) -> usize {
179         return self.0;
180     }
181 
182     /// 计算这一段页帧占用的字节数
183     pub fn bytes(&self) -> usize {
184         return self.0 * MMArch::PAGE_SIZE;
185     }
186 
187     /// 将字节数转换为页帧数量
188     ///
189     /// 如果字节数不是页帧大小的整数倍,则返回None. 否则返回页帧数量
190     pub fn from_bytes(bytes: usize) -> Option<Self> {
191         if bytes & MMArch::PAGE_OFFSET_MASK != 0 {
192             return None;
193         } else {
194             return Some(Self(bytes / MMArch::PAGE_SIZE));
195         }
196     }
197 }
198 
199 impl Add for PageFrameCount {
200     type Output = Self;
201 
202     fn add(self, rhs: Self) -> Self::Output {
203         return Self(self.0 + rhs.0);
204     }
205 }
206 
207 impl AddAssign for PageFrameCount {
208     fn add_assign(&mut self, rhs: Self) {
209         self.0 += rhs.0;
210     }
211 }
212 
213 impl Sub for PageFrameCount {
214     type Output = Self;
215 
216     fn sub(self, rhs: Self) -> Self::Output {
217         return Self(self.0 - rhs.0);
218     }
219 }
220 
221 impl SubAssign for PageFrameCount {
222     fn sub_assign(&mut self, rhs: Self) {
223         self.0 -= rhs.0;
224     }
225 }
226 
227 impl Mul for PageFrameCount {
228     type Output = Self;
229 
230     fn mul(self, rhs: Self) -> Self::Output {
231         return Self(self.0 * rhs.0);
232     }
233 }
234 
235 impl Add<usize> for PageFrameCount {
236     type Output = Self;
237 
238     fn add(self, rhs: usize) -> Self::Output {
239         return Self(self.0 + rhs);
240     }
241 }
242 
243 impl AddAssign<usize> for PageFrameCount {
244     fn add_assign(&mut self, rhs: usize) {
245         self.0 += rhs;
246     }
247 }
248 
249 impl Sub<usize> for PageFrameCount {
250     type Output = Self;
251 
252     fn sub(self, rhs: usize) -> Self::Output {
253         return Self(self.0 - rhs);
254     }
255 }
256 
257 impl SubAssign<usize> for PageFrameCount {
258     fn sub_assign(&mut self, rhs: usize) {
259         self.0 -= rhs;
260     }
261 }
262 
263 impl Mul<usize> for PageFrameCount {
264     type Output = Self;
265 
266     fn mul(self, rhs: usize) -> Self::Output {
267         return Self(self.0 * rhs);
268     }
269 }
270 
271 // 页帧使用情况
272 #[derive(Debug)]
273 pub struct PageFrameUsage {
274     used: PageFrameCount,
275     total: PageFrameCount,
276 }
277 
278 #[allow(dead_code)]
279 impl PageFrameUsage {
280     /// @brief:  初始化FrameUsage
281     /// @param PageFrameCount used 已使用的页帧数量
282     /// @param PageFrameCount total 总的页帧数量
283     pub fn new(used: PageFrameCount, total: PageFrameCount) -> Self {
284         return Self { used, total };
285     }
286     // @brief 获取已使用的页帧数量
287     pub fn used(&self) -> PageFrameCount {
288         return self.used;
289     }
290     // @brief 获取空闲的页帧数量
291     pub fn free(&self) -> PageFrameCount {
292         return self.total - self.used;
293     }
294     // @brief 获取总的页帧数量
295     pub fn total(&self) -> PageFrameCount {
296         return self.total;
297     }
298 }
299 
300 /// 能够分配页帧的分配器需要实现的trait
301 pub trait FrameAllocator {
302     // @brief 分配count个页帧
303     unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)>;
304 
305     // @brief 通过地址释放count个页帧
306     unsafe fn free(&mut self, address: PhysAddr, count: PageFrameCount);
307     // @brief 分配一个页帧
308     unsafe fn allocate_one(&mut self) -> Option<PhysAddr> {
309         return self.allocate(PageFrameCount::new(1)).map(|(addr, _)| addr);
310     }
311     // @brief 通过地址释放一个页帧
312     unsafe fn free_one(&mut self, address: PhysAddr) {
313         return self.free(address, PageFrameCount::new(1));
314     }
315     // @brief 获取页帧使用情况
316     unsafe fn usage(&self) -> PageFrameUsage;
317 }
318 
319 /// @brief 通过一个 &mut T 的引用来对一个实现了 FrameAllocator trait 的类型进行调用,使代码更加灵活
320 impl<T: FrameAllocator> FrameAllocator for &mut T {
321     unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> {
322         return T::allocate(self, count);
323     }
324     unsafe fn free(&mut self, address: PhysAddr, count: PageFrameCount) {
325         return T::free(self, address, count);
326     }
327     unsafe fn allocate_one(&mut self) -> Option<PhysAddr> {
328         return T::allocate_one(self);
329     }
330     unsafe fn free_one(&mut self, address: PhysAddr) {
331         return T::free_one(self, address);
332     }
333     unsafe fn usage(&self) -> PageFrameUsage {
334         return T::usage(self);
335     }
336 }
337 
338 /// @brief 从全局的页帧分配器中分配连续count个页帧
339 ///
340 /// @param count 请求分配的页帧数量
341 pub unsafe fn allocate_page_frames(count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> {
342     let frame = unsafe { LockedFrameAllocator.allocate(count)? };
343     return Some(frame);
344 }
345 
346 /// @brief 向全局页帧分配器释放连续count个页帧
347 ///
348 /// @param frame 要释放的第一个页帧
349 /// @param count 要释放的页帧数量 (必须是2的n次幂)
350 pub unsafe fn deallocate_page_frames(frame: PhysPageFrame, count: PageFrameCount) {
351     unsafe {
352         LockedFrameAllocator.free(frame.phys_address(), count);
353     }
354 }
355