pub mod mswi;
pub mod mtimer;
pub mod sswi;
pub use riscv::HartIdNumber;
pub unsafe trait Clint: Copy {
const BASE: usize;
const MTIME_FREQ: usize;
}
#[allow(clippy::upper_case_acronyms)]
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct CLINT<C> {
_marker: core::marker::PhantomData<C>,
}
impl<C: Clint> CLINT<C> {
#[inline]
pub const fn new() -> Self {
Self {
_marker: core::marker::PhantomData,
}
}
#[inline]
pub const fn mswi(self) -> mswi::MSWI<C> {
mswi::MSWI::new()
}
#[inline]
pub const fn mtimer(self) -> mtimer::MTIMER<C> {
mtimer::MTIMER::new()
}
#[inline]
pub fn is_interrupting(self) -> bool {
self.mswi().is_interrupting() || self.mtimer().is_interrupting()
}
#[inline]
pub fn is_enabled(self) -> bool {
self.mswi().is_enabled() || self.mtimer().is_enabled()
}
#[inline]
pub unsafe fn enable(self) {
self.mswi().enable();
self.mtimer().enable();
}
#[inline]
pub fn disable(self) {
self.mswi().disable();
self.mtimer().disable();
}
}
#[cfg(test)]
pub(crate) mod test {
use crate::test::HartId;
#[allow(dead_code)]
#[test]
fn check_clint() {
crate::clint_codegen!(
CLINT,
base 0x0200_0000,
mtime_freq 32_768,
harts [HartId::H0 => 0, HartId::H1 => 1, HartId::H2 => 2]
);
let clint = CLINT::new();
let mswi = clint.mswi();
let mtimer = clint.mtimer();
let msip0 = mswi.msip(HartId::H0);
let msip1 = mswi.msip(HartId::H1);
let msip2 = mswi.msip(HartId::H2);
assert_eq!(msip0.get_ptr() as usize, 0x0200_0000);
assert_eq!(msip1.get_ptr() as usize, 0x0200_0000 + 4); assert_eq!(msip2.get_ptr() as usize, 0x0200_0000 + 2 * 4);
let mtimecmp0 = mtimer.mtimecmp(HartId::H0);
let mtimecmp1 = mtimer.mtimecmp(HartId::H1);
let mtimecmp2 = mtimer.mtimecmp(HartId::H2);
assert_eq!(mtimecmp0.get_ptr() as usize, 0x0200_4000);
assert_eq!(mtimecmp1.get_ptr() as usize, 0x0200_4000 + 8); assert_eq!(mtimecmp2.get_ptr() as usize, 0x0200_4000 + 2 * 8);
let mtime = mtimer.mtime();
assert_eq!(mtime.get_ptr() as usize, 0x0200_bff8);
assert_eq!(clint.mtimecmp0(), mtimer.mtimecmp(HartId::H0));
assert_eq!(clint.mtimecmp0(), mtimer.mtimecmp0());
assert_eq!(clint.mtimecmp1(), mtimer.mtimecmp(HartId::H1));
assert_eq!(clint.mtimecmp2(), mtimer.mtimecmp(HartId::H2));
assert_eq!(clint.msip0(), mswi.msip(HartId::H0));
assert_eq!(clint.msip1(), mswi.msip(HartId::H1));
assert_eq!(clint.msip2(), mswi.msip(HartId::H2));
}
}