|
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