11//! Priority mask register
22
3+ #[ cfg( cortex_m) ]
4+ use core:: arch:: asm;
5+ #[ cfg( cortex_m) ]
6+ use core:: sync:: atomic:: { compiler_fence, Ordering } ;
7+
38/// All exceptions with configurable priority are ...
49#[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
510pub enum Primask {
@@ -23,13 +28,42 @@ impl Primask {
2328 }
2429}
2530
26- /// Reads the CPU register
31+ /// Reads the prioritizable interrupt mask
32+ #[ cfg( cortex_m) ]
2733#[ inline]
2834pub fn read ( ) -> Primask {
29- let r: u32 = call_asm ! ( __primask_r( ) -> u32 ) ;
30- if r & ( 1 << 0 ) == ( 1 << 0 ) {
35+ if read_raw ( ) & ( 1 << 0 ) == ( 1 << 0 ) {
3136 Primask :: Inactive
3237 } else {
3338 Primask :: Active
3439 }
3540}
41+
42+ /// Reads the entire PRIMASK register
43+ /// Note that bits [31:1] are reserved and UNK (Unknown)
44+ #[ cfg( cortex_m) ]
45+ #[ inline]
46+ pub 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+ /// Note that bits [31:1] are reserved and SBZP (Should-Be-Zero-or-Preserved)
54+ ///
55+ /// # Safety
56+ ///
57+ /// This method is unsafe as other unsafe code may rely on interrupts remaining disabled, for
58+ /// example during a critical section, and being able to safely re-enable them would lead to
59+ /// undefined behaviour. Do not call this function in a context where interrupts are expected to
60+ /// remain disabled -- for example, in the midst of a critical section or `interrupt::free()` call.
61+ #[ cfg( cortex_m) ]
62+ #[ inline]
63+ pub unsafe fn write_raw ( r : u32 ) {
64+ // Ensure no preceeding memory accesses are reordered to after interrupts are possibly enabled.
65+ compiler_fence ( Ordering :: SeqCst ) ;
66+ unsafe { asm ! ( "msr PRIMASK, {}" , in( reg) r, options( nomem, nostack, preserves_flags) ) } ;
67+ // Ensure no subsequent memory accesses are reordered to before interrupts are possibly disabled.
68+ compiler_fence ( Ordering :: SeqCst ) ;
69+ }
0 commit comments