obkrnl/vm/
page.rs

1use crate::lock::Mutex;
2use core::hash::{Hash, Hasher};
3use macros::bitflag;
4
5/// Implementation of `vm_page` structure.
6pub struct VmPage {
7    index: usize,
8    vm: usize,
9    pool: Mutex<usize>,                  // pool
10    addr: u64,                           // phys_addr
11    order: Mutex<usize>,                 // order
12    flags: Mutex<PageFlags>,             // flags
13    extended_flags: Mutex<PageExtFlags>, // oflags
14    access: Mutex<PageAccess>,           // aflags
15    segment: usize,                      // segind
16    unk1: u8,
17}
18
19impl VmPage {
20    pub const FREE_ORDER: usize = 13; // VM_NFREEORDER
21
22    pub fn new(index: usize, vm: usize, pool: usize, addr: u64, segment: usize) -> Self {
23        Self {
24            index,
25            vm,
26            pool: Mutex::new(pool),
27            addr,
28            order: Mutex::new(Self::FREE_ORDER),
29            flags: Mutex::new(PageFlags::zeroed()),
30            extended_flags: Mutex::new(PageExtFlags::zeroed()),
31            access: Mutex::new(PageAccess::zeroed()),
32            segment,
33            unk1: 0,
34        }
35    }
36
37    pub fn index(&self) -> usize {
38        self.index
39    }
40
41    pub fn vm(&self) -> usize {
42        self.vm
43    }
44
45    /// This must be locked **after** [Self::order()] and the lock must be held while putting this
46    /// page to free queues.
47    pub fn pool(&self) -> &Mutex<usize> {
48        &self.pool
49    }
50
51    pub fn addr(&self) -> u64 {
52        self.addr
53    }
54
55    /// This must be locked **after** free queues and the lock must be held while putting this page
56    /// to free queues.
57    pub fn order(&self) -> &Mutex<usize> {
58        &self.order
59    }
60
61    pub fn flags(&self) -> &Mutex<PageFlags> {
62        &self.flags
63    }
64
65    pub fn extended_flags(&self) -> &Mutex<PageExtFlags> {
66        &self.extended_flags
67    }
68
69    pub fn access(&self) -> &Mutex<PageAccess> {
70        &self.access
71    }
72
73    pub fn segment(&self) -> usize {
74        self.segment
75    }
76
77    pub fn unk1(&self) -> u8 {
78        self.unk1
79    }
80}
81
82impl PartialEq for VmPage {
83    fn eq(&self, other: &Self) -> bool {
84        self.addr == other.addr
85    }
86}
87
88impl Eq for VmPage {}
89
90impl Hash for VmPage {
91    fn hash<H: Hasher>(&self, state: &mut H) {
92        self.addr.hash(state);
93    }
94}
95
96/// Value for [VmPage::flags].
97#[bitflag(u8)]
98pub enum PageFlags {
99    /// `PG_CACHED`.
100    Cached = 0x01,
101    /// `PG_ZERO`.
102    Zero = 0x08,
103}
104
105/// Value for [VmPage::extended_flags].
106#[bitflag(u16)]
107pub enum PageExtFlags {
108    /// `VPO_BUSY`.
109    Busy = 0x0001,
110    /// `VPO_UNMANAGED`.
111    Unmanaged = 0x0004,
112}
113
114/// Value for [VmPage::access].
115#[bitflag(u8)]
116pub enum PageAccess {}