|
1 | 1 | //! Interrupts
|
2 | 2 |
|
3 | 3 | // NOTE: Adapted from cortex-m/src/interrupt.rs
|
4 |
| - |
5 |
| -pub mod machine { |
6 |
| - use crate::register::mstatus; |
7 |
| - |
8 |
| - /// Disables all interrupts in the current hart (machine mode). |
9 |
| - #[inline] |
10 |
| - pub fn disable() { |
11 |
| - unsafe { mstatus::clear_mie() } |
12 |
| - } |
13 |
| - |
14 |
| - /// Enables all the interrupts in the current hart (machine mode). |
15 |
| - /// |
16 |
| - /// # Safety |
17 |
| - /// |
18 |
| - /// Do not call this function inside a critical section. |
19 |
| - #[inline] |
20 |
| - pub unsafe fn enable() { |
21 |
| - mstatus::set_mie() |
22 |
| - } |
23 |
| - |
24 |
| - /// Execute closure `f` with interrupts disabled in the current hart (machine mode). |
25 |
| - /// |
26 |
| - /// This method does not synchronise multiple harts, so it is not suitable for |
27 |
| - /// using as a critical section. See the `critical-section` crate for a cross-platform |
28 |
| - /// way to enter a critical section which provides a `CriticalSection` token. |
29 |
| - /// |
30 |
| - /// This crate provides an implementation for `critical-section` suitable for single-hart systems, |
31 |
| - /// based on disabling all interrupts. It can be enabled with the `critical-section-single-hart` feature. |
32 |
| - #[inline] |
33 |
| - pub fn free<F, R>(f: F) -> R |
34 |
| - where |
35 |
| - F: FnOnce() -> R, |
36 |
| - { |
37 |
| - let mstatus = mstatus::read(); |
38 |
| - |
39 |
| - // disable interrupts |
40 |
| - disable(); |
41 |
| - |
42 |
| - let r = f(); |
43 |
| - |
44 |
| - // If the interrupts were active before our `disable` call, then re-enable |
45 |
| - // them. Otherwise, keep them disabled |
46 |
| - if mstatus.mie() { |
47 |
| - unsafe { enable() }; |
48 |
| - } |
49 |
| - |
50 |
| - r |
| 4 | +use crate::register::mstatus; |
| 5 | + |
| 6 | +/// Disables all interrupts in the current hart. |
| 7 | +#[inline] |
| 8 | +pub unsafe fn disable() { |
| 9 | + match () { |
| 10 | + #[cfg(riscv)] |
| 11 | + () => mstatus::clear_mie(), |
| 12 | + #[cfg(not(riscv))] |
| 13 | + () => unimplemented!(), |
51 | 14 | }
|
52 | 15 | }
|
53 |
| -pub mod supervisor { |
54 |
| - use crate::register::sstatus; |
55 | 16 |
|
56 |
| - /// Disables all interrupts in the current hart (supervisor mode). |
57 |
| - #[inline] |
58 |
| - pub fn disable() { |
59 |
| - unsafe { sstatus::clear_sie() } |
| 17 | +/// Enables all the interrupts in the current hart. |
| 18 | +/// |
| 19 | +/// # Safety |
| 20 | +/// |
| 21 | +/// - Do not call this function inside a critical section. |
| 22 | +#[inline] |
| 23 | +pub unsafe fn enable() { |
| 24 | + match () { |
| 25 | + #[cfg(riscv)] |
| 26 | + () => mstatus::set_mie(), |
| 27 | + #[cfg(not(riscv))] |
| 28 | + () => unimplemented!(), |
60 | 29 | }
|
| 30 | +} |
61 | 31 |
|
62 |
| - /// Enables all the interrupts in the current hart (supervisor mode). |
63 |
| - /// |
64 |
| - /// # Safety |
65 |
| - /// |
66 |
| - /// Do not call this function inside a critical section. |
67 |
| - #[inline] |
68 |
| - pub unsafe fn enable() { |
69 |
| - sstatus::set_sie() |
70 |
| - } |
71 |
| - |
72 |
| - /// Execute closure `f` with interrupts disabled in the current hart (supervisor mode). |
73 |
| - /// |
74 |
| - /// This method does not synchronise multiple harts, so it is not suitable for |
75 |
| - /// using as a critical section. See the `critical-section` crate for a cross-platform |
76 |
| - /// way to enter a critical section which provides a `CriticalSection` token. |
77 |
| - /// |
78 |
| - /// This crate provides an implementation for `critical-section` suitable for single-hart systems, |
79 |
| - /// based on disabling all interrupts. It can be enabled with the `critical-section-single-hart` feature. |
80 |
| - #[inline] |
81 |
| - pub fn free<F, R>(f: F) -> R |
82 |
| - where |
83 |
| - F: FnOnce() -> R, |
84 |
| - { |
85 |
| - let sstatus = sstatus::read(); |
86 |
| - |
87 |
| - // disable interrupts |
| 32 | +/// Execute closure `f` with interrupts disabled in the current hart. |
| 33 | +/// |
| 34 | +/// This method does not synchronise multiple harts, so it is not suitable for |
| 35 | +/// using as a critical section. See the `critical-section` crate for a cross-platform |
| 36 | +/// way to enter a critical section which provides a `CriticalSection` token. |
| 37 | +/// |
| 38 | +/// This crate provides an implementation for `critical-section` suitable for single-hart systems, |
| 39 | +/// based on disabling all interrupts. It can be enabled with the `critical-section-single-hart` feature. |
| 40 | +#[inline] |
| 41 | +pub fn free<F, R>(f: F) -> R |
| 42 | +where |
| 43 | + F: FnOnce() -> R, |
| 44 | +{ |
| 45 | + let mstatus = mstatus::read(); |
| 46 | + |
| 47 | + // disable interrupts |
| 48 | + unsafe { |
88 | 49 | disable();
|
| 50 | + } |
89 | 51 |
|
90 |
| - let r = f(); |
| 52 | + let r = f(); |
91 | 53 |
|
92 |
| - // If the interrupts were active before our `disable` call, then re-enable |
93 |
| - // them. Otherwise, keep them disabled |
94 |
| - if sstatus.sie() { |
95 |
| - unsafe { enable() }; |
| 54 | + // If the interrupts were active before our `disable` call, then re-enable |
| 55 | + // them. Otherwise, keep them disabled |
| 56 | + if mstatus.mie() { |
| 57 | + unsafe { |
| 58 | + enable(); |
96 | 59 | }
|
97 |
| - |
98 |
| - r |
99 | 60 | }
|
100 |
| -} |
101 | 61 |
|
102 |
| -#[cfg(not(feature = "s-mode"))] |
103 |
| -pub use machine::*; |
104 |
| -#[cfg(feature = "s-mode")] |
105 |
| -pub use supervisor::*; |
| 62 | + r |
| 63 | +} |
0 commit comments