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