Kernel remapped.

This commit is contained in:
Yifan Wu 2020-12-04 17:23:35 +08:00
parent e37e5708e4
commit b6f4327a3f
9 changed files with 489 additions and 29 deletions

View file

@ -1,20 +1,46 @@
use crate::config::{PAGE_SIZE, PAGE_SIZE_BITS};
use super::PageTableEntry;
use core::fmt::{self, Debug, Formatter};
/// Definitions
#[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);
/// Debugging
impl Debug for VirtAddr {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("VA:{:#x}", self.0))
}
}
impl Debug for VirtPageNum {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("VPN:{:#x}", self.0))
}
}
impl Debug for PhysAddr {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("PA:{:#x}", self.0))
}
}
impl Debug for PhysPageNum {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("PPN:{:#x}", self.0))
}
}
/// T: {PhysAddr, VirtAddr, PhysPageNum, VirtPageNum}
/// T -> usize: T.0
/// usize -> T: usize.into()
use crate::config::{PAGE_SIZE, PAGE_SIZE_BITS};
/// Definitions
#[derive(Copy, Clone, Debug)]
pub struct PhysAddr(pub usize);
#[derive(Copy, Clone, Debug)]
pub struct VirtAddr(pub usize);
#[derive(Copy, Clone, Debug)]
pub struct PhysPageNum(pub usize);
#[derive(Copy, Clone, Debug)]
pub struct VirtPageNum(pub usize);
impl From<usize> for PhysAddr {
fn from(v: usize) -> Self { Self(v) }
@ -22,24 +48,25 @@ impl From<usize> for PhysAddr {
impl From<usize> for PhysPageNum {
fn from(v: usize) -> Self { Self(v) }
}
impl From<usize> for VirtAddr {
fn from(v: usize) -> Self { Self(v) }
}
impl From<usize> for VirtPageNum {
fn from(v: usize) -> Self { Self(v) }
}
impl From<PhysAddr> for usize {
fn from(v: PhysAddr) -> Self { v.0 }
}
impl From<PhysPageNum> for usize {
fn from(v: PhysPageNum) -> Self { v.0 }
}
impl From<usize> for VirtAddr {
fn from(v: usize) -> Self { Self(v) }
}
impl From<usize> for VirtPageNum {
fn from(v: usize) -> Self { Self(v) }
}
impl From<VirtAddr> for usize {
fn from(v: VirtAddr) -> Self { v.0 }
}
impl From<VirtPageNum> for usize {
fn from(v: VirtPageNum) -> Self { v.0 }
}
impl VirtAddr {
pub fn floor(&self) -> VirtPageNum { VirtPageNum(self.0 / PAGE_SIZE) }
pub fn ceil(&self) -> VirtPageNum { VirtPageNum((self.0 + PAGE_SIZE - 1) / PAGE_SIZE) }
@ -67,4 +94,93 @@ impl From<PhysAddr> for PhysPageNum {
}
impl From<PhysPageNum> for PhysAddr {
fn from(v: PhysPageNum) -> Self { Self(v.0 << PAGE_SIZE_BITS) }
}
}
impl VirtPageNum {
pub fn indexes(&self) -> [usize; 3] {
let mut vpn = self.0;
let mut idx = [0usize; 3];
for i in (0..3).rev() {
idx[i] = vpn & 511;
vpn >>= 9;
}
idx
}
}
impl PhysPageNum {
pub fn get_pte_array(&self) -> &'static mut [PageTableEntry] {
let pa: PhysAddr = self.clone().into();
unsafe {
core::slice::from_raw_parts_mut(pa.0 as *mut PageTableEntry, 512)
}
}
pub fn get_bytes_array(&self) -> &'static mut [u8] {
let pa: PhysAddr = self.clone().into();
unsafe {
core::slice::from_raw_parts_mut(pa.0 as *mut u8, 4096)
}
}
pub fn get_mut<T>(&self) -> &'static mut T {
let pa: PhysAddr = self.clone().into();
unsafe {
(pa.0 as *mut T).as_mut().unwrap()
}
}
}
pub trait StepByOne {
fn step(&mut self);
}
impl StepByOne for VirtPageNum {
fn step(&mut self) {
self.0 += 1;
}
}
#[derive(Copy, Clone)]
pub struct SimpleRange<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug, {
l: T,
r: T,
}
impl<T> SimpleRange<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug, {
pub fn new(start: T, end: T) -> Self {
assert!(start <= end, "start {:?} > end {:?}!", start, end);
Self { l: start, r: end }
}
}
impl<T> IntoIterator for SimpleRange<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug, {
type Item = T;
type IntoIter = SimpleRangeIterator<T>;
fn into_iter(self) -> Self::IntoIter {
SimpleRangeIterator::new(self.l, self.r)
}
}
pub struct SimpleRangeIterator<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug, {
current: T,
end: T,
}
impl<T> SimpleRangeIterator<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug, {
pub fn new(l: T, r: T) -> Self {
Self { current: l, end: r, }
}
}
impl<T> Iterator for SimpleRangeIterator<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug, {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.current == self.end {
None
} else {
let t = self.current;
self.current.step();
Some(t)
}
}
}
pub type VPNRange = SimpleRange<VirtPageNum>;