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