#![no_std]
use core::fmt::Debug;
mod def;
pub mod frame;
mod map;
mod table;
mod walk;
pub use def::*;
pub use frame::Frame;
pub use map::*;
pub use table::*;
pub use walk::*;
pub type PagingResult<T = ()> = Result<T, PagingError>;
pub trait FrameAllocator: Clone + Sync + Send + 'static {
fn alloc_frame(&self) -> Option<PhysAddr>;
fn dealloc_frame(&self, frame: PhysAddr);
fn phys_to_virt(&self, paddr: PhysAddr) -> *mut u8;
}
pub trait TableMeta: Sync + Send + Clone + Copy + 'static {
type P: PageTableEntry;
const PAGE_SIZE: usize;
const LEVEL_BITS: &[usize];
const MAX_BLOCK_LEVEL: usize;
fn flush(vaddr: Option<VirtAddr>);
}
pub trait PageTableEntry: Debug + Sync + Send + Clone + Copy + Sized + 'static {
fn from_config(config: PteConfig) -> Self;
fn to_config(&self, is_dir: bool) -> PteConfig;
fn valid(&self) -> bool;
}
pub trait PageTableOp: Send + 'static {
fn addr(&self) -> PhysAddr;
fn map(&mut self, config: &MapConfig) -> PagingResult;
fn unmap(&mut self, virt_start: VirtAddr, size: usize) -> Result<(), PagingError>;
}
impl<T: TableMeta, A: FrameAllocator> PageTableOp for PageTable<T, A> {
fn addr(&self) -> PhysAddr {
self.root_paddr()
}
fn map(&mut self, config: &MapConfig) -> PagingResult {
PageTableRef::map(self, config)
}
fn unmap(&mut self, virt_start: VirtAddr, size: usize) -> PagingResult {
PageTableRef::unmap(self, virt_start, size)
}
}
impl<T: TableMeta, A: FrameAllocator> PageTableOp for PageTableRef<T, A> {
fn addr(&self) -> PhysAddr {
self.root_paddr()
}
fn map(&mut self, config: &MapConfig) -> PagingResult {
self.map(config)
}
fn unmap(&mut self, virt_start: VirtAddr, size: usize) -> Result<(), PagingError> {
self.unmap(virt_start, size)
}
}