1use core::fmt::Display;
5
6use twizzler_rt_abi::{
7 error::{ArgumentError, TwzError},
8 Result,
9};
10
11use crate::object::ObjID;
12
13pub const KSO_NAME_MAX_LEN: usize = 512;
15#[repr(C)]
17pub struct KsoHdr {
18 version: u32,
19 flags: u16,
20 name_len: u16,
21 name: [u8; KSO_NAME_MAX_LEN],
22}
23
24impl Display for KsoHdr {
25 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
26 write!(
27 f,
28 "{}",
29 core::str::from_utf8(&self.name[0..self.name_len as usize])
30 .map_err(|_| core::fmt::Error)?
31 )
32 }
33}
34
35impl KsoHdr {
36 pub fn new(name: &str) -> Self {
38 let b = name.as_bytes();
39 let mut ret = Self {
40 version: 0,
41 flags: 0,
42 name_len: b.len() as u16,
43 name: [0; KSO_NAME_MAX_LEN],
44 };
45 for (i, v) in b.iter().take(KSO_NAME_MAX_LEN).enumerate() {
46 ret.name[i] = *v;
47 }
48 ret
49 }
50}
51
52#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
54#[repr(C)]
55pub enum KactionValue {
56 U64(u64),
57 ObjID(ObjID),
58}
59
60impl From<(u64, u64)> for KactionValue {
61 fn from(x: (u64, u64)) -> Self {
62 if x.0 == 0xFFFFFFFFFFFFFFFF {
63 Self::U64(x.1)
64 } else {
65 Self::ObjID(ObjID::from_parts([x.0, x.1]))
66 }
67 }
68}
69
70impl From<KactionValue> for (u64, u64) {
71 fn from(x: KactionValue) -> Self {
72 let parts = match x {
73 KactionValue::U64(x) => [0xffffffffffffffff, x],
74 KactionValue::ObjID(id) => id.parts(),
75 };
76 (parts[0], parts[1])
77 }
78}
79
80impl KactionValue {
81 pub fn unwrap_objid(self) -> ObjID {
83 match self {
84 KactionValue::U64(_) => panic!("failed to unwrap ObjID"),
85 KactionValue::ObjID(o) => o,
86 }
87 }
88
89 pub fn objid(self) -> Option<ObjID> {
91 match self {
92 KactionValue::U64(_) => None,
93 KactionValue::ObjID(o) => Some(o),
94 }
95 }
96
97 pub fn unwrap_u64(self) -> u64 {
99 match self {
100 KactionValue::ObjID(_) => panic!("failed to unwrap ObjID"),
101 KactionValue::U64(o) => o,
102 }
103 }
104
105 pub fn u64(self) -> Option<u64> {
107 match self {
108 KactionValue::U64(x) => Some(x),
109 KactionValue::ObjID(_) => None,
110 }
111 }
112}
113
114bitflags::bitflags! {
115 pub struct KactionFlags: u64 {
117 }
118}
119
120#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
122#[repr(C)]
123pub enum KactionGenericCmd {
124 GetKsoRoot,
126 GetChild(u16),
128 GetSubObject(u8, u8),
130 PinPages(u16),
132 ReleasePin,
134 MapPhys(u16),
136}
137
138impl From<KactionGenericCmd> for u32 {
139 fn from(x: KactionGenericCmd) -> Self {
140 let (h, l) = match x {
141 KactionGenericCmd::GetKsoRoot => (0, 0),
142 KactionGenericCmd::GetChild(v) => (1, v),
143 KactionGenericCmd::GetSubObject(t, v) => (2, ((t as u16) << 8) | (v as u16)),
144 KactionGenericCmd::PinPages(v) => (3, v),
145 KactionGenericCmd::ReleasePin => (4, 0),
146 KactionGenericCmd::MapPhys(v) => (5, v),
147 };
148 ((h as u32) << 16) | l as u32
149 }
150}
151
152impl TryFrom<u32> for KactionGenericCmd {
153 type Error = TwzError;
154 fn try_from(x: u32) -> Result<KactionGenericCmd> {
155 let (h, l) = ((x >> 16) as u16, (x & 0xffff) as u16);
156 let v = match h {
157 0 => KactionGenericCmd::GetKsoRoot,
158 1 => KactionGenericCmd::GetChild(l),
159 2 => KactionGenericCmd::GetSubObject((l >> 8) as u8, l as u8),
160 3 => KactionGenericCmd::PinPages(l),
161 4 => KactionGenericCmd::ReleasePin,
162 5 => KactionGenericCmd::MapPhys(l),
163 _ => return Err(TwzError::INVALID_ARGUMENT),
164 };
165 Ok(v)
166 }
167}
168
169#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
171#[repr(C)]
172pub enum KactionCmd {
173 Generic(KactionGenericCmd),
174 Specific(u32),
175}
176
177impl From<KactionCmd> for u64 {
178 fn from(x: KactionCmd) -> Self {
179 let (h, l) = match x {
180 KactionCmd::Generic(x) => (0, x.into()),
181 KactionCmd::Specific(x) => (1, x),
182 };
183 ((h as u64) << 32) | l as u64
184 }
185}
186
187impl TryFrom<u64> for KactionCmd {
188 type Error = TwzError;
189 fn try_from(x: u64) -> Result<KactionCmd> {
190 let (h, l) = ((x >> 32) as u32, (x & 0xffffffff) as u32);
191 let v = match h {
192 0 => KactionCmd::Generic(KactionGenericCmd::try_from(l)?),
193 1 => KactionCmd::Specific(l),
194 _ => return Err(ArgumentError::InvalidArgument.into()),
195 };
196 Ok(v)
197 }
198}
199
200const KACTION_PACK_MASK: u64 = 0xffffffff;
201const KACTION_PACK_BITS: u64 = 32;
202pub fn pack_kaction_pin_start_and_len(start: u64, len: usize) -> Option<u64> {
203 let len: u64 = len.try_into().ok()?;
204 if len > KACTION_PACK_MASK || start > KACTION_PACK_MASK {
205 return None;
206 }
207 Some(len << KACTION_PACK_BITS | start)
208}
209
210pub fn unpack_kaction_pin_start_and_len(val: u64) -> Option<(u64, usize)> {
211 Some((
212 val & KACTION_PACK_MASK,
213 (val >> KACTION_PACK_BITS).try_into().ok()?,
214 ))
215}
216
217pub fn pack_kaction_pin_token_and_len(token: u32, len: usize) -> Option<u64> {
218 let len: u64 = len.try_into().ok()?;
219 let token: u64 = token.into();
220 if len > KACTION_PACK_MASK {
221 return None;
222 }
223 Some(len << KACTION_PACK_BITS | token)
224}
225
226pub fn unpack_kaction_pin_token_and_len(val: u64) -> Option<(u32, usize)> {
227 Some((
228 (val & KACTION_PACK_MASK) as u32,
229 (val >> KACTION_PACK_BITS).try_into().ok()?,
230 ))
231}
232
233#[derive(Debug)]
234#[repr(u32)]
235pub enum InterruptPriority {
236 High,
237 Normal,
238 Low,
239}
240
241bitflags::bitflags! {
242 #[derive(Debug)]
243 pub struct InterruptAllocateOptions:u32 {
244 const UNIQUE = 0x1;
245 }
246}
247
248pub fn pack_kaction_int_pri_and_opts(
249 pri: InterruptPriority,
250 opts: InterruptAllocateOptions,
251) -> u64 {
252 ((pri as u64) << KACTION_PACK_BITS) | opts.bits() as u64
253}
254
255pub fn unpack_kaction_int_pri_and_opts(
256 val: u64,
257) -> Option<(InterruptPriority, InterruptAllocateOptions)> {
258 let pri = match val >> KACTION_PACK_BITS {
259 1 => InterruptPriority::Low,
260 2 => InterruptPriority::High,
261 _ => InterruptPriority::Normal,
262 };
263 let opts = InterruptAllocateOptions::from_bits(val as u32)?;
264 Some((pri, opts))
265}