You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
2.1 KiB
Rust
73 lines
2.1 KiB
Rust
2 years ago
|
use crate::config::{PAGE_SIZE, PAGE_SIZE_BITS};
|
||
|
|
||
|
const PA_WIDTH_SV39: usize = 56; // 真实物理地址 的字节宽度 44(物理页宽) + 12(4kb的宽度)
|
||
|
const PPN_WIDTH_SV39: usize = PA_WIDTH_SV39 - PAGE_SIZE_BITS; // 物理页 的宽度, 也就是 物理地址宽度-每页宽度=物理页宽度
|
||
|
|
||
|
|
||
|
// 物理地址
|
||
|
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
||
|
pub struct PhysAddr(pub usize);
|
||
|
|
||
|
// 虚拟地址
|
||
|
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
||
|
pub struct VirtAddr(pub usize);
|
||
|
|
||
|
// 物理页
|
||
|
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
||
|
pub struct PhysPageNum(pub usize);
|
||
|
|
||
|
// 虚拟页
|
||
|
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
||
|
pub struct VirtPageNum(pub usize);
|
||
|
|
||
|
|
||
|
// 把usize 转为真实地址(只保留 PA_WIDTH_SV39 位字节)
|
||
|
impl From<usize> for PhysAddr {
|
||
|
fn from(v: usize) -> Self { Self(v & ( (1 << PA_WIDTH_SV39) - 1 )) }
|
||
|
}
|
||
|
|
||
|
// 把usize类型的物理页号 转为物理页结构体 (只保留物理页的宽度)
|
||
|
impl From<usize> for PhysPageNum {
|
||
|
fn from(v: usize) -> Self { Self(v & ( (1 << PPN_WIDTH_SV39) - 1 )) }
|
||
|
}
|
||
|
|
||
|
// 把物理地址转为 usize, 直接返回即可
|
||
|
impl From<PhysAddr> for usize {
|
||
|
fn from(v: PhysAddr) -> Self { v.0 }
|
||
|
}
|
||
|
|
||
|
// 把物理页结构体转为 usize类型的物理页 直接返回即可
|
||
|
impl From<PhysPageNum> for usize {
|
||
|
fn from(v: PhysPageNum) -> Self { v.0 }
|
||
|
}
|
||
|
|
||
|
|
||
|
impl PhysAddr {
|
||
|
// 从当前物理地址得到页内偏移(只保留12个bit即可)
|
||
|
pub fn page_offset(&self) -> usize {
|
||
|
self.0 & (PAGE_SIZE - 1)
|
||
|
}
|
||
|
|
||
|
// 舍去小数位, 把物理地址, 转为 物理页号
|
||
|
pub fn floor(&self) -> PhysPageNum {
|
||
|
PhysPageNum(self.0 / PAGE_SIZE)
|
||
|
}
|
||
|
|
||
|
// 有小数统一 +1, 物理地址转为物理页号
|
||
|
pub fn ceil(&self) -> PhysPageNum {
|
||
|
PhysPageNum((self.0 + PAGE_SIZE - 1) / PAGE_SIZE)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 把PhysAddr 转为 PhysPageNum
|
||
|
impl From<PhysAddr> for PhysPageNum {
|
||
|
fn from(v: PhysAddr) -> Self {
|
||
|
assert_eq!(v.page_offset(), 0);
|
||
|
v.floor()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 把物理页转为物理地址(左移页宽即可)
|
||
|
impl From<PhysPageNum> for PhysAddr {
|
||
|
fn from(v: PhysPageNum) -> Self { Self(v.0 << PAGE_SIZE_BITS) }
|
||
|
}
|