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