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