resend.rs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. use system_error::SystemError;
  2. use crate::{exception::irqdesc::IrqDescState, libs::spinlock::SpinLockGuard};
  3. use super::{irqdesc::InnerIrqDesc, manage::IrqManager};
  4. impl IrqManager {
  5. /// 检查状态并重发中断
  6. ///
  7. /// ## 参数
  8. ///
  9. /// - `desc_inner_guard`:中断描述符的锁
  10. /// - `inject`:是否注入中断
  11. pub(super) fn irq_check_and_resend(
  12. &self,
  13. desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
  14. inject: bool,
  15. ) -> Result<(), SystemError> {
  16. // https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/resend.c?fi=check_irq_resend#106
  17. /*
  18. * 我们不重新发送电平触发类型的中断。电平触发类型的中断在它们仍然活动时由硬件重新发送。
  19. * 清除PENDING bit,以避免suspend/resume过程中的混淆。
  20. */
  21. if desc_inner_guard
  22. .common_data()
  23. .trigger_type()
  24. .is_level_type()
  25. {
  26. desc_inner_guard
  27. .internal_state_mut()
  28. .remove(IrqDescState::IRQS_PENDING);
  29. return Err(SystemError::EINVAL);
  30. }
  31. if desc_inner_guard
  32. .internal_state()
  33. .contains(IrqDescState::IRQS_REPLAY)
  34. {
  35. return Err(SystemError::EBUSY);
  36. }
  37. if !desc_inner_guard
  38. .internal_state()
  39. .contains(IrqDescState::IRQS_PENDING)
  40. && !inject
  41. {
  42. return Ok(());
  43. }
  44. desc_inner_guard
  45. .internal_state_mut()
  46. .remove(IrqDescState::IRQS_PENDING);
  47. let mut ret = Ok(());
  48. if self.try_retrigger(desc_inner_guard).is_err() {
  49. // todo: 支持发送到tasklet
  50. ret = Err(SystemError::EINVAL);
  51. }
  52. if ret.is_ok() {
  53. desc_inner_guard
  54. .internal_state_mut()
  55. .insert(IrqDescState::IRQS_REPLAY);
  56. }
  57. return ret;
  58. }
  59. fn try_retrigger(
  60. &self,
  61. desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
  62. ) -> Result<(), SystemError> {
  63. if let Err(e) = desc_inner_guard
  64. .irq_data()
  65. .chip_info_read_irqsave()
  66. .chip()
  67. .retrigger(desc_inner_guard.irq_data())
  68. {
  69. if e != SystemError::ENOSYS {
  70. return Err(e);
  71. }
  72. } else {
  73. return Ok(());
  74. }
  75. // 当前中断控制器不支持重发中断,从父中断控制器重发
  76. return self.irq_chip_retrigger_hierarchy(desc_inner_guard.irq_data());
  77. }
  78. }