1#![allow(clippy::useless_conversion)]
8
9use core::mem;
10
11use sel4_config::{sel4_cfg, sel4_cfg_if};
12
13use crate::{
14 AbsoluteCPtr, CNodeCapData, CPtr, CapRights, Error, InvocationContext, ObjectBlueprint, Result,
15 UserContext, Word, cap::*, sys,
16};
17
18#[sel4_cfg(KERNEL_MCS)]
19use crate::Badge;
20
21#[sel4_cfg(KERNEL_MCS)]
23pub type Time = u64;
24
25impl<C: InvocationContext> Untyped<C> {
26 pub fn untyped_retype(
28 self,
29 blueprint: &ObjectBlueprint,
30 dst: &AbsoluteCPtr,
31 dst_offset: usize,
32 num_objects: usize,
33 ) -> Result<()> {
34 Error::wrap(self.invoke(|cptr, ipc_buffer| {
35 ipc_buffer.inner_mut().seL4_Untyped_Retype(
36 cptr.bits(),
37 blueprint.ty().into_sys().into(),
38 blueprint.api_size_bits().unwrap_or(0).try_into().unwrap(),
39 dst.root().bits(),
40 dst.path().bits(),
41 dst.path().depth().try_into().unwrap(),
42 dst_offset.try_into().unwrap(),
43 num_objects.try_into().unwrap(),
44 )
45 }))
46 }
47}
48
49const USER_CONTEXT_MAX_REG_COUNT: usize =
50 mem::size_of::<sys::seL4_UserContext>() / mem::size_of::<Word>();
51
52impl<C: InvocationContext> Tcb<C> {
53 pub fn tcb_read_registers(self, suspend: bool, count: Word) -> Result<UserContext> {
55 let mut regs: UserContext = Default::default();
56 let err = self.invoke(|cptr, ipc_buffer| {
57 ipc_buffer.inner_mut().seL4_TCB_ReadRegisters(
58 cptr.bits(),
59 suspend.into(),
60 0,
61 count,
62 regs.inner_mut(),
63 )
64 });
65 Error::or(err, regs)
66 }
67
68 pub fn tcb_read_all_registers(self, suspend: bool) -> Result<UserContext> {
69 self.tcb_read_registers(suspend, USER_CONTEXT_MAX_REG_COUNT.try_into().unwrap())
70 }
71
72 pub fn tcb_write_registers(
75 self,
76 resume: bool,
77 count: Word,
78 regs: &mut UserContext,
79 ) -> Result<()> {
80 Error::wrap(self.invoke(|cptr, ipc_buffer| {
81 ipc_buffer.inner_mut().seL4_TCB_WriteRegisters(
82 cptr.bits(),
83 resume.into(),
84 0,
85 count,
86 regs.inner_mut(),
87 )
88 }))
89 }
90
91 pub fn tcb_write_all_registers(self, resume: bool, regs: &mut UserContext) -> Result<()> {
92 self.tcb_write_registers(resume, USER_CONTEXT_MAX_REG_COUNT.try_into().unwrap(), regs)
93 }
94
95 pub fn tcb_resume(self) -> Result<()> {
97 Error::wrap(
98 self.invoke(|cptr, ipc_buffer| ipc_buffer.inner_mut().seL4_TCB_Resume(cptr.bits())),
99 )
100 }
101
102 pub fn tcb_suspend(self) -> Result<()> {
104 Error::wrap(
105 self.invoke(|cptr, ipc_buffer| ipc_buffer.inner_mut().seL4_TCB_Suspend(cptr.bits())),
106 )
107 }
108
109 pub fn tcb_set_priority(self, authority: Tcb, priority: Word) -> Result<()> {
111 Error::wrap(self.invoke(|cptr, ipc_buffer| {
112 ipc_buffer
113 .inner_mut()
114 .seL4_TCB_SetPriority(cptr.bits(), authority.bits(), priority)
115 }))
116 }
117
118 pub fn tcb_set_mc_priority(self, authority: Tcb, mcp: Word) -> Result<()> {
120 Error::wrap(self.invoke(|cptr, ipc_buffer| {
121 ipc_buffer
122 .inner_mut()
123 .seL4_TCB_SetMCPriority(cptr.bits(), authority.bits(), mcp)
124 }))
125 }
126
127 sel4_cfg_if! {
128 if #[sel4_cfg(KERNEL_MCS)] {
129 pub fn tcb_configure(
131 self,
132 cspace_root: CNode,
133 cspace_root_data: CNodeCapData,
134 vspace_root: VSpace,
135 ipc_buffer: Word,
136 ipc_buffer_frame: Granule,
137 ) -> Result<()> {
138 Error::wrap(self.invoke(|cptr, ctx_ipc_buffer| {
139 ctx_ipc_buffer.inner_mut().seL4_TCB_Configure(
140 cptr.bits(),
141 cspace_root.bits(),
142 cspace_root_data.into_word(),
143 vspace_root.bits(),
144 0, ipc_buffer,
146 ipc_buffer_frame.bits(),
147 )
148 }))
149 }
150 } else {
151 pub fn tcb_configure(
153 self,
154 fault_ep: CPtr,
155 cspace_root: CNode,
156 cspace_root_data: CNodeCapData,
157 vspace_root: VSpace,
158 ipc_buffer: Word,
159 ipc_buffer_frame: Granule,
160 ) -> Result<()> {
161 Error::wrap(self.invoke(|cptr, ctx_ipc_buffer| {
162 ctx_ipc_buffer.inner_mut().seL4_TCB_Configure(
163 cptr.bits(),
164 fault_ep.bits(),
165 cspace_root.bits(),
166 cspace_root_data.into_word(),
167 vspace_root.bits(),
168 0, ipc_buffer,
170 ipc_buffer_frame.bits(),
171 )
172 }))
173 }
174 }
175 }
176
177 pub fn tcb_set_space(
179 self,
180 fault_ep: CPtr,
181 cspace_root: CNode,
182 cspace_root_data: CNodeCapData,
183 vspace_root: VSpace,
184 ) -> Result<()> {
185 Error::wrap(self.invoke(|cptr, ipc_buffer| {
186 ipc_buffer.inner_mut().seL4_TCB_SetSpace(
187 cptr.bits(),
188 fault_ep.bits(),
189 cspace_root.bits(),
190 cspace_root_data.into_word(),
191 vspace_root.bits(),
192 0, )
194 }))
195 }
196
197 sel4_cfg_if! {
198 if #[sel4_cfg(KERNEL_MCS)] {
199 pub fn tcb_set_sched_params(
201 self,
202 authority: Tcb,
203 mcp: Word,
204 priority: Word,
205 sched_context: SchedContext,
206 fault_ep: Endpoint,
207 ) -> Result<()> {
208 Error::wrap(self.invoke(|cptr, ipc_buffer| {
209 ipc_buffer.inner_mut().seL4_TCB_SetSchedParams(
210 cptr.bits(),
211 authority.bits(),
212 mcp,
213 priority,
214 sched_context.bits(),
215 fault_ep.bits(),
216 )
217 }))
218 }
219 } else {
220 pub fn tcb_set_sched_params(self, authority: Tcb, mcp: Word, priority: Word) -> Result<()> {
222 Error::wrap(self.invoke(|cptr, ipc_buffer| {
223 ipc_buffer.inner_mut().seL4_TCB_SetSchedParams(
224 cptr.bits(),
225 authority.bits(),
226 mcp,
227 priority,
228 )
229 }))
230 }
231 }
232 }
233
234 #[sel4_cfg(KERNEL_MCS)]
235 pub fn tcb_set_timeout_endpoint(self, timeout_endpoint: Endpoint) -> Result<()> {
236 Error::wrap(self.invoke(|cptr, ipc_buffer| {
237 ipc_buffer
238 .inner_mut()
239 .seL4_TCB_SetTimeoutEndpoint(cptr.bits(), timeout_endpoint.bits())
240 }))
241 }
242
243 #[sel4_cfg(all(not(KERNEL_MCS), not(MAX_NUM_NODES = "1")))]
245 pub fn tcb_set_affinity(self, affinity: Word) -> Result<()> {
246 Error::wrap(self.invoke(|cptr, ipc_buffer| {
247 ipc_buffer
248 .inner_mut()
249 .seL4_TCB_SetAffinity(cptr.bits(), affinity)
250 }))
251 }
252
253 pub fn tcb_set_tls_base(self, tls_base: Word) -> Result<()> {
255 Error::wrap(self.invoke(|cptr, ipc_buffer| {
256 ipc_buffer
257 .inner_mut()
258 .seL4_TCB_SetTLSBase(cptr.bits(), tls_base)
259 }))
260 }
261
262 pub fn tcb_bind_notification(self, notification: Notification) -> Result<()> {
264 Error::wrap(self.invoke(|cptr, ipc_buffer| {
265 ipc_buffer
266 .inner_mut()
267 .seL4_TCB_BindNotification(cptr.bits(), notification.bits())
268 }))
269 }
270
271 pub fn tcb_unbind_notification(self) -> Result<()> {
273 Error::wrap(self.invoke(|cptr, ipc_buffer| {
274 ipc_buffer
275 .inner_mut()
276 .seL4_TCB_UnbindNotification(cptr.bits())
277 }))
278 }
279}
280
281#[sel4_cfg(KERNEL_MCS)]
282impl<C: InvocationContext> SchedControl<C> {
283 pub fn sched_control_configure_flags(
285 self,
286 sched_context: SchedContext,
287 budget: Time,
288 period: Time,
289 extra_refills: Word,
290 badge: Badge,
291 flags: Word,
292 ) -> Result<()> {
293 Error::wrap(self.invoke(|cptr, ipc_buffer| {
294 ipc_buffer.inner_mut().seL4_SchedControl_ConfigureFlags(
295 cptr.bits(),
296 sched_context.bits(),
297 budget,
298 period,
299 extra_refills,
300 badge,
301 flags,
302 )
303 }))
304 }
305}
306
307#[sel4_cfg(KERNEL_MCS)]
308impl<C: InvocationContext> SchedContext<C> {
309 pub fn unbind(self) -> Result<()> {
311 Error::wrap(self.invoke(|cptr, ipc_buffer| {
312 ipc_buffer.inner_mut().seL4_SchedContext_Unbind(cptr.bits())
313 }))
314 }
315}
316
317impl<C: InvocationContext> IrqControl<C> {
318 pub fn irq_control_get(self, irq: Word, dst: &AbsoluteCPtr) -> Result<()> {
320 Error::wrap(self.invoke(|cptr, ipc_buffer| {
321 ipc_buffer.inner_mut().seL4_IRQControl_Get(
322 cptr.bits(),
323 irq,
324 dst.root().bits(),
325 dst.path().bits(),
326 dst.path().depth_for_kernel(),
327 )
328 }))
329 }
330}
331
332impl<C: InvocationContext> IrqHandler<C> {
333 pub fn irq_handler_ack(self) -> Result<()> {
335 Error::wrap(
336 self.invoke(|cptr, ipc_buffer| ipc_buffer.inner_mut().seL4_IRQHandler_Ack(cptr.bits())),
337 )
338 }
339
340 pub fn irq_handler_set_notification(self, notification: Notification) -> Result<()> {
342 Error::wrap(self.invoke(|cptr, ipc_buffer| {
343 ipc_buffer
344 .inner_mut()
345 .seL4_IRQHandler_SetNotification(cptr.bits(), notification.bits())
346 }))
347 }
348
349 pub fn irq_handler_clear(self) -> Result<()> {
351 Error::wrap(
352 self.invoke(|cptr, ipc_buffer| {
353 ipc_buffer.inner_mut().seL4_IRQHandler_Clear(cptr.bits())
354 }),
355 )
356 }
357}
358
359impl<C: InvocationContext> AbsoluteCPtr<C> {
360 pub fn revoke(self) -> Result<()> {
362 Error::wrap(self.invoke(|cptr, path, ipc_buffer| {
363 ipc_buffer.inner_mut().seL4_CNode_Revoke(
364 cptr.bits(),
365 path.bits(),
366 path.depth_for_kernel(),
367 )
368 }))
369 }
370
371 pub fn delete(self) -> Result<()> {
373 Error::wrap(self.invoke(|cptr, path, ipc_buffer| {
374 ipc_buffer.inner_mut().seL4_CNode_Delete(
375 cptr.bits(),
376 path.bits(),
377 path.depth_for_kernel(),
378 )
379 }))
380 }
381
382 pub fn copy(self, src: &AbsoluteCPtr, rights: CapRights) -> Result<()> {
384 Error::wrap(self.invoke(|cptr, path, ipc_buffer| {
385 ipc_buffer.inner_mut().seL4_CNode_Copy(
386 cptr.bits(),
387 path.bits(),
388 path.depth_for_kernel(),
389 src.root().bits(),
390 src.path().bits(),
391 src.path().depth_for_kernel(),
392 rights.into_inner(),
393 )
394 }))
395 }
396
397 pub fn mint(self, src: &AbsoluteCPtr, rights: CapRights, badge: Word) -> Result<()> {
399 Error::wrap(self.invoke(|cptr, path, ipc_buffer| {
400 ipc_buffer.inner_mut().seL4_CNode_Mint(
401 cptr.bits(),
402 path.bits(),
403 path.depth_for_kernel(),
404 src.root().bits(),
405 src.path().bits(),
406 src.path().depth_for_kernel(),
407 rights.into_inner(),
408 badge,
409 )
410 }))
411 }
412
413 pub fn move_(self, src: &AbsoluteCPtr) -> Result<()> {
415 Error::wrap(self.invoke(|cptr, path, ipc_buffer| {
416 ipc_buffer.inner_mut().seL4_CNode_Move(
417 cptr.bits(),
418 path.bits(),
419 path.depth_for_kernel(),
420 src.root().bits(),
421 src.path().bits(),
422 src.path().depth_for_kernel(),
423 )
424 }))
425 }
426
427 pub fn mutate(self, src: &AbsoluteCPtr, badge: Word) -> Result<()> {
429 Error::wrap(self.invoke(|cptr, path, ipc_buffer| {
430 ipc_buffer.inner_mut().seL4_CNode_Mutate(
431 cptr.bits(),
432 path.bits(),
433 path.depth_for_kernel(),
434 src.root().bits(),
435 src.path().bits(),
436 src.path().depth_for_kernel(),
437 badge,
438 )
439 }))
440 }
441
442 #[sel4_cfg(not(KERNEL_MCS))]
444 pub fn save_caller(self) -> Result<()> {
445 Error::wrap(self.invoke(|cptr, path, ipc_buffer| {
446 ipc_buffer.inner_mut().seL4_CNode_SaveCaller(
447 cptr.bits(),
448 path.bits(),
449 path.depth_for_kernel(),
450 )
451 }))
452 }
453}