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