os/mm/page_table/
page_table_entry.rs

1//! 页表项模块
2//!
3//! 本模块定义了页表项(Page Table Entry, PTE)的通用接口和标志集,
4//! 以支持不同体系结构的页表实现。
5#![allow(dead_code)]
6use crate::mm::address::Ppn;
7
8bitflags::bitflags! {
9    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
10    /// 定义了一组通用的页表项标志,可以映射到各种体系结构。
11    /// 其低 8 位与 Risc-V SV39 兼容。(如果其他架构需要,可添加更多标志位)
12    pub struct UniversalPTEFlag: usize {
13
14            // ---- RISC-V SV39 兼容标志 ----
15            const VALID = 1 << 0;               // 指示该页表项是否有效
16            const READABLE = 1 << 1;            // 指示该页是否可读
17            const WRITEABLE = 1 << 2;           // 指示该页是否可写
18            const EXECUTABLE = 1 << 3;          // 指示该页是否可执行
19            const USER_ACCESSIBLE = 1 << 4;     // 指示该页是否可从用户模式访问
20            const GLOBAL = 1 << 5;              // 指示该页是否为全局页(Global)
21            const ACCESSED = 1 << 6;            // 指示该页是否已被访问
22            const DIRTY = 1 << 7;               // 指示该页是否已被写入(修改)
23
24            // ---- 额外的通用标志 ----
25            #[allow(dead_code)] // TODO(暂时注释): 巨页支持已暂时禁用
26            const HUGE = 1 << 8;                // 指示该页是否为巨页(Huge Page)
27    }
28}
29
30impl UniversalPTEFlag {
31    /// 构造用户只读访问的标志集合
32    pub const fn user_read() -> Self {
33        Self::VALID
34            .union(Self::READABLE)
35            .union(Self::USER_ACCESSIBLE)
36    }
37
38    /// 构造用户读写访问的标志集合
39    pub const fn user_rw() -> Self {
40        Self::VALID
41            .union(Self::READABLE)
42            .union(Self::WRITEABLE)
43            .union(Self::USER_ACCESSIBLE)
44    }
45
46    /// 构造用户读执行访问的标志集合
47    pub const fn user_rx() -> Self {
48        Self::VALID
49            .union(Self::READABLE)
50            .union(Self::EXECUTABLE)
51            .union(Self::USER_ACCESSIBLE)
52    }
53
54    /// 构造内核读写访问的标志集合
55    pub const fn kernel_rw() -> Self {
56        Self::VALID.union(Self::READABLE).union(Self::WRITEABLE)
57    }
58
59    /// 构造内核只读访问的标志集合
60    pub const fn kernel_r() -> Self {
61        Self::VALID.union(Self::READABLE)
62    }
63
64    /// 构造内核读执行访问的标志集合
65    pub const fn kernel_rx() -> Self {
66        Self::VALID.union(Self::READABLE).union(Self::EXECUTABLE)
67    }
68}
69
70/// 允许将特定架构的标志与通用标志集相互转换的 trait
71pub trait UniversalConvertableFlag {
72    /// 从通用标志集创建特定架构的标志
73    fn from_universal(flag: UniversalPTEFlag) -> Self;
74    /// 将特定架构的标志转换为通用标志集
75    fn to_universal(&self) -> UniversalPTEFlag;
76}
77
78/// 页表项(Page Table Entry, PTE)所需实现的核心接口
79pub trait PageTableEntry {
80    /// 用于表示页表项的底层位模式类型
81    type Bits;
82
83    /// 从位模式创建页表项
84    fn from_bits(bits: Self::Bits) -> Self;
85    /// 获取页表项的位模式
86    fn to_bits(&self) -> Self::Bits;
87    /// 创建一个空的(无效的)页表项
88    fn empty() -> Self;
89    /// 创建一个新的叶节点(普通页映射)
90    fn new_leaf(ppn: Ppn, flags: UniversalPTEFlag) -> Self;
91    /// 创建一个新的表节点(指向下一级页表)
92    fn new_table(ppn: Ppn) -> Self;
93
94    /// 检查页表项是否有效
95    fn is_valid(&self) -> bool;
96    /// 检查页表项是否为巨页映射(如果支持)
97    fn is_huge(&self) -> bool;
98    /// 检查页表项是否为空
99    fn is_empty(&self) -> bool;
100
101    /// 获取页表项中存储的物理页号(Ppn)
102    fn ppn(&self) -> Ppn;
103    /// 获取页表项的通用标志
104    fn flags(&self) -> UniversalPTEFlag;
105
106    /// 设置页表项的物理页号
107    fn set_ppn(&mut self, ppn: Ppn);
108    /// 设置页表项的标志
109    fn set_flags(&mut self, flags: UniversalPTEFlag);
110    /// 清空页表项(使其无效)
111    fn clear(&mut self);
112
113    /// 移除指定的标志
114    // current_flags & !flags
115    fn remove_flags(&mut self, flags: UniversalPTEFlag);
116
117    /// 添加指定的标志
118    // current_flags | flags
119    fn add_flags(&mut self, flags: UniversalPTEFlag);
120}