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