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