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