1use core::arch::asm;
4
5#[inline]
7pub fn disable() -> u32 {
8 unsafe { set_mask(0) }
9}
10
11#[inline]
17pub unsafe fn enable() -> u32 {
18 set_mask(!0)
19}
20
21#[inline]
27pub unsafe fn set_mask(mut mask: u32) -> u32 {
28 asm!("
29 xsr {0}, intenable
30 rsync
31 ",
32 inout(reg) mask, options(nostack)
33 );
34 mask
35}
36
37#[inline]
39pub fn disable_mask(mask: u32) -> u32 {
40 let mut prev: u32 = 0;
41 let _dummy: u32;
42 unsafe {
43 asm!("
44 xsr.intenable {0} // get mask and temporarily disable interrupts
45 and {1}, {1}, {0}
46 rsync
47 wsr.intenable {1}
48 rsync
49 ", inout(reg) prev, inout(reg) !mask => _dummy, options(nostack)
50 );
51 }
52 prev
53}
54
55#[inline]
61pub unsafe fn enable_mask(mask: u32) -> u32 {
62 let mut prev: u32 = 0;
63 let _dummy: u32;
64 asm!("
65 xsr.intenable {0} // get mask and temporarily disable interrupts
66 or {1}, {1}, {0}
67 rsync
68 wsr.intenable {1}
69 rsync
70 ", inout(reg) prev, inout(reg) mask => _dummy, options(nostack));
71 prev
72}
73
74#[inline]
76pub fn get_mask() -> u32 {
77 let mask: u32;
78 unsafe { asm!("rsr.intenable {0}", out(reg) mask) };
79 mask
80}
81
82#[inline]
84pub fn get() -> u32 {
85 let mask: u32;
86 unsafe {
87 asm!("rsr.interrupt {0}", out(reg) mask, options(nostack));
88 }
89 mask
90}
91
92#[inline]
98pub unsafe fn set(mask: u32) {
99 asm!("
100 wsr.intset {0}
101 rsync
102 ",
103 in(reg) mask, options(nostack)
104 );
105}
106
107#[inline]
113pub unsafe fn clear(mask: u32) {
114 asm!("
115 wsr.intclear {0}
116 rsync
117 ",
118 in(reg) mask, options(nostack)
119 );
120}
121
122#[inline]
124pub fn get_level() -> u32 {
125 let ps: u32;
126 unsafe {
127 asm!("rsr.ps {0}", out(reg) ps, options(nostack));
128 };
129 ps & 0xf
130}
131
132#[inline]
139pub fn free<F, R>(f: F) -> R
140where
141 F: FnOnce() -> R,
142{
143 let old_mask = disable();
145
146 let r = f();
147
148 unsafe { enable_mask(old_mask) };
150
151 r
152}