xref: /DragonOS/kernel/src/exception/resend.rs (revision e28411791f090c421fe4b6fa5956fb1bd362a8d9)
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             == false
47             && inject == false
48         {
49             return Ok(());
50         }
51 
52         desc_inner_guard
53             .internal_state_mut()
54             .remove(IrqDescState::IRQS_PENDING);
55 
56         let mut ret = Ok(());
57         if self.try_retrigger(desc_inner_guard).is_err() {
58             // todo: 支持发送到tasklet
59             ret = Err(SystemError::EINVAL);
60         }
61 
62         if ret.is_ok() {
63             desc_inner_guard
64                 .internal_state_mut()
65                 .insert(IrqDescState::IRQS_REPLAY);
66         }
67 
68         return ret;
69     }
70 
71     fn try_retrigger(
72         &self,
73         desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
74     ) -> Result<(), SystemError> {
75         if let Err(e) = desc_inner_guard
76             .irq_data()
77             .chip_info_read_irqsave()
78             .chip()
79             .retrigger(desc_inner_guard.irq_data())
80         {
81             if e != SystemError::ENOSYS {
82                 return Err(e);
83             }
84         } else {
85             return Ok(());
86         }
87 
88         // 当前中断控制器不支持重发中断,从父中断控制器重发
89         return self.irq_chip_retrigger_hierarchy(desc_inner_guard.irq_data());
90     }
91 }
92