1
1
//! mie register
2
2
3
+ use crate :: bits:: { bf_extract, bf_insert} ;
4
+ use riscv_pac:: CoreInterruptNumber ;
5
+
3
6
read_write_csr ! {
4
7
/// `mie` register
5
8
Mie : 0x304 ,
6
- mask: 0xaaa ,
9
+ mask: usize :: MAX ,
7
10
}
8
11
9
12
read_write_csr_field ! {
@@ -42,6 +45,26 @@ read_write_csr_field! {
42
45
mext: 11 ,
43
46
}
44
47
48
+ impl Mie {
49
+ /// Check if a specific core interrupt source is enabled.
50
+ #[ inline]
51
+ pub fn is_enabled < I : CoreInterruptNumber > ( & self , interrupt : I ) -> bool {
52
+ bf_extract ( self . bits , interrupt. number ( ) , 1 ) != 0
53
+ }
54
+
55
+ /// Enable a specific core interrupt source.
56
+ #[ inline]
57
+ pub fn enable < I : CoreInterruptNumber > ( & mut self , interrupt : I ) {
58
+ self . bits = bf_insert ( self . bits , interrupt. number ( ) , 1 , 1 ) ;
59
+ }
60
+
61
+ /// Disable a specific core interrupt source.
62
+ #[ inline]
63
+ pub fn disable < I : CoreInterruptNumber > ( & mut self , interrupt : I ) {
64
+ self . bits = bf_insert ( self . bits , interrupt. number ( ) , 1 , 0 ) ;
65
+ }
66
+ }
67
+
45
68
set ! ( 0x304 ) ;
46
69
clear ! ( 0x304 ) ;
47
70
@@ -64,9 +87,28 @@ set_clear_csr!(
64
87
/// Machine External Interrupt Enable
65
88
, set_mext, clear_mext, 1 << 11 ) ;
66
89
90
+ /// Disables a specific core interrupt source.
91
+ #[ inline]
92
+ pub fn disable < I : CoreInterruptNumber > ( interrupt : I ) {
93
+ // SAFETY: it is safe to disable an interrupt source
94
+ unsafe { _clear ( 1 << interrupt. number ( ) ) } ;
95
+ }
96
+
97
+ /// Enables a specific core interrupt source.
98
+ ///
99
+ /// # Safety
100
+ ///
101
+ /// Enabling interrupts might break critical sections or other synchronization mechanisms.
102
+ /// Ensure that this is called in a safe context where interrupts can be enabled.
103
+ #[ inline]
104
+ pub unsafe fn enable < I : CoreInterruptNumber > ( interrupt : I ) {
105
+ unsafe { _set ( 1 << interrupt. number ( ) ) } ;
106
+ }
107
+
67
108
#[ cfg( test) ]
68
109
mod tests {
69
110
use super :: * ;
111
+ use crate :: interrupt:: machine:: Interrupt ;
70
112
71
113
#[ test]
72
114
fn test_mie ( ) {
@@ -79,4 +121,39 @@ mod tests {
79
121
test_csr_field ! ( m, sext) ;
80
122
test_csr_field ! ( m, mext) ;
81
123
}
124
+
125
+ #[ test]
126
+ fn test_mie_interrupt ( ) {
127
+ let mut m = Mie :: from_bits ( 0 ) ;
128
+
129
+ m. enable ( Interrupt :: SupervisorSoft ) ;
130
+ assert ! ( m. is_enabled( Interrupt :: SupervisorSoft ) ) ;
131
+ m. disable ( Interrupt :: SupervisorSoft ) ;
132
+ assert ! ( !m. is_enabled( Interrupt :: SupervisorSoft ) ) ;
133
+
134
+ m. enable ( Interrupt :: MachineSoft ) ;
135
+ assert ! ( m. is_enabled( Interrupt :: MachineSoft ) ) ;
136
+ m. disable ( Interrupt :: MachineSoft ) ;
137
+ assert ! ( !m. is_enabled( Interrupt :: MachineSoft ) ) ;
138
+
139
+ m. enable ( Interrupt :: SupervisorTimer ) ;
140
+ assert ! ( m. is_enabled( Interrupt :: SupervisorTimer ) ) ;
141
+ m. disable ( Interrupt :: SupervisorTimer ) ;
142
+ assert ! ( !m. is_enabled( Interrupt :: SupervisorTimer ) ) ;
143
+
144
+ m. enable ( Interrupt :: MachineTimer ) ;
145
+ assert ! ( m. is_enabled( Interrupt :: MachineTimer ) ) ;
146
+ m. disable ( Interrupt :: MachineTimer ) ;
147
+ assert ! ( !m. is_enabled( Interrupt :: MachineTimer ) ) ;
148
+
149
+ m. enable ( Interrupt :: SupervisorExternal ) ;
150
+ assert ! ( m. is_enabled( Interrupt :: SupervisorExternal ) ) ;
151
+ m. disable ( Interrupt :: SupervisorExternal ) ;
152
+ assert ! ( !m. is_enabled( Interrupt :: SupervisorExternal ) ) ;
153
+
154
+ m. enable ( Interrupt :: MachineExternal ) ;
155
+ assert ! ( m. is_enabled( Interrupt :: MachineExternal ) ) ;
156
+ m. disable ( Interrupt :: MachineExternal ) ;
157
+ assert ! ( !m. is_enabled( Interrupt :: MachineExternal ) ) ;
158
+ }
82
159
}
0 commit comments