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