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