sel4/
ipc_buffer.rs
1use core::mem;
9use core::slice;
10
11#[sel4_cfg(KERNEL_INVOCATION_REPORT_ERROR_IPC)]
12use core::str::{self, Utf8Error};
13
14use crate::{cap, newtype_methods, sel4_cfg, sys, AbsoluteCPtr, Word};
15
16#[sel4_cfg(KERNEL_INVOCATION_REPORT_ERROR_IPC)]
17use crate::const_helpers::u32_into_usize;
18
19#[derive(Default)]
21#[repr(transparent)]
22pub struct IpcBuffer(sys::seL4_IPCBuffer);
23
24impl IpcBuffer {
25 newtype_methods!(pub sys::seL4_IPCBuffer);
26
27 pub fn msg_regs(&self) -> &[Word] {
28 &self.inner().msg[..]
29 }
30
31 pub fn msg_regs_mut(&mut self) -> &mut [Word] {
32 &mut self.inner_mut().msg[..]
33 }
34
35 pub fn msg_bytes(&self) -> &[u8] {
36 let msg = &self.inner().msg;
37 let msg_ptr = msg as *const Word;
38 let size = mem::size_of_val(msg);
39 unsafe { slice::from_raw_parts(msg_ptr.cast(), size) }
40 }
41
42 pub fn msg_bytes_mut(&mut self) -> &mut [u8] {
43 let msg = &mut self.inner_mut().msg;
44 let msg_ptr = msg as *mut Word;
45 let size = mem::size_of_val(msg);
46 unsafe { slice::from_raw_parts_mut(msg_ptr.cast(), size) }
47 }
48
49 pub fn user_data(&self) -> Word {
50 self.inner().userData
51 }
52
53 pub fn set_user_data(&mut self, data: Word) {
54 self.inner_mut().userData = data;
55 }
56
57 pub fn caps_or_badges(&self) -> &[Word] {
58 &self.inner().caps_or_badges[..]
59 }
60
61 pub fn caps_or_badges_mut(&mut self) -> &mut [Word] {
62 &mut self.inner_mut().caps_or_badges[..]
63 }
64
65 pub fn recv_slot(&self) -> AbsoluteCPtr {
66 let inner = self.inner();
67 cap::CNode::from_bits(inner.receiveCNode).absolute_cptr_from_bits_with_depth(
68 inner.receiveIndex,
69 inner.receiveDepth.try_into().unwrap(),
70 )
71 }
72
73 pub fn set_recv_slot(&mut self, slot: &AbsoluteCPtr) {
74 let inner = self.inner_mut();
75 inner.receiveCNode = slot.root().bits();
76 inner.receiveIndex = slot.path().bits();
77 inner.receiveDepth = slot.path().depth().try_into().unwrap();
78 }
79
80 #[sel4_cfg(KERNEL_INVOCATION_REPORT_ERROR_IPC)]
81 pub fn debug_error_bytes(&self) -> &[u8] {
82 let start = u32_into_usize(sys::DEBUG_MESSAGE_START) * mem::size_of::<Word>();
83 let len = u32_into_usize(sys::DEBUG_MESSAGE_MAXLEN) * mem::size_of::<Word>();
84 let all_bytes = &self.msg_bytes()[start..][..len];
85 let n = all_bytes.iter().take_while(|b| **b != 0).count();
86 &all_bytes[..n]
87 }
88
89 #[sel4_cfg(KERNEL_INVOCATION_REPORT_ERROR_IPC)]
90 pub fn debug_error(&self) -> Result<&str, Utf8Error> {
91 str::from_utf8(self.debug_error_bytes())
92 }
93}