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