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