ipi.rs 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. use crate::{hart_mask::HartMask, util::AmoOnceRef};
  2. use sbi_spec::binary::SbiRet;
  3. /// Inter-processor interrupt support
  4. pub trait Ipi: Send + Sync {
  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 error code `SBI_SUCCESS` if IPI was sent to all the targeted harts successfully.
  12. fn send_ipi_many(&self, hart_mask: HartMask) -> SbiRet;
  13. #[doc(hidden)]
  14. /// Get the maximum hart id available by this IPI support module
  15. fn max_hart_id(&self) -> usize {
  16. unimplemented!("remained for compatibility, should remove in 0.3.0")
  17. }
  18. }
  19. static IPI: AmoOnceRef<dyn Ipi> = AmoOnceRef::new();
  20. pub fn init_ipi(ipi: &'static dyn Ipi) {
  21. if !IPI.try_call_once(ipi) {
  22. panic!("load sbi module when already loaded")
  23. }
  24. }
  25. #[inline]
  26. pub(crate) fn probe_ipi() -> bool {
  27. IPI.get().is_some()
  28. }
  29. pub(crate) fn send_ipi_many(hart_mask: HartMask) -> SbiRet {
  30. if let Some(ipi) = IPI.get() {
  31. return ipi.send_ipi_many(hart_mask);
  32. }
  33. SbiRet::not_supported()
  34. }