123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- 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());
- }
- }
|