aarch32_cpu/interrupt.rs
1//! Interrupts on Arm AArch32
2
3use core::sync::atomic::{compiler_fence, Ordering};
4
5/// Enable interrupts
6///
7/// * Doesn't work in User mode.
8/// * Doesn't enable FIQ.
9///
10/// # Safety
11///
12/// Do not call this function inside an interrupt-based critical section
13#[inline]
14pub unsafe fn enable() {
15 // Ensure no preceeding memory accesses are reordered to after interrupts are enabled.
16 compiler_fence(Ordering::SeqCst);
17 // Safety: as per outer function
18 unsafe {
19 crate::asm::irq_enable();
20 }
21}
22
23/// Disable IRQ
24///
25/// * Doesn't work in User mode.
26/// * Doesn't disable FIQ.
27#[inline]
28pub fn disable() {
29 crate::asm::irq_disable();
30 // Ensure no subsequent memory accesses are reordered to before interrupts are disabled.
31 compiler_fence(Ordering::SeqCst);
32}
33
34/// Run with interrupts disabled
35///
36/// * Doesn't work in User mode.
37/// * Doesn't disable FIQ.
38#[inline]
39pub fn free<F, T>(f: F) -> T
40where
41 F: FnOnce() -> T,
42{
43 let cpsr = crate::register::Cpsr::read();
44 disable();
45 let result = f();
46 if cpsr.i() {
47 // Safety: We're only turning them back on if they were on previously
48 unsafe {
49 enable();
50 }
51 }
52 result
53}