1#![allow(clippy::useless_conversion)]
8
9use core::mem;
10
11use sel4_config::{sel4_cfg, sel4_cfg_if};
12
13use crate::{
14 cap::*, sys, AbsoluteCPtr, CNodeCapData, CPtr, CapRights, Error, InvocationContext,
15 ObjectBlueprint, Result, UserContext, Word,
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 sel4_cfg_if! {
110 if #[sel4_cfg(KERNEL_MCS)] {
111 pub fn tcb_configure(
113 self,
114 cspace_root: CNode,
115 cspace_root_data: CNodeCapData,
116 vspace_root: VSpace,
117 ipc_buffer: Word,
118 ipc_buffer_frame: Granule,
119 ) -> Result<()> {
120 Error::wrap(self.invoke(|cptr, ctx_ipc_buffer| {
121 ctx_ipc_buffer.inner_mut().seL4_TCB_Configure(
122 cptr.bits(),
123 cspace_root.bits(),
124 cspace_root_data.into_word(),
125 vspace_root.bits(),
126 0, ipc_buffer,
128 ipc_buffer_frame.bits(),
129 )
130 }))
131 }
132 } else {
133 pub fn tcb_configure(
135 self,
136 fault_ep: CPtr,
137 cspace_root: CNode,
138 cspace_root_data: CNodeCapData,
139 vspace_root: VSpace,
140 ipc_buffer: Word,
141 ipc_buffer_frame: Granule,
142 ) -> Result<()> {
143 Error::wrap(self.invoke(|cptr, ctx_ipc_buffer| {
144 ctx_ipc_buffer.inner_mut().seL4_TCB_Configure(
145 cptr.bits(),
146 fault_ep.bits(),
147 cspace_root.bits(),
148 cspace_root_data.into_word(),
149 vspace_root.bits(),
150 0, ipc_buffer,
152 ipc_buffer_frame.bits(),
153 )
154 }))
155 }
156 }
157 }
158
159 pub fn tcb_set_space(
161 self,
162 fault_ep: CPtr,
163 cspace_root: CNode,
164 cspace_root_data: CNodeCapData,
165 vspace_root: VSpace,
166 ) -> Result<()> {
167 Error::wrap(self.invoke(|cptr, ipc_buffer| {
168 ipc_buffer.inner_mut().seL4_TCB_SetSpace(
169 cptr.bits(),
170 fault_ep.bits(),
171 cspace_root.bits(),
172 cspace_root_data.into_word(),
173 vspace_root.bits(),
174 0, )
176 }))
177 }
178
179 sel4_cfg_if! {
180 if #[sel4_cfg(KERNEL_MCS)] {
181 pub fn tcb_set_sched_params(
183 self,
184 authority: Tcb,
185 mcp: Word,
186 priority: Word,
187 sched_context: SchedContext,
188 fault_ep: Endpoint,
189 ) -> Result<()> {
190 Error::wrap(self.invoke(|cptr, ipc_buffer| {
191 ipc_buffer.inner_mut().seL4_TCB_SetSchedParams(
192 cptr.bits(),
193 authority.bits(),
194 mcp,
195 priority,
196 sched_context.bits(),
197 fault_ep.bits(),
198 )
199 }))
200 }
201 } else {
202 pub fn tcb_set_sched_params(self, authority: Tcb, mcp: Word, priority: Word) -> Result<()> {
204 Error::wrap(self.invoke(|cptr, ipc_buffer| {
205 ipc_buffer.inner_mut().seL4_TCB_SetSchedParams(
206 cptr.bits(),
207 authority.bits(),
208 mcp,
209 priority,
210 )
211 }))
212 }
213 }
214 }
215
216 #[sel4_cfg(KERNEL_MCS)]
217 pub fn tcb_set_timeout_endpoint(self, timeout_endpoint: Endpoint) -> Result<()> {
218 Error::wrap(self.invoke(|cptr, ipc_buffer| {
219 ipc_buffer
220 .inner_mut()
221 .seL4_TCB_SetTimeoutEndpoint(cptr.bits(), timeout_endpoint.bits())
222 }))
223 }
224
225 #[sel4_cfg(all(not(KERNEL_MCS), not(MAX_NUM_NODES = "1")))]
227 pub fn tcb_set_affinity(self, affinity: Word) -> Result<()> {
228 Error::wrap(self.invoke(|cptr, ipc_buffer| {
229 ipc_buffer
230 .inner_mut()
231 .seL4_TCB_SetAffinity(cptr.bits(), affinity)
232 }))
233 }
234
235 pub fn tcb_set_tls_base(self, tls_base: Word) -> Result<()> {
237 Error::wrap(self.invoke(|cptr, ipc_buffer| {
238 ipc_buffer
239 .inner_mut()
240 .seL4_TCB_SetTLSBase(cptr.bits(), tls_base)
241 }))
242 }
243
244 pub fn tcb_bind_notification(self, notification: Notification) -> Result<()> {
246 Error::wrap(self.invoke(|cptr, ipc_buffer| {
247 ipc_buffer
248 .inner_mut()
249 .seL4_TCB_BindNotification(cptr.bits(), notification.bits())
250 }))
251 }
252
253 pub fn tcb_unbind_notification(self) -> Result<()> {
255 Error::wrap(self.invoke(|cptr, ipc_buffer| {
256 ipc_buffer
257 .inner_mut()
258 .seL4_TCB_UnbindNotification(cptr.bits())
259 }))
260 }
261}
262
263#[sel4_cfg(KERNEL_MCS)]
264impl<C: InvocationContext> SchedControl<C> {
265 pub fn sched_control_configure_flags(
267 self,
268 sched_context: SchedContext,
269 budget: Time,
270 period: Time,
271 extra_refills: Word,
272 badge: Badge,
273 flags: Word,
274 ) -> Result<()> {
275 Error::wrap(self.invoke(|cptr, ipc_buffer| {
276 ipc_buffer.inner_mut().seL4_SchedControl_ConfigureFlags(
277 cptr.bits(),
278 sched_context.bits(),
279 budget,
280 period,
281 extra_refills,
282 badge,
283 flags,
284 )
285 }))
286 }
287}
288
289impl<C: InvocationContext> IrqControl<C> {
290 pub fn irq_control_get(self, irq: Word, dst: &AbsoluteCPtr) -> Result<()> {
292 Error::wrap(self.invoke(|cptr, ipc_buffer| {
293 ipc_buffer.inner_mut().seL4_IRQControl_Get(
294 cptr.bits(),
295 irq,
296 dst.root().bits(),
297 dst.path().bits(),
298 dst.path().depth_for_kernel(),
299 )
300 }))
301 }
302}
303
304impl<C: InvocationContext> IrqHandler<C> {
305 pub fn irq_handler_ack(self) -> Result<()> {
307 Error::wrap(
308 self.invoke(|cptr, ipc_buffer| ipc_buffer.inner_mut().seL4_IRQHandler_Ack(cptr.bits())),
309 )
310 }
311
312 pub fn irq_handler_set_notification(self, notification: Notification) -> Result<()> {
314 Error::wrap(self.invoke(|cptr, ipc_buffer| {
315 ipc_buffer
316 .inner_mut()
317 .seL4_IRQHandler_SetNotification(cptr.bits(), notification.bits())
318 }))
319 }
320
321 pub fn irq_handler_clear(self) -> Result<()> {
323 Error::wrap(
324 self.invoke(|cptr, ipc_buffer| {
325 ipc_buffer.inner_mut().seL4_IRQHandler_Clear(cptr.bits())
326 }),
327 )
328 }
329}
330
331impl<C: InvocationContext> AbsoluteCPtr<C> {
332 pub fn revoke(self) -> Result<()> {
334 Error::wrap(self.invoke(|cptr, path, ipc_buffer| {
335 ipc_buffer.inner_mut().seL4_CNode_Revoke(
336 cptr.bits(),
337 path.bits(),
338 path.depth_for_kernel(),
339 )
340 }))
341 }
342
343 pub fn delete(self) -> Result<()> {
345 Error::wrap(self.invoke(|cptr, path, ipc_buffer| {
346 ipc_buffer.inner_mut().seL4_CNode_Delete(
347 cptr.bits(),
348 path.bits(),
349 path.depth_for_kernel(),
350 )
351 }))
352 }
353
354 pub fn copy(self, src: &AbsoluteCPtr, rights: CapRights) -> Result<()> {
356 Error::wrap(self.invoke(|cptr, path, ipc_buffer| {
357 ipc_buffer.inner_mut().seL4_CNode_Copy(
358 cptr.bits(),
359 path.bits(),
360 path.depth_for_kernel(),
361 src.root().bits(),
362 src.path().bits(),
363 src.path().depth_for_kernel(),
364 rights.into_inner(),
365 )
366 }))
367 }
368
369 pub fn mint(self, src: &AbsoluteCPtr, rights: CapRights, badge: Word) -> Result<()> {
371 Error::wrap(self.invoke(|cptr, path, ipc_buffer| {
372 ipc_buffer.inner_mut().seL4_CNode_Mint(
373 cptr.bits(),
374 path.bits(),
375 path.depth_for_kernel(),
376 src.root().bits(),
377 src.path().bits(),
378 src.path().depth_for_kernel(),
379 rights.into_inner(),
380 badge,
381 )
382 }))
383 }
384
385 pub fn move_(self, src: &AbsoluteCPtr) -> Result<()> {
387 Error::wrap(self.invoke(|cptr, path, ipc_buffer| {
388 ipc_buffer.inner_mut().seL4_CNode_Move(
389 cptr.bits(),
390 path.bits(),
391 path.depth_for_kernel(),
392 src.root().bits(),
393 src.path().bits(),
394 src.path().depth_for_kernel(),
395 )
396 }))
397 }
398
399 pub fn mutate(self, src: &AbsoluteCPtr, badge: Word) -> Result<()> {
401 Error::wrap(self.invoke(|cptr, path, ipc_buffer| {
402 ipc_buffer.inner_mut().seL4_CNode_Mutate(
403 cptr.bits(),
404 path.bits(),
405 path.depth_for_kernel(),
406 src.root().bits(),
407 src.path().bits(),
408 src.path().depth_for_kernel(),
409 badge,
410 )
411 }))
412 }
413
414 #[sel4_cfg(not(KERNEL_MCS))]
416 pub fn save_caller(self) -> Result<()> {
417 Error::wrap(self.invoke(|cptr, path, ipc_buffer| {
418 ipc_buffer.inner_mut().seL4_CNode_SaveCaller(
419 cptr.bits(),
420 path.bits(),
421 path.depth_for_kernel(),
422 )
423 }))
424 }
425}