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