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