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 { 22 pub fn new(paddr: PhysAddr) -> Self { 23 return Self { 24 number: paddr.data() >> MMArch::PAGE_SHIFT, 25 }; 26 } 27 28 /// 从物理页号创建PhysPageFrame结构体 29 pub fn from_ppn(ppn: usize) -> Self { 30 return Self { number: ppn }; 31 } 32 33 /// 获取当前页对应的物理页号 34 pub fn ppn(&self) -> usize { 35 return self.number; 36 } 37 38 /// @brief 获取当前页对应的物理地址 39 pub fn phys_address(&self) -> PhysAddr { 40 return PhysAddr::new(self.number * MMArch::PAGE_SIZE); 41 } 42 43 pub fn next_by(&self, n: usize) -> Self { 44 return Self { 45 number: self.number + n, 46 }; 47 } 48 49 pub fn next(&self) -> Self { 50 return self.next_by(1); 51 } 52 53 /// 构造物理页帧的迭代器,范围为[start, end) 54 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 { 68 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 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 { 97 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)] 105 pub fn from_vpn(vpn: usize) -> Self { 106 return Self { number: vpn }; 107 } 108 109 /// 获取当前虚拟页对应的虚拟地址 110 pub fn virt_address(&self) -> VirtAddr { 111 return VirtAddr::new(self.number * MMArch::PAGE_SIZE); 112 } 113 114 pub fn next_by(&self, n: usize) -> Self { 115 return Self { 116 number: self.number + n, 117 }; 118 } 119 120 pub fn next(&self) -> Self { 121 return self.next_by(1); 122 } 123 124 /// 构造虚拟页帧的迭代器,范围为[start, end) 125 pub fn iter_range(start: Self, end: Self) -> VirtPageFrameIter { 126 return VirtPageFrameIter { 127 current: start, 128 end, 129 }; 130 } 131 132 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) 149 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 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 177 pub const fn new(count: usize) -> Self { 178 return Self(count); 179 } 180 // @brief 获取页帧数量 181 pub fn data(&self) -> usize { 182 return self.0; 183 } 184 185 /// 计算这一段页帧占用的字节数 186 pub fn bytes(&self) -> usize { 187 return self.0 * MMArch::PAGE_SIZE; 188 } 189 190 /// 将字节数转换为页帧数量 191 /// 192 /// 如果字节数不是页帧大小的整数倍,则返回None. 否则返回页帧数量 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)] 202 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 210 fn add(self, rhs: Self) -> Self::Output { 211 return Self(self.0 + rhs.0); 212 } 213 } 214 215 impl AddAssign for PageFrameCount { 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 224 fn sub(self, rhs: Self) -> Self::Output { 225 return Self(self.0 - rhs.0); 226 } 227 } 228 229 impl SubAssign for PageFrameCount { 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 238 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 246 fn add(self, rhs: usize) -> Self::Output { 247 return Self(self.0 + rhs); 248 } 249 } 250 251 impl AddAssign<usize> for PageFrameCount { 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 260 fn sub(self, rhs: usize) -> Self::Output { 261 return Self(self.0 - rhs); 262 } 263 } 264 265 impl SubAssign<usize> for PageFrameCount { 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 274 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 总的页帧数量 291 pub fn new(used: PageFrameCount, total: PageFrameCount) -> Self { 292 return Self { used, total }; 293 } 294 // @brief 获取已使用的页帧数量 295 pub fn used(&self) -> PageFrameCount { 296 return self.used; 297 } 298 // @brief 获取空闲的页帧数量 299 pub fn free(&self) -> PageFrameCount { 300 return self.total - self.used; 301 } 302 // @brief 获取总的页帧数量 303 pub fn total(&self) -> PageFrameCount { 304 return self.total; 305 } 306 } 307 308 /// 能够分配页帧的分配器需要实现的trait 309 pub trait FrameAllocator { 310 // @brief 分配count个页帧 311 unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)>; 312 313 // @brief 通过地址释放count个页帧 314 unsafe fn free(&mut self, address: PhysAddr, count: PageFrameCount); 315 // @brief 分配一个页帧 316 unsafe fn allocate_one(&mut self) -> Option<PhysAddr> { 317 return self.allocate(PageFrameCount::new(1)).map(|(addr, _)| addr); 318 } 319 // @brief 通过地址释放一个页帧 320 unsafe fn free_one(&mut self, address: PhysAddr) { 321 return self.free(address, PageFrameCount::new(1)); 322 } 323 // @brief 获取页帧使用情况 324 unsafe fn usage(&self) -> PageFrameUsage; 325 } 326 327 /// @brief 通过一个 &mut T 的引用来对一个实现了 FrameAllocator trait 的类型进行调用,使代码更加灵活 328 impl<T: FrameAllocator> FrameAllocator for &mut T { 329 unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> { 330 return T::allocate(self, count); 331 } 332 unsafe fn free(&mut self, address: PhysAddr, count: PageFrameCount) { 333 return T::free(self, address, count); 334 } 335 unsafe fn allocate_one(&mut self) -> Option<PhysAddr> { 336 return T::allocate_one(self); 337 } 338 unsafe fn free_one(&mut self, address: PhysAddr) { 339 return T::free_one(self, address); 340 } 341 unsafe fn usage(&self) -> PageFrameUsage { 342 return T::usage(self); 343 } 344 } 345 346 /// @brief 从全局的页帧分配器中分配连续count个页帧 347 /// 348 /// @param count 请求分配的页帧数量 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次幂) 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