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 unsafe { set_mask(!0) }
19}
20
21#[inline]
27pub unsafe fn set_mask(mut mask: u32) -> u32 {
28 unsafe {
29 asm!("
30 xsr {0}, intenable
31 rsync
32 ",
33 inout(reg) mask, options(nostack)
34 );
35 mask
36 }
37}
38
39#[inline]
41pub fn disable_mask(mask: u32) -> u32 {
42 let mut prev: u32 = 0;
43 let _dummy: u32;
44 unsafe {
45 asm!("
46 xsr.intenable {0} // get mask and temporarily disable interrupts
47 and {1}, {1}, {0}
48 rsync
49 wsr.intenable {1}
50 rsync
51 ", inout(reg) prev, inout(reg) !mask => _dummy, options(nostack)
52 );
53 }
54 prev
55}
56
57#[inline]
63pub unsafe fn enable_mask(mask: u32) -> u32 {
64 unsafe {
65 let mut prev: u32 = 0;
66 let _dummy: u32;
67 asm!("
68 xsr.intenable {0} // get mask and temporarily disable interrupts
69 or {1}, {1}, {0}
70 rsync
71 wsr.intenable {1}
72 rsync
73 ", inout(reg) prev, inout(reg) mask => _dummy, options(nostack));
74 prev
75 }
76}
77
78#[inline]
80pub fn get_mask() -> u32 {
81 let mask: u32;
82 unsafe { asm!("rsr.intenable {0}", out(reg) mask) };
83 mask
84}
85
86#[inline]
88pub fn get() -> u32 {
89 let mask: u32;
90 unsafe {
91 asm!("rsr.interrupt {0}", out(reg) mask, options(nostack));
92 }
93 mask
94}
95
96#[inline]
102pub unsafe fn set(mask: u32) {
103 unsafe {
104 asm!("
105 wsr.intset {0}
106 rsync
107 ",
108 in(reg) mask, options(nostack)
109 );
110 }
111}
112
113#[inline]
119pub unsafe fn clear(mask: u32) {
120 unsafe {
121 asm!("
122 wsr.intclear {0}
123 rsync
124 ",
125 in(reg) mask, options(nostack)
126 );
127 }
128}
129
130#[inline]
132pub fn get_level() -> u32 {
133 let ps: u32;
134 unsafe {
135 asm!("rsr.ps {0}", out(reg) ps, options(nostack));
136 };
137 ps & 0xf
138}
139
140#[inline]
147pub fn free<F, R>(f: F) -> R
148where
149 F: FnOnce() -> R,
150{
151 let old_mask = disable();
153
154 let r = f();
155
156 unsafe { enable_mask(old_mask) };
158
159 r
160}