sel4_microkit_base/
ipc.rs
1use crate::MessageInfo;
8
9use crate::{defer::PreparedDeferredAction, Channel, Child};
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 CHANNEL_BADGE_BIT: usize = 63;
16const PD_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(NotifiedEvent),
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, CHANNEL_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, PD_BADGE_BIT) {
43 Self::Fault(
44 Child::new(pd_index.try_into().unwrap()),
45 MessageInfo::from_inner(tag),
46 )
47 } else {
48 Self::Notified(NotifiedEvent(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 NotifiedEvent(sel4::Badge);
60
61impl NotifiedEvent {
62 pub fn iter(&self) -> NotifiedEventIter {
63 NotifiedEventIter(self.0)
64 }
65}
66
67#[doc(hidden)]
68pub struct NotifiedEventIter(sel4::Badge);
69
70impl Iterator for NotifiedEventIter {
71 type Item = Channel;
72
73 fn next(&mut self) -> Option<Self::Item> {
74 let badge_bits = self.0;
75 match badge_bits {
76 0 => None,
77 _ => {
78 let i = badge_bits.trailing_zeros();
79 self.0 = badge_bits & !(1 << i);
80 Some(Channel::new(i.try_into().unwrap()))
81 }
82 }
83 }
84}
85
86pub fn reply(msg_info: MessageInfo) {
87 REPLY_CAP.send(msg_info.into_inner())
88}
89
90pub fn recv() -> Event {
91 Event::from_recv(INPUT_CAP.recv(REPLY_CAP))
92}
93
94pub fn reply_recv(msg_info: MessageInfo) -> Event {
95 Event::from_recv(INPUT_CAP.reply_recv(msg_info.into_inner(), REPLY_CAP))
96}
97
98pub(crate) fn nb_send_recv(action: PreparedDeferredAction) -> Event {
99 Event::from_recv(action.cptr().nb_send_recv(
100 action.msg_info(),
101 INPUT_CAP.cast::<sel4::cap_type::Unspecified>(),
102 REPLY_CAP,
103 ))
104}
105
106pub(crate) fn forfeit_sc() -> PreparedDeferredAction {
107 PreparedDeferredAction::new(
108 MONITOR_EP_CAP.cast(),
109 sel4::MessageInfoBuilder::default().build(),
110 )
111}