1e2841179SLoGin use core::ops::{BitXor, Deref, DerefMut}; 2e2841179SLoGin 3e2841179SLoGin use alloc::{string::String, sync::Arc}; 4e2841179SLoGin 5e2841179SLoGin use system_error::SystemError; 6e2841179SLoGin 7e2841179SLoGin use crate::{ 8e2841179SLoGin driver::base::device::DeviceId, 9e2841179SLoGin exception::{ 10e2841179SLoGin irqchip::IrqChipSetMaskResult, 11e2841179SLoGin irqdesc::{irq_desc_manager, InnerIrqDesc, IrqAction}, 12e2841179SLoGin }, 13e2841179SLoGin libs::{cpumask::CpuMask, spinlock::SpinLockGuard}, 14e2841179SLoGin process::{kthread::KernelThreadMechanism, ProcessManager}, 15e2841179SLoGin smp::cpu::ProcessorId, 16e2841179SLoGin }; 17e2841179SLoGin 18e2841179SLoGin use super::{ 19e2841179SLoGin dummychip::no_irq_chip, 20e2841179SLoGin irqchip::IrqChipFlags, 21e2841179SLoGin irqdata::{IrqData, IrqHandlerData, IrqLineStatus, IrqStatus}, 22e2841179SLoGin irqdesc::{InnerIrqAction, IrqDesc, IrqDescState, IrqHandleFlags, IrqHandler, IrqReturn}, 23e2841179SLoGin irqdomain::irq_domain_manager, 24e2841179SLoGin IrqNumber, 25e2841179SLoGin }; 26e2841179SLoGin 27e2841179SLoGin lazy_static! { 28e2841179SLoGin /// 默认的中断亲和性 29e2841179SLoGin static ref IRQ_DEFAULT_AFFINITY: CpuMask = { 30e2841179SLoGin let mut mask = CpuMask::new(); 31e2841179SLoGin // 默认情况下,中断处理程序将在第一个处理器上运行 32e2841179SLoGin mask.set(ProcessorId::new(0), true); 33e2841179SLoGin mask 34e2841179SLoGin }; 35e2841179SLoGin } 36e2841179SLoGin 37e2841179SLoGin pub fn irq_manager() -> &'static IrqManager { 38e2841179SLoGin &IrqManager 39e2841179SLoGin } 40e2841179SLoGin 41e2841179SLoGin /// 中断管理器 42e2841179SLoGin pub struct IrqManager; 43e2841179SLoGin 44e2841179SLoGin impl IrqManager { 45e2841179SLoGin pub const IRQ_RESEND: bool = true; 46e2841179SLoGin #[allow(dead_code)] 47e2841179SLoGin pub const IRQ_NORESEND: bool = false; 48e2841179SLoGin #[allow(dead_code)] 49e2841179SLoGin pub const IRQ_START_FORCE: bool = true; 50e2841179SLoGin pub const IRQ_START_COND: bool = false; 51e2841179SLoGin 52e2841179SLoGin /// 在中断线上添加一个处理函数 53e2841179SLoGin /// 54e2841179SLoGin /// ## 参数 55e2841179SLoGin /// 56e2841179SLoGin /// - irq: 虚拟中断号(中断线号) 57e2841179SLoGin /// - name: 生成该中断的设备名称 58e2841179SLoGin /// - handler: 中断处理函数 59e2841179SLoGin /// - flags: 中断处理标志 60e2841179SLoGin /// - dev_id: 一个用于标识设备的cookie 61e2841179SLoGin pub fn request_irq( 62e2841179SLoGin &self, 63e2841179SLoGin irq: IrqNumber, 64e2841179SLoGin name: String, 65e2841179SLoGin handler: &'static dyn IrqHandler, 66e2841179SLoGin flags: IrqHandleFlags, 67e2841179SLoGin dev_id: Option<Arc<DeviceId>>, 68e2841179SLoGin ) -> Result<(), SystemError> { 69e2841179SLoGin return self.request_threaded_irq(irq, Some(handler), None, flags, name, dev_id); 70e2841179SLoGin } 71e2841179SLoGin 72e2841179SLoGin /// 在中断线上添加一个处理函数(可以是线程化的中断) 73e2841179SLoGin /// 74e2841179SLoGin /// ## 参数 75e2841179SLoGin /// 76e2841179SLoGin /// - irq: 虚拟中断号 77e2841179SLoGin /// - handler: 当中断发生时将被调用的函数,是 78e2841179SLoGin /// 线程化中断的初级处理程序。如果handler为`None`并且thread_fn不为`None`, 79e2841179SLoGin /// 将安装默认的初级处理程序 80e2841179SLoGin /// - thread_fn: 在中断处理程序线程中调用的函数. 如果为`None`,则不会创建irq线程 81e2841179SLoGin /// - flags: 中断处理标志 82e2841179SLoGin /// - IRQF_SHARED: 中断是共享的 83e2841179SLoGin /// - IRQF_TRIGGER*: 指定中断触发方式 84e2841179SLoGin /// - IRQF_ONESHOT: 在thread_fn中运行时,中断线被遮蔽 85e2841179SLoGin /// - dev_name: 生成该中断的设备名称 86e2841179SLoGin /// - dev_id: 一个用于标识设备的cookie 87e2841179SLoGin /// 88e2841179SLoGin /// ## 说明 89e2841179SLoGin /// 90e2841179SLoGin /// 此调用分配中断资源并启用中断线和IRQ处理。 91e2841179SLoGin /// 从这一点开始,您的处理程序函数可能会被调用。 92e2841179SLoGin /// 因此,您必须确保首先初始化您的硬件, 93e2841179SLoGin /// 并确保以正确的顺序设置中断处理程序。 94e2841179SLoGin /// 95e2841179SLoGin /// 如果您想为您的设备设置线程化中断处理程序 96e2841179SLoGin /// 则需要提供@handler和@thread_fn。@handler仍然 97e2841179SLoGin /// 在硬中断上下文中调用,并且必须检查 98e2841179SLoGin /// 中断是否来自设备。如果是,它需要禁用设备上的中断 99e2841179SLoGin /// 并返回IRQ_WAKE_THREAD,这将唤醒处理程序线程并运行 100e2841179SLoGin /// @thread_fn。这种拆分处理程序设计是为了支持 101e2841179SLoGin /// 共享中断。 102e2841179SLoGin /// 103e2841179SLoGin /// dev_id必须是全局唯一的。通常使用设备数据结构的地址或者uuid 104e2841179SLoGin /// 作为cookie。由于处理程序接收这个值,因此使用它是有意义的。 105e2841179SLoGin /// 106e2841179SLoGin /// 如果您的中断是共享的,您必须传递一个非NULL的dev_id 107e2841179SLoGin /// 因为当释放中断时需要它。 108e2841179SLoGin pub fn request_threaded_irq( 109e2841179SLoGin &self, 110e2841179SLoGin irq: IrqNumber, 111e2841179SLoGin mut handler: Option<&'static dyn IrqHandler>, 112e2841179SLoGin thread_fn: Option<&'static dyn IrqHandler>, 113e2841179SLoGin flags: IrqHandleFlags, 114e2841179SLoGin dev_name: String, 115e2841179SLoGin dev_id: Option<Arc<DeviceId>>, 116e2841179SLoGin ) -> Result<(), SystemError> { 117e2841179SLoGin if irq == IrqNumber::IRQ_NOTCONNECTED { 118e2841179SLoGin return Err(SystemError::ENOTCONN); 119e2841179SLoGin } 120e2841179SLoGin 121e2841179SLoGin // 逻辑检查:共享中断必须传入一个真正的设备ID, 122e2841179SLoGin // 否则后来我们将难以确定哪个中断是哪个(会搞乱中断释放逻辑等)。 123e2841179SLoGin // 此外,共享中断与禁用自动使能不相符。 共享中断可能在仍然禁用时请求它,然后永远等待中断。 124e2841179SLoGin // 另外,IRQF_COND_SUSPEND 仅适用于共享中断,并且它不能与 IRQF_NO_SUSPEND 同时设置。 125e2841179SLoGin 126e2841179SLoGin if ((flags.contains(IrqHandleFlags::IRQF_SHARED)) && dev_id.is_none()) 127e2841179SLoGin || ((flags.contains(IrqHandleFlags::IRQF_SHARED)) 128e2841179SLoGin && (flags.contains(IrqHandleFlags::IRQF_NO_AUTOEN))) 129e2841179SLoGin || (!(flags.contains(IrqHandleFlags::IRQF_SHARED)) 130e2841179SLoGin && (flags.contains(IrqHandleFlags::IRQF_COND_SUSPEND))) 131e2841179SLoGin || ((flags.contains(IrqHandleFlags::IRQF_NO_SUSPEND)) 132e2841179SLoGin && (flags.contains(IrqHandleFlags::IRQF_COND_SUSPEND))) 133e2841179SLoGin { 134e2841179SLoGin return Err(SystemError::EINVAL); 135e2841179SLoGin } 136e2841179SLoGin let desc = irq_desc_manager().lookup(irq).ok_or(SystemError::EINVAL)?; 137e2841179SLoGin if !desc.can_request() { 138e2841179SLoGin kwarn!("desc {} can not request", desc.irq().data()); 139e2841179SLoGin return Err(SystemError::EINVAL); 140e2841179SLoGin } 141e2841179SLoGin 142e2841179SLoGin if handler.is_none() { 143e2841179SLoGin if thread_fn.is_none() { 144e2841179SLoGin // 不允许中断处理函数和线程处理函数都为空 145e2841179SLoGin return Err(SystemError::EINVAL); 146e2841179SLoGin } 147e2841179SLoGin 148e2841179SLoGin // 如果中断处理函数为空,线程处理函数不为空,则使用默认的中断处理函数 149e2841179SLoGin handler = Some(&DefaultPrimaryIrqHandler); 150e2841179SLoGin } 151e2841179SLoGin 152e2841179SLoGin let irqaction = IrqAction::new(irq, dev_name, handler, thread_fn); 153e2841179SLoGin 154e2841179SLoGin let mut action_guard = irqaction.inner(); 155e2841179SLoGin *action_guard.flags_mut() = flags; 156e2841179SLoGin *action_guard.dev_id_mut() = dev_id; 157e2841179SLoGin drop(action_guard); 158*0102d69fSLoGin kdebug!("to inner_setup_irq"); 159e2841179SLoGin return self.inner_setup_irq(irq, irqaction, desc); 160e2841179SLoGin } 161e2841179SLoGin 162e2841179SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c?r=&mo=59252&fi=2138#1497 163e2841179SLoGin #[inline(never)] 164e2841179SLoGin fn inner_setup_irq( 165e2841179SLoGin &self, 166e2841179SLoGin irq: IrqNumber, 167e2841179SLoGin action: Arc<IrqAction>, 168e2841179SLoGin desc: Arc<IrqDesc>, 169e2841179SLoGin ) -> Result<(), SystemError> { 170e2841179SLoGin // ==== 定义错误处理函数 ==== 171e2841179SLoGin let err_out_thread = 172e2841179SLoGin |e: SystemError, mut action_guard: SpinLockGuard<'_, InnerIrqAction>| -> SystemError { 173e2841179SLoGin if let Some(thread_pcb) = action_guard.thread() { 174e2841179SLoGin action_guard.set_thread(None); 175e2841179SLoGin KernelThreadMechanism::stop(&thread_pcb).ok(); 176e2841179SLoGin } 177e2841179SLoGin 178e2841179SLoGin if let Some(secondary) = action_guard.secondary() { 179e2841179SLoGin let mut secondary_guard = secondary.inner(); 180e2841179SLoGin if let Some(thread_pcb) = secondary_guard.thread() { 181e2841179SLoGin secondary_guard.set_thread(None); 182e2841179SLoGin KernelThreadMechanism::stop(&thread_pcb).ok(); 183e2841179SLoGin } 184e2841179SLoGin } 185e2841179SLoGin return e; 186e2841179SLoGin }; 187e2841179SLoGin 188e2841179SLoGin let err_out_bus_unlock = |e: SystemError, 189e2841179SLoGin desc: Arc<IrqDesc>, 190e2841179SLoGin req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>, 191e2841179SLoGin action_guard: SpinLockGuard<'_, InnerIrqAction>| 192e2841179SLoGin -> SystemError { 193e2841179SLoGin desc.chip_bus_sync_unlock(); 194e2841179SLoGin drop(req_mutex_guard); 195e2841179SLoGin return err_out_thread(e, action_guard); 196e2841179SLoGin }; 197e2841179SLoGin 198e2841179SLoGin let err_out_unlock = |e: SystemError, 199e2841179SLoGin desc_guard: SpinLockGuard<'_, InnerIrqDesc>, 200e2841179SLoGin desc: Arc<IrqDesc>, 201e2841179SLoGin req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>, 202e2841179SLoGin action_guard: SpinLockGuard<'_, InnerIrqAction>| 203e2841179SLoGin -> SystemError { 204e2841179SLoGin drop(desc_guard); 205e2841179SLoGin return err_out_bus_unlock(e, desc, req_mutex_guard, action_guard); 206e2841179SLoGin }; 207e2841179SLoGin 208e2841179SLoGin let err_out_mismatch = |old_action_guard: SpinLockGuard<'_, InnerIrqAction>, 209e2841179SLoGin desc_guard: SpinLockGuard<'_, InnerIrqDesc>, 210e2841179SLoGin action_guard: SpinLockGuard<'_, InnerIrqAction>, 211e2841179SLoGin desc: Arc<IrqDesc>, 212e2841179SLoGin req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>| 213e2841179SLoGin -> SystemError { 214e2841179SLoGin if !action_guard 215e2841179SLoGin .flags() 216e2841179SLoGin .contains(IrqHandleFlags::IRQF_PROBE_SHARED) 217e2841179SLoGin { 218e2841179SLoGin 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()); 219e2841179SLoGin } 220e2841179SLoGin return err_out_unlock( 221e2841179SLoGin SystemError::EBUSY, 222e2841179SLoGin desc_guard, 223e2841179SLoGin desc, 224e2841179SLoGin req_mutex_guard, 225e2841179SLoGin action_guard, 226e2841179SLoGin ); 227e2841179SLoGin }; 228e2841179SLoGin 229e2841179SLoGin // ===== 代码开始 ===== 230e2841179SLoGin 231e2841179SLoGin if Arc::ptr_eq( 232e2841179SLoGin &desc.irq_data().chip_info_read_irqsave().chip(), 233e2841179SLoGin &no_irq_chip(), 234e2841179SLoGin ) { 235e2841179SLoGin return Err(SystemError::ENOSYS); 236e2841179SLoGin } 237e2841179SLoGin 238e2841179SLoGin let mut action_guard = action.inner(); 239e2841179SLoGin if !action_guard.flags().trigger_type_specified() { 240e2841179SLoGin // 如果没有指定触发类型,则使用默认的触发类型 241e2841179SLoGin action_guard 242e2841179SLoGin .flags_mut() 243e2841179SLoGin .insert_trigger_type(desc.irq_data().common_data().trigger_type()) 244e2841179SLoGin } 245e2841179SLoGin 246e2841179SLoGin let nested = desc.nested_thread(); 247e2841179SLoGin 248e2841179SLoGin if nested { 249e2841179SLoGin if action_guard.thread_fn().is_none() { 250e2841179SLoGin return Err(SystemError::EINVAL); 251e2841179SLoGin } 252e2841179SLoGin 253e2841179SLoGin action_guard.set_handler(Some(&IrqNestedPrimaryHandler)); 254b5b571e0SLoGin } else if desc.can_thread() { 255e2841179SLoGin self.setup_forced_threading(action_guard.deref_mut())?; 256e2841179SLoGin } 257e2841179SLoGin 258e2841179SLoGin // 如果具有中断线程处理程序,并且中断不是嵌套的,则设置中断线程 259e2841179SLoGin if action_guard.thread_fn().is_some() && !nested { 260e2841179SLoGin self.setup_irq_thread(irq, action_guard.deref(), false)?; 261e2841179SLoGin 262e2841179SLoGin if let Some(secondary) = action_guard.secondary() { 263e2841179SLoGin let secondary_guard = secondary.inner(); 264e2841179SLoGin if let Err(e) = self.setup_irq_thread(irq, secondary_guard.deref(), true) { 265e2841179SLoGin return Err(err_out_thread(e, action_guard)); 266e2841179SLoGin } 267e2841179SLoGin } 268e2841179SLoGin } 269e2841179SLoGin 270e2841179SLoGin // Drivers are often written to work w/o knowledge about the 271e2841179SLoGin // underlying irq chip implementation, so a request for a 272e2841179SLoGin // threaded irq without a primary hard irq context handler 273e2841179SLoGin // requires the ONESHOT flag to be set. Some irq chips like 274e2841179SLoGin // MSI based interrupts are per se one shot safe. Check the 275e2841179SLoGin // chip flags, so we can avoid the unmask dance at the end of 276e2841179SLoGin // the threaded handler for those. 277e2841179SLoGin 278e2841179SLoGin if desc 279e2841179SLoGin .irq_data() 280e2841179SLoGin .chip_info_read_irqsave() 281e2841179SLoGin .chip() 282e2841179SLoGin .flags() 283e2841179SLoGin .contains(IrqChipFlags::IRQCHIP_ONESHOT_SAFE) 284e2841179SLoGin { 285e2841179SLoGin *action_guard.flags_mut() &= !IrqHandleFlags::IRQF_ONESHOT; 286e2841179SLoGin } 287e2841179SLoGin 288e2841179SLoGin // Protects against a concurrent __free_irq() call which might wait 289e2841179SLoGin // for synchronize_hardirq() to complete without holding the optional 290e2841179SLoGin // chip bus lock and desc->lock. Also protects against handing out 291e2841179SLoGin // a recycled oneshot thread_mask bit while it's still in use by 292e2841179SLoGin // its previous owner. 293e2841179SLoGin let req_mutex_guard = desc.request_mutex_lock(); 294e2841179SLoGin 295e2841179SLoGin // Acquire bus lock as the irq_request_resources() callback below 296e2841179SLoGin // might rely on the serialization or the magic power management 297e2841179SLoGin // functions which are abusing the irq_bus_lock() callback, 298e2841179SLoGin desc.chip_bus_lock(); 299e2841179SLoGin 300e2841179SLoGin // 如果当前中断线上还没有irqaction, 则先为中断线申请资源 301e2841179SLoGin if desc.actions().is_empty() { 302e2841179SLoGin if let Err(e) = self.irq_request_resources(desc.clone()) { 303e2841179SLoGin kerror!( 304e2841179SLoGin "Failed to request resources for {} (irq {}) on irqchip {}, error {:?}", 305e2841179SLoGin action_guard.name(), 306e2841179SLoGin irq.data(), 307e2841179SLoGin desc.irq_data().chip_info_read_irqsave().chip().name(), 308e2841179SLoGin e 309e2841179SLoGin ); 310e2841179SLoGin return Err(err_out_bus_unlock( 311e2841179SLoGin e, 312e2841179SLoGin desc.clone(), 313e2841179SLoGin req_mutex_guard, 314e2841179SLoGin action_guard, 315e2841179SLoGin )); 316e2841179SLoGin } 317e2841179SLoGin } 318e2841179SLoGin 319e2841179SLoGin let mut desc_inner_guard: SpinLockGuard<'_, InnerIrqDesc> = desc.inner(); 320e2841179SLoGin 321e2841179SLoGin // 标记当前irq是否是共享的 322e2841179SLoGin let mut irq_shared = false; 323b5b571e0SLoGin if !desc_inner_guard.actions().is_empty() { 324e2841179SLoGin // 除非双方都同意并且是相同类型(级别、边沿、极性),否则不能共享中断。 325e2841179SLoGin // 因此,两个标志字段都必须设置IRQF_SHARED,并且设置触发类型的位必须匹配。 326e2841179SLoGin // 另外,所有各方都必须就ONESHOT达成一致。 327e2841179SLoGin // NMI用途的中断线不能共享。 328e2841179SLoGin if desc_inner_guard 329e2841179SLoGin .internal_state() 330e2841179SLoGin .contains(IrqDescState::IRQS_NMI) 331e2841179SLoGin { 332e2841179SLoGin kerror!( 333e2841179SLoGin "Invalid attempt to share NMI for {} (irq {}) on irqchip {}", 334e2841179SLoGin action_guard.name(), 335e2841179SLoGin irq.data(), 336e2841179SLoGin desc_inner_guard 337e2841179SLoGin .irq_data() 338e2841179SLoGin .chip_info_read_irqsave() 339e2841179SLoGin .chip() 340e2841179SLoGin .name() 341e2841179SLoGin ); 342e2841179SLoGin return Err(err_out_unlock( 343e2841179SLoGin SystemError::EINVAL, 344e2841179SLoGin desc_inner_guard, 345e2841179SLoGin desc.clone(), 346e2841179SLoGin req_mutex_guard, 347e2841179SLoGin action_guard, 348e2841179SLoGin )); 349e2841179SLoGin } 350e2841179SLoGin 351e2841179SLoGin let irq_data = desc_inner_guard.irq_data(); 352e2841179SLoGin 353e2841179SLoGin let old_trigger_type: super::irqdata::IrqLineStatus; 354e2841179SLoGin let status = irq_data.common_data().status(); 355e2841179SLoGin if status.trigger_type_was_set() { 356e2841179SLoGin old_trigger_type = status.trigger_type(); 357e2841179SLoGin } else { 358e2841179SLoGin old_trigger_type = action_guard.flags().trigger_type(); 359e2841179SLoGin irq_data.common_data().set_trigger_type(old_trigger_type); 360e2841179SLoGin } 361e2841179SLoGin 362e2841179SLoGin let old = &desc_inner_guard.actions()[0].clone(); 363e2841179SLoGin let old_guard = old.inner(); 364e2841179SLoGin 365b5b571e0SLoGin if (!(old_guard 366e2841179SLoGin .flags() 367e2841179SLoGin .intersection(*action_guard.flags()) 368b5b571e0SLoGin .contains(IrqHandleFlags::IRQF_SHARED))) 369e2841179SLoGin || (old_trigger_type != (action_guard.flags().trigger_type())) 370e2841179SLoGin || ((old_guard.flags().bitxor(*action_guard.flags())) 371e2841179SLoGin .contains(IrqHandleFlags::IRQF_ONESHOT)) 372e2841179SLoGin { 373*0102d69fSLoGin kdebug!( 374*0102d69fSLoGin "Flags mismatch for irq {} (name: {}, flags: {:?}). old action name: {}, old flags: {:?}", 375*0102d69fSLoGin irq.data(), 376*0102d69fSLoGin action_guard.name(), 377*0102d69fSLoGin action_guard.flags(), 378*0102d69fSLoGin old_guard.name(), 379*0102d69fSLoGin old_guard.flags() 380*0102d69fSLoGin ); 381*0102d69fSLoGin 382e2841179SLoGin return Err(err_out_mismatch( 383e2841179SLoGin old_guard, 384e2841179SLoGin desc_inner_guard, 385e2841179SLoGin action_guard, 386e2841179SLoGin desc.clone(), 387e2841179SLoGin req_mutex_guard, 388e2841179SLoGin )); 389e2841179SLoGin } 390e2841179SLoGin 391e2841179SLoGin // all handlers must agree on per-cpuness 392e2841179SLoGin if *old_guard.flags() & IrqHandleFlags::IRQF_PERCPU 393e2841179SLoGin != *action_guard.flags() & IrqHandleFlags::IRQF_PERCPU 394e2841179SLoGin { 395*0102d69fSLoGin kdebug!( 396*0102d69fSLoGin "Per-cpu mismatch for irq {} (name: {}, flags: {:?})", 397*0102d69fSLoGin irq.data(), 398*0102d69fSLoGin action_guard.name(), 399*0102d69fSLoGin action_guard.flags() 400*0102d69fSLoGin ); 401e2841179SLoGin return Err(err_out_mismatch( 402e2841179SLoGin old_guard, 403e2841179SLoGin desc_inner_guard, 404e2841179SLoGin action_guard, 405e2841179SLoGin desc.clone(), 406e2841179SLoGin req_mutex_guard, 407e2841179SLoGin )); 408e2841179SLoGin } 409e2841179SLoGin 410e2841179SLoGin irq_shared = true; 411e2841179SLoGin } 412e2841179SLoGin 413e2841179SLoGin if action_guard.flags().contains(IrqHandleFlags::IRQF_ONESHOT) { 414e2841179SLoGin // todo: oneshot 415e2841179SLoGin } else if action_guard.handler().is_some_and(|h| { 416e2841179SLoGin h.type_id() == (&DefaultPrimaryIrqHandler as &dyn IrqHandler).type_id() 417b5b571e0SLoGin }) && !desc_inner_guard 418e2841179SLoGin .irq_data() 419e2841179SLoGin .chip_info_read_irqsave() 420e2841179SLoGin .chip() 421e2841179SLoGin .flags() 422e2841179SLoGin .contains(IrqChipFlags::IRQCHIP_ONESHOT_SAFE) 423e2841179SLoGin { 424e2841179SLoGin // 请求中断时 hander = NULL,因此我们为其使用默认的主处理程序。 425e2841179SLoGin // 但它没有设置ONESHOT标志。与电平触发中断结合时, 426e2841179SLoGin // 这是致命的,因为默认的主处理程序只是唤醒线程,然后重新启用 irq 线路, 427e2841179SLoGin // 但设备仍然保持电平中断生效。周而复始.... 428e2841179SLoGin // 虽然这对于边缘类型中断来说可行,但我们为了安全起见,不加条件地拒绝, 429e2841179SLoGin // 因为我们不能确定这个中断实际上具有什么类型。 430e2841179SLoGin // 由于底层芯片实现可能会覆盖它们,所以类型标志并不可靠. 431e2841179SLoGin 432e2841179SLoGin kerror!( 433e2841179SLoGin "Requesting irq {} without a handler, and ONESHOT flags not set for irqaction: {}", 434e2841179SLoGin irq.data(), 435e2841179SLoGin action_guard.name() 436e2841179SLoGin ); 437e2841179SLoGin return Err(err_out_unlock( 438e2841179SLoGin SystemError::EINVAL, 439e2841179SLoGin desc_inner_guard, 440e2841179SLoGin desc.clone(), 441e2841179SLoGin req_mutex_guard, 442e2841179SLoGin action_guard, 443e2841179SLoGin )); 444e2841179SLoGin } 445e2841179SLoGin 446e2841179SLoGin // 第一次在当前irqdesc上注册中断处理函数 447e2841179SLoGin if !irq_shared { 448e2841179SLoGin // 设置中断触发方式 449e2841179SLoGin if action_guard.flags().trigger_type_specified() { 450e2841179SLoGin let trigger_type = action_guard.flags().trigger_type(); 451e2841179SLoGin if let Err(e) = 452e2841179SLoGin self.do_set_irq_trigger(desc.clone(), &mut desc_inner_guard, trigger_type) 453e2841179SLoGin { 454*0102d69fSLoGin kdebug!( 455*0102d69fSLoGin "Failed to set trigger type for irq {} (name: {}, flags: {:?}), error {:?}", 456*0102d69fSLoGin irq.data(), 457*0102d69fSLoGin action_guard.name(), 458*0102d69fSLoGin action_guard.flags(), 459*0102d69fSLoGin e 460*0102d69fSLoGin ); 461e2841179SLoGin return Err(err_out_unlock( 462e2841179SLoGin e, 463e2841179SLoGin desc_inner_guard, 464e2841179SLoGin desc.clone(), 465e2841179SLoGin req_mutex_guard, 466e2841179SLoGin action_guard, 467e2841179SLoGin )); 468e2841179SLoGin } 469e2841179SLoGin } 470*0102d69fSLoGin kdebug!("to irq_activate"); 471e2841179SLoGin // 激活中断。这种激活必须独立于IRQ_NOAUTOEN进行*desc_inner_guard.internal_state_mut() |= IrqDescState::IRQS_NOREQUEST;uest. 472338f6903SLoGin if let Err(e) = self.irq_activate(&desc, &mut desc_inner_guard) { 473*0102d69fSLoGin kdebug!( 474*0102d69fSLoGin "Failed to activate irq {} (name: {}, flags: {:?}), error {:?}", 475*0102d69fSLoGin irq.data(), 476*0102d69fSLoGin action_guard.name(), 477*0102d69fSLoGin action_guard.flags(), 478*0102d69fSLoGin e 479*0102d69fSLoGin ); 480e2841179SLoGin return Err(err_out_unlock( 481e2841179SLoGin e, 482e2841179SLoGin desc_inner_guard, 483e2841179SLoGin desc.clone(), 484e2841179SLoGin req_mutex_guard, 485e2841179SLoGin action_guard, 486e2841179SLoGin )); 487e2841179SLoGin } 488e2841179SLoGin 489e2841179SLoGin *desc_inner_guard.internal_state_mut() &= !(IrqDescState::IRQS_AUTODETECT 490e2841179SLoGin | IrqDescState::IRQS_SPURIOUS_DISABLED 491e2841179SLoGin | IrqDescState::IRQS_ONESHOT 492e2841179SLoGin | IrqDescState::IRQS_WAITING); 493e2841179SLoGin desc_inner_guard 494e2841179SLoGin .common_data() 495e2841179SLoGin .clear_status(IrqStatus::IRQD_IRQ_INPROGRESS); 496e2841179SLoGin 497e2841179SLoGin if action_guard.flags().contains(IrqHandleFlags::IRQF_PERCPU) { 498e2841179SLoGin desc_inner_guard 499e2841179SLoGin .common_data() 500e2841179SLoGin .insert_status(IrqStatus::IRQD_PER_CPU); 501e2841179SLoGin desc_inner_guard.line_status_set_per_cpu(); 502e2841179SLoGin 503e2841179SLoGin if action_guard.flags().contains(IrqHandleFlags::IRQF_NO_DEBUG) { 504e2841179SLoGin desc_inner_guard.line_status_set_no_debug(); 505e2841179SLoGin } 506e2841179SLoGin } 507e2841179SLoGin 508e2841179SLoGin if action_guard.flags().contains(IrqHandleFlags::IRQF_ONESHOT) { 509e2841179SLoGin *desc_inner_guard.internal_state_mut() |= IrqDescState::IRQS_ONESHOT; 510e2841179SLoGin } 511e2841179SLoGin 512e2841179SLoGin // 如果有要求的话,则忽略IRQ的均衡。 513e2841179SLoGin if action_guard 514e2841179SLoGin .flags() 515e2841179SLoGin .contains(IrqHandleFlags::IRQF_NOBALANCING) 516e2841179SLoGin { 517e2841179SLoGin todo!("IRQF_NO_BALANCING"); 518e2841179SLoGin } 519e2841179SLoGin 520e2841179SLoGin if !action_guard 521e2841179SLoGin .flags() 522e2841179SLoGin .contains(IrqHandleFlags::IRQF_NO_AUTOEN) 523e2841179SLoGin && desc_inner_guard.can_autoenable() 524e2841179SLoGin { 525e2841179SLoGin // 如果没有设置IRQF_NOAUTOEN,则自动使能中断 526e2841179SLoGin self.irq_startup( 527338f6903SLoGin &desc, 528e2841179SLoGin &mut desc_inner_guard, 529e2841179SLoGin Self::IRQ_RESEND, 530e2841179SLoGin Self::IRQ_START_COND, 531e2841179SLoGin ) 532e2841179SLoGin .ok(); 533e2841179SLoGin } else { 534e2841179SLoGin // 共享中断与禁用自动使能不太兼容。 535e2841179SLoGin // 共享中断可能在它仍然被禁用时请求它,然后永远等待中断。 536e2841179SLoGin 537e2841179SLoGin static mut WARNED: bool = false; 538b5b571e0SLoGin if action_guard.flags().contains(IrqHandleFlags::IRQF_SHARED) && unsafe { !WARNED } 539b5b571e0SLoGin { 540e2841179SLoGin kwarn!( 541e2841179SLoGin "Shared interrupt {} for {} requested but not auto enabled", 542e2841179SLoGin irq.data(), 543e2841179SLoGin action_guard.name() 544e2841179SLoGin ); 545e2841179SLoGin unsafe { WARNED = true }; 546e2841179SLoGin } 547e2841179SLoGin 548e2841179SLoGin desc_inner_guard.set_depth(1); 549e2841179SLoGin } 550e2841179SLoGin } else if action_guard.flags().trigger_type_specified() { 551e2841179SLoGin let new_trigger_type = action_guard.flags().trigger_type(); 552e2841179SLoGin let old_trigger_type = desc_inner_guard.common_data().trigger_type(); 553e2841179SLoGin if new_trigger_type != old_trigger_type { 554e2841179SLoGin kwarn!("Irq {} uses trigger type: {old_trigger_type:?}, but requested trigger type: {new_trigger_type:?}.", irq.data()); 555e2841179SLoGin } 556e2841179SLoGin } 557e2841179SLoGin 558e2841179SLoGin // 在队列末尾添加新的irqaction 559e2841179SLoGin desc_inner_guard.add_action(action.clone()); 560e2841179SLoGin 561e2841179SLoGin // 检查我们是否曾经通过虚构的中断处理程序禁用过irq。重新启用它并再给它一次机会。 562e2841179SLoGin if irq_shared 563e2841179SLoGin && desc_inner_guard 564e2841179SLoGin .internal_state() 565e2841179SLoGin .contains(IrqDescState::IRQS_SPURIOUS_DISABLED) 566e2841179SLoGin { 567e2841179SLoGin desc_inner_guard 568e2841179SLoGin .internal_state_mut() 569e2841179SLoGin .remove(IrqDescState::IRQS_SPURIOUS_DISABLED); 570e2841179SLoGin self.do_enable_irq(desc.clone(), &mut desc_inner_guard).ok(); 571e2841179SLoGin } 572e2841179SLoGin 573e2841179SLoGin drop(desc_inner_guard); 574e2841179SLoGin desc.chip_bus_sync_unlock(); 575e2841179SLoGin drop(req_mutex_guard); 576e2841179SLoGin 577e2841179SLoGin drop(action_guard); 578e2841179SLoGin self.wake_up_and_wait_for_irq_thread_ready(&desc, Some(action.clone())); 579e2841179SLoGin self.wake_up_and_wait_for_irq_thread_ready(&desc, action.inner().secondary()); 580e2841179SLoGin return Ok(()); 581e2841179SLoGin } 582e2841179SLoGin 583e2841179SLoGin /// 唤醒中断线程并等待中断线程准备好 584e2841179SLoGin /// 585e2841179SLoGin /// ## 参数 586e2841179SLoGin /// 587e2841179SLoGin /// - desc: 中断描述符 588e2841179SLoGin /// - action: 要唤醒的中断处理函数 589e2841179SLoGin /// 590e2841179SLoGin /// ## 锁 591e2841179SLoGin /// 592e2841179SLoGin /// 进入当前函数时,`action`的锁需要被释放 593e2841179SLoGin fn wake_up_and_wait_for_irq_thread_ready( 594e2841179SLoGin &self, 595e2841179SLoGin desc: &Arc<IrqDesc>, 596e2841179SLoGin action: Option<Arc<IrqAction>>, 597e2841179SLoGin ) { 598e2841179SLoGin if action.is_none() { 599e2841179SLoGin return; 600e2841179SLoGin } 601e2841179SLoGin 602e2841179SLoGin let action = action.unwrap(); 603e2841179SLoGin 604e2841179SLoGin let action_guard = action.inner(); 605e2841179SLoGin if action_guard.thread().is_none() { 606e2841179SLoGin return; 607e2841179SLoGin } 608e2841179SLoGin 609e2841179SLoGin ProcessManager::wakeup(&action_guard.thread().unwrap()).ok(); 610e2841179SLoGin drop(action_guard); 611e2841179SLoGin action 612e2841179SLoGin .thread_completion() 613e2841179SLoGin .wait_for_completion() 614e2841179SLoGin .map_err(|e| { 615e2841179SLoGin kwarn!( 616e2841179SLoGin "Failed to wait for irq thread ready for {} (irq {:?}), error {:?}", 617e2841179SLoGin action.inner().name(), 618e2841179SLoGin desc.irq_data().irq(), 619e2841179SLoGin e 620e2841179SLoGin ); 621e2841179SLoGin }) 622e2841179SLoGin .ok(); 623e2841179SLoGin } 624e2841179SLoGin 625338f6903SLoGin pub(super) fn irq_activate_and_startup( 626338f6903SLoGin &self, 627338f6903SLoGin desc: &Arc<IrqDesc>, 628338f6903SLoGin desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>, 629338f6903SLoGin resend: bool, 630338f6903SLoGin ) -> Result<(), SystemError> { 631*0102d69fSLoGin kdebug!( 632*0102d69fSLoGin "irq_activate_and_startup: irq: {}, name: {:?}", 633*0102d69fSLoGin desc.irq().data(), 634*0102d69fSLoGin desc_inner_guard.name() 635*0102d69fSLoGin ); 636338f6903SLoGin self.irq_activate(desc, desc_inner_guard)?; 637338f6903SLoGin self.irq_startup(desc, desc_inner_guard, resend, Self::IRQ_START_FORCE) 638338f6903SLoGin } 639338f6903SLoGin 640e2841179SLoGin pub(super) fn irq_activate( 641e2841179SLoGin &self, 642338f6903SLoGin _desc: &Arc<IrqDesc>, 643e2841179SLoGin desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>, 644e2841179SLoGin ) -> Result<(), SystemError> { 645e2841179SLoGin let irq_data = desc_inner_guard.irq_data(); 646e2841179SLoGin 647e2841179SLoGin if !desc_inner_guard.common_data().status().affinity_managed() { 648e2841179SLoGin return irq_domain_manager().activate_irq(irq_data, false); 649e2841179SLoGin } 650e2841179SLoGin 651e2841179SLoGin return Ok(()); 652e2841179SLoGin } 653e2841179SLoGin 654e2841179SLoGin /// 设置CPU亲和性并开启中断 655e2841179SLoGin pub(super) fn irq_startup( 656e2841179SLoGin &self, 657338f6903SLoGin desc: &Arc<IrqDesc>, 658e2841179SLoGin desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>, 659e2841179SLoGin resend: bool, 660e2841179SLoGin force: bool, 661e2841179SLoGin ) -> Result<(), SystemError> { 662*0102d69fSLoGin kdebug!( 663*0102d69fSLoGin "irq_startup: irq: {}, name: {:?}", 664*0102d69fSLoGin desc_inner_guard.irq_data().irq().data(), 665*0102d69fSLoGin desc_inner_guard.name() 666*0102d69fSLoGin ); 667e2841179SLoGin let mut ret = Ok(()); 668e2841179SLoGin let irq_data = desc_inner_guard.irq_data().clone(); 669e2841179SLoGin let affinity = desc_inner_guard.common_data().affinity(); 670e2841179SLoGin desc_inner_guard.set_depth(0); 671e2841179SLoGin 672e2841179SLoGin if desc_inner_guard.common_data().status().started() { 673e2841179SLoGin self.irq_enable(desc_inner_guard); 674e2841179SLoGin } else { 675e2841179SLoGin match self.__irq_startup_managed(desc_inner_guard, &affinity, force) { 676e2841179SLoGin IrqStartupResult::Normal => { 677e2841179SLoGin if irq_data 678e2841179SLoGin .chip_info_read_irqsave() 679e2841179SLoGin .chip() 680e2841179SLoGin .flags() 681e2841179SLoGin .contains(IrqChipFlags::IRQCHIP_AFFINITY_PRE_STARTUP) 682e2841179SLoGin { 683338f6903SLoGin self.irq_setup_affinity(desc, desc_inner_guard).ok(); 684e2841179SLoGin } 685e2841179SLoGin 686e2841179SLoGin ret = self.__irq_startup(desc_inner_guard); 687e2841179SLoGin 688e2841179SLoGin if !irq_data 689e2841179SLoGin .chip_info_read_irqsave() 690e2841179SLoGin .chip() 691e2841179SLoGin .flags() 692e2841179SLoGin .contains(IrqChipFlags::IRQCHIP_AFFINITY_PRE_STARTUP) 693e2841179SLoGin { 694338f6903SLoGin self.irq_setup_affinity(desc, desc_inner_guard).ok(); 695e2841179SLoGin } 696e2841179SLoGin } 697e2841179SLoGin IrqStartupResult::Managed => { 698b5b571e0SLoGin self.irq_do_set_affinity(&irq_data, desc_inner_guard, &affinity, false) 699e2841179SLoGin .ok(); 700e2841179SLoGin ret = self.__irq_startup(desc_inner_guard); 701e2841179SLoGin } 702e2841179SLoGin IrqStartupResult::Abort => { 703e2841179SLoGin desc_inner_guard 704e2841179SLoGin .common_data() 705e2841179SLoGin .insert_status(IrqStatus::IRQD_MANAGED_SHUTDOWN); 706e2841179SLoGin return Ok(()); 707e2841179SLoGin } 708e2841179SLoGin } 709e2841179SLoGin } 710e2841179SLoGin 711e2841179SLoGin if resend { 712e2841179SLoGin if let Err(e) = self.irq_check_and_resend(desc_inner_guard, false) { 713e2841179SLoGin kerror!( 714e2841179SLoGin "Failed to check and resend irq {}, error {:?}", 715e2841179SLoGin irq_data.irq().data(), 716e2841179SLoGin e 717e2841179SLoGin ); 718e2841179SLoGin } 719e2841179SLoGin } 720e2841179SLoGin 721e2841179SLoGin return ret; 722e2841179SLoGin } 723e2841179SLoGin 724e2841179SLoGin pub fn irq_enable(&self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>) { 725e2841179SLoGin let common_data = desc_inner_guard.common_data(); 726e2841179SLoGin if !common_data.status().disabled() { 727e2841179SLoGin self.unmask_irq(desc_inner_guard); 728e2841179SLoGin } else { 729e2841179SLoGin common_data.clear_disabled(); 730e2841179SLoGin 731e2841179SLoGin let chip = desc_inner_guard.irq_data().chip_info_read_irqsave().chip(); 732e2841179SLoGin 733b5b571e0SLoGin if let Err(e) = chip.irq_enable(desc_inner_guard.irq_data()) { 734e2841179SLoGin if e == SystemError::ENOSYS { 735e2841179SLoGin self.unmask_irq(desc_inner_guard); 736e2841179SLoGin } 737e2841179SLoGin kerror!( 738e2841179SLoGin "Failed to enable irq {} (name: {:?}), error {:?}", 739e2841179SLoGin desc_inner_guard.irq_data().irq().data(), 740e2841179SLoGin desc_inner_guard.name(), 741e2841179SLoGin e 742e2841179SLoGin ); 743e2841179SLoGin } else { 744e2841179SLoGin common_data.clear_masked(); 745e2841179SLoGin } 746e2841179SLoGin } 747e2841179SLoGin } 748e2841179SLoGin 749e2841179SLoGin /// 自动设置中断的CPU亲和性 750e2841179SLoGin /// 751e2841179SLoGin /// 752e2841179SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c#589 753e2841179SLoGin pub fn irq_setup_affinity( 754e2841179SLoGin &self, 755e2841179SLoGin _desc: &Arc<IrqDesc>, 756e2841179SLoGin desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>, 757e2841179SLoGin ) -> Result<(), SystemError> { 758e2841179SLoGin let common_data = desc_inner_guard.common_data(); 759e2841179SLoGin if !desc_inner_guard.can_set_affinity() { 760e2841179SLoGin return Ok(()); 761e2841179SLoGin } 762e2841179SLoGin 763e2841179SLoGin let mut to_set = IRQ_DEFAULT_AFFINITY.clone(); 764e2841179SLoGin if common_data.status().affinity_managed() 765e2841179SLoGin || common_data.status().contains(IrqStatus::IRQD_AFFINITY_SET) 766e2841179SLoGin { 767e2841179SLoGin // FIXME: 要判断affinity跟已上线的CPU是否有交集 768e2841179SLoGin 769e2841179SLoGin let irq_aff = common_data.affinity(); 770e2841179SLoGin if irq_aff.is_empty() { 771e2841179SLoGin common_data.clear_status(IrqStatus::IRQD_AFFINITY_SET); 772e2841179SLoGin } else { 773e2841179SLoGin to_set = irq_aff; 774e2841179SLoGin } 775e2841179SLoGin } 776e2841179SLoGin 777e2841179SLoGin // FIXME: 求to_set和在线CPU的交集 778e2841179SLoGin 779e2841179SLoGin return self.irq_do_set_affinity( 780e2841179SLoGin desc_inner_guard.irq_data(), 781b5b571e0SLoGin desc_inner_guard, 782e2841179SLoGin &to_set, 783e2841179SLoGin false, 784e2841179SLoGin ); 785e2841179SLoGin } 786e2841179SLoGin 787*0102d69fSLoGin pub fn irq_set_affinity( 788*0102d69fSLoGin &self, 789*0102d69fSLoGin irq_data: &Arc<IrqData>, 790*0102d69fSLoGin desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>, 791*0102d69fSLoGin cpumask: &CpuMask, 792*0102d69fSLoGin ) -> Result<(), SystemError> { 793*0102d69fSLoGin return self.irq_do_set_affinity(irq_data, desc_inner_guard, cpumask, false); 794*0102d69fSLoGin } 795*0102d69fSLoGin fn irq_do_set_affinity( 796e2841179SLoGin &self, 797e2841179SLoGin irq_data: &Arc<IrqData>, 798e2841179SLoGin desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>, 799e2841179SLoGin cpumask: &CpuMask, 800e2841179SLoGin force: bool, 801e2841179SLoGin ) -> Result<(), SystemError> { 802e2841179SLoGin let chip = irq_data.chip_info_read_irqsave().chip(); 803e2841179SLoGin if !chip.can_set_affinity() { 804e2841179SLoGin return Err(SystemError::EINVAL); 805e2841179SLoGin } 806e2841179SLoGin 807e2841179SLoGin // todo: 处理CPU中断隔离相关的逻辑 808e2841179SLoGin 809e2841179SLoGin let common_data = desc_inner_guard.common_data(); 810b5b571e0SLoGin let r = if force || !cpumask.is_empty() { 811b5b571e0SLoGin chip.irq_set_affinity(irq_data, cpumask, force) 812e2841179SLoGin } else { 813e2841179SLoGin return Err(SystemError::EINVAL); 814b5b571e0SLoGin }; 815e2841179SLoGin 816e2841179SLoGin let mut ret = Ok(()); 817e2841179SLoGin if let Ok(rs) = r { 818e2841179SLoGin match rs { 819b5b571e0SLoGin IrqChipSetMaskResult::Success | IrqChipSetMaskResult::Done => { 820e2841179SLoGin common_data.set_affinity(cpumask.clone()); 821e2841179SLoGin } 822b5b571e0SLoGin IrqChipSetMaskResult::NoChange => { 823e2841179SLoGin 824e2841179SLoGin // irq_validate_effective_affinity(data); 825e2841179SLoGin // irq_set_thread_affinity(desc); 826e2841179SLoGin } 827e2841179SLoGin } 828e2841179SLoGin } else { 829e2841179SLoGin ret = Err(r.unwrap_err()); 830e2841179SLoGin } 831e2841179SLoGin 832e2841179SLoGin return ret; 833e2841179SLoGin } 834e2841179SLoGin 835e2841179SLoGin fn __irq_startup( 836e2841179SLoGin &self, 837e2841179SLoGin desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>, 838e2841179SLoGin ) -> Result<(), SystemError> { 839e2841179SLoGin let common_data = desc_inner_guard.common_data(); 840e2841179SLoGin 841e2841179SLoGin if let Err(e) = desc_inner_guard 842e2841179SLoGin .irq_data() 843e2841179SLoGin .chip_info_read_irqsave() 844e2841179SLoGin .chip() 845e2841179SLoGin .irq_startup(desc_inner_guard.irq_data()) 846e2841179SLoGin { 847e2841179SLoGin if e == SystemError::ENOSYS { 848e2841179SLoGin self.irq_enable(desc_inner_guard); 849e2841179SLoGin } else { 850e2841179SLoGin return Err(e); 851e2841179SLoGin } 852e2841179SLoGin } else { 853e2841179SLoGin common_data.clear_disabled(); 854e2841179SLoGin common_data.clear_masked(); 855e2841179SLoGin } 856e2841179SLoGin 857e2841179SLoGin common_data.set_started(); 858e2841179SLoGin 859e2841179SLoGin return Ok(()); 860e2841179SLoGin } 861e2841179SLoGin 862e2841179SLoGin fn __irq_startup_managed( 863e2841179SLoGin &self, 864e2841179SLoGin desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>, 865e2841179SLoGin _affinity: &CpuMask, 866e2841179SLoGin _force: bool, 867e2841179SLoGin ) -> IrqStartupResult { 868e2841179SLoGin let irq_data = desc_inner_guard.irq_data(); 869e2841179SLoGin let common_data = desc_inner_guard.common_data(); 870e2841179SLoGin 871e2841179SLoGin if !common_data.status().affinity_managed() { 872e2841179SLoGin return IrqStartupResult::Normal; 873e2841179SLoGin } 874e2841179SLoGin 875e2841179SLoGin common_data.clear_managed_shutdown(); 876e2841179SLoGin 877e2841179SLoGin /* 878e2841179SLoGin - 检查Affinity掩码是否包括所有的在线CPU。如果是,这意味着有代码试图在管理的中断上使用enable_irq(), 879e2841179SLoGin 这可能是非法的。在这种情况下,如果force不是真值,函数会返回IRQ_STARTUP_ABORT,表示中断处理应该被放弃。 880e2841179SLoGin - 如果Affinity掩码中没有任何在线的CPU,那么中断请求是不可用的,因为没有任何CPU可以处理它。 881e2841179SLoGin 在这种情况下,如果force不是真值,函数同样会返回IRQ_STARTUP_ABORT。 882e2841179SLoGin - 如果以上条件都不满足,尝试激活中断,并将其设置为管理模式。这是通过调用 `irq_domain_manager().activate_irq()` 函数来实现的。 883e2841179SLoGin 如果这个调用失败,表示有保留的资源无法访问,函数会返回IRQ_STARTUP_ABORT。 884e2841179SLoGin - 如果一切顺利,函数会返回IRQ_STARTUP_MANAGED,表示中断已经被成功管理并激活。 885e2841179SLoGin */ 886e2841179SLoGin 887e2841179SLoGin // if (cpumask_any_and(aff, cpu_online_mask) >= nr_cpu_ids) { 888e2841179SLoGin // /* 889e2841179SLoGin // * Catch code which fiddles with enable_irq() on a managed 890e2841179SLoGin // * and potentially shutdown IRQ. Chained interrupt 891e2841179SLoGin // * installment or irq auto probing should not happen on 892e2841179SLoGin // * managed irqs either. 893e2841179SLoGin // */ 894e2841179SLoGin // if (WARN_ON_ONCE(force)) 895e2841179SLoGin // return IRQ_STARTUP_ABORT; 896e2841179SLoGin // /* 897e2841179SLoGin // * The interrupt was requested, but there is no online CPU 898e2841179SLoGin // * in it's affinity mask. Put it into managed shutdown 899e2841179SLoGin // * state and let the cpu hotplug mechanism start it up once 900e2841179SLoGin // * a CPU in the mask becomes available. 901e2841179SLoGin // */ 902e2841179SLoGin // return IRQ_STARTUP_ABORT; 903e2841179SLoGin // } 904e2841179SLoGin 905e2841179SLoGin let r = irq_domain_manager().activate_irq(irq_data, false); 906e2841179SLoGin if r.is_err() { 907e2841179SLoGin return IrqStartupResult::Abort; 908e2841179SLoGin } 909e2841179SLoGin 910e2841179SLoGin return IrqStartupResult::Managed; 911e2841179SLoGin } 912e2841179SLoGin 913e2841179SLoGin pub fn do_enable_irq( 914e2841179SLoGin &self, 915e2841179SLoGin _desc: Arc<IrqDesc>, 916e2841179SLoGin _desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>, 917e2841179SLoGin ) -> Result<(), SystemError> { 918e2841179SLoGin // https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c?r=&mo=59252&fi=2138#776 919e2841179SLoGin todo!("do_enable_irq") 920e2841179SLoGin } 921e2841179SLoGin 922e2841179SLoGin #[inline(never)] 923e2841179SLoGin pub fn do_set_irq_trigger( 924e2841179SLoGin &self, 925e2841179SLoGin _desc: Arc<IrqDesc>, 926e2841179SLoGin desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>, 927e2841179SLoGin mut trigger_type: IrqLineStatus, 928e2841179SLoGin ) -> Result<(), SystemError> { 929e2841179SLoGin let chip = desc_inner_guard.irq_data().chip_info_read_irqsave().chip(); 930e2841179SLoGin let mut to_unmask = false; 931e2841179SLoGin 932e2841179SLoGin if !chip.can_set_flow_type() { 933e2841179SLoGin // kdebug!( 934e2841179SLoGin // "No set_irq_type function for irq {}, chip {}", 935e2841179SLoGin // desc_inner_guard.irq_data().irq().data(), 936e2841179SLoGin // chip.name() 937e2841179SLoGin // ); 938e2841179SLoGin return Ok(()); 939e2841179SLoGin } 940e2841179SLoGin 941e2841179SLoGin if chip.flags().contains(IrqChipFlags::IRQCHIP_SET_TYPE_MASKED) { 942b5b571e0SLoGin if !desc_inner_guard.common_data().status().masked() { 943e2841179SLoGin self.mask_irq(desc_inner_guard.irq_data()); 944e2841179SLoGin } 945b5b571e0SLoGin if !desc_inner_guard.common_data().status().disabled() { 946e2841179SLoGin to_unmask = true; 947e2841179SLoGin } 948e2841179SLoGin } 949e2841179SLoGin 950e2841179SLoGin trigger_type &= IrqLineStatus::IRQ_TYPE_SENSE_MASK; 951e2841179SLoGin 952e2841179SLoGin let r = chip.irq_set_type(desc_inner_guard.irq_data(), trigger_type); 953e2841179SLoGin let ret; 954e2841179SLoGin if let Ok(rs) = r { 955e2841179SLoGin match rs { 956b5b571e0SLoGin IrqChipSetMaskResult::Success | IrqChipSetMaskResult::Done => { 957e2841179SLoGin let common_data = desc_inner_guard.common_data(); 958e2841179SLoGin common_data.clear_status(IrqStatus::IRQD_TRIGGER_MASK); 959e2841179SLoGin let mut irqstatus = IrqStatus::empty(); 960e2841179SLoGin irqstatus.set_trigger_type(trigger_type); 961e2841179SLoGin common_data.insert_status(irqstatus); 962e2841179SLoGin } 963b5b571e0SLoGin IrqChipSetMaskResult::NoChange => { 964e2841179SLoGin let flags = desc_inner_guard.common_data().trigger_type(); 965e2841179SLoGin desc_inner_guard.set_trigger_type(flags); 966e2841179SLoGin desc_inner_guard 967e2841179SLoGin .common_data() 968e2841179SLoGin .clear_status(IrqStatus::IRQD_LEVEL); 969e2841179SLoGin desc_inner_guard.clear_level(); 970e2841179SLoGin 971b5b571e0SLoGin if !(flags & IrqLineStatus::IRQ_TYPE_LEVEL_MASK).is_empty() { 972e2841179SLoGin desc_inner_guard.set_level(); 973e2841179SLoGin desc_inner_guard 974e2841179SLoGin .common_data() 975e2841179SLoGin .insert_status(IrqStatus::IRQD_LEVEL); 976e2841179SLoGin } 977e2841179SLoGin } 978e2841179SLoGin } 979e2841179SLoGin 980e2841179SLoGin ret = Ok(()); 981e2841179SLoGin } else { 982e2841179SLoGin kerror!( 983e2841179SLoGin "Failed to set irq {} trigger type to {:?} on irqchip {}, error {:?}", 984e2841179SLoGin desc_inner_guard.irq_data().irq().data(), 985e2841179SLoGin trigger_type, 986e2841179SLoGin chip.name(), 987e2841179SLoGin r 988e2841179SLoGin ); 989e2841179SLoGin 990e2841179SLoGin ret = Err(r.unwrap_err()); 991e2841179SLoGin } 992e2841179SLoGin 993e2841179SLoGin if to_unmask { 994e2841179SLoGin self.unmask_irq(desc_inner_guard); 995e2841179SLoGin } 996e2841179SLoGin return ret; 997e2841179SLoGin } 998e2841179SLoGin 999e2841179SLoGin fn irq_request_resources(&self, desc: Arc<IrqDesc>) -> Result<(), SystemError> { 1000e2841179SLoGin let irq_data = desc.irq_data(); 1001e2841179SLoGin let irq_chip = irq_data.chip_info_read_irqsave().chip(); 1002e2841179SLoGin irq_chip.irq_request_resources(&irq_data) 1003e2841179SLoGin } 1004e2841179SLoGin 1005e2841179SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c?r=&mo=59252&fi=2138#1448 1006e2841179SLoGin fn setup_irq_thread( 1007e2841179SLoGin &self, 1008e2841179SLoGin _irq: IrqNumber, 1009e2841179SLoGin _action: &InnerIrqAction, 1010e2841179SLoGin _secondary: bool, 1011e2841179SLoGin ) -> Result<(), SystemError> { 1012e2841179SLoGin // if secondary { 1013e2841179SLoGin // KernelThreadMechanism::create(func, name) 1014e2841179SLoGin // } 1015e2841179SLoGin 1016e2841179SLoGin todo!("setup_irq_thread") 1017e2841179SLoGin } 1018e2841179SLoGin 1019e2841179SLoGin fn setup_forced_threading(&self, _action: &mut InnerIrqAction) -> Result<(), SystemError> { 1020e2841179SLoGin // todo: 处理强制线程化的逻辑,参考linux的`irq_setup_forced_threading()` 1021e2841179SLoGin return Ok(()); 1022e2841179SLoGin } 1023e2841179SLoGin 1024e2841179SLoGin pub fn irq_clear_status_flags( 1025e2841179SLoGin &self, 1026e2841179SLoGin irq: IrqNumber, 1027e2841179SLoGin status: IrqLineStatus, 1028e2841179SLoGin ) -> Result<(), SystemError> { 1029e2841179SLoGin let desc = irq_desc_manager().lookup(irq).ok_or(SystemError::EINVAL)?; 1030e2841179SLoGin desc.modify_status(status, IrqLineStatus::empty()); 1031e2841179SLoGin return Ok(()); 1032e2841179SLoGin } 1033e2841179SLoGin 1034e2841179SLoGin /// 屏蔽中断 1035e2841179SLoGin pub(super) fn mask_irq(&self, irq_data: &Arc<IrqData>) { 1036e2841179SLoGin if irq_data.common_data().status().masked() { 1037e2841179SLoGin return; 1038e2841179SLoGin } 1039e2841179SLoGin 1040e2841179SLoGin let chip = irq_data.chip_info_read_irqsave().chip(); 1041e2841179SLoGin let r = chip.irq_mask(irq_data); 1042e2841179SLoGin 1043e2841179SLoGin if r.is_ok() { 1044e2841179SLoGin irq_data.common_data().set_masked(); 1045e2841179SLoGin } 1046e2841179SLoGin } 1047e2841179SLoGin 1048e2841179SLoGin /// 解除屏蔽中断 1049e2841179SLoGin pub(super) fn unmask_irq(&self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>) { 1050b5b571e0SLoGin if !desc_inner_guard.common_data().status().masked() { 1051e2841179SLoGin return; 1052e2841179SLoGin } 1053e2841179SLoGin 1054e2841179SLoGin let r = desc_inner_guard 1055e2841179SLoGin .irq_data() 1056e2841179SLoGin .chip_info_read_irqsave() 1057e2841179SLoGin .chip() 1058b5b571e0SLoGin .irq_unmask(desc_inner_guard.irq_data()); 1059e2841179SLoGin 1060e2841179SLoGin if let Err(e) = r { 1061e2841179SLoGin if e != SystemError::ENOSYS { 1062e2841179SLoGin kerror!( 1063e2841179SLoGin "Failed to unmask irq {} on irqchip {}, error {:?}", 1064e2841179SLoGin desc_inner_guard.irq_data().irq().data(), 1065e2841179SLoGin desc_inner_guard 1066e2841179SLoGin .irq_data() 1067e2841179SLoGin .chip_info_read_irqsave() 1068e2841179SLoGin .chip() 1069e2841179SLoGin .name(), 1070e2841179SLoGin e 1071e2841179SLoGin ); 1072e2841179SLoGin } 1073e2841179SLoGin } else { 1074e2841179SLoGin desc_inner_guard 1075e2841179SLoGin .common_data() 1076e2841179SLoGin .clear_status(IrqStatus::IRQD_IRQ_MASKED); 1077e2841179SLoGin } 1078e2841179SLoGin } 1079e2841179SLoGin 1080e2841179SLoGin /// 释放使用request_irq分配的中断 1081e2841179SLoGin /// 1082e2841179SLoGin /// ## 参数 1083e2841179SLoGin /// 1084e2841179SLoGin /// - irq: 要释放的中断线 1085e2841179SLoGin /// - dev_id: 要释放的设备身份 1086e2841179SLoGin /// 1087e2841179SLoGin /// ## 返回 1088e2841179SLoGin /// 1089e2841179SLoGin /// 返回传递给request_irq的devname参数 1090e2841179SLoGin /// 1091e2841179SLoGin /// ## 说明 1092e2841179SLoGin /// 1093e2841179SLoGin /// 移除一个中断处理程序。处理程序被移除,如果该中断线不再被任何驱动程序使用,则会被禁用。 1094e2841179SLoGin /// 1095e2841179SLoGin /// 在共享IRQ的情况下,调用者必须确保在调用此功能之前,它在所驱动的卡上禁用了中断。 1096e2841179SLoGin /// 1097e2841179SLoGin /// ## 注意 1098e2841179SLoGin /// 1099e2841179SLoGin /// 此函数不可以在中断上下文中调用。 1100*0102d69fSLoGin /// 1101*0102d69fSLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/irq/manage.c#2026 1102e2841179SLoGin pub fn free_irq(&self, _irq: IrqNumber, _dev_id: Option<Arc<DeviceId>>) { 1103e2841179SLoGin kwarn!("Unimplemented free_irq"); 1104e2841179SLoGin } 1105e2841179SLoGin } 1106e2841179SLoGin 1107e2841179SLoGin enum IrqStartupResult { 1108e2841179SLoGin Normal, 1109e2841179SLoGin Managed, 1110e2841179SLoGin Abort, 1111e2841179SLoGin } 1112e2841179SLoGin /// 默认的初级中断处理函数 1113e2841179SLoGin /// 1114e2841179SLoGin /// 该处理函数仅仅返回`WakeThread`,即唤醒中断线程 1115e2841179SLoGin #[derive(Debug)] 1116e2841179SLoGin struct DefaultPrimaryIrqHandler; 1117e2841179SLoGin 1118e2841179SLoGin impl IrqHandler for DefaultPrimaryIrqHandler { 1119e2841179SLoGin fn handle( 1120e2841179SLoGin &self, 1121e2841179SLoGin _irq: IrqNumber, 1122e2841179SLoGin _static_data: Option<&dyn IrqHandlerData>, 1123e2841179SLoGin _dynamic_data: Option<Arc<dyn IrqHandlerData>>, 1124e2841179SLoGin ) -> Result<IrqReturn, SystemError> { 1125e2841179SLoGin return Ok(IrqReturn::WakeThread); 1126e2841179SLoGin } 1127e2841179SLoGin } 1128e2841179SLoGin 1129e2841179SLoGin /// Primary handler for nested threaded interrupts. 1130e2841179SLoGin /// Should never be called. 1131e2841179SLoGin #[derive(Debug)] 1132e2841179SLoGin struct IrqNestedPrimaryHandler; 1133e2841179SLoGin 1134e2841179SLoGin impl IrqHandler for IrqNestedPrimaryHandler { 1135e2841179SLoGin fn handle( 1136e2841179SLoGin &self, 1137e2841179SLoGin irq: IrqNumber, 1138e2841179SLoGin _static_data: Option<&dyn IrqHandlerData>, 1139e2841179SLoGin _dynamic_data: Option<Arc<dyn IrqHandlerData>>, 1140e2841179SLoGin ) -> Result<IrqReturn, SystemError> { 1141e2841179SLoGin kwarn!("Primary handler called for nested irq {}", irq.data()); 1142e2841179SLoGin return Ok(IrqReturn::NotHandled); 1143e2841179SLoGin } 1144e2841179SLoGin } 1145