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