sel4/
ipc_buffer.rs

1//
2// Copyright 2023, Colias Group, LLC
3// Copyright (c) 2020 Arm Limited
4//
5// SPDX-License-Identifier: MIT
6//
7
8use 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/// Corresponds to `seL4_IPCBuffer`.
20#[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}