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}