sel4_microkit_simple_ipc/
lib.rs1#![no_std]
8
9use core::error::Error;
10use core::fmt;
11
12use serde::{Deserialize, Serialize};
13use zerocopy::IntoBytes;
14
15use sel4_microkit_base::{
16 Channel, MessageInfo, MessageLabel, MessageRegisterValue, with_msg_regs, with_msg_regs_mut,
17};
18
19const MAX_MESSAGE_LABEL: MessageLabel =
20 !0 >> (size_of::<MessageInfo>() * 8 - MessageInfo::label_width());
21
22pub const UNSPECIFIED_ERROR_MESSAGE_LABEL: MessageLabel = MAX_MESSAGE_LABEL;
23
24pub fn send_unspecified_error() -> MessageInfo {
25 MessageInfo::new(UNSPECIFIED_ERROR_MESSAGE_LABEL, 0)
26}
27
28pub fn try_send<T: Serialize>(val: T) -> Result<MessageInfo, postcard::Error> {
29 with_msg_regs_mut(|buf| {
30 let used = postcard::to_slice(&val, buf.as_mut_bytes())?;
31 let count = bytes_to_words(used.len());
32 Ok(MessageInfo::new(0, count))
33 })
34}
35
36pub fn send<T: Serialize>(val: T) -> MessageInfo {
37 try_send(val).unwrap()
38}
39
40pub fn recv<T: for<'a> Deserialize<'a>>(msg_info: MessageInfo) -> Result<T, RecvError> {
41 let label = msg_info.label();
42 if label != 0 {
43 return Err(RecvError::UnexpectedLabel { label });
44 }
45 with_msg_regs(|buf| postcard::from_bytes(buf.as_bytes()).map_err(RecvError::PostcardError))
46}
47
48pub fn try_call<T: Serialize, U: for<'a> Deserialize<'a>>(
49 channel: Channel,
50 val: T,
51) -> Result<U, TryCallError> {
52 let req_msg_info = try_send(val).map_err(TryCallError::SendError)?;
53 let resp_msg_info = channel.pp_call(req_msg_info);
54 recv(resp_msg_info).map_err(TryCallError::RecvError)
55}
56
57pub fn call<T: Serialize, U: for<'a> Deserialize<'a>>(
58 channel: Channel,
59 val: T,
60) -> Result<U, RecvError> {
61 try_call(channel, val).map_err(|err| match err {
62 TryCallError::SendError(err) => panic!("send error: {err}"),
63 TryCallError::RecvError(err) => err,
64 })
65}
66
67#[derive(Clone, Debug)]
68pub enum RecvError {
69 UnexpectedLabel { label: MessageLabel },
70 PostcardError(postcard::Error),
71}
72
73impl fmt::Display for RecvError {
74 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75 match self {
76 Self::UnexpectedLabel { label } => write!(f, "unexpected label: {label}"),
77 Self::PostcardError(err) => write!(f, "postcard error: {err}"),
78 }
79 }
80}
81
82impl Error for RecvError {}
83
84#[derive(Clone, Debug)]
85pub enum TryCallError {
86 SendError(postcard::Error),
87 RecvError(RecvError),
88}
89
90impl fmt::Display for TryCallError {
91 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92 match self {
93 Self::SendError(err) => write!(f, "send error: {err}"),
94 Self::RecvError(err) => write!(f, "recv error: {err}"),
95 }
96 }
97}
98
99impl Error for TryCallError {}
100
101fn bytes_to_words(num_bytes: usize) -> usize {
104 let d = size_of::<MessageRegisterValue>();
105 num_bytes.next_multiple_of(d) / d
106}