1use core::marker::PhantomData;
10use core::ops::Range;
11
12use sel4_config::sel4_cfg;
13
14use crate::{
15 cap_type,
16 const_helpers::{u32_into_usize, usize_into_word, word_into_usize},
17 sys, CPtr, CPtrBits, Cap, CapType,
18};
19
20#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
22pub struct Slot<T: CapType = cap_type::Unspecified> {
23 index: usize,
24 _phantom: PhantomData<T>,
25}
26
27impl<T: CapType> Slot<T> {
28 const fn from_sys(slot: u32) -> Self {
29 Self::from_index(u32_into_usize(slot))
30 }
31
32 pub const fn from_index(index: usize) -> Self {
33 Self {
34 index,
35 _phantom: PhantomData,
36 }
37 }
38
39 pub const fn index(&self) -> usize {
40 self.index
41 }
42
43 pub const fn cptr_bits(&self) -> CPtrBits {
44 usize_into_word(self.index)
45 }
46
47 pub const fn cptr(&self) -> CPtr {
48 CPtr::from_bits(self.cptr_bits())
49 }
50
51 pub const fn cap(&self) -> Cap<T> {
52 self.cptr().cast()
53 }
54
55 pub const fn cast<T1: CapType>(&self) -> Slot<T1> {
56 Slot::from_index(self.index)
57 }
58
59 pub const fn upcast(&self) -> Slot {
60 self.cast()
61 }
62}
63
64impl Slot {
65 pub const fn downcast<T: CapType>(&self) -> Slot<T> {
66 self.cast()
67 }
68}
69
70#[derive(Debug, Clone, Eq, PartialEq)]
72pub struct SlotRegion<T: CapType> {
73 range: Range<usize>,
74 _phantom: PhantomData<T>,
75}
76
77#[allow(clippy::len_without_is_empty)]
78impl<T: CapType> SlotRegion<T> {
79 pub(crate) const fn from_range(range: Range<usize>) -> Self {
80 Self {
81 range,
82 _phantom: PhantomData,
83 }
84 }
85
86 pub(crate) const fn from_sys(sys: sys::seL4_SlotRegion) -> Self {
87 Self::from_range(word_into_usize(sys.start)..word_into_usize(sys.end))
88 }
89
90 pub const fn start(&self) -> usize {
91 self.range.start
92 }
93
94 pub const fn end(&self) -> usize {
95 self.range.end
96 }
97
98 pub const fn range(&self) -> Range<usize> {
99 self.start()..self.end()
100 }
101
102 pub fn len(&self) -> usize {
103 self.range.len()
104 }
105
106 pub fn index(&self, i: usize) -> Slot<T> {
107 assert!(i < self.len());
108 Slot::from_index(self.range.start + i)
109 }
110}
111
112pub mod slot {
114 use super::{cap_type, sel4_cfg, sys, Slot};
115
116 macro_rules! mk {
117 [
118 $(
119 $(#[$outer:meta])*
120 ($name:ident, $cap_type:ident, $sys_name:ident),
121 )*
122 ] => {
123 $(
124 $(#[$outer])*
125 #[doc = "Corresponds to `"]
126 #[doc = stringify!($sys_name)]
127 #[doc = "`."]
128 pub const $name: Slot<cap_type::$cap_type> = Slot::from_sys(sys::seL4_RootCNodeCapSlots::$sys_name);
129 )*
130 };
131 }
132
133 mk![
134 (NULL, Null, seL4_CapNull),
135 (TCB, Tcb, seL4_CapInitThreadTCB),
136 (CNODE, CNode, seL4_CapInitThreadCNode),
137 (VSPACE, VSpace, seL4_CapInitThreadVSpace),
138 (IRQ_CONTROL, IrqControl, seL4_CapIRQControl),
139 (ASID_CONTROL, AsidControl, seL4_CapASIDControl),
140 (ASID_POOL, AsidPool, seL4_CapInitThreadASIDPool),
141 #[sel4_cfg(not(ARCH_X86_64))]
142 (IO_PORT_CONTROL, Null, seL4_CapIOPortControl),
143 #[sel4_cfg(ARCH_X86_64)]
144 (IO_PORT_CONTROL, IOPortControl, seL4_CapIOPortControl),
145 #[cfg(any())] (IO_SPACE, Null, seL4_CapIOSpace),
147 (BOOT_INFO_FRAME, Granule, seL4_CapBootInfoFrame),
148 (IPC_BUFFER, Granule, seL4_CapInitThreadIPCBuffer),
149 #[cfg(any())] (DOMAIN, Null, seL4_CapDomain),
151 #[cfg(any())] (SMMU_SID_CONTROL, Null, seL4_CapSMMUSIDControl),
153 #[cfg(any())] (SMMU_CB_CONTROL, Null, seL4_CapSMMUCBControl),
155 #[sel4_cfg(KERNEL_MCS)]
156 (SC, SchedControl, seL4_CapInitThreadSC),
157 #[cfg(any())] (SMC, Null, seL4_CapSMC),
159 ];
160}
161
162#[cfg(feature = "state")]
164pub fn suspend_self<T>() -> T {
165 slot::TCB.cap().tcb_suspend().unwrap();
166
167 unreachable!()
168}