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}