Skip to main content

cortex_m/register/
primask.rs

1//! Priority mask register
2
3#[cfg(cortex_m)]
4use core::arch::asm;
5#[cfg(cortex_m)]
6use core::sync::atomic::{Ordering, compiler_fence};
7use cortex_m_macros::asm_cfg;
8
9/// All exceptions with configurable priority are ...
10#[derive(Clone, Copy, Debug, Eq, PartialEq)]
11pub enum Primask {
12    /// Active
13    Active,
14    /// Inactive
15    Inactive,
16}
17
18impl Primask {
19    /// All exceptions with configurable priority are active
20    #[inline]
21    pub fn is_active(self) -> bool {
22        self == Primask::Active
23    }
24
25    /// All exceptions with configurable priority are inactive
26    #[inline]
27    pub fn is_inactive(self) -> bool {
28        self == Primask::Inactive
29    }
30}
31
32/// Reads the prioritizable interrupt mask
33#[inline]
34pub fn read() -> Primask {
35    if read_raw() & (1 << 0) == (1 << 0) {
36        Primask::Inactive
37    } else {
38        Primask::Active
39    }
40}
41
42/// Reads the entire PRIMASK register
43/// Note that bits `[31:1]` are reserved and UNK (Unknown)
44#[inline]
45#[asm_cfg(cortex_m)]
46pub fn read_raw() -> u32 {
47    let r: u32;
48    unsafe { asm!("mrs {}, PRIMASK", out(reg) r, options(nomem, nostack, preserves_flags)) };
49    r
50}
51
52/// Writes the entire PRIMASK register
53///
54/// Note that bits `[31:1]` are reserved and SBZP (Should-Be-Zero-or-Preserved)
55///
56/// # Safety
57///
58/// This method is unsafe as other unsafe code may rely on interrupts remaining disabled, for
59/// example during a critical section, and being able to safely re-enable them would lead to
60/// undefined behaviour. Do not call this function in a context where interrupts are expected to
61/// remain disabled -- for example, in the midst of a critical section or `interrupt::free()` call.
62#[inline]
63#[asm_cfg(cortex_m)]
64pub unsafe fn write_raw(r: u32) {
65    // Ensure no preceeding memory accesses are reordered to after interrupts are possibly enabled.
66    compiler_fence(Ordering::SeqCst);
67    unsafe { asm!("msr PRIMASK, {}", in(reg) r, options(nomem, nostack, preserves_flags)) };
68    // Ensure no subsequent memory accesses are reordered to before interrupts are possibly disabled.
69    compiler_fence(Ordering::SeqCst);
70}