1 use core::{
2 any::Any,
3 fmt::Debug,
4 sync::atomic::{AtomicI64, Ordering},
5 };
6
7 use alloc::{
8 collections::{btree_map, BTreeMap},
9 string::{String, ToString},
10 sync::{Arc, Weak},
11 vec::Vec,
12 };
13 use system_error::SystemError;
14
15 use crate::{
16 arch::{interrupt::TrapFrame, CurrentIrqArch},
17 driver::base::{
18 device::DeviceId,
19 kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
20 kset::KSet,
21 },
22 filesystem::kernfs::KernFSInode,
23 libs::{
24 cpumask::CpuMask,
25 mutex::{Mutex, MutexGuard},
26 rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
27 spinlock::{SpinLock, SpinLockGuard},
28 },
29 mm::percpu::PerCpuVar,
30 process::ProcessControlBlock,
31 sched::completion::Completion,
32 smp::cpu::smp_cpu_manager,
33 };
34
35 use super::{
36 dummychip::no_irq_chip,
37 handle::bad_irq_handler,
38 irqchip::IrqChip,
39 irqdata::{IrqCommonData, IrqData, IrqHandlerData, IrqLineStatus, IrqStatus},
40 sysfs::{irq_sysfs_del, IrqKObjType},
41 HardwareIrqNumber, InterruptArch, IrqNumber,
42 };
43
44 /// 中断流处理程序
45 pub trait IrqFlowHandler: Debug + Send + Sync + Any {
handle(&self, irq_desc: &Arc<IrqDesc>, trap_frame: &mut TrapFrame)46 fn handle(&self, irq_desc: &Arc<IrqDesc>, trap_frame: &mut TrapFrame);
47 }
48
49 /// 中断处理程序
50 pub trait IrqHandler: Debug + Send + Sync + Any {
handle( &self, irq: IrqNumber, static_data: Option<&dyn IrqHandlerData>, dynamic_data: Option<Arc<dyn IrqHandlerData>>, ) -> Result<IrqReturn, SystemError>51 fn handle(
52 &self,
53 irq: IrqNumber,
54 static_data: Option<&dyn IrqHandlerData>,
55 dynamic_data: Option<Arc<dyn IrqHandlerData>>,
56 ) -> Result<IrqReturn, SystemError>;
57 }
58
59 /// 中断处理函数返回值
60 ///
61 /// 用于指示中断处理函数是否处理了中断
62 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
63 pub enum IrqReturn {
64 /// 中断未被处理
65 NotHandled,
66 /// 中断已被处理
67 Handled,
68 /// 中断已被处理,并且需要唤醒中断线程
69 WakeThread,
70 }
71
72 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irqdesc.h#55
73 #[derive(Debug)]
74 pub struct IrqDesc {
75 inner: SpinLock<InnerIrqDesc>,
76
77 handler: RwLock<Option<&'static dyn IrqFlowHandler>>,
78 /// 一个用于串行化 request_irq()和free_irq() 的互斥锁
79 request_mutex: Mutex<()>,
80 kobj_state: LockedKObjectState,
81 /// 当前描述符内正在运行的中断线程数
82 threads_active: AtomicI64,
83 }
84
85 impl IrqDesc {
86 #[inline(never)]
new(irq: IrqNumber, name: Option<String>, irqd_flags: IrqStatus) -> Arc<Self>87 pub fn new(irq: IrqNumber, name: Option<String>, irqd_flags: IrqStatus) -> Arc<Self> {
88 // 初始化的过程参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdesc.c#392
89 let common_data = Arc::new(IrqCommonData::new());
90 let irq_data = Arc::new(IrqData::new(
91 irq,
92 HardwareIrqNumber::new(irq.data()),
93 common_data.clone(),
94 no_irq_chip(),
95 ));
96
97 irq_data.irqd_set(IrqStatus::IRQD_IRQ_DISABLED);
98 common_data.insert_status(IrqStatus::IRQD_IRQ_MASKED);
99
100 let irq_desc = IrqDesc {
101 inner: SpinLock::new(InnerIrqDesc {
102 percpu_affinity: None,
103 percpu_enabled: None,
104 common_data,
105 irq_data,
106 desc_internal_state: IrqDescState::empty(),
107 line_status: IrqLineStatus::empty(),
108 actions: Vec::new(),
109 name,
110 parent_irq: None,
111 depth: 1,
112 wake_depth: 0,
113 kern_inode: None,
114 kset: None,
115 parent_kobj: None,
116 }),
117 request_mutex: Mutex::new(()),
118 handler: RwLock::new(None),
119 kobj_state: LockedKObjectState::new(Some(KObjectState::INITIALIZED)),
120 threads_active: AtomicI64::new(0),
121 };
122
123 irq_desc.set_handler(bad_irq_handler());
124 irq_desc.inner().irq_data.irqd_set(irqd_flags);
125
126 return Arc::new(irq_desc);
127 }
128
129 /// 返回当前活跃的中断线程数量
130 #[allow(dead_code)]
threads_active(&self) -> i64131 pub fn threads_active(&self) -> i64 {
132 self.threads_active.load(Ordering::SeqCst)
133 }
134
135 /// 增加当前活跃的中断线程数量, 返回增加前的值
inc_threads_active(&self) -> i64136 pub fn inc_threads_active(&self) -> i64 {
137 self.threads_active.fetch_add(1, Ordering::SeqCst)
138 }
139
140 /// 减少当前活跃的中断线程数量, 返回减少前的值
141 #[allow(dead_code)]
dec_threads_active(&self) -> i64142 pub fn dec_threads_active(&self) -> i64 {
143 self.threads_active.fetch_sub(1, Ordering::SeqCst)
144 }
145
set_handler(&self, handler: &'static dyn IrqFlowHandler)146 pub fn set_handler(&self, handler: &'static dyn IrqFlowHandler) {
147 self.chip_bus_lock();
148 let mut guard = self.handler.write_irqsave();
149 *guard = Some(handler);
150 self.chip_bus_sync_unlock();
151 }
152
153 /// 设置中断处理程序(不对desc->inner)
154 ///
155 ///
156 /// ## Safety
157 ///
158 /// 需要保证irq_data和chip是当前irqdesc的
set_handler_no_lock_inner( &self, handler: &'static dyn IrqFlowHandler, irq_data: &Arc<IrqData>, chip: &Arc<dyn IrqChip>, )159 pub fn set_handler_no_lock_inner(
160 &self,
161 handler: &'static dyn IrqFlowHandler,
162 irq_data: &Arc<IrqData>,
163 chip: &Arc<dyn IrqChip>,
164 ) {
165 chip.irq_bus_lock(irq_data).ok();
166 let mut guard = self.handler.write_irqsave();
167 *guard = Some(handler);
168 chip.irq_bus_sync_unlock(irq_data).ok();
169 }
170
handler(&self) -> Option<&'static dyn IrqFlowHandler>171 pub fn handler(&self) -> Option<&'static dyn IrqFlowHandler> {
172 let guard = self.handler.read_irqsave();
173 *guard
174 }
175
inner(&self) -> SpinLockGuard<InnerIrqDesc>176 pub fn inner(&self) -> SpinLockGuard<InnerIrqDesc> {
177 self.inner.lock_irqsave()
178 }
179
actions(&self) -> Vec<Arc<IrqAction>>180 pub fn actions(&self) -> Vec<Arc<IrqAction>> {
181 self.inner().actions.clone()
182 }
183
184 /// 对中断请求过程加锁
request_mutex_lock(&self) -> MutexGuard<()>185 pub fn request_mutex_lock(&self) -> MutexGuard<()> {
186 self.request_mutex.lock()
187 }
188
irq(&self) -> IrqNumber189 pub fn irq(&self) -> IrqNumber {
190 self.inner().irq_data.irq()
191 }
192
hardware_irq(&self) -> HardwareIrqNumber193 pub fn hardware_irq(&self) -> HardwareIrqNumber {
194 self.inner().irq_data.hardware_irq()
195 }
196
irq_data(&self) -> Arc<IrqData>197 pub fn irq_data(&self) -> Arc<IrqData> {
198 self.inner().irq_data.clone()
199 }
200
201 /// 标记当前irq描述符已经被添加到sysfs
mark_in_sysfs(&self)202 pub fn mark_in_sysfs(&self) {
203 self.inner()
204 .desc_internal_state
205 .insert(IrqDescState::IRQS_SYSFS);
206 }
207
mark_not_in_sysfs(&self)208 pub fn mark_not_in_sysfs(&self) {
209 self.inner()
210 .desc_internal_state
211 .remove(IrqDescState::IRQS_SYSFS);
212 }
213
214 /// 判断当前描述符是否已经添加到了sysfs
in_sysfs(&self) -> bool215 pub fn in_sysfs(&self) -> bool {
216 self.inner()
217 .desc_internal_state
218 .contains(IrqDescState::IRQS_SYSFS)
219 }
220
name(&self) -> Option<String>221 pub fn name(&self) -> Option<String> {
222 self.inner().name.clone()
223 }
224
can_request(&self) -> bool225 pub fn can_request(&self) -> bool {
226 self.inner().can_request()
227 }
228
229 #[allow(dead_code)]
set_norequest(&self)230 pub fn set_norequest(&self) {
231 self.inner().set_norequest();
232 }
233
234 #[allow(dead_code)]
clear_norequest(&self)235 pub fn clear_norequest(&self) {
236 self.inner().clear_norequest();
237 }
238
nested_thread(&self) -> bool239 pub fn nested_thread(&self) -> bool {
240 self.inner().nested_thread()
241 }
242
243 /// 中断是否可以线程化
can_thread(&self) -> bool244 pub fn can_thread(&self) -> bool {
245 !self
246 .inner()
247 .line_status
248 .contains(IrqLineStatus::IRQ_NOTHREAD)
249 }
250
chip_bus_lock(&self)251 pub fn chip_bus_lock(&self) {
252 let irq_data = self.inner().irq_data.clone();
253 irq_data
254 .chip_info_read_irqsave()
255 .chip()
256 .irq_bus_lock(&irq_data)
257 .ok();
258 }
259
260 /// 同步释放低速总线锁
261 ///
262 /// ## 锁
263 ///
264 /// 进入此函数时,必须持有低速总线锁,并且desc的inner锁和irqdata的inner锁
265 /// 必须已经释放。否则将死锁。
chip_bus_sync_unlock(&self)266 pub fn chip_bus_sync_unlock(&self) {
267 let irq_data = self.inner().irq_data.clone();
268 irq_data
269 .chip_info_write_irqsave()
270 .chip()
271 .irq_bus_sync_unlock(&irq_data)
272 .ok();
273 }
274
set_percpu_devid_flags(&self)275 pub fn set_percpu_devid_flags(&self) {
276 self.modify_status(
277 IrqLineStatus::empty(),
278 IrqLineStatus::IRQ_NOAUTOEN
279 | IrqLineStatus::IRQ_PER_CPU
280 | IrqLineStatus::IRQ_NOTHREAD
281 | IrqLineStatus::IRQ_NOPROBE
282 | IrqLineStatus::IRQ_PER_CPU_DEVID,
283 );
284 }
285
modify_status(&self, clear: IrqLineStatus, set: IrqLineStatus)286 pub fn modify_status(&self, clear: IrqLineStatus, set: IrqLineStatus) {
287 let mut desc_guard = self.inner();
288 desc_guard.line_status.remove(clear);
289 desc_guard.line_status.insert(set);
290
291 let mut trigger = desc_guard.common_data().trigger_type();
292
293 desc_guard.common_data().clear_status(
294 IrqStatus::IRQD_NO_BALANCING
295 | IrqStatus::IRQD_PER_CPU
296 | IrqStatus::IRQD_TRIGGER_MASK
297 | IrqStatus::IRQD_LEVEL
298 | IrqStatus::IRQD_MOVE_PCNTXT,
299 );
300
301 if desc_guard
302 .line_status
303 .contains(IrqLineStatus::IRQ_NO_BALANCING)
304 {
305 desc_guard
306 .common_data()
307 .insert_status(IrqStatus::IRQD_NO_BALANCING);
308 }
309
310 if desc_guard.line_status.contains(IrqLineStatus::IRQ_PER_CPU) {
311 desc_guard
312 .common_data()
313 .insert_status(IrqStatus::IRQD_PER_CPU);
314 }
315
316 if desc_guard
317 .line_status
318 .contains(IrqLineStatus::IRQ_MOVE_PCNTXT)
319 {
320 desc_guard
321 .common_data()
322 .insert_status(IrqStatus::IRQD_MOVE_PCNTXT);
323 }
324
325 if desc_guard.line_status.is_level_type() {
326 desc_guard
327 .common_data()
328 .insert_status(IrqStatus::IRQD_LEVEL);
329 }
330
331 let tmp = desc_guard.line_status.trigger_type();
332
333 if tmp != IrqLineStatus::IRQ_TYPE_NONE {
334 trigger = tmp;
335 }
336
337 desc_guard.common_data().set_trigger_type(trigger);
338 }
339 }
340
341 #[allow(dead_code)]
342 #[derive(Debug)]
343 pub struct InnerIrqDesc {
344 /// per irq and chip data passed down to chip functions
345 common_data: Arc<IrqCommonData>,
346 irq_data: Arc<IrqData>,
347 actions: Vec<Arc<IrqAction>>,
348 name: Option<String>,
349 parent_irq: Option<IrqNumber>,
350 /// nested irq disables
351 depth: u32,
352 /// nested wake enables
353 wake_depth: u32,
354 desc_internal_state: IrqDescState,
355 /// 中断线的状态
356 line_status: IrqLineStatus,
357
358 kern_inode: Option<Arc<KernFSInode>>,
359 kset: Option<Arc<KSet>>,
360 parent_kobj: Option<Weak<dyn KObject>>,
361 /// per-cpu enabled mask
362 percpu_enabled: Option<CpuMask>,
363 /// per-cpu affinity
364 percpu_affinity: Option<CpuMask>,
365 // wait_for_threads: EventWaitQueue
366 }
367
368 impl InnerIrqDesc {
name(&self) -> Option<&String>369 pub fn name(&self) -> Option<&String> {
370 self.name.as_ref()
371 }
372
373 #[allow(dead_code)]
set_name(&mut self, name: Option<String>)374 pub fn set_name(&mut self, name: Option<String>) {
375 self.name = name;
376 }
377
can_request(&self) -> bool378 pub fn can_request(&self) -> bool {
379 !self.line_status.contains(IrqLineStatus::IRQ_NOREQUEST)
380 }
381
382 #[allow(dead_code)]
set_norequest(&mut self)383 pub fn set_norequest(&mut self) {
384 self.line_status.insert(IrqLineStatus::IRQ_NOREQUEST);
385 }
386
387 #[allow(dead_code)]
clear_norequest(&mut self)388 pub fn clear_norequest(&mut self) {
389 self.line_status.remove(IrqLineStatus::IRQ_NOREQUEST);
390 }
391
392 #[allow(dead_code)]
set_noprobe(&mut self)393 pub fn set_noprobe(&mut self) {
394 self.line_status.insert(IrqLineStatus::IRQ_NOPROBE);
395 }
396
397 #[allow(dead_code)]
clear_noprobe(&mut self)398 pub fn clear_noprobe(&mut self) {
399 self.line_status.remove(IrqLineStatus::IRQ_NOPROBE);
400 }
401
set_nothread(&mut self)402 pub fn set_nothread(&mut self) {
403 self.line_status.insert(IrqLineStatus::IRQ_NOTHREAD);
404 }
405
clear_nothread(&mut self)406 pub fn clear_nothread(&mut self) {
407 self.line_status.remove(IrqLineStatus::IRQ_NOTHREAD);
408 }
409
nested_thread(&self) -> bool410 pub fn nested_thread(&self) -> bool {
411 self.line_status.contains(IrqLineStatus::IRQ_NESTED_THREAD)
412 }
413
line_status_set_per_cpu(&mut self)414 pub fn line_status_set_per_cpu(&mut self) {
415 self.line_status.insert(IrqLineStatus::IRQ_PER_CPU);
416 }
417
418 #[allow(dead_code)]
line_status_clear_per_cpu(&mut self)419 pub fn line_status_clear_per_cpu(&mut self) {
420 self.line_status.remove(IrqLineStatus::IRQ_PER_CPU);
421 }
422
423 #[allow(dead_code)]
line_status(&self) -> &IrqLineStatus424 pub fn line_status(&self) -> &IrqLineStatus {
425 &self.line_status
426 }
427
line_status_set_no_debug(&mut self)428 pub fn line_status_set_no_debug(&mut self) {
429 self.line_status.insert(IrqLineStatus::IRQ_NO_BALANCING);
430 }
431
432 #[allow(dead_code)]
line_status_clear_no_debug(&mut self)433 pub fn line_status_clear_no_debug(&mut self) {
434 self.line_status.remove(IrqLineStatus::IRQ_NO_BALANCING);
435 }
436
can_autoenable(&self) -> bool437 pub fn can_autoenable(&self) -> bool {
438 !self.line_status.contains(IrqLineStatus::IRQ_NOAUTOEN)
439 }
440
can_thread(&self) -> bool441 pub fn can_thread(&self) -> bool {
442 !self.line_status.contains(IrqLineStatus::IRQ_NOTHREAD)
443 }
444
445 /// 中断是否可以设置CPU亲和性
can_set_affinity(&self) -> bool446 pub fn can_set_affinity(&self) -> bool {
447 if self.common_data.status().can_balance() == false
448 || self
449 .irq_data()
450 .chip_info_read_irqsave()
451 .chip()
452 .can_set_affinity()
453 == false
454 {
455 return false;
456 }
457
458 return true;
459 }
460
actions(&self) -> &Vec<Arc<IrqAction>>461 pub fn actions(&self) -> &Vec<Arc<IrqAction>> {
462 &self.actions
463 }
464
add_action(&mut self, action: Arc<IrqAction>)465 pub fn add_action(&mut self, action: Arc<IrqAction>) {
466 self.actions.push(action);
467 }
468
clear_actions(&mut self)469 pub fn clear_actions(&mut self) {
470 self.actions.clear();
471 }
472
remove_action(&mut self, action: &Arc<IrqAction>)473 pub fn remove_action(&mut self, action: &Arc<IrqAction>) {
474 self.actions.retain(|a| !Arc::ptr_eq(a, action));
475 }
476
internal_state(&self) -> &IrqDescState477 pub fn internal_state(&self) -> &IrqDescState {
478 &self.desc_internal_state
479 }
480
internal_state_mut(&mut self) -> &mut IrqDescState481 pub(super) fn internal_state_mut(&mut self) -> &mut IrqDescState {
482 &mut self.desc_internal_state
483 }
484
irq_data(&self) -> &Arc<IrqData>485 pub fn irq_data(&self) -> &Arc<IrqData> {
486 &self.irq_data
487 }
488
common_data(&self) -> &Arc<IrqCommonData>489 pub fn common_data(&self) -> &Arc<IrqCommonData> {
490 &self.common_data
491 }
492
depth(&self) -> u32493 pub fn depth(&self) -> u32 {
494 self.depth
495 }
496
wake_depth(&self) -> u32497 pub fn wake_depth(&self) -> u32 {
498 self.wake_depth
499 }
500
set_depth(&mut self, depth: u32)501 pub fn set_depth(&mut self, depth: u32) {
502 self.depth = depth;
503 }
504
set_trigger_type(&mut self, trigger: IrqLineStatus)505 pub fn set_trigger_type(&mut self, trigger: IrqLineStatus) {
506 self.line_status.remove(IrqLineStatus::IRQ_TYPE_SENSE_MASK);
507 self.line_status
508 .insert(trigger & IrqLineStatus::IRQ_TYPE_SENSE_MASK);
509 }
510
clear_level(&mut self)511 pub fn clear_level(&mut self) {
512 self.line_status.remove(IrqLineStatus::IRQ_LEVEL);
513 }
514
set_level(&mut self)515 pub fn set_level(&mut self) {
516 self.line_status.insert(IrqLineStatus::IRQ_LEVEL);
517 }
518
percpu_enabled(&self) -> &Option<CpuMask>519 pub fn percpu_enabled(&self) -> &Option<CpuMask> {
520 &self.percpu_enabled
521 }
522
percpu_enabled_mut(&mut self) -> &mut Option<CpuMask>523 pub fn percpu_enabled_mut(&mut self) -> &mut Option<CpuMask> {
524 &mut self.percpu_enabled
525 }
526
percpu_affinity(&self) -> &Option<CpuMask>527 pub fn percpu_affinity(&self) -> &Option<CpuMask> {
528 &self.percpu_affinity
529 }
530
percpu_affinity_mut(&mut self) -> &mut Option<CpuMask>531 pub fn percpu_affinity_mut(&mut self) -> &mut Option<CpuMask> {
532 &mut self.percpu_affinity
533 }
534 }
535
536 impl KObject for IrqDesc {
as_any_ref(&self) -> &dyn Any537 fn as_any_ref(&self) -> &dyn Any {
538 self
539 }
540
set_inode(&self, inode: Option<Arc<KernFSInode>>)541 fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
542 self.inner().kern_inode = inode;
543 }
544
inode(&self) -> Option<Arc<KernFSInode>>545 fn inode(&self) -> Option<Arc<KernFSInode>> {
546 self.inner().kern_inode.clone()
547 }
548
parent(&self) -> Option<Weak<dyn KObject>>549 fn parent(&self) -> Option<Weak<dyn KObject>> {
550 self.inner().parent_kobj.clone()
551 }
552
set_parent(&self, parent: Option<Weak<dyn KObject>>)553 fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
554 self.inner().parent_kobj = parent;
555 }
556
kset(&self) -> Option<Arc<KSet>>557 fn kset(&self) -> Option<Arc<KSet>> {
558 self.inner().kset.clone()
559 }
560
set_kset(&self, kset: Option<Arc<KSet>>)561 fn set_kset(&self, kset: Option<Arc<KSet>>) {
562 self.inner().kset = kset;
563 }
564
kobj_type(&self) -> Option<&'static dyn KObjType>565 fn kobj_type(&self) -> Option<&'static dyn KObjType> {
566 Some(&IrqKObjType)
567 }
568
set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>)569 fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {}
570
name(&self) -> String571 fn name(&self) -> String {
572 self.inner().irq_data.irq().data().to_string()
573 }
574
set_name(&self, _name: String)575 fn set_name(&self, _name: String) {}
576
kobj_state(&self) -> RwLockReadGuard<KObjectState>577 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
578 self.kobj_state.read()
579 }
580
kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>581 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
582 self.kobj_state.write()
583 }
584
set_kobj_state(&self, state: KObjectState)585 fn set_kobj_state(&self, state: KObjectState) {
586 *self.kobj_state_mut() = state;
587 }
588 }
589
590 bitflags! {
591 /// Bit masks for desc->desc_internal_state
592 pub struct IrqDescState: u32 {
593 /// autodetection in progress
594 const IRQS_AUTODETECT = 0x00000001;
595 /// was disabled due to spurious interrupt detection
596 const IRQS_SPURIOUS_DISABLED = 0x00000002;
597 /// polling in progress
598 const IRQS_POLL_INPROGRESS = 0x00000008;
599 /// irq is not unmasked in primary handler
600 const IRQS_ONESHOT = 0x00000020;
601 /// irq is replayed
602 const IRQS_REPLAY = 0x00000040;
603 /// irq is waiting
604 const IRQS_WAITING = 0x00000080;
605 /// irq is pending and replayed later
606 const IRQS_PENDING = 0x00000200;
607 /// irq is suspended
608 const IRQS_SUSPENDED = 0x00000800;
609 /// irq line is used to deliver NMIs
610 const IRQS_NMI = 0x00002000;
611 /// descriptor has been added to sysfs
612 const IRQS_SYSFS = 0x00004000;
613 }
614 }
615
616 /// 每个中断的响应动作的描述符
617 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/interrupt.h#118
618 #[allow(dead_code)]
619 #[derive(Debug)]
620 pub struct IrqAction {
621 inner: SpinLock<InnerIrqAction>,
622 /// 用于等待线程被创建的完成量
623 thread_completion: Completion,
624 }
625
626 impl IrqAction {
627 #[allow(dead_code)]
new( irq: IrqNumber, name: String, handler: Option<&'static dyn IrqHandler>, thread_fn: Option<&'static dyn IrqHandler>, ) -> Arc<Self>628 pub fn new(
629 irq: IrqNumber,
630 name: String,
631 handler: Option<&'static dyn IrqHandler>,
632 thread_fn: Option<&'static dyn IrqHandler>,
633 ) -> Arc<Self> {
634 let action: IrqAction = IrqAction {
635 inner: SpinLock::new(InnerIrqAction {
636 dev_id: None,
637 per_cpu_dev_id: None,
638 handler,
639 thread_fn,
640 thread: None,
641 secondary: None,
642 irq,
643 flags: IrqHandleFlags::empty(),
644 name,
645 thread_flags: ThreadedHandlerFlags::empty(),
646 }),
647 thread_completion: Completion::new(),
648 };
649
650 return Arc::new(action);
651 }
652
inner(&self) -> SpinLockGuard<InnerIrqAction>653 pub fn inner(&self) -> SpinLockGuard<InnerIrqAction> {
654 self.inner.lock_irqsave()
655 }
656
thread_completion(&self) -> &Completion657 pub fn thread_completion(&self) -> &Completion {
658 &self.thread_completion
659 }
660 }
661
662 #[allow(dead_code)]
663 #[derive(Debug)]
664 pub struct InnerIrqAction {
665 /// cookie to identify the device
666 dev_id: Option<Arc<DeviceId>>,
667 /// cookie to identify the device (per cpu)
668 per_cpu_dev_id: Option<PerCpuVar<Arc<DeviceId>>>,
669 /// 中断处理程序
670 handler: Option<&'static dyn IrqHandler>,
671 /// interrupt handler function for threaded interrupts
672 thread_fn: Option<&'static dyn IrqHandler>,
673 /// thread pointer for threaded interrupts
674 thread: Option<Arc<ProcessControlBlock>>,
675 /// pointer to secondary irqaction (force threading)
676 secondary: Option<Arc<IrqAction>>,
677 /// 中断号
678 irq: IrqNumber,
679 flags: IrqHandleFlags,
680 /// 中断线程的标志
681 thread_flags: ThreadedHandlerFlags,
682 /// name of the device
683 name: String,
684 }
685
686 impl InnerIrqAction {
dev_id(&self) -> &Option<Arc<DeviceId>>687 pub fn dev_id(&self) -> &Option<Arc<DeviceId>> {
688 &self.dev_id
689 }
690
dev_id_mut(&mut self) -> &mut Option<Arc<DeviceId>>691 pub fn dev_id_mut(&mut self) -> &mut Option<Arc<DeviceId>> {
692 &mut self.dev_id
693 }
694
per_cpu_dev_id(&self) -> Option<&Arc<DeviceId>>695 pub fn per_cpu_dev_id(&self) -> Option<&Arc<DeviceId>> {
696 self.per_cpu_dev_id.as_ref().map(|v| v.get())
697 }
698
699 #[allow(dead_code)]
per_cpu_dev_id_mut(&mut self) -> Option<&mut Arc<DeviceId>>700 pub fn per_cpu_dev_id_mut(&mut self) -> Option<&mut Arc<DeviceId>> {
701 self.per_cpu_dev_id.as_mut().map(|v| v.get_mut())
702 }
703
handler(&self) -> Option<&'static dyn IrqHandler>704 pub fn handler(&self) -> Option<&'static dyn IrqHandler> {
705 self.handler
706 }
707
set_handler(&mut self, handler: Option<&'static dyn IrqHandler>)708 pub fn set_handler(&mut self, handler: Option<&'static dyn IrqHandler>) {
709 self.handler = handler;
710 }
711
thread_fn(&self) -> Option<&'static dyn IrqHandler>712 pub fn thread_fn(&self) -> Option<&'static dyn IrqHandler> {
713 self.thread_fn
714 }
715
thread(&self) -> Option<Arc<ProcessControlBlock>>716 pub fn thread(&self) -> Option<Arc<ProcessControlBlock>> {
717 self.thread.clone()
718 }
719
set_thread(&mut self, thread: Option<Arc<ProcessControlBlock>>)720 pub fn set_thread(&mut self, thread: Option<Arc<ProcessControlBlock>>) {
721 self.thread = thread;
722 }
723
724 #[allow(dead_code)]
thread_flags(&self) -> &ThreadedHandlerFlags725 pub fn thread_flags(&self) -> &ThreadedHandlerFlags {
726 &self.thread_flags
727 }
728
thread_flags_mut(&mut self) -> &mut ThreadedHandlerFlags729 pub fn thread_flags_mut(&mut self) -> &mut ThreadedHandlerFlags {
730 &mut self.thread_flags
731 }
732
secondary(&self) -> Option<Arc<IrqAction>>733 pub fn secondary(&self) -> Option<Arc<IrqAction>> {
734 self.secondary.clone()
735 }
736
737 #[allow(dead_code)]
irq(&self) -> IrqNumber738 pub fn irq(&self) -> IrqNumber {
739 self.irq
740 }
741
742 #[allow(dead_code)]
set_irq(&mut self, irq: IrqNumber)743 pub fn set_irq(&mut self, irq: IrqNumber) {
744 self.irq = irq;
745 }
746
flags(&self) -> &IrqHandleFlags747 pub fn flags(&self) -> &IrqHandleFlags {
748 &self.flags
749 }
750
flags_mut(&mut self) -> &mut IrqHandleFlags751 pub fn flags_mut(&mut self) -> &mut IrqHandleFlags {
752 &mut self.flags
753 }
754
name(&self) -> &String755 pub fn name(&self) -> &String {
756 &self.name
757 }
758 }
759
760 bitflags! {
761 /// 这些标志由线程处理程序使用
762 pub struct ThreadedHandlerFlags: u32 {
763 /// IRQTF_RUNTHREAD - 表示应运行中断处理程序线程
764 const IRQTF_RUNTHREAD = 1 << 0;
765 /// IRQTF_WARNED - 已打印警告 "IRQ_WAKE_THREAD w/o thread_fn"
766 const IRQTF_WARNED = 1 << 1;
767 /// IRQTF_AFFINITY - 请求irq线程调整亲和性
768 const IRQTF_AFFINITY = 1 << 2;
769 /// IRQTF_FORCED_THREAD - irq操作被强制线程化
770 const IRQTF_FORCED_THREAD = 1 << 3;
771 /// IRQTF_READY - 表示irq线程已准备就绪
772 const IRQTF_READY = 1 << 4;
773 }
774 }
775
776 /// Implements the `ThreadedHandlerFlags` structure.
777 impl ThreadedHandlerFlags {
778 /// 在 `ThreadedHandlerFlags` 结构中测试并设置特定的位。
779 ///
780 /// # 参数
781 ///
782 /// * `bit` - 要测试并设置的位。
783 ///
784 /// # 返回
785 ///
786 /// 如果操作前该位已被设置,则返回 `true`,否则返回 `false`。
test_and_set_bit(&mut self, bit: ThreadedHandlerFlags) -> bool787 pub fn test_and_set_bit(&mut self, bit: ThreadedHandlerFlags) -> bool {
788 let res = (self.bits & bit.bits) != 0;
789 self.bits |= bit.bits;
790 return res;
791 }
792 }
793
794 // 定义IrqFlags位标志
795 bitflags! {
796 /// 这些标志仅由内核在中断处理例程中使用。
797 pub struct IrqHandleFlags: u32 {
798
799 const IRQF_TRIGGER_NONE = IrqLineStatus::IRQ_TYPE_NONE.bits();
800 const IRQF_TRIGGER_RISING = IrqLineStatus::IRQ_TYPE_EDGE_RISING.bits();
801 const IRQF_TRIGGER_FALLING = IrqLineStatus::IRQ_TYPE_EDGE_FALLING.bits();
802 const IRQF_TRIGGER_HIGH = IrqLineStatus::IRQ_TYPE_LEVEL_HIGH.bits();
803 const IRQF_TRIGGER_LOW = IrqLineStatus::IRQ_TYPE_LEVEL_LOW.bits();
804 const IRQF_TRIGGER_MASK = Self::IRQF_TRIGGER_HIGH.bits | Self::IRQF_TRIGGER_LOW.bits | Self::IRQF_TRIGGER_RISING.bits | Self::IRQF_TRIGGER_FALLING.bits;
805 /// IRQF_SHARED - 允许多个设备共享中断
806 const IRQF_SHARED = 0x00000080;
807 /// IRQF_PROBE_SHARED - 当预期出现共享不匹配时,由调用者设置
808 const IRQF_PROBE_SHARED = 0x00000100;
809 /// IRQF_TIMER - 标记此中断为定时器中断
810 const __IRQF_TIMER = 0x00000200;
811 /// IRQF_PERCPU - 中断是每个CPU的
812 const IRQF_PERCPU = 0x00000400;
813 /// IRQF_NOBALANCING - 将此中断从中断平衡中排除
814 const IRQF_NOBALANCING = 0x00000800;
815 /// IRQF_IRQPOLL - 中断用于轮询(出于性能原因,只有在共享中断中首次注册的中断会被考虑)
816 const IRQF_IRQPOLL = 0x00001000;
817 /// IRQF_ONESHOT - 在硬中断处理程序完成后,不会重新启用中断。由需要在运行线程处理程序之前保持中断线路禁用的线程中断使用。
818 const IRQF_ONESHOT = 0x00002000;
819 /// IRQF_NO_SUSPEND - 在挂起期间不禁用此IRQ。不能保证此中断会从挂起状态唤醒系统。
820 const IRQF_NO_SUSPEND = 0x00004000;
821 /// IRQF_FORCE_RESUME - 即使设置了IRQF_NO_SUSPEND,也强制在恢复时启用它
822 const IRQF_FORCE_RESUME = 0x00008000;
823 /// IRQF_NO_THREAD - 中断不能被线程化
824 const IRQF_NO_THREAD = 0x00010000;
825 /// IRQF_EARLY_RESUME - 在syscore而不是在设备恢复时间早期恢复IRQ。
826 const IRQF_EARLY_RESUME = 0x00020000;
827 /// IRQF_COND_SUSPEND - 如果IRQ与NO_SUSPEND用户共享,则在挂起中断后执行此中断处理程序。对于系统唤醒设备用户,需要在他们的中断处理程序中实现唤醒检测。
828 const IRQF_COND_SUSPEND = 0x00040000;
829 /// IRQF_NO_AUTOEN - 当用户请求时,不会自动启用IRQ或NMI。用户稍后会通过enable_irq()或enable_nmi()显式启用它。
830 const IRQF_NO_AUTOEN = 0x00080000;
831 /// IRQF_NO_DEBUG - 从IPI和类似处理程序的逃逸检测中排除,取决于IRQF_PERCPU。
832 const IRQF_NO_DEBUG = 0x00100000;
833 const IRQF_TIMER = Self::__IRQF_TIMER.bits | Self::IRQF_NO_SUSPEND.bits | Self::IRQF_NO_THREAD.bits;
834 }
835 }
836
837 impl IrqHandleFlags {
838 /// 检查是否指定了触发类型
839 #[inline(always)]
trigger_type_specified(&self) -> bool840 pub fn trigger_type_specified(&self) -> bool {
841 (self.bits & Self::IRQF_TRIGGER_MASK.bits) != 0
842 }
843
844 /// 插入触发类型
insert_trigger_type(&mut self, trigger: IrqLineStatus)845 pub fn insert_trigger_type(&mut self, trigger: IrqLineStatus) {
846 self.bits |= trigger.trigger_bits() & IrqHandleFlags::IRQF_TRIGGER_MASK.bits;
847 }
848
849 #[allow(dead_code)]
remove_trigger_type(&mut self, trigger: IrqLineStatus)850 pub fn remove_trigger_type(&mut self, trigger: IrqLineStatus) {
851 self.bits &= !(trigger.trigger_bits() & IrqHandleFlags::IRQF_TRIGGER_MASK.bits);
852 }
853
trigger_type(&self) -> IrqLineStatus854 pub fn trigger_type(&self) -> IrqLineStatus {
855 IrqLineStatus::from_bits_truncate(self.bits & IrqHandleFlags::IRQF_TRIGGER_MASK.bits)
856 }
857 }
858
859 #[inline(never)]
early_irq_init() -> Result<(), SystemError>860 pub(super) fn early_irq_init() -> Result<(), SystemError> {
861 let irqcnt = CurrentIrqArch::probe_total_irq_num();
862 let mut manager = IrqDescManager::new();
863 for i in 0..irqcnt {
864 let irq_desc = IrqDesc::new(IrqNumber::new(i), None, IrqStatus::empty());
865 manager.insert(IrqNumber::new(i), irq_desc);
866 }
867
868 unsafe {
869 IRQ_DESC_MANAGER = Some(manager);
870 }
871
872 return CurrentIrqArch::arch_early_irq_init();
873 }
874
875 static mut IRQ_DESC_MANAGER: Option<IrqDescManager> = None;
876
877 /// 获取中断描述符管理器的引用
878 #[inline(always)]
irq_desc_manager() -> &'static IrqDescManager879 pub fn irq_desc_manager() -> &'static IrqDescManager {
880 return unsafe { IRQ_DESC_MANAGER.as_ref().unwrap() };
881 }
882
883 pub struct IrqDescManager {
884 irq_descs: BTreeMap<IrqNumber, Arc<IrqDesc>>,
885 }
886
887 impl IrqDescManager {
new() -> Self888 fn new() -> Self {
889 IrqDescManager {
890 irq_descs: BTreeMap::new(),
891 }
892 }
893
894 /// 查找中断描述符
lookup(&self, irq: IrqNumber) -> Option<Arc<IrqDesc>>895 pub fn lookup(&self, irq: IrqNumber) -> Option<Arc<IrqDesc>> {
896 self.irq_descs.get(&irq).map(|desc| desc.clone())
897 }
898
899 /// 查找中断描述符并锁定总线(没有对irqdesc进行加锁)
900 #[allow(dead_code)]
lookup_and_lock_bus( &self, irq: IrqNumber, check_global: bool, check_percpu: bool, ) -> Option<Arc<IrqDesc>>901 pub fn lookup_and_lock_bus(
902 &self,
903 irq: IrqNumber,
904 check_global: bool,
905 check_percpu: bool,
906 ) -> Option<Arc<IrqDesc>> {
907 self.do_lookup_and_lock(irq, true, check_global, check_percpu)
908 }
909
do_lookup_and_lock( &self, irq: IrqNumber, lock_bus: bool, check_global: bool, check_percpu: bool, ) -> Option<Arc<IrqDesc>>910 fn do_lookup_and_lock(
911 &self,
912 irq: IrqNumber,
913 lock_bus: bool,
914 check_global: bool,
915 check_percpu: bool,
916 ) -> Option<Arc<IrqDesc>> {
917 let desc = self.lookup(irq)?;
918 if check_global || check_percpu {
919 if check_percpu && !desc.inner().line_status().is_per_cpu_devid() {
920 return None;
921 }
922
923 if check_global && desc.inner().line_status().is_per_cpu_devid() {
924 return None;
925 }
926 }
927
928 if lock_bus {
929 desc.chip_bus_lock();
930 }
931
932 return Some(desc);
933 }
934
insert(&mut self, irq: IrqNumber, desc: Arc<IrqDesc>)935 fn insert(&mut self, irq: IrqNumber, desc: Arc<IrqDesc>) {
936 self.irq_descs.insert(irq, desc);
937 }
938
939 /// 释放中断描述符
940 #[allow(dead_code)]
free_desc(&mut self, irq: IrqNumber)941 fn free_desc(&mut self, irq: IrqNumber) {
942 if let Some(desc) = self.irq_descs.get(&irq) {
943 irq_sysfs_del(desc);
944 self.irq_descs.remove(&irq);
945 }
946 }
947
948 /// 迭代中断描述符
iter_descs(&self) -> btree_map::Iter<'_, IrqNumber, Arc<IrqDesc>>949 pub fn iter_descs(&self) -> btree_map::Iter<'_, IrqNumber, Arc<IrqDesc>> {
950 self.irq_descs.iter()
951 }
952
953 /// 设置指定irq的可用cpu为所有cpu
set_percpu_devid_all(&self, irq: IrqNumber) -> Result<(), SystemError>954 pub fn set_percpu_devid_all(&self, irq: IrqNumber) -> Result<(), SystemError> {
955 self.set_percpu_devid(irq, None)
956 }
957
958 /// 设置指定irq的可用cpu
959 ///
960 /// 如果affinity为None,则表示设置为所有cpu
set_percpu_devid( &self, irq: IrqNumber, affinity: Option<&CpuMask>, ) -> Result<(), SystemError>961 pub fn set_percpu_devid(
962 &self,
963 irq: IrqNumber,
964 affinity: Option<&CpuMask>,
965 ) -> Result<(), SystemError> {
966 let desc = self.lookup(irq).ok_or(SystemError::EINVAL)?;
967 let mut desc_inner = desc.inner();
968
969 if desc_inner.percpu_enabled().is_some() {
970 return Err(SystemError::EINVAL);
971 }
972
973 *desc_inner.percpu_enabled_mut() = Some(CpuMask::new());
974
975 if let Some(affinity) = affinity {
976 desc_inner.percpu_affinity_mut().replace(affinity.clone());
977 } else {
978 desc_inner
979 .percpu_affinity_mut()
980 .replace(smp_cpu_manager().possible_cpus().clone());
981 }
982
983 drop(desc_inner);
984
985 desc.set_percpu_devid_flags();
986
987 return Ok(());
988 }
989 }
990