2
2
3
3
#[ cfg( cortex_m) ]
4
4
use core:: arch:: asm;
5
+ #[ cfg( cortex_m) ]
6
+ use core:: sync:: atomic:: { compiler_fence, Ordering } ;
5
7
6
8
/// All exceptions with configurable priority are ...
7
9
#[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
@@ -26,15 +28,42 @@ impl Primask {
26
28
}
27
29
}
28
30
29
- /// Reads the CPU register
31
+ /// Reads the prioritizable interrupt mask
30
32
#[ cfg( cortex_m) ]
31
33
#[ inline]
32
34
pub 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 ) {
36
36
Primask :: Inactive
37
37
} else {
38
38
Primask :: Active
39
39
}
40
40
}
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