rustsbi/
ipi.rs

1use sbi_spec::binary::{HartMask, SbiRet};
2
3/// Inter-processor interrupt support.
4pub trait Ipi {
5    /// Send an inter-processor interrupt to all the harts defined in `hart_mask`.
6    ///
7    /// Inter-processor interrupts manifest at the receiving harts as the supervisor software interrupts.
8    ///
9    /// # Return value
10    ///
11    /// Should return `SbiRet::success()` if IPI was sent to all the targeted harts successfully.
12    fn send_ipi(&self, hart_mask: HartMask) -> SbiRet;
13    /// Function internal to macros. Do not use.
14    #[doc(hidden)]
15    #[inline]
16    fn _rustsbi_probe(&self) -> usize {
17        sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1)
18    }
19}
20
21impl<T: Ipi> Ipi for &T {
22    #[inline]
23    fn send_ipi(&self, hart_mask: HartMask) -> SbiRet {
24        T::send_ipi(self, hart_mask)
25    }
26}
27
28impl<T: Ipi> Ipi for Option<T> {
29    #[inline]
30    fn send_ipi(&self, hart_mask: HartMask) -> SbiRet {
31        self.as_ref()
32            .map(|inner| T::send_ipi(inner, hart_mask))
33            .unwrap_or(SbiRet::not_supported())
34    }
35    #[inline]
36    fn _rustsbi_probe(&self) -> usize {
37        match self {
38            Some(_) => sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1),
39            None => sbi_spec::base::UNAVAILABLE_EXTENSION,
40        }
41    }
42}