Skip to main content

page_table_generic/
lib.rs

1#![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
27pub trait TableMeta: Sync + Send + Clone + Copy + 'static {
28    type P: PageTableEntry;
29
30    /// 页面大小(支持4KB、16KB、64KB等)
31    const PAGE_SIZE: usize;
32
33    /// 各级索引位数数组,从最高级到最低级
34    const LEVEL_BITS: &[usize];
35
36    /// 大页最高支持的级别
37    const MAX_BLOCK_LEVEL: usize;
38
39    /// 刷新TLB
40    fn flush(vaddr: Option<VirtAddr>);
41}
42
43pub trait PageTableEntry: Debug + Sync + Send + Clone + Copy + Sized + 'static {
44    /// 从 PteConfig 创建页表项
45    ///
46    /// # 参数
47    /// - `config`: 包含所有页表项配置的结构
48    ///
49    /// # 返回
50    /// 新的页表项实例
51    fn from_config(config: PteConfig) -> Self;
52
53    /// 将页表项转换为 PteConfig
54    ///
55    /// # 参数
56    /// - `is_dir`: 是否为目录项(影响物理地址布局解析)
57    ///   - true: 目录项(可能包含大页映射或子页表指针)
58    ///   - false: 页表项(叶子级别,基本页映射)
59    ///
60    /// # 返回
61    /// 包含当前页表项所有状态的 PteConfig
62    fn to_config(&self, is_dir: bool) -> PteConfig;
63
64    fn valid(&self) -> bool;
65}
66
67pub trait PageTableOp: Send + 'static {
68    fn addr(&self) -> PhysAddr;
69    fn map(&mut self, config: &MapConfig) -> PagingResult;
70    fn unmap(&mut self, virt_start: VirtAddr, size: usize) -> Result<(), PagingError>;
71}
72
73impl<T: TableMeta, A: FrameAllocator> PageTableOp for PageTable<T, A> {
74    fn addr(&self) -> PhysAddr {
75        self.root_paddr()
76    }
77
78    fn map(&mut self, config: &MapConfig) -> PagingResult {
79        PageTableRef::map(self, config)
80    }
81
82    fn unmap(&mut self, virt_start: VirtAddr, size: usize) -> PagingResult {
83        PageTableRef::unmap(self, virt_start, size)
84    }
85}
86
87impl<T: TableMeta, A: FrameAllocator> PageTableOp for PageTableRef<T, A> {
88    fn addr(&self) -> PhysAddr {
89        self.root_paddr()
90    }
91
92    fn map(&mut self, config: &MapConfig) -> PagingResult {
93        self.map(config)
94    }
95
96    fn unmap(&mut self, virt_start: VirtAddr, size: usize) -> Result<(), PagingError> {
97        self.unmap(virt_start, size)
98    }
99}