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}
135
136impl From<KactionGenericCmd> for u32 {
137 fn from(x: KactionGenericCmd) -> Self {
138 let (h, l) = match x {
139 KactionGenericCmd::GetKsoRoot => (0, 0),
140 KactionGenericCmd::GetChild(v) => (1, v),
141 KactionGenericCmd::GetSubObject(t, v) => (2, ((t as u16) << 8) | (v as u16)),
142 KactionGenericCmd::PinPages(v) => (3, v),
143 KactionGenericCmd::ReleasePin => (4, 0),
144 };
145 ((h as u32) << 16) | l as u32
146 }
147}
148
149impl TryFrom<u32> for KactionGenericCmd {
150 type Error = TwzError;
151 fn try_from(x: u32) -> Result<KactionGenericCmd> {
152 let (h, l) = ((x >> 16) as u16, (x & 0xffff) as u16);
153 let v = match h {
154 0 => KactionGenericCmd::GetKsoRoot,
155 1 => KactionGenericCmd::GetChild(l),
156 2 => KactionGenericCmd::GetSubObject((l >> 8) as u8, l as u8),
157 3 => KactionGenericCmd::PinPages(l),
158 4 => KactionGenericCmd::ReleasePin,
159 _ => return Err(ArgumentError::InvalidArgument.into()),
160 };
161 Ok(v)
162 }
163}
164
165#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
167#[repr(C)]
168pub enum KactionCmd {
169 Generic(KactionGenericCmd),
170 Specific(u32),
171}
172
173impl From<KactionCmd> for u64 {
174 fn from(x: KactionCmd) -> Self {
175 let (h, l) = match x {
176 KactionCmd::Generic(x) => (0, x.into()),
177 KactionCmd::Specific(x) => (1, x),
178 };
179 ((h as u64) << 32) | l as u64
180 }
181}
182
183impl TryFrom<u64> for KactionCmd {
184 type Error = TwzError;
185 fn try_from(x: u64) -> Result<KactionCmd> {
186 let (h, l) = ((x >> 32) as u32, (x & 0xffffffff) as u32);
187 let v = match h {
188 0 => KactionCmd::Generic(KactionGenericCmd::try_from(l)?),
189 1 => KactionCmd::Specific(l),
190 _ => return Err(ArgumentError::InvalidArgument.into()),
191 };
192 Ok(v)
193 }
194}
195
196const KACTION_PACK_MASK: u64 = 0xffffffff;
197const KACTION_PACK_BITS: u64 = 32;
198pub fn pack_kaction_pin_start_and_len(start: u64, len: usize) -> Option<u64> {
199 let len: u64 = len.try_into().ok()?;
200 if len > KACTION_PACK_MASK || start > KACTION_PACK_MASK {
201 return None;
202 }
203 Some(len << KACTION_PACK_BITS | start)
204}
205
206pub fn unpack_kaction_pin_start_and_len(val: u64) -> Option<(u64, usize)> {
207 Some((
208 val & KACTION_PACK_MASK,
209 (val >> KACTION_PACK_BITS).try_into().ok()?,
210 ))
211}
212
213pub fn pack_kaction_pin_token_and_len(token: u32, len: usize) -> Option<u64> {
214 let len: u64 = len.try_into().ok()?;
215 let token: u64 = token.into();
216 if len > KACTION_PACK_MASK {
217 return None;
218 }
219 Some(len << KACTION_PACK_BITS | token)
220}
221
222pub fn unpack_kaction_pin_token_and_len(val: u64) -> Option<(u32, usize)> {
223 Some((
224 (val & KACTION_PACK_MASK) as u32,
225 (val >> KACTION_PACK_BITS).try_into().ok()?,
226 ))
227}
228
229#[derive(Debug)]
230#[repr(u32)]
231pub enum InterruptPriority {
232 High,
233 Normal,
234 Low,
235}
236
237bitflags::bitflags! {
238 #[derive(Debug)]
239 pub struct InterruptAllocateOptions:u32 {
240 const UNIQUE = 0x1;
241 }
242}
243
244pub fn pack_kaction_int_pri_and_opts(
245 pri: InterruptPriority,
246 opts: InterruptAllocateOptions,
247) -> u64 {
248 ((pri as u64) << KACTION_PACK_BITS) | opts.bits() as u64
249}
250
251pub fn unpack_kaction_int_pri_and_opts(
252 val: u64,
253) -> Option<(InterruptPriority, InterruptAllocateOptions)> {
254 let pri = match val >> KACTION_PACK_BITS {
255 1 => InterruptPriority::Low,
256 2 => InterruptPriority::High,
257 _ => InterruptPriority::Normal,
258 };
259 let opts = InterruptAllocateOptions::from_bits(val as u32)?;
260 Some((pri, opts))
261}