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