11//! mie register
22
3+ use riscv_pac:: CoreInterruptNumber ;
4+
35read_write_csr ! {
46 /// `mie` register
57 Mie : 0x304 ,
6- mask: 0xaaa ,
8+ mask: usize :: MAX ,
79}
810
911read_write_csr_field ! {
@@ -42,6 +44,26 @@ read_write_csr_field! {
4244 mext: 11 ,
4345}
4446
47+ impl Mie {
48+ /// Check if a specific core interrupt source is enabled.
49+ #[ inline]
50+ pub fn is_enabled < I : CoreInterruptNumber > ( & self , interrupt : I ) -> bool {
51+ ( self . bits & ( 1 << interrupt. number ( ) ) ) != 0
52+ }
53+
54+ /// Enable a specific core interrupt source.
55+ #[ inline]
56+ pub fn enable < I : CoreInterruptNumber > ( & mut self , interrupt : I ) {
57+ self . bits |= 1 << interrupt. number ( ) ;
58+ }
59+
60+ /// Disable a specific core interrupt source.
61+ #[ inline]
62+ pub fn disable < I : CoreInterruptNumber > ( & mut self , interrupt : I ) {
63+ self . bits &= !( 1 << interrupt. number ( ) ) ;
64+ }
65+ }
66+
4567set ! ( 0x304 ) ;
4668clear ! ( 0x304 ) ;
4769
@@ -64,9 +86,28 @@ set_clear_csr!(
6486 /// Machine External Interrupt Enable
6587 , set_mext, clear_mext, 1 << 11 ) ;
6688
89+ /// Disables a specific core interrupt source.
90+ #[ inline]
91+ pub fn clear_interrupt < I : CoreInterruptNumber > ( interrupt : I ) {
92+ // SAFETY: it is safe to disable an interrupt source
93+ unsafe { _clear ( 1 << interrupt. number ( ) ) } ;
94+ }
95+
96+ /// Enables a specific core interrupt source.
97+ ///
98+ /// # Safety
99+ ///
100+ /// Enabling interrupts might break critical sections or other synchronization mechanisms.
101+ /// Ensure that this is called in a safe context where interrupts can be enabled.
102+ #[ inline]
103+ pub unsafe fn set_interrupt < I : CoreInterruptNumber > ( interrupt : I ) {
104+ unsafe { _set ( 1 << interrupt. number ( ) ) } ;
105+ }
106+
67107#[ cfg( test) ]
68108mod tests {
69109 use super :: * ;
110+ use crate :: interrupt:: machine:: Interrupt ;
70111
71112 #[ test]
72113 fn test_mie ( ) {
@@ -79,4 +120,39 @@ mod tests {
79120 test_csr_field ! ( m, sext) ;
80121 test_csr_field ! ( m, mext) ;
81122 }
123+
124+ #[ test]
125+ fn test_mie_interrupt ( ) {
126+ let mut m = Mie :: from_bits ( 0 ) ;
127+
128+ m. enable ( Interrupt :: SupervisorSoft ) ;
129+ assert ! ( m. is_enabled( Interrupt :: SupervisorSoft ) ) ;
130+ m. disable ( Interrupt :: SupervisorSoft ) ;
131+ assert ! ( !m. is_enabled( Interrupt :: SupervisorSoft ) ) ;
132+
133+ m. enable ( Interrupt :: MachineSoft ) ;
134+ assert ! ( m. is_enabled( Interrupt :: MachineSoft ) ) ;
135+ m. disable ( Interrupt :: MachineSoft ) ;
136+ assert ! ( !m. is_enabled( Interrupt :: MachineSoft ) ) ;
137+
138+ m. enable ( Interrupt :: SupervisorTimer ) ;
139+ assert ! ( m. is_enabled( Interrupt :: SupervisorTimer ) ) ;
140+ m. disable ( Interrupt :: SupervisorTimer ) ;
141+ assert ! ( !m. is_enabled( Interrupt :: SupervisorTimer ) ) ;
142+
143+ m. enable ( Interrupt :: MachineTimer ) ;
144+ assert ! ( m. is_enabled( Interrupt :: MachineTimer ) ) ;
145+ m. disable ( Interrupt :: MachineTimer ) ;
146+ assert ! ( !m. is_enabled( Interrupt :: MachineTimer ) ) ;
147+
148+ m. enable ( Interrupt :: SupervisorExternal ) ;
149+ assert ! ( m. is_enabled( Interrupt :: SupervisorExternal ) ) ;
150+ m. disable ( Interrupt :: SupervisorExternal ) ;
151+ assert ! ( !m. is_enabled( Interrupt :: SupervisorExternal ) ) ;
152+
153+ m. enable ( Interrupt :: MachineExternal ) ;
154+ assert ! ( m. is_enabled( Interrupt :: MachineExternal ) ) ;
155+ m. disable ( Interrupt :: MachineExternal ) ;
156+ assert ! ( !m. is_enabled( Interrupt :: MachineExternal ) ) ;
157+ }
82158}
0 commit comments