sel4_microkit_message/
lib.rs

1//
2// Copyright 2023, Colias Group, LLC
3//
4// SPDX-License-Identifier: BSD-2-Clause
5//
6
7#![no_std]
8
9use core::fmt;
10use core::mem;
11
12#[cfg(feature = "postcard")]
13use serde::{Deserialize, Serialize};
14
15use sel4_microkit_base::{with_msg_bytes, with_msg_bytes_mut, MessageInfo, MessageRegisterValue};
16
17use sel4_microkit_message_types::{
18    EmptyMessage, EmptyMessageValue, MessageLabel, MessageRecv, MessageSend, MessageValueRecv,
19    MessageValueSend, TriviallyLabeled,
20};
21
22#[cfg(feature = "postcard")]
23use sel4_microkit_message_types::MessageValueUsingPostcard;
24
25pub use sel4_microkit_message_types as types;
26
27const MAX_MESSAGE_LABEL: MessageLabel =
28    !0 >> (mem::size_of::<MessageInfo>() * 8 - MessageInfo::label_width());
29
30// // //
31
32pub const UNSPECIFIED_ERROR_MESSAGE_LABEL: MessageLabel = MAX_MESSAGE_LABEL;
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
35pub struct UnspecifiedErrorMessage;
36
37impl From<TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL>>
38    for UnspecifiedErrorMessage
39{
40    fn from(_: TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL>) -> Self {
41        Default::default()
42    }
43}
44
45impl From<UnspecifiedErrorMessage>
46    for TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL>
47{
48    fn from(_: UnspecifiedErrorMessage) -> Self {
49        Default::default()
50    }
51}
52
53impl MessageSend for UnspecifiedErrorMessage {
54    type Label = <TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL> as MessageSend>::Label;
55
56    type Error = <TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL> as MessageSend>::Error;
57
58    fn write_message(self, buf: &mut [u8]) -> Result<(Self::Label, usize), Self::Error> {
59        <TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL>>::from(self)
60            .write_message(buf)
61    }
62}
63
64impl MessageRecv for UnspecifiedErrorMessage {
65    type Label = <TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL> as MessageRecv>::Label;
66
67    type Error = <TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL> as MessageRecv>::Error;
68
69    fn read_message(label: Self::Label, buf: &[u8]) -> Result<Self, Self::Error> {
70        <TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL>>::read_message(
71            label, buf,
72        )
73        .map(Into::into)
74    }
75}
76
77// // //
78
79pub trait MessageInfoExt: Sized {
80    fn send<T: MessageSend>(val: T) -> Result<Self, T::Error>;
81
82    fn recv<T: MessageRecv>(self) -> Result<T, MessageRecvErrorFor<T>>;
83
84    fn send_unspecified_error() -> Self {
85        Self::send(UnspecifiedErrorMessage).unwrap_or_else(|absurdity| match absurdity {})
86    }
87
88    fn send_empty() -> Self {
89        Self::send(EmptyMessage).unwrap_or_else(|absurdity| match absurdity {})
90    }
91
92    fn recv_empty(self) -> Result<(), MessageRecvErrorFor<EmptyMessage>> {
93        self.recv().map(|EmptyMessage| ())
94    }
95
96    fn send_with_trivial_label<T: MessageValueSend>(val: T) -> Result<Self, T::Error> {
97        type Helper<T> = TriviallyLabeled<T>; // get default LABEL
98        Self::send(Helper::new(val))
99    }
100
101    fn recv_with_trivial_label<T: MessageValueRecv>(
102        self,
103    ) -> Result<T, MessageRecvErrorFor<TriviallyLabeled<T>>> {
104        self.recv().map(TriviallyLabeled::into_inner)
105    }
106
107    #[cfg(feature = "postcard")]
108    fn send_using_postcard<T: Serialize>(
109        val: T,
110    ) -> Result<Self, <MessageValueUsingPostcard<T> as MessageValueSend>::Error> {
111        Self::send_with_trivial_label(MessageValueUsingPostcard(val))
112    }
113
114    #[cfg(feature = "postcard")]
115    fn recv_using_postcard<T: for<'a> Deserialize<'a>>(
116        self,
117    ) -> Result<T, MessageRecvErrorFor<TriviallyLabeled<MessageValueUsingPostcard<T>>>> {
118        self.recv_with_trivial_label()
119            .map(|MessageValueUsingPostcard(val)| val)
120    }
121}
122
123impl MessageInfoExt for MessageInfo {
124    fn send<T: MessageSend>(val: T) -> Result<Self, T::Error> {
125        let (label, num_bytes) = with_msg_bytes_mut(|buf| val.write_message(buf))?;
126        let label = label.into();
127        assert!(label <= MAX_MESSAGE_LABEL);
128        // assert!(label != UNSPECIFIED_ERROR_MESSAGE_LABEL);
129        Ok(Self::new(label, bytes_to_mrs(num_bytes)))
130    }
131
132    fn recv<T: MessageRecv>(self) -> Result<T, MessageRecvErrorFor<T>> {
133        // if self.label() == UNSPECIFIED_ERROR_MESSAGE_LABEL) {
134        //     return Err(MessageRecvError::Unspecified);
135        // }
136        let label = self
137            .label()
138            .try_into()
139            .map_err(MessageRecvError::LabelError)?;
140        with_msg_bytes(|buf| T::read_message(label, &buf[..mrs_to_bytes(self.count())]))
141            .map_err(MessageRecvError::ValueError)
142    }
143
144    // fn send_unspecified_error() -> Self {
145    //     Self::new(UNSPECIFIED_ERROR_MESSAGE_LABEL, 0)
146    // }
147}
148
149pub type MessageRecvErrorFor<T> = MessageRecvError<
150    <<T as MessageRecv>::Label as TryFrom<MessageLabel>>::Error,
151    <T as MessageRecv>::Error,
152>;
153
154#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
155pub enum MessageRecvError<E1, E2> {
156    LabelError(E1),
157    ValueError(E2),
158    // Unspecified,
159}
160
161impl<E1: fmt::Display, E2: fmt::Display> fmt::Display for MessageRecvError<E1, E2> {
162    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
163        match self {
164            Self::LabelError(err) => write!(f, "label error: {}", err),
165            Self::ValueError(err) => write!(f, "value error: {}", err),
166            // Self::Unspecified => write!(f, "unspecified error"),
167        }
168    }
169}
170
171fn mrs_to_bytes(num_mrs: usize) -> usize {
172    num_mrs * mem::size_of::<MessageRegisterValue>()
173}
174
175fn bytes_to_mrs(num_bytes: usize) -> usize {
176    let d = mem::size_of::<MessageRegisterValue>();
177    num_bytes.next_multiple_of(d) / d
178}