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
227impl core::ops::Add<u64> for PhysRange {
228    type Output = Self;
229
230    fn add(self, rhs: u64) -> Self::Output {
231        if rhs == 0 {
232            Self::new(self.start, self.end)
233        } else {
234            Self::new(self.end, self.end + NULLPAGE_SIZE as u64)
235        }
236    }
237}
238
239impl ObjectRange {
240    pub fn new(start: u64, end: u64) -> Self {
241        Self { start, end }
242    }
243
244    pub fn len(&self) -> usize {
245        (self.end - self.start) as usize
246    }
247
248    pub fn pages(&self) -> impl Iterator<Item = u64> {
249        let first_page = self.start / NULLPAGE_SIZE as u64;
250        let last_page = self.end / NULLPAGE_SIZE as u64;
251        first_page..last_page
252    }
253}
254
255#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
256pub struct ObjectEvictInfo {
257    pub obj_id: ObjID,
258    pub range: ObjectRange,
259    pub phys: PhysRange,
260    pub version: u64,
261    pub flags: ObjectEvictFlags,
262}
263
264impl ObjectEvictInfo {
265    pub fn new(
266        obj_id: ObjID,
267        range: ObjectRange,
268        phys: PhysRange,
269        version: u64,
270        flags: ObjectEvictFlags,
271    ) -> Self {
272        Self {
273            obj_id,
274            range,
275            phys,
276            version,
277            flags,
278        }
279    }
280}
281
282bitflags::bitflags! {
283    #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
284    pub struct ObjectEvictFlags: u32 {
285        const SYNC = 1;
286        const FENCE = 2;
287    }
288}