use system_error::SystemError; use crate::{exception::irqdesc::IrqDescState, libs::spinlock::SpinLockGuard}; use super::{irqdesc::InnerIrqDesc, manage::IrqManager}; impl IrqManager { /// 检查状态并重发中断 /// /// ## 参数 /// /// - `desc_inner_guard`:中断描述符的锁 /// - `inject`:是否注入中断 pub(super) fn irq_check_and_resend( &self, desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>, inject: bool, ) -> Result<(), SystemError> { // https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/resend.c?fi=check_irq_resend#106 /* * 我们不重新发送电平触发类型的中断。电平触发类型的中断在它们仍然活动时由硬件重新发送。 * 清除PENDING bit,以避免suspend/resume过程中的混淆。 */ if desc_inner_guard .common_data() .trigger_type() .is_level_type() { desc_inner_guard .internal_state_mut() .remove(IrqDescState::IRQS_PENDING); return Err(SystemError::EINVAL); } if desc_inner_guard .internal_state() .contains(IrqDescState::IRQS_REPLAY) { return Err(SystemError::EBUSY); } if !desc_inner_guard .internal_state() .contains(IrqDescState::IRQS_PENDING) && !inject { return Ok(()); } desc_inner_guard .internal_state_mut() .remove(IrqDescState::IRQS_PENDING); let mut ret = Ok(()); if self.try_retrigger(desc_inner_guard).is_err() { // todo: 支持发送到tasklet ret = Err(SystemError::EINVAL); } if ret.is_ok() { desc_inner_guard .internal_state_mut() .insert(IrqDescState::IRQS_REPLAY); } return ret; } fn try_retrigger( &self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>, ) -> Result<(), SystemError> { if let Err(e) = desc_inner_guard .irq_data() .chip_info_read_irqsave() .chip() .retrigger(desc_inner_guard.irq_data()) { if e != SystemError::ENOSYS { return Err(e); } } else { return Ok(()); } // 当前中断控制器不支持重发中断,从父中断控制器重发 return self.irq_chip_retrigger_hierarchy(desc_inner_guard.irq_data()); } }