use crate::{
bits::{bf_extract, bf_insert},
CoreInterruptNumber,
};
read_write_csr! {
Mie: 0x304,
mask: usize::MAX,
}
read_write_csr_field! {
Mie,
ssoft: 1,
}
read_write_csr_field! {
Mie,
msoft: 3,
}
read_write_csr_field! {
Mie,
stimer: 5,
}
read_write_csr_field! {
Mie,
mtimer: 7,
}
read_write_csr_field! {
Mie,
sext: 9,
}
read_write_csr_field! {
Mie,
mext: 11,
}
impl Mie {
#[inline]
pub fn is_enabled<I: CoreInterruptNumber>(&self, interrupt: I) -> bool {
bf_extract(self.bits, interrupt.number(), 1) != 0
}
#[inline]
pub fn enable<I: CoreInterruptNumber>(&mut self, interrupt: I) {
self.bits = bf_insert(self.bits, interrupt.number(), 1, 1);
}
#[inline]
pub fn disable<I: CoreInterruptNumber>(&mut self, interrupt: I) {
self.bits = bf_insert(self.bits, interrupt.number(), 1, 0);
}
}
set!(0x304);
clear!(0x304);
set_clear_csr!(
, set_ssoft, clear_ssoft, 1 << 1);
set_clear_csr!(
, set_msoft, clear_msoft, 1 << 3);
set_clear_csr!(
, set_stimer, clear_stimer, 1 << 5);
set_clear_csr!(
, set_mtimer, clear_mtimer, 1 << 7);
set_clear_csr!(
, set_sext, clear_sext, 1 << 9);
set_clear_csr!(
, set_mext, clear_mext, 1 << 11);
#[inline]
pub fn disable<I: CoreInterruptNumber>(interrupt: I) {
unsafe { _clear(1 << interrupt.number()) };
}
#[inline]
pub unsafe fn enable<I: CoreInterruptNumber>(interrupt: I) {
unsafe { _set(1 << interrupt.number()) };
}
#[cfg(test)]
mod tests {
use super::*;
use crate::interrupt::machine::Interrupt;
#[test]
fn test_mie() {
let mut m = Mie::from_bits(0);
test_csr_field!(m, ssoft);
test_csr_field!(m, msoft);
test_csr_field!(m, stimer);
test_csr_field!(m, mtimer);
test_csr_field!(m, sext);
test_csr_field!(m, mext);
}
#[test]
fn test_mie_interrupt() {
let mut m = Mie::from_bits(0);
m.enable(Interrupt::SupervisorSoft);
assert!(m.is_enabled(Interrupt::SupervisorSoft));
m.disable(Interrupt::SupervisorSoft);
assert!(!m.is_enabled(Interrupt::SupervisorSoft));
m.enable(Interrupt::MachineSoft);
assert!(m.is_enabled(Interrupt::MachineSoft));
m.disable(Interrupt::MachineSoft);
assert!(!m.is_enabled(Interrupt::MachineSoft));
m.enable(Interrupt::SupervisorTimer);
assert!(m.is_enabled(Interrupt::SupervisorTimer));
m.disable(Interrupt::SupervisorTimer);
assert!(!m.is_enabled(Interrupt::SupervisorTimer));
m.enable(Interrupt::MachineTimer);
assert!(m.is_enabled(Interrupt::MachineTimer));
m.disable(Interrupt::MachineTimer);
assert!(!m.is_enabled(Interrupt::MachineTimer));
m.enable(Interrupt::SupervisorExternal);
assert!(m.is_enabled(Interrupt::SupervisorExternal));
m.disable(Interrupt::SupervisorExternal);
assert!(!m.is_enabled(Interrupt::SupervisorExternal));
m.enable(Interrupt::MachineExternal);
assert!(m.is_enabled(Interrupt::MachineExternal));
m.disable(Interrupt::MachineExternal);
assert!(!m.is_enabled(Interrupt::MachineExternal));
}
}