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