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 {
new(paddr: PhysAddr) -> Self20 pub fn new(paddr: PhysAddr) -> Self {
21 return Self {
22 number: paddr.data() / MMArch::PAGE_SIZE,
23 };
24 }
25
26 /// @brief 获取当前页对应的物理地址
phys_address(&self) -> PhysAddr27 pub fn phys_address(&self) -> PhysAddr {
28 return PhysAddr::new(self.number * MMArch::PAGE_SIZE);
29 }
30
next_by(&self, n: usize) -> Self31 pub fn next_by(&self, n: usize) -> Self {
32 return Self {
33 number: self.number + n,
34 };
35 }
36
next(&self) -> Self37 pub fn next(&self) -> Self {
38 return self.next_by(1);
39 }
40
41 /// 构造物理页帧的迭代器,范围为[start, end)
iter_range(start: Self, end: Self) -> PhysPageFrameIter42 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 {
new(start: PhysPageFrame, end: PhysPageFrame) -> Self56 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
next(&mut self) -> Option<Self::Item>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 {
new(vaddr: VirtAddr) -> Self84 pub fn new(vaddr: VirtAddr) -> Self {
85 return Self {
86 number: vaddr.data() / MMArch::PAGE_SIZE,
87 };
88 }
89
90 /// 获取当前虚拟页对应的虚拟地址
virt_address(&self) -> VirtAddr91 pub fn virt_address(&self) -> VirtAddr {
92 return VirtAddr::new(self.number * MMArch::PAGE_SIZE);
93 }
94
next_by(&self, n: usize) -> Self95 pub fn next_by(&self, n: usize) -> Self {
96 return Self {
97 number: self.number + n,
98 };
99 }
100
next(&self) -> Self101 pub fn next(&self) -> Self {
102 return self.next_by(1);
103 }
104
105 /// 构造虚拟页帧的迭代器,范围为[start, end)
iter_range(start: Self, end: Self) -> VirtPageFrameIter106 pub fn iter_range(start: Self, end: Self) -> VirtPageFrameIter {
107 return VirtPageFrameIter {
108 current: start,
109 end,
110 };
111 }
112
add(&self, n: PageFrameCount) -> Self113 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)
new(start: VirtPageFrame, end: VirtPageFrame) -> Self130 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
next(&mut self) -> Option<Self::Item>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
new(count: usize) -> Self158 pub const fn new(count: usize) -> Self {
159 return Self(count);
160 }
161 // @brief 获取页帧数量
data(&self) -> usize162 pub fn data(&self) -> usize {
163 return self.0;
164 }
165
166 /// 计算这一段页帧占用的字节数
bytes(&self) -> usize167 pub fn bytes(&self) -> usize {
168 return self.0 * MMArch::PAGE_SIZE;
169 }
170
171 /// 将字节数转换为页帧数量
172 ///
173 /// 如果字节数不是页帧大小的整数倍,则返回None. 否则返回页帧数量
from_bytes(bytes: usize) -> Option<Self>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
add(self, rhs: Self) -> Self::Output186 fn add(self, rhs: Self) -> Self::Output {
187 return Self(self.0 + rhs.0);
188 }
189 }
190
191 impl AddAssign for PageFrameCount {
add_assign(&mut self, rhs: Self)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
sub(self, rhs: Self) -> Self::Output200 fn sub(self, rhs: Self) -> Self::Output {
201 return Self(self.0 - rhs.0);
202 }
203 }
204
205 impl SubAssign for PageFrameCount {
sub_assign(&mut self, rhs: Self)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
mul(self, rhs: Self) -> Self::Output214 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
add(self, rhs: usize) -> Self::Output222 fn add(self, rhs: usize) -> Self::Output {
223 return Self(self.0 + rhs);
224 }
225 }
226
227 impl AddAssign<usize> for PageFrameCount {
add_assign(&mut self, rhs: usize)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
sub(self, rhs: usize) -> Self::Output236 fn sub(self, rhs: usize) -> Self::Output {
237 return Self(self.0 - rhs);
238 }
239 }
240
241 impl SubAssign<usize> for PageFrameCount {
sub_assign(&mut self, rhs: usize)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
mul(self, rhs: usize) -> Self::Output250 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 总的页帧数量
new(used: PageFrameCount, total: PageFrameCount) -> Self267 pub fn new(used: PageFrameCount, total: PageFrameCount) -> Self {
268 return Self { used, total };
269 }
270 // @brief 获取已使用的页帧数量
used(&self) -> PageFrameCount271 pub fn used(&self) -> PageFrameCount {
272 return self.used;
273 }
274 // @brief 获取空闲的页帧数量
free(&self) -> PageFrameCount275 pub fn free(&self) -> PageFrameCount {
276 return PageFrameCount(self.total.0 - self.used.0);
277 }
278 // @brief 获取总的页帧数量
total(&self) -> PageFrameCount279 pub fn total(&self) -> PageFrameCount {
280 return self.total;
281 }
282 }
283
284 /// 能够分配页帧的分配器需要实现的trait
285 pub trait FrameAllocator {
286 // @brief 分配count个页帧
allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)>287 unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)>;
288
289 // @brief 通过地址释放count个页帧
free(&mut self, address: PhysAddr, count: PageFrameCount)290 unsafe fn free(&mut self, address: PhysAddr, count: PageFrameCount);
291 // @brief 分配一个页帧
allocate_one(&mut self) -> Option<PhysAddr>292 unsafe fn allocate_one(&mut self) -> Option<PhysAddr> {
293 return self.allocate(PageFrameCount::new(1)).map(|(addr, _)| addr);
294 }
295 // @brief 通过地址释放一个页帧
free_one(&mut self, address: PhysAddr)296 unsafe fn free_one(&mut self, address: PhysAddr) {
297 return self.free(address, PageFrameCount::new(1));
298 }
299 // @brief 获取页帧使用情况
usage(&self) -> PageFrameUsage300 unsafe fn usage(&self) -> PageFrameUsage;
301 }
302
303 /// @brief 通过一个 &mut T 的引用来对一个实现了 FrameAllocator trait 的类型进行调用,使代码更加灵活
304 impl<T: FrameAllocator> FrameAllocator for &mut T {
allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)>305 unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> {
306 return T::allocate(self, count);
307 }
free(&mut self, address: PhysAddr, count: PageFrameCount)308 unsafe fn free(&mut self, address: PhysAddr, count: PageFrameCount) {
309 return T::free(self, address, count);
310 }
allocate_one(&mut self) -> Option<PhysAddr>311 unsafe fn allocate_one(&mut self) -> Option<PhysAddr> {
312 return T::allocate_one(self);
313 }
free_one(&mut self, address: PhysAddr)314 unsafe fn free_one(&mut self, address: PhysAddr) {
315 return T::free_one(self, address);
316 }
usage(&self) -> PageFrameUsage317 unsafe fn usage(&self) -> PageFrameUsage {
318 return T::usage(self);
319 }
320 }
321
322 /// @brief 从全局的页帧分配器中分配连续count个页帧
323 ///
324 /// @param count 请求分配的页帧数量
allocate_page_frames(count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)>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次幂)
deallocate_page_frames(frame: PhysPageFrame, count: PageFrameCount)334 pub unsafe fn deallocate_page_frames(frame: PhysPageFrame, count: PageFrameCount) {
335 unsafe {
336 LockedFrameAllocator.free(frame.phys_address(), count);
337 }
338 }
339