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}