sel4_microkit_base/
ipc.rs1use core::fmt;
8
9use crate::{Channel, Child, MessageInfo, defer::PreparedDeferredAction};
10
11const INPUT_CAP: sel4::cap::Endpoint = sel4::Cap::from_bits(1);
12const REPLY_CAP: sel4::cap::Reply = sel4::Cap::from_bits(4);
13const MONITOR_EP_CAP: sel4::cap::Endpoint = sel4::Cap::from_bits(5);
14
15const IS_ENDPOINT_BADGE_BIT: usize = 63;
16const IS_FAULT_BADGE_BIT: usize = 62;
17
18fn strip_flag(badge: sel4::Badge, bit: usize) -> Option<sel4::Word> {
19 let mask = 1 << bit;
20 if badge & mask != 0 {
21 Some(badge & !mask)
22 } else {
23 None
24 }
25}
26
27#[doc(hidden)]
28#[derive(Debug, Clone)]
29pub enum Event {
30 Notified(ChannelSet),
31 Protected(Channel, MessageInfo),
32 Fault(Child, MessageInfo),
33}
34
35impl Event {
36 fn new(tag: sel4::MessageInfo, badge: sel4::Badge) -> Self {
37 if let Some(channel_index) = strip_flag(badge, IS_ENDPOINT_BADGE_BIT) {
38 Self::Protected(
39 Channel::new(channel_index.try_into().unwrap()),
40 MessageInfo::from_inner(tag),
41 )
42 } else if let Some(pd_index) = strip_flag(badge, IS_FAULT_BADGE_BIT) {
43 Self::Fault(
44 Child::new(pd_index.try_into().unwrap()),
45 MessageInfo::from_inner(tag),
46 )
47 } else {
48 Self::Notified(ChannelSet(badge))
49 }
50 }
51
52 fn from_recv(recv: (sel4::MessageInfo, sel4::Badge)) -> Self {
53 Self::new(recv.0, recv.1)
54 }
55}
56
57#[doc(hidden)]
58#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
59pub struct ChannelSet(sel4::Badge);
60
61impl ChannelSet {
62 pub fn contains(&self, channel: Channel) -> bool {
63 (self.0 & (1 << channel.index())) != 0
64 }
65
66 pub fn iter(&self) -> ChannelSetIter {
67 ChannelSetIter(self.0)
68 }
69
70 pub fn display(&self) -> DisplayChannelSet<'_> {
71 DisplayChannelSet(self)
72 }
73}
74
75#[doc(hidden)]
76pub struct ChannelSetIter(sel4::Badge);
77
78impl Iterator for ChannelSetIter {
79 type Item = Channel;
80
81 fn next(&mut self) -> Option<Self::Item> {
82 let badge_bits = self.0;
83 match badge_bits {
84 0 => None,
85 _ => {
86 let i = badge_bits.trailing_zeros();
87 self.0 = badge_bits & !(1 << i);
88 Some(Channel::new(i.try_into().unwrap()))
89 }
90 }
91 }
92}
93
94pub struct DisplayChannelSet<'a>(&'a ChannelSet);
95
96impl fmt::Display for DisplayChannelSet<'_> {
97 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
98 write!(f, "{{")?;
99 let mut first = true;
100 for channel in self.0.iter() {
101 if !first {
102 write!(f, ", ")?;
103 }
104 write!(f, "{}", channel.index())?;
105 first = false;
106 }
107 write!(f, "}}")?;
108 Ok(())
109 }
110}
111
112pub fn reply(msg_info: MessageInfo) {
113 REPLY_CAP.send(msg_info.into_inner())
114}
115
116pub fn recv() -> Event {
117 Event::from_recv(INPUT_CAP.recv(REPLY_CAP))
118}
119
120pub fn reply_recv(msg_info: MessageInfo) -> Event {
121 Event::from_recv(INPUT_CAP.reply_recv(msg_info.into_inner(), REPLY_CAP))
122}
123
124pub(crate) fn nb_send_recv(action: PreparedDeferredAction) -> Event {
125 Event::from_recv(action.cptr().nb_send_recv(
126 action.msg_info(),
127 INPUT_CAP.cast::<sel4::cap_type::Unspecified>(),
128 REPLY_CAP,
129 ))
130}
131
132pub(crate) fn forfeit_sc() -> PreparedDeferredAction {
133 PreparedDeferredAction::new(
134 MONITOR_EP_CAP.cast(),
135 sel4::MessageInfoBuilder::default().build(),
136 )
137}