xref: /DragonOS/kernel/src/exception/manage.rs (revision 9a0802fd2ddda39e96342997abbfc30bf65f1f0e)
1 use core::ops::{BitXor, Deref, DerefMut};
2 
3 use alloc::{string::String, sync::Arc};
4 
5 use system_error::SystemError;
6 
7 use crate::{
8     driver::base::device::DeviceId,
9     exception::{
10         irqchip::IrqChipSetMaskResult,
11         irqdesc::{irq_desc_manager, InnerIrqDesc, IrqAction},
12     },
13     libs::{cpumask::CpuMask, spinlock::SpinLockGuard},
14     process::{kthread::KernelThreadMechanism, ProcessManager},
15     smp::cpu::ProcessorId,
16 };
17 
18 use super::{
19     dummychip::no_irq_chip,
20     irqchip::IrqChipFlags,
21     irqdata::{IrqData, IrqHandlerData, IrqLineStatus, IrqStatus},
22     irqdesc::{InnerIrqAction, IrqDesc, IrqDescState, IrqHandleFlags, IrqHandler, IrqReturn},
23     irqdomain::irq_domain_manager,
24     IrqNumber,
25 };
26 
27 lazy_static! {
28     /// 默认的中断亲和性
29     static ref IRQ_DEFAULT_AFFINITY: CpuMask = {
30         let mut mask = CpuMask::new();
31         // 默认情况下,中断处理程序将在第一个处理器上运行
32         mask.set(ProcessorId::new(0), true);
33         mask
34     };
35 }
36 
37 pub fn irq_manager() -> &'static IrqManager {
38     &IrqManager
39 }
40 
41 /// 中断管理器
42 pub struct IrqManager;
43 
44 impl IrqManager {
45     pub const IRQ_RESEND: bool = true;
46     #[allow(dead_code)]
47     pub const IRQ_NORESEND: bool = false;
48     #[allow(dead_code)]
49     pub const IRQ_START_FORCE: bool = true;
50     pub const IRQ_START_COND: bool = false;
51 
52     /// 在中断线上添加一个处理函数
53     ///
54     /// ## 参数
55     ///
56     /// - irq: 虚拟中断号(中断线号)
57     /// - name: 生成该中断的设备名称
58     /// - handler: 中断处理函数
59     /// - flags: 中断处理标志
60     /// - dev_id: 一个用于标识设备的cookie
61     pub fn request_irq(
62         &self,
63         irq: IrqNumber,
64         name: String,
65         handler: &'static dyn IrqHandler,
66         flags: IrqHandleFlags,
67         dev_id: Option<Arc<DeviceId>>,
68     ) -> Result<(), SystemError> {
69         return self.request_threaded_irq(irq, Some(handler), None, flags, name, dev_id);
70     }
71 
72     /// 在中断线上添加一个处理函数(可以是线程化的中断)
73     ///
74     /// ## 参数
75     ///
76     /// - irq: 虚拟中断号
77     /// - handler: 当中断发生时将被调用的函数,是
78     ///     线程化中断的初级处理程序。如果handler为`None`并且thread_fn不为`None`,
79     ///    将安装默认的初级处理程序
80     /// - thread_fn: 在中断处理程序线程中调用的函数. 如果为`None`,则不会创建irq线程
81     /// - flags: 中断处理标志
82     ///     - IRQF_SHARED: 中断是共享的
83     ///     - IRQF_TRIGGER*: 指定中断触发方式
84     ///     - IRQF_ONESHOT: 在thread_fn中运行时,中断线被遮蔽
85     /// - dev_name: 生成该中断的设备名称
86     /// - dev_id: 一个用于标识设备的cookie
87     ///
88     /// ## 说明
89     ///
90     /// 此调用分配中断资源并启用中断线和IRQ处理。
91     /// 从这一点开始,您的处理程序函数可能会被调用。
92     /// 因此,您必须确保首先初始化您的硬件,
93     /// 并确保以正确的顺序设置中断处理程序。
94     ///
95     /// 如果您想为您的设备设置线程化中断处理程序
96     /// 则需要提供@handler和@thread_fn。@handler仍然
97     /// 在硬中断上下文中调用,并且必须检查
98     /// 中断是否来自设备。如果是,它需要禁用设备上的中断
99     /// 并返回IRQ_WAKE_THREAD,这将唤醒处理程序线程并运行
100     /// @thread_fn。这种拆分处理程序设计是为了支持
101     /// 共享中断。
102     ///
103     /// dev_id必须是全局唯一的。通常使用设备数据结构的地址或者uuid
104     /// 作为cookie。由于处理程序接收这个值,因此使用它是有意义的。
105     ///
106     /// 如果您的中断是共享的,您必须传递一个非NULL的dev_id
107     /// 因为当释放中断时需要它。
108     pub fn request_threaded_irq(
109         &self,
110         irq: IrqNumber,
111         mut handler: Option<&'static dyn IrqHandler>,
112         thread_fn: Option<&'static dyn IrqHandler>,
113         flags: IrqHandleFlags,
114         dev_name: String,
115         dev_id: Option<Arc<DeviceId>>,
116     ) -> Result<(), SystemError> {
117         if irq == IrqNumber::IRQ_NOTCONNECTED {
118             return Err(SystemError::ENOTCONN);
119         }
120 
121         // 逻辑检查:共享中断必须传入一个真正的设备ID,
122         // 否则后来我们将难以确定哪个中断是哪个(会搞乱中断释放逻辑等)。
123         // 此外,共享中断与禁用自动使能不相符。 共享中断可能在仍然禁用时请求它,然后永远等待中断。
124         // 另外,IRQF_COND_SUSPEND 仅适用于共享中断,并且它不能与 IRQF_NO_SUSPEND 同时设置。
125 
126         if ((flags.contains(IrqHandleFlags::IRQF_SHARED)) && dev_id.is_none())
127             || ((flags.contains(IrqHandleFlags::IRQF_SHARED))
128                 && (flags.contains(IrqHandleFlags::IRQF_NO_AUTOEN)))
129             || (!(flags.contains(IrqHandleFlags::IRQF_SHARED))
130                 && (flags.contains(IrqHandleFlags::IRQF_COND_SUSPEND)))
131             || ((flags.contains(IrqHandleFlags::IRQF_NO_SUSPEND))
132                 && (flags.contains(IrqHandleFlags::IRQF_COND_SUSPEND)))
133         {
134             return Err(SystemError::EINVAL);
135         }
136         let desc = irq_desc_manager().lookup(irq).ok_or(SystemError::EINVAL)?;
137         if !desc.can_request() {
138             kwarn!("desc {} can not request", desc.irq().data());
139             return Err(SystemError::EINVAL);
140         }
141 
142         if handler.is_none() {
143             if thread_fn.is_none() {
144                 // 不允许中断处理函数和线程处理函数都为空
145                 return Err(SystemError::EINVAL);
146             }
147 
148             // 如果中断处理函数为空,线程处理函数不为空,则使用默认的中断处理函数
149             handler = Some(&DefaultPrimaryIrqHandler);
150         }
151 
152         let irqaction = IrqAction::new(irq, dev_name, handler, thread_fn);
153 
154         let mut action_guard = irqaction.inner();
155         *action_guard.flags_mut() = flags;
156         *action_guard.dev_id_mut() = dev_id;
157         drop(action_guard);
158         kdebug!("to inner_setup_irq");
159         return self.inner_setup_irq(irq, irqaction, desc);
160     }
161 
162     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c?r=&mo=59252&fi=2138#1497
163     #[inline(never)]
164     fn inner_setup_irq(
165         &self,
166         irq: IrqNumber,
167         action: Arc<IrqAction>,
168         desc: Arc<IrqDesc>,
169     ) -> Result<(), SystemError> {
170         // ==== 定义错误处理函数 ====
171         let err_out_thread =
172             |e: SystemError, mut action_guard: SpinLockGuard<'_, InnerIrqAction>| -> SystemError {
173                 if let Some(thread_pcb) = action_guard.thread() {
174                     action_guard.set_thread(None);
175                     KernelThreadMechanism::stop(&thread_pcb).ok();
176                 }
177 
178                 if let Some(secondary) = action_guard.secondary() {
179                     let mut secondary_guard = secondary.inner();
180                     if let Some(thread_pcb) = secondary_guard.thread() {
181                         secondary_guard.set_thread(None);
182                         KernelThreadMechanism::stop(&thread_pcb).ok();
183                     }
184                 }
185                 return e;
186             };
187 
188         let err_out_bus_unlock = |e: SystemError,
189                                   desc: Arc<IrqDesc>,
190                                   req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>,
191                                   action_guard: SpinLockGuard<'_, InnerIrqAction>|
192          -> SystemError {
193             desc.chip_bus_sync_unlock();
194             drop(req_mutex_guard);
195             return err_out_thread(e, action_guard);
196         };
197 
198         let err_out_unlock = |e: SystemError,
199                               desc_guard: SpinLockGuard<'_, InnerIrqDesc>,
200                               desc: Arc<IrqDesc>,
201                               req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>,
202                               action_guard: SpinLockGuard<'_, InnerIrqAction>|
203          -> SystemError {
204             drop(desc_guard);
205             return err_out_bus_unlock(e, desc, req_mutex_guard, action_guard);
206         };
207 
208         let err_out_mismatch = |old_action_guard: SpinLockGuard<'_, InnerIrqAction>,
209                                 desc_guard: SpinLockGuard<'_, InnerIrqDesc>,
210                                 action_guard: SpinLockGuard<'_, InnerIrqAction>,
211                                 desc: Arc<IrqDesc>,
212                                 req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>|
213          -> SystemError {
214             if !action_guard
215                 .flags()
216                 .contains(IrqHandleFlags::IRQF_PROBE_SHARED)
217             {
218                 kerror!("Flags mismatch for irq {} (name: {}, flags: {:?}). old action name: {}, old flags: {:?}", irq.data(), action_guard.name(), action_guard.flags(), old_action_guard.name(), old_action_guard.flags());
219             }
220             return err_out_unlock(
221                 SystemError::EBUSY,
222                 desc_guard,
223                 desc,
224                 req_mutex_guard,
225                 action_guard,
226             );
227         };
228 
229         // ===== 代码开始 =====
230 
231         if Arc::ptr_eq(
232             &desc.irq_data().chip_info_read_irqsave().chip(),
233             &no_irq_chip(),
234         ) {
235             return Err(SystemError::ENOSYS);
236         }
237 
238         let mut action_guard = action.inner();
239         if !action_guard.flags().trigger_type_specified() {
240             // 如果没有指定触发类型,则使用默认的触发类型
241             action_guard
242                 .flags_mut()
243                 .insert_trigger_type(desc.irq_data().common_data().trigger_type())
244         }
245 
246         let nested = desc.nested_thread();
247 
248         if nested {
249             if action_guard.thread_fn().is_none() {
250                 return Err(SystemError::EINVAL);
251             }
252 
253             action_guard.set_handler(Some(&IrqNestedPrimaryHandler));
254         } else if desc.can_thread() {
255             self.setup_forced_threading(action_guard.deref_mut())?;
256         }
257 
258         // 如果具有中断线程处理程序,并且中断不是嵌套的,则设置中断线程
259         if action_guard.thread_fn().is_some() && !nested {
260             self.setup_irq_thread(irq, action_guard.deref(), false)?;
261 
262             if let Some(secondary) = action_guard.secondary() {
263                 let secondary_guard = secondary.inner();
264                 if let Err(e) = self.setup_irq_thread(irq, secondary_guard.deref(), true) {
265                     return Err(err_out_thread(e, action_guard));
266                 }
267             }
268         }
269 
270         // Drivers are often written to work w/o knowledge about the
271         // underlying irq chip implementation, so a request for a
272         // threaded irq without a primary hard irq context handler
273         // requires the ONESHOT flag to be set. Some irq chips like
274         // MSI based interrupts are per se one shot safe. Check the
275         // chip flags, so we can avoid the unmask dance at the end of
276         // the threaded handler for those.
277 
278         if desc
279             .irq_data()
280             .chip_info_read_irqsave()
281             .chip()
282             .flags()
283             .contains(IrqChipFlags::IRQCHIP_ONESHOT_SAFE)
284         {
285             *action_guard.flags_mut() &= !IrqHandleFlags::IRQF_ONESHOT;
286         }
287 
288         // Protects against a concurrent __free_irq() call which might wait
289         // for synchronize_hardirq() to complete without holding the optional
290         // chip bus lock and desc->lock. Also protects against handing out
291         // a recycled oneshot thread_mask bit while it's still in use by
292         // its previous owner.
293         let req_mutex_guard = desc.request_mutex_lock();
294 
295         // Acquire bus lock as the irq_request_resources() callback below
296         // might rely on the serialization or the magic power management
297         // functions which are abusing the irq_bus_lock() callback,
298         desc.chip_bus_lock();
299 
300         // 如果当前中断线上还没有irqaction, 则先为中断线申请资源
301         if desc.actions().is_empty() {
302             if let Err(e) = self.irq_request_resources(desc.clone()) {
303                 kerror!(
304                     "Failed to request resources for {} (irq {}) on irqchip {}, error {:?}",
305                     action_guard.name(),
306                     irq.data(),
307                     desc.irq_data().chip_info_read_irqsave().chip().name(),
308                     e
309                 );
310                 return Err(err_out_bus_unlock(
311                     e,
312                     desc.clone(),
313                     req_mutex_guard,
314                     action_guard,
315                 ));
316             }
317         }
318 
319         let mut desc_inner_guard: SpinLockGuard<'_, InnerIrqDesc> = desc.inner();
320 
321         // 标记当前irq是否是共享的
322         let mut irq_shared = false;
323         if !desc_inner_guard.actions().is_empty() {
324             // 除非双方都同意并且是相同类型(级别、边沿、极性),否则不能共享中断。
325             // 因此,两个标志字段都必须设置IRQF_SHARED,并且设置触发类型的位必须匹配。
326             // 另外,所有各方都必须就ONESHOT达成一致。
327             // NMI用途的中断线不能共享。
328             if desc_inner_guard
329                 .internal_state()
330                 .contains(IrqDescState::IRQS_NMI)
331             {
332                 kerror!(
333                     "Invalid attempt to share NMI for {} (irq {}) on irqchip {}",
334                     action_guard.name(),
335                     irq.data(),
336                     desc_inner_guard
337                         .irq_data()
338                         .chip_info_read_irqsave()
339                         .chip()
340                         .name()
341                 );
342                 return Err(err_out_unlock(
343                     SystemError::EINVAL,
344                     desc_inner_guard,
345                     desc.clone(),
346                     req_mutex_guard,
347                     action_guard,
348                 ));
349             }
350 
351             let irq_data = desc_inner_guard.irq_data();
352 
353             let old_trigger_type: super::irqdata::IrqLineStatus;
354             let status = irq_data.common_data().status();
355             if status.trigger_type_was_set() {
356                 old_trigger_type = status.trigger_type();
357             } else {
358                 old_trigger_type = action_guard.flags().trigger_type();
359                 irq_data.common_data().set_trigger_type(old_trigger_type);
360             }
361 
362             let old = &desc_inner_guard.actions()[0].clone();
363             let old_guard = old.inner();
364 
365             if (!(old_guard
366                 .flags()
367                 .intersection(*action_guard.flags())
368                 .contains(IrqHandleFlags::IRQF_SHARED)))
369                 || (old_trigger_type != (action_guard.flags().trigger_type()))
370                 || ((old_guard.flags().bitxor(*action_guard.flags()))
371                     .contains(IrqHandleFlags::IRQF_ONESHOT))
372             {
373                 kdebug!(
374                     "Flags mismatch for irq {} (name: {}, flags: {:?}). old action name: {}, old flags: {:?}",
375                     irq.data(),
376                     action_guard.name(),
377                     action_guard.flags(),
378                     old_guard.name(),
379                     old_guard.flags()
380                 );
381 
382                 return Err(err_out_mismatch(
383                     old_guard,
384                     desc_inner_guard,
385                     action_guard,
386                     desc.clone(),
387                     req_mutex_guard,
388                 ));
389             }
390 
391             // all handlers must agree on per-cpuness
392             if *old_guard.flags() & IrqHandleFlags::IRQF_PERCPU
393                 != *action_guard.flags() & IrqHandleFlags::IRQF_PERCPU
394             {
395                 kdebug!(
396                     "Per-cpu mismatch for irq {} (name: {}, flags: {:?})",
397                     irq.data(),
398                     action_guard.name(),
399                     action_guard.flags()
400                 );
401                 return Err(err_out_mismatch(
402                     old_guard,
403                     desc_inner_guard,
404                     action_guard,
405                     desc.clone(),
406                     req_mutex_guard,
407                 ));
408             }
409 
410             irq_shared = true;
411         }
412 
413         if action_guard.flags().contains(IrqHandleFlags::IRQF_ONESHOT) {
414             // todo: oneshot
415         } else if action_guard.handler().is_some_and(|h| {
416             h.type_id() == (&DefaultPrimaryIrqHandler as &dyn IrqHandler).type_id()
417         }) && !desc_inner_guard
418             .irq_data()
419             .chip_info_read_irqsave()
420             .chip()
421             .flags()
422             .contains(IrqChipFlags::IRQCHIP_ONESHOT_SAFE)
423         {
424             // 请求中断时 hander = NULL,因此我们为其使用默认的主处理程序。
425             // 但它没有设置ONESHOT标志。与电平触发中断结合时,
426             // 这是致命的,因为默认的主处理程序只是唤醒线程,然后重新启用 irq 线路,
427             // 但设备仍然保持电平中断生效。周而复始....
428             // 虽然这对于边缘类型中断来说可行,但我们为了安全起见,不加条件地拒绝,
429             // 因为我们不能确定这个中断实际上具有什么类型。
430             // 由于底层芯片实现可能会覆盖它们,所以类型标志并不可靠.
431 
432             kerror!(
433                 "Requesting irq {} without a handler, and ONESHOT flags not set for irqaction: {}",
434                 irq.data(),
435                 action_guard.name()
436             );
437             return Err(err_out_unlock(
438                 SystemError::EINVAL,
439                 desc_inner_guard,
440                 desc.clone(),
441                 req_mutex_guard,
442                 action_guard,
443             ));
444         }
445 
446         // 第一次在当前irqdesc上注册中断处理函数
447         if !irq_shared {
448             // 设置中断触发方式
449             if action_guard.flags().trigger_type_specified() {
450                 let trigger_type = action_guard.flags().trigger_type();
451                 if let Err(e) =
452                     self.do_set_irq_trigger(desc.clone(), &mut desc_inner_guard, trigger_type)
453                 {
454                     kdebug!(
455                         "Failed to set trigger type for irq {} (name: {}, flags: {:?}), error {:?}",
456                         irq.data(),
457                         action_guard.name(),
458                         action_guard.flags(),
459                         e
460                     );
461                     return Err(err_out_unlock(
462                         e,
463                         desc_inner_guard,
464                         desc.clone(),
465                         req_mutex_guard,
466                         action_guard,
467                     ));
468                 }
469             }
470             kdebug!("to irq_activate");
471             // 激活中断。这种激活必须独立于IRQ_NOAUTOEN进行*desc_inner_guard.internal_state_mut() |= IrqDescState::IRQS_NOREQUEST;uest.
472             if let Err(e) = self.irq_activate(&desc, &mut desc_inner_guard) {
473                 kdebug!(
474                     "Failed to activate irq {} (name: {}, flags: {:?}), error {:?}",
475                     irq.data(),
476                     action_guard.name(),
477                     action_guard.flags(),
478                     e
479                 );
480                 return Err(err_out_unlock(
481                     e,
482                     desc_inner_guard,
483                     desc.clone(),
484                     req_mutex_guard,
485                     action_guard,
486                 ));
487             }
488 
489             *desc_inner_guard.internal_state_mut() &= !(IrqDescState::IRQS_AUTODETECT
490                 | IrqDescState::IRQS_SPURIOUS_DISABLED
491                 | IrqDescState::IRQS_ONESHOT
492                 | IrqDescState::IRQS_WAITING);
493             desc_inner_guard
494                 .common_data()
495                 .clear_status(IrqStatus::IRQD_IRQ_INPROGRESS);
496 
497             if action_guard.flags().contains(IrqHandleFlags::IRQF_PERCPU) {
498                 desc_inner_guard
499                     .common_data()
500                     .insert_status(IrqStatus::IRQD_PER_CPU);
501                 desc_inner_guard.line_status_set_per_cpu();
502 
503                 if action_guard.flags().contains(IrqHandleFlags::IRQF_NO_DEBUG) {
504                     desc_inner_guard.line_status_set_no_debug();
505                 }
506             }
507 
508             if action_guard.flags().contains(IrqHandleFlags::IRQF_ONESHOT) {
509                 *desc_inner_guard.internal_state_mut() |= IrqDescState::IRQS_ONESHOT;
510             }
511 
512             // 如果有要求的话,则忽略IRQ的均衡。
513             if action_guard
514                 .flags()
515                 .contains(IrqHandleFlags::IRQF_NOBALANCING)
516             {
517                 todo!("IRQF_NO_BALANCING");
518             }
519 
520             if !action_guard
521                 .flags()
522                 .contains(IrqHandleFlags::IRQF_NO_AUTOEN)
523                 && desc_inner_guard.can_autoenable()
524             {
525                 // 如果没有设置IRQF_NOAUTOEN,则自动使能中断
526                 self.irq_startup(
527                     &desc,
528                     &mut desc_inner_guard,
529                     Self::IRQ_RESEND,
530                     Self::IRQ_START_COND,
531                 )
532                 .ok();
533             } else {
534                 // 共享中断与禁用自动使能不太兼容。
535                 // 共享中断可能在它仍然被禁用时请求它,然后永远等待中断。
536 
537                 static mut WARNED: bool = false;
538                 if action_guard.flags().contains(IrqHandleFlags::IRQF_SHARED) && unsafe { !WARNED }
539                 {
540                     kwarn!(
541                         "Shared interrupt {} for {} requested but not auto enabled",
542                         irq.data(),
543                         action_guard.name()
544                     );
545                     unsafe { WARNED = true };
546                 }
547 
548                 desc_inner_guard.set_depth(1);
549             }
550         } else if action_guard.flags().trigger_type_specified() {
551             let new_trigger_type = action_guard.flags().trigger_type();
552             let old_trigger_type = desc_inner_guard.common_data().trigger_type();
553             if new_trigger_type != old_trigger_type {
554                 kwarn!("Irq {} uses trigger type: {old_trigger_type:?}, but requested trigger type: {new_trigger_type:?}.", irq.data());
555             }
556         }
557 
558         // 在队列末尾添加新的irqaction
559         desc_inner_guard.add_action(action.clone());
560 
561         // 检查我们是否曾经通过虚构的中断处理程序禁用过irq。重新启用它并再给它一次机会。
562         if irq_shared
563             && desc_inner_guard
564                 .internal_state()
565                 .contains(IrqDescState::IRQS_SPURIOUS_DISABLED)
566         {
567             desc_inner_guard
568                 .internal_state_mut()
569                 .remove(IrqDescState::IRQS_SPURIOUS_DISABLED);
570             self.do_enable_irq(desc.clone(), &mut desc_inner_guard).ok();
571         }
572 
573         drop(desc_inner_guard);
574         desc.chip_bus_sync_unlock();
575         drop(req_mutex_guard);
576 
577         drop(action_guard);
578         self.wake_up_and_wait_for_irq_thread_ready(&desc, Some(action.clone()));
579         self.wake_up_and_wait_for_irq_thread_ready(&desc, action.inner().secondary());
580         return Ok(());
581     }
582 
583     /// 唤醒中断线程并等待中断线程准备好
584     ///
585     /// ## 参数
586     ///
587     /// - desc: 中断描述符
588     /// - action: 要唤醒的中断处理函数
589     ///
590     /// ## 锁
591     ///
592     /// 进入当前函数时,`action`的锁需要被释放
593     fn wake_up_and_wait_for_irq_thread_ready(
594         &self,
595         desc: &Arc<IrqDesc>,
596         action: Option<Arc<IrqAction>>,
597     ) {
598         if action.is_none() {
599             return;
600         }
601 
602         let action = action.unwrap();
603 
604         let action_guard = action.inner();
605         if action_guard.thread().is_none() {
606             return;
607         }
608 
609         ProcessManager::wakeup(&action_guard.thread().unwrap()).ok();
610         drop(action_guard);
611         action
612             .thread_completion()
613             .wait_for_completion()
614             .map_err(|e| {
615                 kwarn!(
616                     "Failed to wait for irq thread ready for {} (irq {:?}), error {:?}",
617                     action.inner().name(),
618                     desc.irq_data().irq(),
619                     e
620                 );
621             })
622             .ok();
623     }
624 
625     pub(super) fn irq_activate_and_startup(
626         &self,
627         desc: &Arc<IrqDesc>,
628         desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
629         resend: bool,
630     ) -> Result<(), SystemError> {
631         kdebug!(
632             "irq_activate_and_startup: irq: {}, name: {:?}",
633             desc.irq().data(),
634             desc_inner_guard.name()
635         );
636         self.irq_activate(desc, desc_inner_guard)?;
637         self.irq_startup(desc, desc_inner_guard, resend, Self::IRQ_START_FORCE)
638     }
639 
640     pub(super) fn irq_activate(
641         &self,
642         _desc: &Arc<IrqDesc>,
643         desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
644     ) -> Result<(), SystemError> {
645         let irq_data = desc_inner_guard.irq_data();
646 
647         if !desc_inner_guard.common_data().status().affinity_managed() {
648             return irq_domain_manager().activate_irq(irq_data, false);
649         }
650 
651         return Ok(());
652     }
653 
654     /// 设置CPU亲和性并开启中断
655     pub(super) fn irq_startup(
656         &self,
657         desc: &Arc<IrqDesc>,
658         desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
659         resend: bool,
660         force: bool,
661     ) -> Result<(), SystemError> {
662         kdebug!(
663             "irq_startup: irq: {}, name: {:?}",
664             desc_inner_guard.irq_data().irq().data(),
665             desc_inner_guard.name()
666         );
667         let mut ret = Ok(());
668         let irq_data = desc_inner_guard.irq_data().clone();
669         let affinity = desc_inner_guard.common_data().affinity();
670         desc_inner_guard.set_depth(0);
671 
672         if desc_inner_guard.common_data().status().started() {
673             self.irq_enable(desc_inner_guard);
674         } else {
675             match self.__irq_startup_managed(desc_inner_guard, &affinity, force) {
676                 IrqStartupResult::Normal => {
677                     if irq_data
678                         .chip_info_read_irqsave()
679                         .chip()
680                         .flags()
681                         .contains(IrqChipFlags::IRQCHIP_AFFINITY_PRE_STARTUP)
682                     {
683                         self.irq_setup_affinity(desc, desc_inner_guard).ok();
684                     }
685 
686                     ret = self.__irq_startup(desc_inner_guard);
687 
688                     if !irq_data
689                         .chip_info_read_irqsave()
690                         .chip()
691                         .flags()
692                         .contains(IrqChipFlags::IRQCHIP_AFFINITY_PRE_STARTUP)
693                     {
694                         self.irq_setup_affinity(desc, desc_inner_guard).ok();
695                     }
696                 }
697                 IrqStartupResult::Managed => {
698                     self.irq_do_set_affinity(&irq_data, desc_inner_guard, &affinity, false)
699                         .ok();
700                     ret = self.__irq_startup(desc_inner_guard);
701                 }
702                 IrqStartupResult::Abort => {
703                     desc_inner_guard
704                         .common_data()
705                         .insert_status(IrqStatus::IRQD_MANAGED_SHUTDOWN);
706                     return Ok(());
707                 }
708             }
709         }
710 
711         if resend {
712             if let Err(e) = self.irq_check_and_resend(desc_inner_guard, false) {
713                 kerror!(
714                     "Failed to check and resend irq {}, error {:?}",
715                     irq_data.irq().data(),
716                     e
717                 );
718             }
719         }
720 
721         return ret;
722     }
723 
724     pub fn irq_enable(&self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>) {
725         let common_data = desc_inner_guard.common_data();
726         if !common_data.status().disabled() {
727             self.unmask_irq(desc_inner_guard);
728         } else {
729             common_data.clear_disabled();
730 
731             let chip = desc_inner_guard.irq_data().chip_info_read_irqsave().chip();
732 
733             if let Err(e) = chip.irq_enable(desc_inner_guard.irq_data()) {
734                 if e == SystemError::ENOSYS {
735                     self.unmask_irq(desc_inner_guard);
736                 }
737                 kerror!(
738                     "Failed to enable irq {} (name: {:?}), error {:?}",
739                     desc_inner_guard.irq_data().irq().data(),
740                     desc_inner_guard.name(),
741                     e
742                 );
743             } else {
744                 common_data.clear_masked();
745             }
746         }
747     }
748 
749     /// 自动设置中断的CPU亲和性
750     ///
751     ///
752     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c#589
753     pub fn irq_setup_affinity(
754         &self,
755         _desc: &Arc<IrqDesc>,
756         desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
757     ) -> Result<(), SystemError> {
758         let common_data = desc_inner_guard.common_data();
759         if !desc_inner_guard.can_set_affinity() {
760             return Ok(());
761         }
762 
763         let mut to_set = IRQ_DEFAULT_AFFINITY.clone();
764         if common_data.status().affinity_managed()
765             || common_data.status().contains(IrqStatus::IRQD_AFFINITY_SET)
766         {
767             // FIXME: 要判断affinity跟已上线的CPU是否有交集
768 
769             let irq_aff = common_data.affinity();
770             if irq_aff.is_empty() {
771                 common_data.clear_status(IrqStatus::IRQD_AFFINITY_SET);
772             } else {
773                 to_set = irq_aff;
774             }
775         }
776 
777         // FIXME: 求to_set和在线CPU的交集
778 
779         return self.irq_do_set_affinity(
780             desc_inner_guard.irq_data(),
781             desc_inner_guard,
782             &to_set,
783             false,
784         );
785     }
786 
787     pub fn irq_set_affinity(
788         &self,
789         irq_data: &Arc<IrqData>,
790         desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
791         cpumask: &CpuMask,
792     ) -> Result<(), SystemError> {
793         return self.irq_do_set_affinity(irq_data, desc_inner_guard, cpumask, false);
794     }
795     fn irq_do_set_affinity(
796         &self,
797         irq_data: &Arc<IrqData>,
798         desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
799         cpumask: &CpuMask,
800         force: bool,
801     ) -> Result<(), SystemError> {
802         let chip = irq_data.chip_info_read_irqsave().chip();
803         if !chip.can_set_affinity() {
804             return Err(SystemError::EINVAL);
805         }
806 
807         // todo: 处理CPU中断隔离相关的逻辑
808 
809         let common_data = desc_inner_guard.common_data();
810         let r = if force || !cpumask.is_empty() {
811             chip.irq_set_affinity(irq_data, cpumask, force)
812         } else {
813             return Err(SystemError::EINVAL);
814         };
815 
816         let mut ret = Ok(());
817         if let Ok(rs) = r {
818             match rs {
819                 IrqChipSetMaskResult::Success | IrqChipSetMaskResult::Done => {
820                     common_data.set_affinity(cpumask.clone());
821                 }
822                 IrqChipSetMaskResult::NoChange => {
823 
824                     // irq_validate_effective_affinity(data);
825                     // irq_set_thread_affinity(desc);
826                 }
827             }
828         } else {
829             ret = Err(r.unwrap_err());
830         }
831 
832         return ret;
833     }
834 
835     fn __irq_startup(
836         &self,
837         desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
838     ) -> Result<(), SystemError> {
839         let common_data = desc_inner_guard.common_data();
840 
841         if let Err(e) = desc_inner_guard
842             .irq_data()
843             .chip_info_read_irqsave()
844             .chip()
845             .irq_startup(desc_inner_guard.irq_data())
846         {
847             if e == SystemError::ENOSYS {
848                 self.irq_enable(desc_inner_guard);
849             } else {
850                 return Err(e);
851             }
852         } else {
853             common_data.clear_disabled();
854             common_data.clear_masked();
855         }
856 
857         common_data.set_started();
858 
859         return Ok(());
860     }
861 
862     fn __irq_startup_managed(
863         &self,
864         desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
865         _affinity: &CpuMask,
866         _force: bool,
867     ) -> IrqStartupResult {
868         let irq_data = desc_inner_guard.irq_data();
869         let common_data = desc_inner_guard.common_data();
870 
871         if !common_data.status().affinity_managed() {
872             return IrqStartupResult::Normal;
873         }
874 
875         common_data.clear_managed_shutdown();
876 
877         /*
878             - 检查Affinity掩码是否包括所有的在线CPU。如果是,这意味着有代码试图在管理的中断上使用enable_irq(),
879                 这可能是非法的。在这种情况下,如果force不是真值,函数会返回IRQ_STARTUP_ABORT,表示中断处理应该被放弃。
880             - 如果Affinity掩码中没有任何在线的CPU,那么中断请求是不可用的,因为没有任何CPU可以处理它。
881                 在这种情况下,如果force不是真值,函数同样会返回IRQ_STARTUP_ABORT。
882             - 如果以上条件都不满足,尝试激活中断,并将其设置为管理模式。这是通过调用 `irq_domain_manager().activate_irq()` 函数来实现的。
883                 如果这个调用失败,表示有保留的资源无法访问,函数会返回IRQ_STARTUP_ABORT。
884             - 如果一切顺利,函数会返回IRQ_STARTUP_MANAGED,表示中断已经被成功管理并激活。
885         */
886 
887         // if (cpumask_any_and(aff, cpu_online_mask) >= nr_cpu_ids) {
888         //     /*
889         //      * Catch code which fiddles with enable_irq() on a managed
890         //      * and potentially shutdown IRQ. Chained interrupt
891         //      * installment or irq auto probing should not happen on
892         //      * managed irqs either.
893         //      */
894         //     if (WARN_ON_ONCE(force))
895         //         return IRQ_STARTUP_ABORT;
896         //     /*
897         //      * The interrupt was requested, but there is no online CPU
898         //      * in it's affinity mask. Put it into managed shutdown
899         //      * state and let the cpu hotplug mechanism start it up once
900         //      * a CPU in the mask becomes available.
901         //      */
902         //     return IRQ_STARTUP_ABORT;
903         // }
904 
905         let r = irq_domain_manager().activate_irq(irq_data, false);
906         if r.is_err() {
907             return IrqStartupResult::Abort;
908         }
909 
910         return IrqStartupResult::Managed;
911     }
912 
913     pub fn do_enable_irq(
914         &self,
915         _desc: Arc<IrqDesc>,
916         _desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
917     ) -> Result<(), SystemError> {
918         // https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c?r=&mo=59252&fi=2138#776
919         todo!("do_enable_irq")
920     }
921 
922     #[inline(never)]
923     pub fn do_set_irq_trigger(
924         &self,
925         _desc: Arc<IrqDesc>,
926         desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
927         mut trigger_type: IrqLineStatus,
928     ) -> Result<(), SystemError> {
929         let chip = desc_inner_guard.irq_data().chip_info_read_irqsave().chip();
930         let mut to_unmask = false;
931 
932         if !chip.can_set_flow_type() {
933             // kdebug!(
934             //     "No set_irq_type function for irq {}, chip {}",
935             //     desc_inner_guard.irq_data().irq().data(),
936             //     chip.name()
937             // );
938             return Ok(());
939         }
940 
941         if chip.flags().contains(IrqChipFlags::IRQCHIP_SET_TYPE_MASKED) {
942             if !desc_inner_guard.common_data().status().masked() {
943                 self.mask_irq(desc_inner_guard.irq_data());
944             }
945             if !desc_inner_guard.common_data().status().disabled() {
946                 to_unmask = true;
947             }
948         }
949 
950         trigger_type &= IrqLineStatus::IRQ_TYPE_SENSE_MASK;
951 
952         let r = chip.irq_set_type(desc_inner_guard.irq_data(), trigger_type);
953         let ret;
954         if let Ok(rs) = r {
955             match rs {
956                 IrqChipSetMaskResult::Success | IrqChipSetMaskResult::Done => {
957                     let common_data = desc_inner_guard.common_data();
958                     common_data.clear_status(IrqStatus::IRQD_TRIGGER_MASK);
959                     let mut irqstatus = IrqStatus::empty();
960                     irqstatus.set_trigger_type(trigger_type);
961                     common_data.insert_status(irqstatus);
962                 }
963                 IrqChipSetMaskResult::NoChange => {
964                     let flags = desc_inner_guard.common_data().trigger_type();
965                     desc_inner_guard.set_trigger_type(flags);
966                     desc_inner_guard
967                         .common_data()
968                         .clear_status(IrqStatus::IRQD_LEVEL);
969                     desc_inner_guard.clear_level();
970 
971                     if !(flags & IrqLineStatus::IRQ_TYPE_LEVEL_MASK).is_empty() {
972                         desc_inner_guard.set_level();
973                         desc_inner_guard
974                             .common_data()
975                             .insert_status(IrqStatus::IRQD_LEVEL);
976                     }
977                 }
978             }
979 
980             ret = Ok(());
981         } else {
982             kerror!(
983                 "Failed to set irq {} trigger type to {:?} on irqchip {}, error {:?}",
984                 desc_inner_guard.irq_data().irq().data(),
985                 trigger_type,
986                 chip.name(),
987                 r
988             );
989 
990             ret = Err(r.unwrap_err());
991         }
992 
993         if to_unmask {
994             self.unmask_irq(desc_inner_guard);
995         }
996         return ret;
997     }
998 
999     fn irq_request_resources(&self, desc: Arc<IrqDesc>) -> Result<(), SystemError> {
1000         let irq_data = desc.irq_data();
1001         let irq_chip = irq_data.chip_info_read_irqsave().chip();
1002         irq_chip.irq_request_resources(&irq_data)
1003     }
1004 
1005     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c?r=&mo=59252&fi=2138#1448
1006     fn setup_irq_thread(
1007         &self,
1008         _irq: IrqNumber,
1009         _action: &InnerIrqAction,
1010         _secondary: bool,
1011     ) -> Result<(), SystemError> {
1012         // if secondary {
1013         //     KernelThreadMechanism::create(func, name)
1014         // }
1015 
1016         todo!("setup_irq_thread")
1017     }
1018 
1019     fn setup_forced_threading(&self, _action: &mut InnerIrqAction) -> Result<(), SystemError> {
1020         // todo: 处理强制线程化的逻辑,参考linux的`irq_setup_forced_threading()`
1021         return Ok(());
1022     }
1023 
1024     pub fn irq_clear_status_flags(
1025         &self,
1026         irq: IrqNumber,
1027         status: IrqLineStatus,
1028     ) -> Result<(), SystemError> {
1029         let desc = irq_desc_manager().lookup(irq).ok_or(SystemError::EINVAL)?;
1030         desc.modify_status(status, IrqLineStatus::empty());
1031         return Ok(());
1032     }
1033 
1034     /// 屏蔽中断
1035     pub(super) fn mask_irq(&self, irq_data: &Arc<IrqData>) {
1036         if irq_data.common_data().status().masked() {
1037             return;
1038         }
1039 
1040         let chip = irq_data.chip_info_read_irqsave().chip();
1041         let r = chip.irq_mask(irq_data);
1042 
1043         if r.is_ok() {
1044             irq_data.common_data().set_masked();
1045         }
1046     }
1047 
1048     /// 解除屏蔽中断
1049     pub(super) fn unmask_irq(&self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>) {
1050         if !desc_inner_guard.common_data().status().masked() {
1051             return;
1052         }
1053 
1054         let r = desc_inner_guard
1055             .irq_data()
1056             .chip_info_read_irqsave()
1057             .chip()
1058             .irq_unmask(desc_inner_guard.irq_data());
1059 
1060         if let Err(e) = r {
1061             if e != SystemError::ENOSYS {
1062                 kerror!(
1063                     "Failed to unmask irq {} on irqchip {}, error {:?}",
1064                     desc_inner_guard.irq_data().irq().data(),
1065                     desc_inner_guard
1066                         .irq_data()
1067                         .chip_info_read_irqsave()
1068                         .chip()
1069                         .name(),
1070                     e
1071                 );
1072             }
1073         } else {
1074             desc_inner_guard
1075                 .common_data()
1076                 .clear_status(IrqStatus::IRQD_IRQ_MASKED);
1077         }
1078     }
1079 
1080     /// 释放使用request_irq分配的中断
1081     ///
1082     /// ## 参数
1083     ///
1084     /// - irq: 要释放的中断线
1085     /// - dev_id: 要释放的设备身份
1086     ///
1087     /// ## 返回
1088     ///
1089     /// 返回传递给request_irq的devname参数
1090     ///
1091     /// ## 说明
1092     ///
1093     /// 移除一个中断处理程序。处理程序被移除,如果该中断线不再被任何驱动程序使用,则会被禁用。
1094     ///
1095     /// 在共享IRQ的情况下,调用者必须确保在调用此功能之前,它在所驱动的卡上禁用了中断。
1096     ///
1097     /// ## 注意
1098     ///
1099     /// 此函数不可以在中断上下文中调用。
1100     ///
1101     /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/irq/manage.c#2026
1102     pub fn free_irq(&self, _irq: IrqNumber, _dev_id: Option<Arc<DeviceId>>) {
1103         kwarn!("Unimplemented free_irq");
1104     }
1105 }
1106 
1107 enum IrqStartupResult {
1108     Normal,
1109     Managed,
1110     Abort,
1111 }
1112 /// 默认的初级中断处理函数
1113 ///
1114 /// 该处理函数仅仅返回`WakeThread`,即唤醒中断线程
1115 #[derive(Debug)]
1116 struct DefaultPrimaryIrqHandler;
1117 
1118 impl IrqHandler for DefaultPrimaryIrqHandler {
1119     fn handle(
1120         &self,
1121         _irq: IrqNumber,
1122         _static_data: Option<&dyn IrqHandlerData>,
1123         _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
1124     ) -> Result<IrqReturn, SystemError> {
1125         return Ok(IrqReturn::WakeThread);
1126     }
1127 }
1128 
1129 /// Primary handler for nested threaded interrupts.
1130 /// Should never be called.
1131 #[derive(Debug)]
1132 struct IrqNestedPrimaryHandler;
1133 
1134 impl IrqHandler for IrqNestedPrimaryHandler {
1135     fn handle(
1136         &self,
1137         irq: IrqNumber,
1138         _static_data: Option<&dyn IrqHandlerData>,
1139         _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
1140     ) -> Result<IrqReturn, SystemError> {
1141         kwarn!("Primary handler called for nested irq {}", irq.data());
1142         return Ok(IrqReturn::NotHandled);
1143     }
1144 }
1145