1use core::marker::PhantomData;
4
5use crate::interface::{CONTEXT_IRQSAVE, CONTEXT_PREEMPT, CONTEXT_PREEMPT_IRQSAVE, ContextState};
6
7#[doc(hidden)]
9#[inline(always)]
10pub fn irq_save_and_disable() -> usize {
11 crate::interface::context_enter(CONTEXT_IRQSAVE).irq()
12}
13
14#[doc(hidden)]
21#[inline(always)]
22pub unsafe fn irq_restore(state: usize) {
23 crate::interface::context_exit(CONTEXT_IRQSAVE, ContextState::new(0, state));
24}
25
26#[doc(hidden)]
28pub trait GuardState {
29 type State: Clone + Copy;
31
32 fn acquire() -> Self::State;
34
35 fn release(state: Self::State);
37}
38
39#[doc(hidden)]
41pub struct RawState;
42
43#[doc(hidden)]
45pub struct PreemptState;
46
47#[doc(hidden)]
49pub struct IrqSaveState;
50
51#[doc(hidden)]
53pub struct PreemptIrqSaveState;
54
55impl GuardState for RawState {
56 type State = ();
57
58 fn acquire() -> Self::State {}
59
60 fn release(_state: Self::State) {}
61}
62
63impl GuardState for PreemptState {
64 type State = ContextState;
65
66 fn acquire() -> Self::State {
67 crate::interface::context_enter(CONTEXT_PREEMPT)
68 }
69
70 fn release(state: Self::State) {
71 crate::interface::context_exit(CONTEXT_PREEMPT, state);
72 }
73}
74
75impl GuardState for IrqSaveState {
76 type State = ContextState;
77
78 fn acquire() -> Self::State {
79 crate::interface::context_enter(CONTEXT_IRQSAVE)
80 }
81
82 fn release(state: Self::State) {
83 crate::interface::context_exit(CONTEXT_IRQSAVE, state);
84 }
85}
86
87impl GuardState for PreemptIrqSaveState {
88 type State = ContextState;
89
90 fn acquire() -> Self::State {
91 crate::interface::context_enter(CONTEXT_PREEMPT_IRQSAVE)
92 }
93
94 fn release(state: Self::State) {
95 crate::interface::context_exit(CONTEXT_PREEMPT_IRQSAVE, state);
96 }
97}
98
99pub struct PreemptGuard {
106 state: ContextState,
107 _not_send: PhantomData<*mut ()>,
108}
109
110impl PreemptGuard {
111 pub fn new() -> Self {
113 Self {
114 state: PreemptState::acquire(),
115 _not_send: PhantomData,
116 }
117 }
118}
119
120impl Default for PreemptGuard {
121 fn default() -> Self {
122 Self::new()
123 }
124}
125
126impl Drop for PreemptGuard {
127 fn drop(&mut self) {
128 PreemptState::release(self.state);
129 }
130}
131
132pub struct IrqSaveGuard {
139 state: ContextState,
140 _not_send: PhantomData<*mut ()>,
141}
142
143impl IrqSaveGuard {
144 pub fn new() -> Self {
146 Self {
147 state: IrqSaveState::acquire(),
148 _not_send: PhantomData,
149 }
150 }
151
152 pub fn disable_preempt_for_irq_return(&mut self) -> IrqReturnPreemptGuard<'_> {
154 IrqReturnPreemptGuard {
155 state: crate::interface::irq_return_preempt_enter(),
156 _irq_guard: PhantomData,
157 _not_send: PhantomData,
158 }
159 }
160}
161
162#[must_use = "dropping the guard completes IRQ-return preemption exit"]
164pub struct IrqReturnPreemptGuard<'irq> {
165 state: usize,
166 _irq_guard: PhantomData<&'irq mut IrqSaveGuard>,
167 _not_send: PhantomData<*mut ()>,
168}
169
170impl Drop for IrqReturnPreemptGuard<'_> {
171 fn drop(&mut self) {
172 crate::interface::irq_return_preempt_exit(self.state);
173 }
174}
175
176pub fn hardirq_enter() {
178 crate::interface::hardirq_enter();
179}
180
181pub fn hardirq_exit() {
183 crate::interface::hardirq_exit();
184}
185
186impl Default for IrqSaveGuard {
187 fn default() -> Self {
188 Self::new()
189 }
190}
191
192impl Drop for IrqSaveGuard {
193 fn drop(&mut self) {
194 IrqSaveState::release(self.state);
195 }
196}
197
198pub struct PreemptIrqSaveGuard {
208 state: ContextState,
209 _not_send: PhantomData<*mut ()>,
210}
211
212impl PreemptIrqSaveGuard {
213 pub fn new() -> Self {
215 Self {
216 state: PreemptIrqSaveState::acquire(),
217 _not_send: PhantomData,
218 }
219 }
220}
221
222impl Default for PreemptIrqSaveGuard {
223 fn default() -> Self {
224 Self::new()
225 }
226}
227
228impl Drop for PreemptIrqSaveGuard {
229 fn drop(&mut self) {
230 PreemptIrqSaveState::release(self.state);
231 }
232}