twizzler_abi/
pager.rs

1use core::fmt::Debug;
2
3use bitflags::bitflags;
4use twizzler_rt_abi::{
5    error::RawTwzError,
6    object::{ObjID, Protections},
7};
8
9use crate::{
10    object::NULLPAGE_SIZE,
11    syscall::{BackingType, LifetimeType},
12};
13
14bitflags::bitflags! {
15    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
16    pub struct PagerFlags : u32 {
17        const PREFETCH = 1;
18    }
19}
20
21#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
22pub struct RequestFromKernel {
23    cmd: KernelCommand,
24}
25
26impl RequestFromKernel {
27    pub fn new(cmd: KernelCommand) -> Self {
28        Self { cmd }
29    }
30
31    pub fn cmd(&self) -> KernelCommand {
32        self.cmd
33    }
34
35    pub fn id(&self) -> Option<ObjID> {
36        match self.cmd() {
37            KernelCommand::PageDataReq(objid, _, _) => Some(objid),
38            KernelCommand::ObjectInfoReq(objid) => Some(objid),
39            KernelCommand::ObjectEvict(info) => Some(info.obj_id),
40            KernelCommand::ObjectDel(objid) => Some(objid),
41            KernelCommand::ObjectCreate(objid, _) => Some(objid),
42            KernelCommand::DramPages(_) => None,
43        }
44    }
45}
46
47#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
48pub enum KernelCommand {
49    PageDataReq(ObjID, ObjectRange, PagerFlags),
50    ObjectInfoReq(ObjID),
51    ObjectEvict(ObjectEvictInfo),
52    ObjectDel(ObjID),
53    ObjectCreate(ObjID, ObjectInfo),
54    DramPages(PhysRange),
55}
56
57#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
58pub struct CompletionToKernel {
59    data: KernelCompletionData,
60    flags: KernelCompletionFlags,
61}
62
63bitflags! {
64    #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
65    pub struct KernelCompletionFlags: u32 {
66        const DONE = 1;
67    }
68}
69
70impl CompletionToKernel {
71    pub fn new(data: KernelCompletionData, flags: KernelCompletionFlags) -> Self {
72        Self { data, flags }
73    }
74
75    pub fn data(&self) -> KernelCompletionData {
76        self.data
77    }
78
79    pub fn flags(&self) -> KernelCompletionFlags {
80        self.flags
81    }
82
83    pub fn set_flags(&mut self, flags: KernelCompletionFlags) {
84        self.flags |= flags;
85    }
86
87    pub fn clear_flags(&mut self, flags: KernelCompletionFlags) {
88        self.flags &= !flags;
89    }
90}
91
92bitflags::bitflags! {
93    #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
94    pub struct PageFlags: u32 {
95        const WIRED = 0x1;
96    }
97}
98
99#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
100pub enum KernelCompletionData {
101    Okay,
102    Error(RawTwzError),
103    PageDataCompletion(ObjID, ObjectRange, PhysRange, PageFlags),
104    ObjectInfoCompletion(ObjID, ObjectInfo),
105}
106
107#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
108pub struct RequestFromPager {
109    cmd: PagerRequest,
110}
111
112impl RequestFromPager {
113    pub fn new(cmd: PagerRequest) -> Self {
114        Self { cmd }
115    }
116
117    pub fn cmd(&self) -> PagerRequest {
118        self.cmd
119    }
120}
121
122#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
123pub enum PagerRequest {
124    Ready,
125    CopyUserPhys {
126        target_object: ObjID,
127        offset: usize,
128        len: usize,
129        phys: PhysRange,
130        write_phys: bool,
131    },
132    RegisterPhys(u64, u64),
133}
134
135#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
136pub struct CompletionToPager {
137    data: PagerCompletionData,
138}
139
140impl CompletionToPager {
141    pub fn new(data: PagerCompletionData) -> Self {
142        Self { data }
143    }
144
145    pub fn data(&self) -> PagerCompletionData {
146        self.data
147    }
148}
149
150#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
151pub enum PagerCompletionData {
152    Okay,
153    Error(RawTwzError),
154    DramPages(PhysRange),
155}
156
157pub struct PageDataReq {
158    pub objid: ObjID,
159    pub object_range: ObjectRange,
160}
161
162#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
163pub struct ObjectInfo {
164    pub lifetime: LifetimeType,
165    pub backing: BackingType,
166    pub kuid: ObjID,
167    pub nonce: u128,
168    pub def_prot: Protections,
169}
170
171impl ObjectInfo {
172    pub fn new(
173        lifetime: LifetimeType,
174        backing: BackingType,
175        kuid: ObjID,
176        nonce: u128,
177        def_prot: Protections,
178    ) -> Self {
179        Self {
180            lifetime,
181            backing,
182            kuid,
183            nonce,
184            def_prot,
185        }
186    }
187}
188
189#[derive(Clone, Copy, PartialEq, PartialOrd, Ord, Eq)]
190pub struct PhysRange {
191    pub start: u64,
192    pub end: u64,
193}
194
195#[derive(Clone, Copy, PartialEq, PartialOrd, Ord, Eq)]
196pub struct ObjectRange {
197    pub start: u64,
198    pub end: u64,
199}
200
201impl Debug for ObjectRange {
202    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
203        write!(f, "ObjRange[{:x} - {:x})", self.start, self.end)
204    }
205}
206impl Debug for PhysRange {
207    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
208        write!(f, "PhyRange[{:x} - {:x})", self.start, self.end)
209    }
210}
211impl PhysRange {
212    pub fn new(start: u64, end: u64) -> Self {
213        Self { start, end }
214    }
215
216    pub fn len(&self) -> usize {
217        (self.end - self.start) as usize
218    }
219
220    pub fn pages(&self) -> impl Iterator<Item = u64> {
221        let first_page = self.start / NULLPAGE_SIZE as u64;
222        let last_page = self.end / NULLPAGE_SIZE as u64;
223        first_page..last_page
224    }
225
226    pub fn page_count(&self) -> usize {
227        let first_page = self.start / NULLPAGE_SIZE as u64;
228        let last_page = self.end / NULLPAGE_SIZE as u64;
229        (last_page - first_page) as usize
230    }
231}
232
233impl core::ops::Add<u64> for PhysRange {
234    type Output = Self;
235
236    fn add(self, rhs: u64) -> Self::Output {
237        if rhs == 0 {
238            Self::new(self.start, self.end)
239        } else {
240            Self::new(self.end, self.end + NULLPAGE_SIZE as u64)
241        }
242    }
243}
244
245impl ObjectRange {
246    pub fn new(start: u64, end: u64) -> Self {
247        Self { start, end }
248    }
249
250    pub fn len(&self) -> usize {
251        (self.end - self.start) as usize
252    }
253
254    pub fn pages(&self) -> impl Iterator<Item = u64> {
255        let first_page = self.start / NULLPAGE_SIZE as u64;
256        let last_page = self.end / NULLPAGE_SIZE as u64;
257        first_page..last_page
258    }
259
260    pub fn page_count(&self) -> usize {
261        let first_page = self.start / NULLPAGE_SIZE as u64;
262        let last_page = self.end / NULLPAGE_SIZE as u64;
263        (last_page - first_page) as usize
264    }
265}
266
267#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
268pub struct ObjectEvictInfo {
269    pub obj_id: ObjID,
270    pub range: ObjectRange,
271    pub phys: PhysRange,
272    pub version: u64,
273    pub flags: ObjectEvictFlags,
274    pub uniq_id: ObjID,
275}
276
277impl ObjectEvictInfo {
278    pub fn new(
279        obj_id: ObjID,
280        range: ObjectRange,
281        phys: PhysRange,
282        version: u64,
283        flags: ObjectEvictFlags,
284        uniq_id: ObjID,
285    ) -> Self {
286        Self {
287            uniq_id,
288            obj_id,
289            range,
290            phys,
291            version,
292            flags,
293        }
294    }
295}
296
297bitflags::bitflags! {
298    #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
299    pub struct ObjectEvictFlags: u32 {
300        const SYNC = 1;
301        const FENCE = 2;
302    }
303}