page_table_generic/
lib.rs1#![no_std]
2
3use core::fmt::Debug;
4
5mod def;
6pub mod frame;
7mod map;
8mod table;
9mod walk;
10
11pub use def::*;
12pub use frame::Frame;
13pub use map::*;
14pub use table::*;
15pub use walk::*;
16
17pub type PagingResult<T = ()> = Result<T, PagingError>;
18
19pub trait FrameAllocator: Clone + Sync + Send + 'static {
20 fn alloc_frame(&self) -> Option<PhysAddr>;
21
22 fn dealloc_frame(&self, frame: PhysAddr);
23
24 fn phys_to_virt(&self, paddr: PhysAddr) -> *mut u8;
25
26 fn alloc_frames(&self, frames: usize, _align: usize) -> Option<PhysAddr> {
27 if frames == 1 {
28 self.alloc_frame()
29 } else {
30 None
31 }
32 }
33
34 fn dealloc_frames(&self, start: PhysAddr, frames: usize, frame_size: usize) {
35 if frames == 1 {
36 self.dealloc_frame(start);
37 return;
38 }
39 for i in 0..frames {
40 self.dealloc_frame(PhysAddr::new(start.raw() + i * frame_size));
41 }
42 }
43}
44
45pub trait TableMeta: Sync + Send + Clone + Copy + 'static {
46 type P: PageTableEntry;
47
48 const PAGE_SIZE: usize;
50
51 const LEVEL_BITS: &[usize];
53
54 const MAX_BLOCK_LEVEL: usize;
56
57 const STRICT_ADDRESS_WIDTH: bool = false;
59
60 fn flush(vaddr: Option<VirtAddr>);
62}
63
64pub trait PageTableEntry: Debug + Sync + Send + Clone + Copy + Sized + 'static {
65 fn from_config(config: PteConfig) -> Self;
73
74 fn to_config(&self, is_dir: bool) -> PteConfig;
84
85 fn valid(&self) -> bool;
86}
87
88pub trait PageTableOp: Send + 'static {
89 fn addr(&self) -> PhysAddr;
90 fn map(&mut self, config: &MapConfig) -> PagingResult;
91 fn unmap(&mut self, virt_start: VirtAddr, size: usize) -> Result<(), PagingError>;
92}
93
94impl<T: TableMeta, A: FrameAllocator> PageTableOp for PageTable<T, A> {
95 fn addr(&self) -> PhysAddr {
96 self.root_paddr()
97 }
98
99 fn map(&mut self, config: &MapConfig) -> PagingResult {
100 PageTableRef::map(self, config)
101 }
102
103 fn unmap(&mut self, virt_start: VirtAddr, size: usize) -> PagingResult {
104 PageTableRef::unmap(self, virt_start, size)
105 }
106}
107
108impl<T: TableMeta, A: FrameAllocator> PageTableOp for PageTableRef<T, A> {
109 fn addr(&self) -> PhysAddr {
110 self.root_paddr()
111 }
112
113 fn map(&mut self, config: &MapConfig) -> PagingResult {
114 self.map(config)
115 }
116
117 fn unmap(&mut self, virt_start: VirtAddr, size: usize) -> Result<(), PagingError> {
118 self.unmap(virt_start, size)
119 }
120}