13bc96fa4SLoGin use core::{any::Any, fmt::Debug}; 23bc96fa4SLoGin 33bc96fa4SLoGin use alloc::{ 4*196b75dcSLoGin collections::{btree_map, BTreeMap}, 5*196b75dcSLoGin string::{String, ToString}, 63bc96fa4SLoGin sync::{Arc, Weak}, 73bc96fa4SLoGin vec::Vec, 83bc96fa4SLoGin }; 93bc96fa4SLoGin use system_error::SystemError; 103bc96fa4SLoGin 113bc96fa4SLoGin use crate::{ 123bc96fa4SLoGin arch::CurrentIrqArch, 133bc96fa4SLoGin driver::base::{ 143bc96fa4SLoGin device::DeviceId, 153bc96fa4SLoGin kobject::{KObjType, KObject, KObjectState, LockedKObjectState}, 163bc96fa4SLoGin kset::KSet, 173bc96fa4SLoGin }, 183bc96fa4SLoGin filesystem::kernfs::KernFSInode, 193bc96fa4SLoGin libs::{ 203bc96fa4SLoGin rwlock::{RwLockReadGuard, RwLockWriteGuard}, 213bc96fa4SLoGin spinlock::{SpinLock, SpinLockGuard}, 223bc96fa4SLoGin }, 233bc96fa4SLoGin process::ProcessControlBlock, 243bc96fa4SLoGin }; 253bc96fa4SLoGin 263bc96fa4SLoGin use super::{ 273bc96fa4SLoGin dummychip::no_irq_chip, 283bc96fa4SLoGin handle::bad_irq_handler, 293bc96fa4SLoGin irqdata::{IrqCommonData, IrqData, IrqStatus}, 30*196b75dcSLoGin sysfs::{irq_sysfs_del, IrqKObjType}, 313bc96fa4SLoGin HardwareIrqNumber, InterruptArch, IrqNumber, 323bc96fa4SLoGin }; 333bc96fa4SLoGin 343bc96fa4SLoGin /// 中断流处理程序 353bc96fa4SLoGin pub trait IrqFlowHandler: Debug + Send + Sync { 363bc96fa4SLoGin fn handle(&self, irq_desc: &Arc<IrqDesc>); 373bc96fa4SLoGin } 383bc96fa4SLoGin 393bc96fa4SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irqdesc.h#55 403bc96fa4SLoGin #[derive(Debug)] 413bc96fa4SLoGin pub struct IrqDesc { 423bc96fa4SLoGin inner: SpinLock<InnerIrqDesc>, 433bc96fa4SLoGin 443bc96fa4SLoGin handler: SpinLock<Option<&'static dyn IrqFlowHandler>>, 453bc96fa4SLoGin 463bc96fa4SLoGin kobj_state: LockedKObjectState, 473bc96fa4SLoGin } 483bc96fa4SLoGin 493bc96fa4SLoGin impl IrqDesc { 503bc96fa4SLoGin #[inline(never)] 513bc96fa4SLoGin pub fn new(irq: IrqNumber, name: Option<String>, irqd_flags: IrqStatus) -> Arc<Self> { 523bc96fa4SLoGin // 初始化的过程参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdesc.c#392 533bc96fa4SLoGin let common_data = Arc::new(IrqCommonData::new()); 543bc96fa4SLoGin let irq_data = Arc::new(IrqData::new( 553bc96fa4SLoGin irq, 563bc96fa4SLoGin HardwareIrqNumber::new(irq.data()), 573bc96fa4SLoGin common_data.clone(), 583bc96fa4SLoGin no_irq_chip(), 593bc96fa4SLoGin )); 603bc96fa4SLoGin 613bc96fa4SLoGin irq_data.irqd_set(IrqStatus::IRQD_IRQ_DISABLED); 623bc96fa4SLoGin common_data.irqd_set(IrqStatus::IRQD_IRQ_MASKED); 633bc96fa4SLoGin 643bc96fa4SLoGin let irq_desc = IrqDesc { 653bc96fa4SLoGin inner: SpinLock::new(InnerIrqDesc { 663bc96fa4SLoGin common_data, 673bc96fa4SLoGin irq_data, 68*196b75dcSLoGin desc_internal_state: IrqDescState::empty(), 693bc96fa4SLoGin actions: Vec::new(), 703bc96fa4SLoGin name, 713bc96fa4SLoGin parent_irq: None, 723bc96fa4SLoGin depth: 1, 733bc96fa4SLoGin wake_depth: 0, 743bc96fa4SLoGin kern_inode: None, 753bc96fa4SLoGin kset: None, 763bc96fa4SLoGin parent_kobj: None, 773bc96fa4SLoGin }), 783bc96fa4SLoGin handler: SpinLock::new(None), 793bc96fa4SLoGin kobj_state: LockedKObjectState::new(Some(KObjectState::INITIALIZED)), 803bc96fa4SLoGin }; 813bc96fa4SLoGin 823bc96fa4SLoGin irq_desc.set_handler(bad_irq_handler()); 833bc96fa4SLoGin irq_desc.inner().irq_data.irqd_set(irqd_flags); 843bc96fa4SLoGin 853bc96fa4SLoGin return Arc::new(irq_desc); 863bc96fa4SLoGin } 873bc96fa4SLoGin 883bc96fa4SLoGin pub fn set_handler(&self, handler: &'static dyn IrqFlowHandler) { 893bc96fa4SLoGin let mut guard = self.handler.lock_irqsave(); 903bc96fa4SLoGin *guard = Some(handler); 913bc96fa4SLoGin } 923bc96fa4SLoGin 933bc96fa4SLoGin fn inner(&self) -> SpinLockGuard<InnerIrqDesc> { 943bc96fa4SLoGin self.inner.lock_irqsave() 953bc96fa4SLoGin } 963bc96fa4SLoGin 97*196b75dcSLoGin pub fn actions(&self) -> Vec<Arc<IrqAction>> { 98*196b75dcSLoGin self.inner().actions.clone() 99*196b75dcSLoGin } 100*196b75dcSLoGin 1013bc96fa4SLoGin pub fn irq(&self) -> IrqNumber { 1023bc96fa4SLoGin self.inner().irq_data.irq() 1033bc96fa4SLoGin } 104*196b75dcSLoGin 105*196b75dcSLoGin pub fn hardware_irq(&self) -> HardwareIrqNumber { 106*196b75dcSLoGin self.inner().irq_data.hardware_irq() 107*196b75dcSLoGin } 108*196b75dcSLoGin 109*196b75dcSLoGin pub fn irq_data(&self) -> Arc<IrqData> { 110*196b75dcSLoGin self.inner().irq_data.clone() 111*196b75dcSLoGin } 112*196b75dcSLoGin 113*196b75dcSLoGin /// 标记当前irq描述符已经被添加到sysfs 114*196b75dcSLoGin pub fn mark_in_sysfs(&self) { 115*196b75dcSLoGin self.inner() 116*196b75dcSLoGin .desc_internal_state 117*196b75dcSLoGin .insert(IrqDescState::IRQS_SYSFS); 118*196b75dcSLoGin } 119*196b75dcSLoGin 120*196b75dcSLoGin pub fn mark_not_in_sysfs(&self) { 121*196b75dcSLoGin self.inner() 122*196b75dcSLoGin .desc_internal_state 123*196b75dcSLoGin .remove(IrqDescState::IRQS_SYSFS); 124*196b75dcSLoGin } 125*196b75dcSLoGin 126*196b75dcSLoGin /// 判断当前描述符是否已经添加到了sysfs 127*196b75dcSLoGin pub fn in_sysfs(&self) -> bool { 128*196b75dcSLoGin self.inner() 129*196b75dcSLoGin .desc_internal_state 130*196b75dcSLoGin .contains(IrqDescState::IRQS_SYSFS) 131*196b75dcSLoGin } 132*196b75dcSLoGin 133*196b75dcSLoGin pub fn name(&self) -> Option<String> { 134*196b75dcSLoGin self.inner().name.clone() 135*196b75dcSLoGin } 1363bc96fa4SLoGin } 1373bc96fa4SLoGin 1383bc96fa4SLoGin #[allow(dead_code)] 1393bc96fa4SLoGin #[derive(Debug)] 1403bc96fa4SLoGin struct InnerIrqDesc { 1413bc96fa4SLoGin /// per irq and chip data passed down to chip functions 1423bc96fa4SLoGin common_data: Arc<IrqCommonData>, 1433bc96fa4SLoGin irq_data: Arc<IrqData>, 1443bc96fa4SLoGin actions: Vec<Arc<IrqAction>>, 1453bc96fa4SLoGin name: Option<String>, 1463bc96fa4SLoGin parent_irq: Option<IrqNumber>, 1473bc96fa4SLoGin /// nested irq disables 1483bc96fa4SLoGin depth: u32, 1493bc96fa4SLoGin /// nested wake enables 1503bc96fa4SLoGin wake_depth: u32, 151*196b75dcSLoGin desc_internal_state: IrqDescState, 1523bc96fa4SLoGin 1533bc96fa4SLoGin kern_inode: Option<Arc<KernFSInode>>, 1543bc96fa4SLoGin kset: Option<Arc<KSet>>, 1553bc96fa4SLoGin parent_kobj: Option<Weak<dyn KObject>>, 1563bc96fa4SLoGin } 1573bc96fa4SLoGin 1583bc96fa4SLoGin impl KObject for IrqDesc { 1593bc96fa4SLoGin fn as_any_ref(&self) -> &dyn Any { 1603bc96fa4SLoGin self 1613bc96fa4SLoGin } 1623bc96fa4SLoGin 1633bc96fa4SLoGin fn set_inode(&self, inode: Option<Arc<KernFSInode>>) { 1643bc96fa4SLoGin self.inner().kern_inode = inode; 1653bc96fa4SLoGin } 1663bc96fa4SLoGin 1673bc96fa4SLoGin fn inode(&self) -> Option<Arc<KernFSInode>> { 1683bc96fa4SLoGin self.inner().kern_inode.clone() 1693bc96fa4SLoGin } 1703bc96fa4SLoGin 1713bc96fa4SLoGin fn parent(&self) -> Option<Weak<dyn KObject>> { 1723bc96fa4SLoGin self.inner().parent_kobj.clone() 1733bc96fa4SLoGin } 1743bc96fa4SLoGin 1753bc96fa4SLoGin fn set_parent(&self, parent: Option<Weak<dyn KObject>>) { 1763bc96fa4SLoGin self.inner().parent_kobj = parent; 1773bc96fa4SLoGin } 1783bc96fa4SLoGin 1793bc96fa4SLoGin fn kset(&self) -> Option<Arc<KSet>> { 1803bc96fa4SLoGin self.inner().kset.clone() 1813bc96fa4SLoGin } 1823bc96fa4SLoGin 1833bc96fa4SLoGin fn set_kset(&self, kset: Option<Arc<KSet>>) { 1843bc96fa4SLoGin self.inner().kset = kset; 1853bc96fa4SLoGin } 1863bc96fa4SLoGin 1873bc96fa4SLoGin fn kobj_type(&self) -> Option<&'static dyn KObjType> { 1883bc96fa4SLoGin Some(&IrqKObjType) 1893bc96fa4SLoGin } 1903bc96fa4SLoGin 1913bc96fa4SLoGin fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {} 1923bc96fa4SLoGin 1933bc96fa4SLoGin fn name(&self) -> String { 194*196b75dcSLoGin self.inner().irq_data.irq().data().to_string() 1953bc96fa4SLoGin } 1963bc96fa4SLoGin 1973bc96fa4SLoGin fn set_name(&self, _name: String) {} 1983bc96fa4SLoGin 1993bc96fa4SLoGin fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 2003bc96fa4SLoGin self.kobj_state.read() 2013bc96fa4SLoGin } 2023bc96fa4SLoGin 2033bc96fa4SLoGin fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 2043bc96fa4SLoGin self.kobj_state.write() 2053bc96fa4SLoGin } 2063bc96fa4SLoGin 2073bc96fa4SLoGin fn set_kobj_state(&self, state: KObjectState) { 2083bc96fa4SLoGin *self.kobj_state_mut() = state; 2093bc96fa4SLoGin } 2103bc96fa4SLoGin } 2113bc96fa4SLoGin 212*196b75dcSLoGin bitflags! { 213*196b75dcSLoGin /// Bit masks for desc->desc_internal_state 214*196b75dcSLoGin struct IrqDescState: u32 { 215*196b75dcSLoGin /// autodetection in progress 216*196b75dcSLoGin const IRQS_AUTODETECT = 0x00000001; 217*196b75dcSLoGin /// was disabled due to spurious interrupt detection 218*196b75dcSLoGin const IRQS_SPURIOUS_DISABLED = 0x00000002; 219*196b75dcSLoGin /// polling in progress 220*196b75dcSLoGin const IRQS_POLL_INPROGRESS = 0x00000008; 221*196b75dcSLoGin /// irq is not unmasked in primary handler 222*196b75dcSLoGin const IRQS_ONESHOT = 0x00000020; 223*196b75dcSLoGin /// irq is replayed 224*196b75dcSLoGin const IRQS_REPLAY = 0x00000040; 225*196b75dcSLoGin /// irq is waiting 226*196b75dcSLoGin const IRQS_WAITING = 0x00000080; 227*196b75dcSLoGin /// irq is pending and replayed later 228*196b75dcSLoGin const IRQS_PENDING = 0x00000200; 229*196b75dcSLoGin /// irq is suspended 230*196b75dcSLoGin const IRQS_SUSPENDED = 0x00000800; 231*196b75dcSLoGin /// irq line is used to deliver NMIs 232*196b75dcSLoGin const IRQS_NMI = 0x00002000; 233*196b75dcSLoGin /// descriptor has been added to sysfs 234*196b75dcSLoGin const IRQS_SYSFS = 0x00004000; 235*196b75dcSLoGin } 236*196b75dcSLoGin } 237*196b75dcSLoGin 2383bc96fa4SLoGin /// 每个中断的响应动作的描述符 2393bc96fa4SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/interrupt.h#118 2403bc96fa4SLoGin #[allow(dead_code)] 2413bc96fa4SLoGin #[derive(Debug)] 2423bc96fa4SLoGin pub struct IrqAction { 2433bc96fa4SLoGin inner: SpinLock<InnerIrqAction>, 2443bc96fa4SLoGin } 2453bc96fa4SLoGin 2463bc96fa4SLoGin impl IrqAction { 2473bc96fa4SLoGin #[allow(dead_code)] 2483bc96fa4SLoGin pub fn new( 2493bc96fa4SLoGin irq: IrqNumber, 2503bc96fa4SLoGin name: String, 2513bc96fa4SLoGin handler: Option<&'static dyn IrqFlowHandler>, 2523bc96fa4SLoGin ) -> Arc<Self> { 2533bc96fa4SLoGin let action = IrqAction { 2543bc96fa4SLoGin inner: SpinLock::new(InnerIrqAction { 2553bc96fa4SLoGin dev_id: None, 2563bc96fa4SLoGin handler, 2573bc96fa4SLoGin thread_fn: None, 2583bc96fa4SLoGin thread: None, 2593bc96fa4SLoGin secondary: None, 2603bc96fa4SLoGin irq, 2613bc96fa4SLoGin flags: IrqHandleFlags::empty(), 2623bc96fa4SLoGin name, 2633bc96fa4SLoGin }), 2643bc96fa4SLoGin }; 2653bc96fa4SLoGin 2663bc96fa4SLoGin return Arc::new(action); 2673bc96fa4SLoGin } 268*196b75dcSLoGin 269*196b75dcSLoGin pub fn name(&self) -> String { 270*196b75dcSLoGin self.inner().name.clone() 271*196b75dcSLoGin } 272*196b75dcSLoGin 273*196b75dcSLoGin fn inner(&self) -> SpinLockGuard<InnerIrqAction> { 274*196b75dcSLoGin self.inner.lock_irqsave() 275*196b75dcSLoGin } 2763bc96fa4SLoGin } 2773bc96fa4SLoGin 2783bc96fa4SLoGin #[allow(dead_code)] 2793bc96fa4SLoGin #[derive(Debug)] 2803bc96fa4SLoGin struct InnerIrqAction { 2813bc96fa4SLoGin /// cookie to identify the device 2823bc96fa4SLoGin dev_id: Option<DeviceId>, 2833bc96fa4SLoGin /// 中断处理程序 2843bc96fa4SLoGin handler: Option<&'static dyn IrqFlowHandler>, 2853bc96fa4SLoGin /// interrupt handler function for threaded interrupts 2863bc96fa4SLoGin thread_fn: Option<&'static dyn IrqFlowHandler>, 2873bc96fa4SLoGin /// thread pointer for threaded interrupts 2883bc96fa4SLoGin thread: Option<Arc<ProcessControlBlock>>, 2893bc96fa4SLoGin /// pointer to secondary irqaction (force threading) 2903bc96fa4SLoGin secondary: Option<Arc<IrqAction>>, 2913bc96fa4SLoGin /// 中断号 2923bc96fa4SLoGin irq: IrqNumber, 2933bc96fa4SLoGin flags: IrqHandleFlags, 2943bc96fa4SLoGin /// name of the device 2953bc96fa4SLoGin name: String, 2963bc96fa4SLoGin } 2973bc96fa4SLoGin 2983bc96fa4SLoGin // 定义IrqFlags位标志 2993bc96fa4SLoGin bitflags! { 3003bc96fa4SLoGin /// 这些标志仅由内核在中断处理例程中使用。 3013bc96fa4SLoGin pub struct IrqHandleFlags: u32 { 3023bc96fa4SLoGin /// IRQF_SHARED - 允许多个设备共享中断 3033bc96fa4SLoGin const IRQF_SHARED = 0x00000080; 3043bc96fa4SLoGin /// IRQF_PROBE_SHARED - 当预期出现共享不匹配时,由调用者设置 3053bc96fa4SLoGin const IRQF_PROBE_SHARED = 0x00000100; 3063bc96fa4SLoGin /// IRQF_TIMER - 标记此中断为定时器中断 3073bc96fa4SLoGin const __IRQF_TIMER = 0x00000200; 3083bc96fa4SLoGin /// IRQF_PERCPU - 中断是每个CPU的 3093bc96fa4SLoGin const IRQF_PERCPU = 0x00000400; 3103bc96fa4SLoGin /// IRQF_NOBALANCING - 将此中断从中断平衡中排除 3113bc96fa4SLoGin const IRQF_NOBALANCING = 0x00000800; 3123bc96fa4SLoGin /// IRQF_IRQPOLL - 中断用于轮询(出于性能原因,只有在共享中断中首次注册的中断会被考虑) 3133bc96fa4SLoGin const IRQF_IRQPOLL = 0x00001000; 3143bc96fa4SLoGin /// IRQF_ONESHOT - 在硬中断处理程序完成后,不会重新启用中断。由需要在运行线程处理程序之前保持中断线路禁用的线程中断使用。 3153bc96fa4SLoGin const IRQF_ONESHOT = 0x00002000; 3163bc96fa4SLoGin /// IRQF_NO_SUSPEND - 在挂起期间不禁用此IRQ。不能保证此中断会从挂起状态唤醒系统。 3173bc96fa4SLoGin const IRQF_NO_SUSPEND = 0x00004000; 3183bc96fa4SLoGin /// IRQF_FORCE_RESUME - 即使设置了IRQF_NO_SUSPEND,也强制在恢复时启用它 3193bc96fa4SLoGin const IRQF_FORCE_RESUME = 0x00008000; 3203bc96fa4SLoGin /// IRQF_NO_THREAD - 中断不能被线程化 3213bc96fa4SLoGin const IRQF_NO_THREAD = 0x00010000; 3223bc96fa4SLoGin /// IRQF_EARLY_RESUME - 在syscore而不是在设备恢复时间早期恢复IRQ。 3233bc96fa4SLoGin const IRQF_EARLY_RESUME = 0x00020000; 3243bc96fa4SLoGin /// IRQF_COND_SUSPEND - 如果IRQ与NO_SUSPEND用户共享,则在挂起中断后执行此中断处理程序。对于系统唤醒设备用户,需要在他们的中断处理程序中实现唤醒检测。 3253bc96fa4SLoGin const IRQF_COND_SUSPEND = 0x00040000; 3263bc96fa4SLoGin /// IRQF_NO_AUTOEN - 当用户请求时,不会自动启用IRQ或NMI。用户稍后会通过enable_irq()或enable_nmi()显式启用它。 3273bc96fa4SLoGin const IRQF_NO_AUTOEN = 0x00080000; 3283bc96fa4SLoGin /// IRQF_NO_DEBUG - 从IPI和类似处理程序的逃逸检测中排除,取决于IRQF_PERCPU。 3293bc96fa4SLoGin const IRQF_NO_DEBUG = 0x00100000; 3303bc96fa4SLoGin const IRQF_TIMER = Self::__IRQF_TIMER.bits | Self::IRQF_NO_SUSPEND.bits | Self::IRQF_NO_THREAD.bits; 3313bc96fa4SLoGin } 3323bc96fa4SLoGin } 3333bc96fa4SLoGin 3343bc96fa4SLoGin #[inline(never)] 3353bc96fa4SLoGin pub(super) fn early_irq_init() -> Result<(), SystemError> { 3363bc96fa4SLoGin let irqcnt = CurrentIrqArch::probe_total_irq_num(); 3373bc96fa4SLoGin let mut manager = IrqDescManager::new(); 3383bc96fa4SLoGin for i in 0..irqcnt { 3393bc96fa4SLoGin let irq_desc = IrqDesc::new(IrqNumber::new(i), None, IrqStatus::empty()); 3403bc96fa4SLoGin manager.insert(IrqNumber::new(i), irq_desc); 3413bc96fa4SLoGin } 3423bc96fa4SLoGin 343*196b75dcSLoGin unsafe { 344*196b75dcSLoGin IRQ_DESC_MANAGER = Some(manager); 345*196b75dcSLoGin } 346*196b75dcSLoGin 3473bc96fa4SLoGin return CurrentIrqArch::arch_early_irq_init(); 3483bc96fa4SLoGin } 3493bc96fa4SLoGin 350*196b75dcSLoGin static mut IRQ_DESC_MANAGER: Option<IrqDescManager> = None; 351*196b75dcSLoGin 352*196b75dcSLoGin /// 获取中断描述符管理器的引用 353*196b75dcSLoGin #[inline(always)] 354*196b75dcSLoGin pub(super) fn irq_desc_manager() -> &'static IrqDescManager { 355*196b75dcSLoGin return unsafe { IRQ_DESC_MANAGER.as_ref().unwrap() }; 356*196b75dcSLoGin } 357*196b75dcSLoGin 3583bc96fa4SLoGin pub(super) struct IrqDescManager { 3593bc96fa4SLoGin irq_descs: BTreeMap<IrqNumber, Arc<IrqDesc>>, 3603bc96fa4SLoGin } 3613bc96fa4SLoGin 3623bc96fa4SLoGin impl IrqDescManager { 3633bc96fa4SLoGin fn new() -> Self { 3643bc96fa4SLoGin IrqDescManager { 3653bc96fa4SLoGin irq_descs: BTreeMap::new(), 3663bc96fa4SLoGin } 3673bc96fa4SLoGin } 3683bc96fa4SLoGin 3693bc96fa4SLoGin /// 查找中断描述符 3703bc96fa4SLoGin #[allow(dead_code)] 3713bc96fa4SLoGin pub fn lookup(&self, irq: IrqNumber) -> Option<Arc<IrqDesc>> { 3723bc96fa4SLoGin self.irq_descs.get(&irq).map(|desc| desc.clone()) 3733bc96fa4SLoGin } 3743bc96fa4SLoGin 3753bc96fa4SLoGin fn insert(&mut self, irq: IrqNumber, desc: Arc<IrqDesc>) { 3763bc96fa4SLoGin self.irq_descs.insert(irq, desc); 3773bc96fa4SLoGin } 378*196b75dcSLoGin 379*196b75dcSLoGin /// 释放中断描述符 380*196b75dcSLoGin #[allow(dead_code)] 381*196b75dcSLoGin fn free_desc(&mut self, irq: IrqNumber) { 382*196b75dcSLoGin if let Some(desc) = self.irq_descs.get(&irq) { 383*196b75dcSLoGin irq_sysfs_del(desc); 384*196b75dcSLoGin self.irq_descs.remove(&irq); 385*196b75dcSLoGin } 386*196b75dcSLoGin } 387*196b75dcSLoGin 388*196b75dcSLoGin /// 迭代中断描述符 389*196b75dcSLoGin pub fn iter_descs(&self) -> btree_map::Iter<'_, IrqNumber, Arc<IrqDesc>> { 390*196b75dcSLoGin self.irq_descs.iter() 391*196b75dcSLoGin } 3923bc96fa4SLoGin } 393