22
33#[ cfg( cortex_m) ]
44use core:: arch:: asm;
5+ #[ cfg( cortex_m) ]
6+ use core:: sync:: atomic:: { compiler_fence, Ordering } ;
57
68/// All exceptions with configurable priority are ...
79#[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
@@ -26,15 +28,42 @@ impl Primask {
2628 }
2729}
2830
29- /// Reads the CPU register
31+ /// Reads the prioritizable interrupt mask
3032#[ cfg( cortex_m) ]
3133#[ inline]
3234pub fn read ( ) -> Primask {
33- let r: u32 ;
34- unsafe { asm ! ( "mrs {}, PRIMASK" , out( reg) r, options( nomem, nostack, preserves_flags) ) } ;
35- if r & ( 1 << 0 ) == ( 1 << 0 ) {
35+ if read_raw ( ) & ( 1 << 0 ) == ( 1 << 0 ) {
3636 Primask :: Inactive
3737 } else {
3838 Primask :: Active
3939 }
4040}
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