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