xref: /DragonOS/kernel/src/exception/irqchip.rs (revision 338f6903262c5031abad3c8e361813355a27fcdb)
1*338f6903SLoGin use core::{any::Any, fmt::Debug, intrinsics::unlikely};
2ce5850adSLoGin 
3ce5850adSLoGin use alloc::{
4*338f6903SLoGin     string::{String, ToString},
5ce5850adSLoGin     sync::{Arc, Weak},
6ce5850adSLoGin     vec::Vec,
7ce5850adSLoGin };
8ce5850adSLoGin use system_error::SystemError;
9ce5850adSLoGin 
10e2841179SLoGin use crate::{
11*338f6903SLoGin     exception::{
12*338f6903SLoGin         dummychip::no_irq_chip,
13*338f6903SLoGin         handle::{bad_irq_handler, mask_ack_irq},
14*338f6903SLoGin         irqdata::IrqStatus,
15*338f6903SLoGin         irqdesc::irq_desc_manager,
16*338f6903SLoGin         manage::irq_manager,
17*338f6903SLoGin     },
18*338f6903SLoGin     libs::{
19*338f6903SLoGin         cpumask::CpuMask,
20*338f6903SLoGin         once::Once,
21*338f6903SLoGin         spinlock::{SpinLock, SpinLockGuard},
22*338f6903SLoGin     },
23e2841179SLoGin     mm::VirtAddr,
24*338f6903SLoGin     smp::cpu::ProcessorId,
25e2841179SLoGin };
26ce5850adSLoGin 
27ce5850adSLoGin use super::{
28*338f6903SLoGin     irqdata::{IrqData, IrqHandlerData, IrqLineStatus},
29*338f6903SLoGin     irqdesc::{InnerIrqDesc, IrqAction, IrqDesc, IrqFlowHandler, IrqHandler, IrqReturn},
30ce5850adSLoGin     irqdomain::IrqDomain,
31e2841179SLoGin     manage::IrqManager,
32ce5850adSLoGin     msi::MsiMsg,
33*338f6903SLoGin     IrqNumber,
34ce5850adSLoGin };
35ce5850adSLoGin 
36ce5850adSLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h#506
37ce5850adSLoGin pub trait IrqChip: Sync + Send + Any + Debug {
38ce5850adSLoGin     fn name(&self) -> &'static str;
39ce5850adSLoGin     /// start up the interrupt (defaults to ->enable if ENOSYS)
40ce5850adSLoGin     fn irq_startup(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
41ce5850adSLoGin         Err(SystemError::ENOSYS)
42ce5850adSLoGin     }
43ce5850adSLoGin 
44ce5850adSLoGin     /// shut down the interrupt (defaults to ->disable if ENOSYS)
45ce5850adSLoGin     fn irq_shutdown(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
46ce5850adSLoGin         Err(SystemError::ENOSYS)
47ce5850adSLoGin     }
48ce5850adSLoGin 
49ce5850adSLoGin     /// enable the interrupt
50ce5850adSLoGin     ///
51ce5850adSLoGin     /// (defaults to ->unmask if ENOSYS)
52ce5850adSLoGin     fn irq_enable(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
53ce5850adSLoGin         Err(SystemError::ENOSYS)
54ce5850adSLoGin     }
55ce5850adSLoGin 
56ce5850adSLoGin     /// disable the interrupt
57ce5850adSLoGin     fn irq_disable(&self, irq: &Arc<IrqData>);
58ce5850adSLoGin 
59ce5850adSLoGin     /// start of a new interrupt
60ce5850adSLoGin     fn irq_ack(&self, irq: &Arc<IrqData>);
61ce5850adSLoGin 
62ce5850adSLoGin     /// mask an interrupt source
63e2841179SLoGin     ///
64e2841179SLoGin     /// 用于屏蔽中断
65e2841179SLoGin     ///
66*338f6903SLoGin     /// 如果返回ENOSYS,则表明irq_mask()不支持. 那么中断机制代码将调用irq_disable()。
67e2841179SLoGin     ///
68e2841179SLoGin     /// 如果返回错误,那么中断的屏蔽状态将不会改变。
69e2841179SLoGin     fn irq_mask(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
70e2841179SLoGin         Err(SystemError::ENOSYS)
71e2841179SLoGin     }
72e2841179SLoGin 
73e2841179SLoGin     /// 指示当前芯片是否实现了`irq_mask_ack`函数
74e2841179SLoGin     fn can_mask_ack(&self) -> bool;
75e2841179SLoGin 
76ce5850adSLoGin     /// ack and mask an interrupt source
773bc96fa4SLoGin     fn irq_mask_ack(&self, _irq: &Arc<IrqData>) {}
78e2841179SLoGin 
79ce5850adSLoGin     /// unmask an interrupt source
80e2841179SLoGin     ///
81e2841179SLoGin     /// 用于取消屏蔽中断
82e2841179SLoGin     ///
83e2841179SLoGin     /// 如果返回ENOSYS,则表明irq_unmask()不支持.
84e2841179SLoGin     fn irq_unmask(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
85e2841179SLoGin         Err(SystemError::ENOSYS)
86e2841179SLoGin     }
87ce5850adSLoGin     /// end of interrupt
883bc96fa4SLoGin     fn irq_eoi(&self, _irq: &Arc<IrqData>) {}
89ce5850adSLoGin 
90e2841179SLoGin     /// 指示当前芯片是否可以设置中断亲和性。
91e2841179SLoGin     fn can_set_affinity(&self) -> bool;
92e2841179SLoGin 
93e2841179SLoGin     /// 在SMP机器上设置CPU亲和性。
94e2841179SLoGin     ///
95e2841179SLoGin     /// 如果force参数为真,它告诉驱动程序无条件地应用亲和性设置。
96e2841179SLoGin     /// 不需要对提供的亲和性掩码进行完整性检查。这用于CPU热插拔,其中目标CPU尚未在cpu_online_mask中设置。
97e2841179SLoGin     fn irq_set_affinity(
98e2841179SLoGin         &self,
99e2841179SLoGin         _irq: &Arc<IrqData>,
100e2841179SLoGin         _cpu: &CpuMask,
101e2841179SLoGin         _force: bool,
102e2841179SLoGin     ) -> Result<IrqChipSetMaskResult, SystemError> {
103e2841179SLoGin         Err(SystemError::ENOSYS)
104e2841179SLoGin     }
105ce5850adSLoGin 
106ce5850adSLoGin     /// retrigger an IRQ to the CPU
107e2841179SLoGin     fn retrigger(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
108e2841179SLoGin         Err(SystemError::ENOSYS)
109e2841179SLoGin     }
110e2841179SLoGin 
111e2841179SLoGin     /// 指示当前芯片是否可以设置中断流类型。
112e2841179SLoGin     ///
113e2841179SLoGin     /// 如果返回true,则可以调用irq_set_type()。
114e2841179SLoGin     fn can_set_flow_type(&self) -> bool;
115ce5850adSLoGin 
116ce5850adSLoGin     /// set the flow type of an interrupt
117ce5850adSLoGin     ///
118ce5850adSLoGin     /// flow_type: the flow type to set
119ce5850adSLoGin     ///
120ce5850adSLoGin     fn irq_set_type(
121ce5850adSLoGin         &self,
122ce5850adSLoGin         _irq: &Arc<IrqData>,
123ce5850adSLoGin         _flow_type: IrqLineStatus,
124e2841179SLoGin     ) -> Result<IrqChipSetMaskResult, SystemError> {
125ce5850adSLoGin         Err(SystemError::ENOSYS)
126ce5850adSLoGin     }
127ce5850adSLoGin 
128ce5850adSLoGin     /// enable/disable power management wake-on of an interrupt
129ce5850adSLoGin     fn irq_set_wake(&self, _irq: &Arc<IrqData>, _on: bool) -> Result<(), SystemError> {
130ce5850adSLoGin         Err(SystemError::ENOSYS)
131ce5850adSLoGin     }
132ce5850adSLoGin 
133ce5850adSLoGin     /// function to lock access to slow bus (i2c) chips
134ce5850adSLoGin     fn irq_bus_lock(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
135ce5850adSLoGin         Ok(())
136ce5850adSLoGin     }
137ce5850adSLoGin 
138ce5850adSLoGin     /// function to sync and unlock slow bus (i2c) chips
139ce5850adSLoGin     fn irq_bus_sync_unlock(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
140ce5850adSLoGin         Ok(())
141ce5850adSLoGin     }
142ce5850adSLoGin 
143ce5850adSLoGin     /// function called from core code on suspend once per
144ce5850adSLoGin     /// chip, when one or more interrupts are installed
1453bc96fa4SLoGin     fn irq_suspend(&self, _irq: &Arc<IrqData>) {}
146ce5850adSLoGin 
147ce5850adSLoGin     /// function called from core code on resume once per chip,
148ce5850adSLoGin     /// when one ore more interrupts are installed
1493bc96fa4SLoGin     fn irq_resume(&self, _irq: &Arc<IrqData>) {}
150ce5850adSLoGin 
151ce5850adSLoGin     /// function called from core code on shutdown once per chip
1523bc96fa4SLoGin     fn irq_pm_shutdown(&self, _irq: &Arc<IrqData>) {}
153ce5850adSLoGin 
154ce5850adSLoGin     /// Optional function to set irq_data.mask for special cases
155ce5850adSLoGin     fn irq_calc_mask(&self, _irq: &Arc<IrqData>) {}
156ce5850adSLoGin 
157ce5850adSLoGin     // todo: print chip
158ce5850adSLoGin 
159ce5850adSLoGin     /// optional to request resources before calling
160ce5850adSLoGin     /// any other callback related to this irq
161ce5850adSLoGin     fn irq_request_resources(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
162ce5850adSLoGin         Ok(())
163ce5850adSLoGin     }
164ce5850adSLoGin 
165ce5850adSLoGin     /// optional to release resources acquired with
166ce5850adSLoGin     /// irq_request_resources
167ce5850adSLoGin     fn irq_release_resources(&self, _irq: &Arc<IrqData>) {}
168ce5850adSLoGin 
169ce5850adSLoGin     /// optional to compose message content for MSI
170e2841179SLoGin     ///
171e2841179SLoGin     /// 组装MSI消息并返回到msg中
172ce5850adSLoGin     fn irq_compose_msi_msg(&self, _irq: &Arc<IrqData>, _msg: &mut MsiMsg) {}
173ce5850adSLoGin 
174ce5850adSLoGin     /// optional to write message content for MSI
175ce5850adSLoGin     fn irq_write_msi_msg(&self, _irq: &Arc<IrqData>, _msg: &MsiMsg) {}
176ce5850adSLoGin 
177ce5850adSLoGin     /// return the internal state of an interrupt
178ce5850adSLoGin     fn irqchip_state(
179ce5850adSLoGin         &self,
180ce5850adSLoGin         _irq: &Arc<IrqData>,
181ce5850adSLoGin         _which: IrqChipState,
182ce5850adSLoGin     ) -> Result<bool, SystemError> {
183ce5850adSLoGin         Err(SystemError::ENOSYS)
184ce5850adSLoGin     }
185ce5850adSLoGin 
186ce5850adSLoGin     /// set the internal state of an interrupt
187ce5850adSLoGin     fn set_irqchip_state(
188ce5850adSLoGin         &self,
189ce5850adSLoGin         _irq: &Arc<IrqData>,
190ce5850adSLoGin         _which: IrqChipState,
191ce5850adSLoGin         _state: bool,
192ce5850adSLoGin     ) -> Result<(), SystemError> {
193ce5850adSLoGin         Err(SystemError::ENOSYS)
194ce5850adSLoGin     }
195ce5850adSLoGin 
196ce5850adSLoGin     // todo: set vcpu affinity
197ce5850adSLoGin 
198ce5850adSLoGin     /// send a single IPI to destination cpus
1993bc96fa4SLoGin     fn send_single_ipi(&self, _irq: &Arc<IrqData>, _cpu: u32) {}
200ce5850adSLoGin 
201ce5850adSLoGin     // todo: send ipi with cpu mask
202ce5850adSLoGin 
203ce5850adSLoGin     /// function called from core code before enabling an NMI
204ce5850adSLoGin     fn irq_nmi_setup(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
205ce5850adSLoGin         Err(SystemError::ENOSYS)
206ce5850adSLoGin     }
207ce5850adSLoGin 
208ce5850adSLoGin     /// function called from core code after disabling an NMI
2093bc96fa4SLoGin     fn irq_nmi_teardown(&self, _irq: &Arc<IrqData>) {}
2103bc96fa4SLoGin 
2113bc96fa4SLoGin     fn flags(&self) -> IrqChipFlags;
212ce5850adSLoGin }
213ce5850adSLoGin 
214ce5850adSLoGin #[allow(dead_code)]
215ce5850adSLoGin #[derive(Debug, Clone, Copy)]
216ce5850adSLoGin pub enum IrqChipState {
217ce5850adSLoGin     /// Is the interrupt pending?
218ce5850adSLoGin     Pending,
219ce5850adSLoGin     /// Is the interrupt in progress?
220ce5850adSLoGin     Active,
221ce5850adSLoGin     /// Is the interrupt masked?
222ce5850adSLoGin     Masked,
223ce5850adSLoGin     /// Is Irq line high?
224ce5850adSLoGin     LineLevel,
225ce5850adSLoGin }
226ce5850adSLoGin 
227e2841179SLoGin /// 中断芯片的数据(per-irq的)
228e2841179SLoGin pub trait IrqChipData: Sync + Send + Any + Debug {
229e2841179SLoGin     fn as_any_ref(&self) -> &dyn Any;
230e2841179SLoGin }
231ce5850adSLoGin 
232ce5850adSLoGin bitflags! {
233ce5850adSLoGin     /// 定义 IrqGcFlags 位标志
234ce5850adSLoGin     pub struct IrqGcFlags: u32 {
235ce5850adSLoGin         /// 通过读取mask reg来初始化mask_cache
236ce5850adSLoGin         const IRQ_GC_INIT_MASK_CACHE = 1 << 0;
237ce5850adSLoGin         /// 对于需要在父irq上调用irq_set_wake()的irq芯片, 将irqs的锁类设置为嵌套。Usually GPIO implementations
238ce5850adSLoGin         const IRQ_GC_INIT_NESTED_LOCK = 1 << 1;
239ce5850adSLoGin         /// Mask cache是芯片类型私有的
240ce5850adSLoGin         const IRQ_GC_MASK_CACHE_PER_TYPE = 1 << 2;
241ce5850adSLoGin         /// 不计算irqData->mask
242ce5850adSLoGin         const IRQ_GC_NO_MASK = 1 << 3;
243ce5850adSLoGin         /// 使用大端字节序的寄存器访问(默认:小端LE)
244ce5850adSLoGin         const IRQ_GC_BE_IO = 1 << 4;
245ce5850adSLoGin     }
246ce5850adSLoGin }
247ce5850adSLoGin 
248ce5850adSLoGin #[allow(dead_code)]
249ce5850adSLoGin #[derive(Debug)]
250ce5850adSLoGin pub struct IrqChipGeneric {
251ce5850adSLoGin     inner: SpinLock<InnerIrqChipGeneric>,
252ce5850adSLoGin }
253ce5850adSLoGin 
254ce5850adSLoGin #[allow(dead_code)]
255ce5850adSLoGin #[derive(Debug)]
256ce5850adSLoGin struct InnerIrqChipGeneric {
257ce5850adSLoGin     /// Register base address
258ce5850adSLoGin     reg_base: VirtAddr,
259ce5850adSLoGin     ops: &'static dyn IrqChipGenericOps,
260ce5850adSLoGin     /// Interrupt base num for this chip
261ce5850adSLoGin     irq_base: u32,
262ce5850adSLoGin     /// Number of interrupts handled by this chip
263ce5850adSLoGin     irq_cnt: u32,
264ce5850adSLoGin     /// Cached mask register shared between all chip types
265ce5850adSLoGin     mask_cache: u32,
266ce5850adSLoGin     /// Cached type register
267ce5850adSLoGin     type_cache: u32,
268ce5850adSLoGin     /// Cached polarity register
269ce5850adSLoGin     polarity_cache: u32,
270ce5850adSLoGin     /// Interrupt can wakeup from suspend
271ce5850adSLoGin     wake_enabled: bool,
272ce5850adSLoGin     /// Interrupt is marked as an wakeup from suspend source
273ce5850adSLoGin     wake_active: bool,
274ce5850adSLoGin     /// Number of available irq_chip_type instances (usually 1)
275ce5850adSLoGin     num_chip_type: u32,
276ce5850adSLoGin     private_data: Option<Arc<dyn IrqChipGenericPrivateData>>,
277ce5850adSLoGin     installed: u64,
278ce5850adSLoGin     unused: u64,
279ce5850adSLoGin     domain: Weak<IrqDomain>,
280ce5850adSLoGin     chip_types: Vec<IrqChipType>,
281ce5850adSLoGin }
282ce5850adSLoGin 
2833bc96fa4SLoGin pub trait IrqChipGenericOps: Debug + Send + Sync {
284ce5850adSLoGin     /// Alternate I/O accessor (defaults to readl if NULL)
285ce5850adSLoGin     unsafe fn reg_readl(&self, addr: VirtAddr) -> u32;
286ce5850adSLoGin 
287ce5850adSLoGin     /// Alternate I/O accessor (defaults to writel if NULL)
288ce5850adSLoGin     unsafe fn reg_writel(&self, addr: VirtAddr, val: u32);
289ce5850adSLoGin 
290ce5850adSLoGin     /// Function called from core code on suspend once per
291ce5850adSLoGin     /// chip; can be useful instead of irq_chip::suspend to
292ce5850adSLoGin     /// handle chip details even when no interrupts are in use
293ce5850adSLoGin     fn suspend(&self, gc: &Arc<IrqChipGeneric>);
294ce5850adSLoGin     /// Function called from core code on resume once per chip;
295ce5850adSLoGin     /// can be useful instead of irq_chip::resume to handle chip
296ce5850adSLoGin     /// details even when no interrupts are in use
297ce5850adSLoGin     fn resume(&self, gc: &Arc<IrqChipGeneric>);
298ce5850adSLoGin }
299ce5850adSLoGin 
300ce5850adSLoGin pub trait IrqChipGenericPrivateData: Sync + Send + Any + Debug {}
301ce5850adSLoGin 
302ce5850adSLoGin #[derive(Debug)]
303ce5850adSLoGin pub struct IrqChipType {
304ce5850adSLoGin     // todo https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h#1024
305ce5850adSLoGin }
3063bc96fa4SLoGin 
307e2841179SLoGin #[allow(dead_code)]
308e2841179SLoGin #[derive(Debug)]
309e2841179SLoGin pub enum IrqChipSetMaskResult {
310e2841179SLoGin     /// core updates mask ok.
311e2841179SLoGin     SetMaskOk,
312e2841179SLoGin     /// core updates mask ok. No change.
313e2841179SLoGin     SetMaskOkNoChange,
314e2841179SLoGin     /// core updates mask ok. Done.(same as SetMaskOk)
315e2841179SLoGin     ///
316e2841179SLoGin     /// 支持堆叠irq芯片的特殊代码, 表示跳过所有子irq芯片。
317e2841179SLoGin     SetMaskOkDone,
318e2841179SLoGin }
319e2841179SLoGin 
3203bc96fa4SLoGin bitflags! {
3213bc96fa4SLoGin     /// IrqChip specific flags
3223bc96fa4SLoGin     pub struct IrqChipFlags: u32 {
323e2841179SLoGin         /// 在调用chip.irq_set_type()之前屏蔽中断
3243bc96fa4SLoGin         const IRQCHIP_SET_TYPE_MASKED = 1 << 0;
3253bc96fa4SLoGin         /// 只有在irq被处理时才发出irq_eoi()
3263bc96fa4SLoGin         const IRQCHIP_EOI_IF_HANDLED = 1 << 1;
3273bc96fa4SLoGin         /// 在挂起路径中屏蔽非唤醒irq
3283bc96fa4SLoGin         const IRQCHIP_MASK_ON_SUSPEND = 1 << 2;
3293bc96fa4SLoGin         /// 只有在irq启用时才调用irq_on/off_line回调
3303bc96fa4SLoGin         const IRQCHIP_ONOFFLINE_ENABLED = 1 << 3;
3313bc96fa4SLoGin         /// 跳过chip.irq_set_wake(),对于这个irq芯片
3323bc96fa4SLoGin         const IRQCHIP_SKIP_SET_WAKE = 1 << 4;
3333bc96fa4SLoGin         /// 单次触发不需要屏蔽/取消屏蔽
3343bc96fa4SLoGin         const IRQCHIP_ONESHOT_SAFE = 1 << 5;
3353bc96fa4SLoGin         /// 芯片在线程模式下需要在取消屏蔽时eoi()
3363bc96fa4SLoGin         const IRQCHIP_EOI_THREADED = 1 << 6;
3373bc96fa4SLoGin         /// 芯片可以为Level MSIs提供两个门铃
3383bc96fa4SLoGin         const IRQCHIP_SUPPORTS_LEVEL_MSI = 1 << 7;
3393bc96fa4SLoGin         /// 芯片可以传递NMIs,仅适用于根irqchips
3403bc96fa4SLoGin         const IRQCHIP_SUPPORTS_NMI = 1 << 8;
3413bc96fa4SLoGin         /// 在挂起路径中,如果它们处于禁用状态,则调用__enable_irq()/__disable_irq()以唤醒irq
3423bc96fa4SLoGin         const IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND = 1 << 9;
3433bc96fa4SLoGin         /// 在启动前更新默认亲和性
3443bc96fa4SLoGin         const IRQCHIP_AFFINITY_PRE_STARTUP = 1 << 10;
3453bc96fa4SLoGin         /// 不要在这个芯片中改变任何东西
3463bc96fa4SLoGin         const IRQCHIP_IMMUTABLE = 1 << 11;
3473bc96fa4SLoGin     }
3483bc96fa4SLoGin }
349e2841179SLoGin 
350e2841179SLoGin impl IrqManager {
351e2841179SLoGin     /// Acknowledge the parent interrupt
352e2841179SLoGin     #[allow(dead_code)]
353e2841179SLoGin     pub fn irq_chip_ack_parent(&self, irq_data: &Arc<IrqData>) {
354e2841179SLoGin         let parent_data = irq_data.parent_data().map(|p| p.upgrade()).flatten();
355e2841179SLoGin 
356e2841179SLoGin         if let Some(parent_data) = parent_data {
357e2841179SLoGin             let parent_chip = parent_data.chip_info_read_irqsave().chip();
358e2841179SLoGin             parent_chip.irq_ack(&parent_data);
359e2841179SLoGin         }
360e2841179SLoGin     }
361e2841179SLoGin 
362e2841179SLoGin     /// 在硬件中重新触发中断
363e2841179SLoGin     ///
364e2841179SLoGin     /// 遍历中断域的层次结构,并检查是否存在一个硬件重新触发函数。如果存在则调用它
365e2841179SLoGin     pub fn irq_chip_retrigger_hierarchy(&self, irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
366e2841179SLoGin         let mut data: Option<Arc<IrqData>> = Some(irq_data.clone());
367e2841179SLoGin         loop {
368e2841179SLoGin             if let Some(d) = data {
369e2841179SLoGin                 if let Err(e) = d.chip_info_read_irqsave().chip().retrigger(&d) {
370e2841179SLoGin                     if e == SystemError::ENOSYS {
371e2841179SLoGin                         data = d.parent_data().map(|p| p.upgrade()).flatten();
372e2841179SLoGin                     } else {
373e2841179SLoGin                         return Err(e);
374e2841179SLoGin                     }
375e2841179SLoGin                 } else {
376e2841179SLoGin                     return Ok(());
377e2841179SLoGin                 }
378e2841179SLoGin             } else {
379e2841179SLoGin                 break;
380e2841179SLoGin             }
381e2841179SLoGin         }
382e2841179SLoGin 
383e2841179SLoGin         return Ok(());
384e2841179SLoGin     }
385*338f6903SLoGin 
386*338f6903SLoGin     pub(super) fn __irq_set_handler(
387*338f6903SLoGin         &self,
388*338f6903SLoGin         irq: IrqNumber,
389*338f6903SLoGin         handler: &'static dyn IrqFlowHandler,
390*338f6903SLoGin         is_chained: bool,
391*338f6903SLoGin         name: Option<String>,
392*338f6903SLoGin     ) {
393*338f6903SLoGin         let r = irq_desc_manager().lookup_and_lock_bus(irq, false, false);
394*338f6903SLoGin         if r.is_none() {
395*338f6903SLoGin             return;
396*338f6903SLoGin         }
397*338f6903SLoGin 
398*338f6903SLoGin         let irq_desc = r.unwrap();
399*338f6903SLoGin 
400*338f6903SLoGin         let mut desc_inner = irq_desc.inner();
401*338f6903SLoGin         self.__irq_do_set_handler(&irq_desc, &mut desc_inner, Some(handler), is_chained, name);
402*338f6903SLoGin 
403*338f6903SLoGin         drop(desc_inner);
404*338f6903SLoGin         irq_desc.chip_bus_sync_unlock();
405*338f6903SLoGin     }
406*338f6903SLoGin 
407*338f6903SLoGin     fn __irq_do_set_handler(
408*338f6903SLoGin         &self,
409*338f6903SLoGin         desc: &Arc<IrqDesc>,
410*338f6903SLoGin         desc_inner: &mut SpinLockGuard<'_, InnerIrqDesc>,
411*338f6903SLoGin         mut handler: Option<&'static dyn IrqFlowHandler>,
412*338f6903SLoGin         is_chained: bool,
413*338f6903SLoGin         name: Option<String>,
414*338f6903SLoGin     ) {
415*338f6903SLoGin         if handler.is_none() {
416*338f6903SLoGin             handler = Some(bad_irq_handler());
417*338f6903SLoGin         } else {
418*338f6903SLoGin             let mut irq_data = Some(desc_inner.irq_data().clone());
419*338f6903SLoGin 
420*338f6903SLoGin             /*
421*338f6903SLoGin              * 在具有中断域继承的domain中,我们可能会遇到这样的情况,
422*338f6903SLoGin              * 最外层的芯片还没有设置好,但是内部的芯片已经存在了。
423*338f6903SLoGin              * 我们选择安装处理程序,而不是退出,
424*338f6903SLoGin              * 但显然我们此时无法启用/启动中断。
425*338f6903SLoGin              */
426*338f6903SLoGin             while irq_data.is_some() {
427*338f6903SLoGin                 let dt = irq_data.as_ref().unwrap().clone();
428*338f6903SLoGin 
429*338f6903SLoGin                 let chip_info = dt.chip_info_read_irqsave();
430*338f6903SLoGin 
431*338f6903SLoGin                 if !Arc::ptr_eq(&chip_info.chip(), &no_irq_chip()) {
432*338f6903SLoGin                     break;
433*338f6903SLoGin                 }
434*338f6903SLoGin 
435*338f6903SLoGin                 /*
436*338f6903SLoGin                  * 如果最外层的芯片没有设置好,并且预期立即开始中断,
437*338f6903SLoGin                  * 则放弃。
438*338f6903SLoGin                  */
439*338f6903SLoGin                 if unlikely(is_chained) {
440*338f6903SLoGin                     kwarn!(
441*338f6903SLoGin                         "Chained handler for irq {} is not supported",
442*338f6903SLoGin                         dt.irq().data()
443*338f6903SLoGin                     );
444*338f6903SLoGin                     return;
445*338f6903SLoGin                 }
446*338f6903SLoGin 
447*338f6903SLoGin                 //  try the parent
448*338f6903SLoGin                 let parent_data = dt.parent_data().map(|p| p.upgrade()).flatten();
449*338f6903SLoGin 
450*338f6903SLoGin                 irq_data = parent_data;
451*338f6903SLoGin             }
452*338f6903SLoGin 
453*338f6903SLoGin             if unlikely(
454*338f6903SLoGin                 irq_data.is_none()
455*338f6903SLoGin                     || Arc::ptr_eq(
456*338f6903SLoGin                         &irq_data.as_ref().unwrap().chip_info_read_irqsave().chip(),
457*338f6903SLoGin                         &no_irq_chip(),
458*338f6903SLoGin                     ),
459*338f6903SLoGin             ) {
460*338f6903SLoGin                 kwarn!("No irq chip for irq {}", desc_inner.irq_data().irq().data());
461*338f6903SLoGin                 return;
462*338f6903SLoGin             }
463*338f6903SLoGin         }
464*338f6903SLoGin         let handler = handler.unwrap();
465*338f6903SLoGin         if core::ptr::eq(handler, bad_irq_handler()) {
466*338f6903SLoGin             if Arc::ptr_eq(
467*338f6903SLoGin                 &desc_inner.irq_data().chip_info_read_irqsave().chip(),
468*338f6903SLoGin                 &no_irq_chip(),
469*338f6903SLoGin             ) {
470*338f6903SLoGin                 let irq_data = desc_inner.irq_data();
471*338f6903SLoGin                 mask_ack_irq(irq_data);
472*338f6903SLoGin 
473*338f6903SLoGin                 irq_data.irqd_set(IrqStatus::IRQD_IRQ_DISABLED);
474*338f6903SLoGin 
475*338f6903SLoGin                 if is_chained {
476*338f6903SLoGin                     desc_inner.clear_actions();
477*338f6903SLoGin                 }
478*338f6903SLoGin                 desc_inner.set_depth(1);
479*338f6903SLoGin             }
480*338f6903SLoGin         }
481*338f6903SLoGin         let chip = desc_inner.irq_data().chip_info_read_irqsave().chip();
482*338f6903SLoGin         desc.set_handler_no_lock_inner(handler, desc_inner.irq_data(), &chip);
483*338f6903SLoGin         desc_inner.set_name(name);
484*338f6903SLoGin 
485*338f6903SLoGin         if !core::ptr::eq(handler, bad_irq_handler()) && is_chained {
486*338f6903SLoGin             let trigger_type = desc_inner.common_data().trigger_type();
487*338f6903SLoGin 
488*338f6903SLoGin             /*
489*338f6903SLoGin              * 我们即将立即启动这个中断,
490*338f6903SLoGin              * 因此需要设置触发配置。
491*338f6903SLoGin              * 但是 .irq_set_type 回调可能已经覆盖了
492*338f6903SLoGin              * irqflowhandler,忽略了我们正在处理的
493*338f6903SLoGin              * 是一个链式中断。立即重置它,因为我们
494*338f6903SLoGin              * 确实知道更好的处理方式。
495*338f6903SLoGin              */
496*338f6903SLoGin 
497*338f6903SLoGin             if trigger_type != IrqLineStatus::IRQ_TYPE_NONE {
498*338f6903SLoGin                 irq_manager()
499*338f6903SLoGin                     .do_set_irq_trigger(desc.clone(), desc_inner, trigger_type)
500*338f6903SLoGin                     .ok();
501*338f6903SLoGin                 desc.set_handler(handler);
502*338f6903SLoGin             }
503*338f6903SLoGin 
504*338f6903SLoGin             desc_inner.set_noprobe();
505*338f6903SLoGin             desc_inner.set_norequest();
506*338f6903SLoGin             desc_inner.set_nothread();
507*338f6903SLoGin 
508*338f6903SLoGin             desc_inner.clear_actions();
509*338f6903SLoGin             desc_inner.add_action(chained_action());
510*338f6903SLoGin 
511*338f6903SLoGin             irq_manager()
512*338f6903SLoGin                 .irq_activate_and_startup(desc, desc_inner, IrqManager::IRQ_RESEND)
513*338f6903SLoGin                 .ok();
514*338f6903SLoGin         }
515*338f6903SLoGin 
516*338f6903SLoGin         return;
517*338f6903SLoGin     }
518*338f6903SLoGin 
519*338f6903SLoGin     pub fn irq_set_handler_data(
520*338f6903SLoGin         &self,
521*338f6903SLoGin         irq: IrqNumber,
522*338f6903SLoGin         data: Option<Arc<dyn IrqHandlerData>>,
523*338f6903SLoGin     ) -> Result<(), SystemError> {
524*338f6903SLoGin         let desc = irq_desc_manager().lookup(irq).ok_or(SystemError::EINVAL)?;
525*338f6903SLoGin         desc.inner().common_data().inner().set_handler_data(data);
526*338f6903SLoGin 
527*338f6903SLoGin         return Ok(());
528*338f6903SLoGin     }
529*338f6903SLoGin 
530*338f6903SLoGin     pub fn irq_percpu_disable(
531*338f6903SLoGin         &self,
532*338f6903SLoGin         desc: &Arc<IrqDesc>,
533*338f6903SLoGin         irq_data: &Arc<IrqData>,
534*338f6903SLoGin         irq_chip: &Arc<dyn IrqChip>,
535*338f6903SLoGin         cpu: ProcessorId,
536*338f6903SLoGin     ) {
537*338f6903SLoGin         if let Err(e) = irq_chip.irq_mask(irq_data) {
538*338f6903SLoGin             if e == SystemError::ENOSYS {
539*338f6903SLoGin                 irq_chip.irq_disable(irq_data);
540*338f6903SLoGin             }
541*338f6903SLoGin         }
542*338f6903SLoGin 
543*338f6903SLoGin         desc.inner()
544*338f6903SLoGin             .percpu_enabled_mut()
545*338f6903SLoGin             .as_mut()
546*338f6903SLoGin             .unwrap()
547*338f6903SLoGin             .set(cpu, false);
548*338f6903SLoGin     }
549*338f6903SLoGin }
550*338f6903SLoGin 
551*338f6903SLoGin lazy_static! {
552*338f6903SLoGin     pub(super) static ref CHAINED_ACTION: Arc<IrqAction> = IrqAction::new(
553*338f6903SLoGin         IrqNumber::new(0),
554*338f6903SLoGin         "".to_string(),
555*338f6903SLoGin         Some(&ChainedActionHandler),
556*338f6903SLoGin         None,
557*338f6903SLoGin     );
558*338f6903SLoGin }
559*338f6903SLoGin 
560*338f6903SLoGin #[allow(dead_code)]
561*338f6903SLoGin pub(super) fn chained_action() -> Arc<IrqAction> {
562*338f6903SLoGin     CHAINED_ACTION.clone()
563*338f6903SLoGin }
564*338f6903SLoGin 
565*338f6903SLoGin /// Chained handlers 永远不应该在它们的IRQ上调用irqaction。如果发生这种情况,
566*338f6903SLoGin /// 这个默认irqaction将发出警告。
567*338f6903SLoGin #[derive(Debug)]
568*338f6903SLoGin struct ChainedActionHandler;
569*338f6903SLoGin 
570*338f6903SLoGin impl IrqHandler for ChainedActionHandler {
571*338f6903SLoGin     fn handle(
572*338f6903SLoGin         &self,
573*338f6903SLoGin         irq: IrqNumber,
574*338f6903SLoGin         _static_data: Option<&dyn IrqHandlerData>,
575*338f6903SLoGin         _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
576*338f6903SLoGin     ) -> Result<IrqReturn, SystemError> {
577*338f6903SLoGin         static ONCE: Once = Once::new();
578*338f6903SLoGin         ONCE.call_once(|| {
579*338f6903SLoGin             kwarn!("Chained irq {} should not call an action.", irq.data());
580*338f6903SLoGin         });
581*338f6903SLoGin 
582*338f6903SLoGin         Ok(IrqReturn::NotHandled)
583*338f6903SLoGin     }
584e2841179SLoGin }
585