1ce5850adSLoGin use core::{any::Any, fmt::Debug}; 2ce5850adSLoGin 3ce5850adSLoGin use alloc::sync::{Arc, Weak}; 4e2841179SLoGin use intertrait::CastFromSync; 5ce5850adSLoGin 6e2841179SLoGin use crate::libs::{ 7e2841179SLoGin cpumask::CpuMask, 8e2841179SLoGin rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}, 9e2841179SLoGin spinlock::{SpinLock, SpinLockGuard}, 10e2841179SLoGin }; 11ce5850adSLoGin 12ce5850adSLoGin use super::{ 13ce5850adSLoGin irqchip::{IrqChip, IrqChipData}, 14f049d1afSLoGin irqdesc::IrqDesc, 15ce5850adSLoGin irqdomain::IrqDomain, 16ce5850adSLoGin msi::MsiDesc, 17ce5850adSLoGin HardwareIrqNumber, IrqNumber, 18ce5850adSLoGin }; 19ce5850adSLoGin 20ce5850adSLoGin /// per irq chip data passed down to chip functions 21ce5850adSLoGin /// 22ce5850adSLoGin /// 该结构体用于表示每个Irq的私有数据,且与具体的中断芯片绑定 23ce5850adSLoGin /// 24ce5850adSLoGin /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h#179 25ce5850adSLoGin #[allow(dead_code)] 26ce5850adSLoGin #[derive(Debug)] 27ce5850adSLoGin pub struct IrqData { 28ce5850adSLoGin /// 中断号, 用于表示软件逻辑视角的中断号,全局唯一 29ce5850adSLoGin irq: IrqNumber, 303bc96fa4SLoGin inner: SpinLock<InnerIrqData>, 31e2841179SLoGin 32e2841179SLoGin chip_info: RwLock<InnerIrqChipInfo>, 333bc96fa4SLoGin } 343bc96fa4SLoGin 353bc96fa4SLoGin impl IrqData { new( irq: IrqNumber, hwirq: HardwareIrqNumber, common_data: Arc<IrqCommonData>, chip: Arc<dyn IrqChip>, ) -> Self363bc96fa4SLoGin pub fn new( 373bc96fa4SLoGin irq: IrqNumber, 383bc96fa4SLoGin hwirq: HardwareIrqNumber, 393bc96fa4SLoGin common_data: Arc<IrqCommonData>, 403bc96fa4SLoGin chip: Arc<dyn IrqChip>, 413bc96fa4SLoGin ) -> Self { 423bc96fa4SLoGin return IrqData { 433bc96fa4SLoGin irq, 443bc96fa4SLoGin inner: SpinLock::new(InnerIrqData { 453bc96fa4SLoGin hwirq, 463bc96fa4SLoGin common_data, 47f049d1afSLoGin desc: Weak::new(), 483bc96fa4SLoGin domain: None, 493bc96fa4SLoGin parent_data: None, 503bc96fa4SLoGin }), 51e2841179SLoGin chip_info: RwLock::new(InnerIrqChipInfo { 52e2841179SLoGin chip: Some(chip), 53e2841179SLoGin chip_data: None, 54e2841179SLoGin }), 553bc96fa4SLoGin }; 563bc96fa4SLoGin } 573bc96fa4SLoGin irqd_set(&self, status: IrqStatus)583bc96fa4SLoGin pub fn irqd_set(&self, status: IrqStatus) { 593bc96fa4SLoGin // clone是为了释放inner锁 60e2841179SLoGin let common_data = self.inner.lock_irqsave().common_data.clone(); 61e2841179SLoGin common_data.insert_status(status); 623bc96fa4SLoGin } 633bc96fa4SLoGin 643bc96fa4SLoGin #[allow(dead_code)] irqd_clear(&self, status: IrqStatus)653bc96fa4SLoGin pub fn irqd_clear(&self, status: IrqStatus) { 663bc96fa4SLoGin // clone是为了释放inner锁 67e2841179SLoGin let common_data = self.inner.lock_irqsave().common_data.clone(); 68e2841179SLoGin common_data.clear_status(status); 693bc96fa4SLoGin } 703bc96fa4SLoGin irq(&self) -> IrqNumber713bc96fa4SLoGin pub fn irq(&self) -> IrqNumber { 723bc96fa4SLoGin self.irq 733bc96fa4SLoGin } 74196b75dcSLoGin irq_desc(&self) -> Option<Arc<IrqDesc>>75f049d1afSLoGin pub fn irq_desc(&self) -> Option<Arc<IrqDesc>> { 76f049d1afSLoGin self.inner.lock_irqsave().desc.upgrade() 77f049d1afSLoGin } 78f049d1afSLoGin set_irq_desc(&self, desc: Weak<IrqDesc>)79f049d1afSLoGin pub fn set_irq_desc(&self, desc: Weak<IrqDesc>) { 80f049d1afSLoGin self.inner.lock_irqsave().desc = desc; 81f049d1afSLoGin } 82f049d1afSLoGin 83*0102d69fSLoGin #[allow(dead_code)] clear_irq_desc(&self)84f049d1afSLoGin pub fn clear_irq_desc(&self) { 85f049d1afSLoGin self.inner.lock_irqsave().desc = Weak::new(); 86f049d1afSLoGin } 87f049d1afSLoGin hardware_irq(&self) -> HardwareIrqNumber88196b75dcSLoGin pub fn hardware_irq(&self) -> HardwareIrqNumber { 89196b75dcSLoGin self.inner.lock_irqsave().hwirq 90196b75dcSLoGin } 91196b75dcSLoGin 92196b75dcSLoGin /// 是否为电平触发 is_level_type(&self) -> bool93196b75dcSLoGin pub fn is_level_type(&self) -> bool { 94196b75dcSLoGin self.inner 95196b75dcSLoGin .lock_irqsave() 96196b75dcSLoGin .common_data 97196b75dcSLoGin .inner 98e2841179SLoGin .lock_irqsave() 99196b75dcSLoGin .state 100196b75dcSLoGin .is_level_type() 101196b75dcSLoGin } 102196b75dcSLoGin is_wakeup_set(&self) -> bool103196b75dcSLoGin pub fn is_wakeup_set(&self) -> bool { 104196b75dcSLoGin self.inner 105196b75dcSLoGin .lock_irqsave() 106196b75dcSLoGin .common_data 107196b75dcSLoGin .inner 108e2841179SLoGin .lock_irqsave() 109196b75dcSLoGin .state 110196b75dcSLoGin .is_wakeup_set() 111196b75dcSLoGin } 112e2841179SLoGin common_data(&self) -> Arc<IrqCommonData>113e2841179SLoGin pub fn common_data(&self) -> Arc<IrqCommonData> { 114e2841179SLoGin self.inner.lock_irqsave().common_data.clone() 115e2841179SLoGin } 116e2841179SLoGin domain(&self) -> Option<Arc<IrqDomain>>117e2841179SLoGin pub fn domain(&self) -> Option<Arc<IrqDomain>> { 118e2841179SLoGin self.inner.lock_irqsave().domain.clone() 119e2841179SLoGin } 120e2841179SLoGin inner(&self) -> SpinLockGuard<InnerIrqData>121e2841179SLoGin pub fn inner(&self) -> SpinLockGuard<InnerIrqData> { 122e2841179SLoGin self.inner.lock_irqsave() 123e2841179SLoGin } 124e2841179SLoGin chip_info_read(&self) -> RwLockReadGuard<InnerIrqChipInfo>125e2841179SLoGin pub fn chip_info_read(&self) -> RwLockReadGuard<InnerIrqChipInfo> { 126e2841179SLoGin self.chip_info.read() 127e2841179SLoGin } 128e2841179SLoGin chip_info_read_irqsave(&self) -> RwLockReadGuard<InnerIrqChipInfo>129e2841179SLoGin pub fn chip_info_read_irqsave(&self) -> RwLockReadGuard<InnerIrqChipInfo> { 130e2841179SLoGin self.chip_info.read_irqsave() 131e2841179SLoGin } 132e2841179SLoGin chip_info_write_irqsave(&self) -> RwLockWriteGuard<InnerIrqChipInfo>133e2841179SLoGin pub fn chip_info_write_irqsave(&self) -> RwLockWriteGuard<InnerIrqChipInfo> { 134e2841179SLoGin self.chip_info.write_irqsave() 135e2841179SLoGin } 136e2841179SLoGin parent_data(&self) -> Option<Weak<IrqData>>137e2841179SLoGin pub fn parent_data(&self) -> Option<Weak<IrqData>> { 138e2841179SLoGin self.inner.lock_irqsave().parent_data.clone() 139e2841179SLoGin } 1403bc96fa4SLoGin } 1413bc96fa4SLoGin 1423bc96fa4SLoGin #[allow(dead_code)] 1433bc96fa4SLoGin #[derive(Debug)] 144e2841179SLoGin pub struct InnerIrqData { 145ce5850adSLoGin /// 硬件中断号, 用于表示在某个IrqDomain中的中断号 146ce5850adSLoGin hwirq: HardwareIrqNumber, 147ce5850adSLoGin /// 涉及的所有irqchip之间共享的数据 148ce5850adSLoGin common_data: Arc<IrqCommonData>, 149e2841179SLoGin 150f049d1afSLoGin desc: Weak<IrqDesc>, 151f049d1afSLoGin 152ce5850adSLoGin /// 中断域 1533bc96fa4SLoGin domain: Option<Arc<IrqDomain>>, 154ce5850adSLoGin /// 中断的父中断(如果具有中断域继承的话) 155ce5850adSLoGin parent_data: Option<Weak<IrqData>>, 156ce5850adSLoGin } 157ce5850adSLoGin 158e2841179SLoGin impl InnerIrqData { set_hwirq(&mut self, hwirq: HardwareIrqNumber)159e2841179SLoGin pub fn set_hwirq(&mut self, hwirq: HardwareIrqNumber) { 160e2841179SLoGin self.hwirq = hwirq; 161e2841179SLoGin } 162e2841179SLoGin 163e2841179SLoGin #[allow(dead_code)] domain(&self) -> Option<Arc<IrqDomain>>164e2841179SLoGin pub fn domain(&self) -> Option<Arc<IrqDomain>> { 165e2841179SLoGin self.domain.clone() 166e2841179SLoGin } 167e2841179SLoGin set_domain(&mut self, domain: Option<Arc<IrqDomain>>)168e2841179SLoGin pub fn set_domain(&mut self, domain: Option<Arc<IrqDomain>>) { 169e2841179SLoGin self.domain = domain; 170e2841179SLoGin } 171e2841179SLoGin } 172e2841179SLoGin 173e2841179SLoGin #[derive(Debug)] 174e2841179SLoGin pub struct InnerIrqChipInfo { 175e2841179SLoGin /// 绑定到的中断芯片 176e2841179SLoGin chip: Option<Arc<dyn IrqChip>>, 177e2841179SLoGin /// 中断芯片的私有数据(与当前irq相关) 178e2841179SLoGin chip_data: Option<Arc<dyn IrqChipData>>, 179e2841179SLoGin } 180e2841179SLoGin 181e2841179SLoGin impl InnerIrqChipInfo { set_chip(&mut self, chip: Option<Arc<dyn IrqChip>>)182e2841179SLoGin pub fn set_chip(&mut self, chip: Option<Arc<dyn IrqChip>>) { 183e2841179SLoGin self.chip = chip; 184e2841179SLoGin } 185e2841179SLoGin set_chip_data(&mut self, chip_data: Option<Arc<dyn IrqChipData>>)186e2841179SLoGin pub fn set_chip_data(&mut self, chip_data: Option<Arc<dyn IrqChipData>>) { 187e2841179SLoGin self.chip_data = chip_data; 188e2841179SLoGin } 189e2841179SLoGin chip(&self) -> Arc<dyn IrqChip>190e2841179SLoGin pub fn chip(&self) -> Arc<dyn IrqChip> { 191e2841179SLoGin self.chip.clone().unwrap() 192e2841179SLoGin } 193e2841179SLoGin chip_data(&self) -> Option<Arc<dyn IrqChipData>>194e2841179SLoGin pub fn chip_data(&self) -> Option<Arc<dyn IrqChipData>> { 195e2841179SLoGin self.chip_data.clone() 196e2841179SLoGin } 197e2841179SLoGin } 198e2841179SLoGin 199ce5850adSLoGin /// per irq data shared by all irqchips 200ce5850adSLoGin /// 201ce5850adSLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h#147 202ce5850adSLoGin #[derive(Debug)] 203ce5850adSLoGin pub struct IrqCommonData { 204ce5850adSLoGin inner: SpinLock<InnerIrqCommonData>, 205ce5850adSLoGin } 206ce5850adSLoGin 2073bc96fa4SLoGin impl IrqCommonData { new() -> Self2083bc96fa4SLoGin pub fn new() -> Self { 2093bc96fa4SLoGin let inner = InnerIrqCommonData { 2103bc96fa4SLoGin state: IrqStatus::empty(), 2113bc96fa4SLoGin handler_data: None, 2123bc96fa4SLoGin msi_desc: None, 213e2841179SLoGin affinity: CpuMask::new(), 214*0102d69fSLoGin effective_affinity: CpuMask::new(), 2153bc96fa4SLoGin }; 2163bc96fa4SLoGin return IrqCommonData { 2173bc96fa4SLoGin inner: SpinLock::new(inner), 2183bc96fa4SLoGin }; 2193bc96fa4SLoGin } 2203bc96fa4SLoGin insert_status(&self, status: IrqStatus)221e2841179SLoGin pub fn insert_status(&self, status: IrqStatus) { 222e2841179SLoGin self.inner.lock_irqsave().irqd_insert(status); 2233bc96fa4SLoGin } 2243bc96fa4SLoGin clear_status(&self, status: IrqStatus)225e2841179SLoGin pub fn clear_status(&self, status: IrqStatus) { 2263bc96fa4SLoGin self.inner.lock_irqsave().irqd_clear(status); 2273bc96fa4SLoGin } 228e2841179SLoGin clear_managed_shutdown(&self)229e2841179SLoGin pub fn clear_managed_shutdown(&self) { 230e2841179SLoGin self.inner 231e2841179SLoGin .lock_irqsave() 232e2841179SLoGin .state 233e2841179SLoGin .remove(IrqStatus::IRQD_MANAGED_SHUTDOWN); 234e2841179SLoGin } 235e2841179SLoGin 236e2841179SLoGin #[allow(dead_code)] masked(&self) -> bool237e2841179SLoGin pub fn masked(&self) -> bool { 238e2841179SLoGin self.inner.lock_irqsave().state.masked() 239e2841179SLoGin } 240e2841179SLoGin set_masked(&self)241e2841179SLoGin pub fn set_masked(&self) { 242e2841179SLoGin self.inner 243e2841179SLoGin .lock_irqsave() 244e2841179SLoGin .state 245e2841179SLoGin .insert(IrqStatus::IRQD_IRQ_MASKED); 246e2841179SLoGin } 247e2841179SLoGin clear_masked(&self)248e2841179SLoGin pub fn clear_masked(&self) { 249e2841179SLoGin self.clear_status(IrqStatus::IRQD_IRQ_MASKED); 250e2841179SLoGin } 251e2841179SLoGin set_inprogress(&self)252e2841179SLoGin pub fn set_inprogress(&self) { 253e2841179SLoGin self.inner 254e2841179SLoGin .lock_irqsave() 255e2841179SLoGin .state 256e2841179SLoGin .insert(IrqStatus::IRQD_IRQ_INPROGRESS); 257e2841179SLoGin } 258e2841179SLoGin clear_inprogress(&self)259e2841179SLoGin pub fn clear_inprogress(&self) { 260e2841179SLoGin self.inner 261e2841179SLoGin .lock_irqsave() 262e2841179SLoGin .state 263e2841179SLoGin .remove(IrqStatus::IRQD_IRQ_INPROGRESS); 264e2841179SLoGin } 265e2841179SLoGin disabled(&self) -> bool266e2841179SLoGin pub fn disabled(&self) -> bool { 267e2841179SLoGin self.inner.lock_irqsave().state.disabled() 268e2841179SLoGin } 269e2841179SLoGin 270e2841179SLoGin #[allow(dead_code)] set_disabled(&self)271e2841179SLoGin pub fn set_disabled(&self) { 272e2841179SLoGin self.inner 273e2841179SLoGin .lock_irqsave() 274e2841179SLoGin .state 275e2841179SLoGin .insert(IrqStatus::IRQD_IRQ_DISABLED); 276e2841179SLoGin } 277e2841179SLoGin clear_disabled(&self)278e2841179SLoGin pub fn clear_disabled(&self) { 279e2841179SLoGin self.clear_status(IrqStatus::IRQD_IRQ_DISABLED); 280e2841179SLoGin } 281e2841179SLoGin status(&self) -> IrqStatus282e2841179SLoGin pub fn status(&self) -> IrqStatus { 283e2841179SLoGin self.inner.lock_irqsave().state 284e2841179SLoGin } 285e2841179SLoGin trigger_type(&self) -> IrqLineStatus286e2841179SLoGin pub fn trigger_type(&self) -> IrqLineStatus { 287e2841179SLoGin self.inner.lock_irqsave().state.trigger_type() 288e2841179SLoGin } 289e2841179SLoGin set_trigger_type(&self, trigger: IrqLineStatus)290e2841179SLoGin pub fn set_trigger_type(&self, trigger: IrqLineStatus) { 291e2841179SLoGin self.inner.lock_irqsave().state.set_trigger_type(trigger); 292e2841179SLoGin } 293e2841179SLoGin set_started(&self)294e2841179SLoGin pub fn set_started(&self) { 295e2841179SLoGin self.inner 296e2841179SLoGin .lock_irqsave() 297e2841179SLoGin .state 298e2841179SLoGin .insert(IrqStatus::IRQD_IRQ_STARTED); 299e2841179SLoGin } 300e2841179SLoGin affinity(&self) -> CpuMask301e2841179SLoGin pub fn affinity(&self) -> CpuMask { 302e2841179SLoGin self.inner.lock_irqsave().affinity.clone() 303e2841179SLoGin } 304e2841179SLoGin set_affinity(&self, affinity: CpuMask)305e2841179SLoGin pub fn set_affinity(&self, affinity: CpuMask) { 306e2841179SLoGin self.inner.lock_irqsave().affinity = affinity; 307e2841179SLoGin } 308338f6903SLoGin set_effective_affinity(&self, affinity: CpuMask)309*0102d69fSLoGin pub fn set_effective_affinity(&self, affinity: CpuMask) { 310*0102d69fSLoGin self.inner.lock_irqsave().effective_affinity = affinity; 311*0102d69fSLoGin } 312*0102d69fSLoGin inner(&self) -> SpinLockGuard<InnerIrqCommonData>313338f6903SLoGin pub fn inner(&self) -> SpinLockGuard<InnerIrqCommonData> { 314338f6903SLoGin self.inner.lock_irqsave() 315338f6903SLoGin } 3163bc96fa4SLoGin } 3173bc96fa4SLoGin 318ce5850adSLoGin #[allow(dead_code)] 319ce5850adSLoGin #[derive(Debug)] 320338f6903SLoGin pub struct InnerIrqCommonData { 321ce5850adSLoGin /// status information for irq chip functions. 322ce5850adSLoGin state: IrqStatus, 323ce5850adSLoGin /// per-IRQ data for the irq_chip methods 324ce5850adSLoGin handler_data: Option<Arc<dyn IrqHandlerData>>, 325ce5850adSLoGin msi_desc: Option<Arc<MsiDesc>>, 326e2841179SLoGin affinity: CpuMask, 327*0102d69fSLoGin effective_affinity: CpuMask, 328ce5850adSLoGin } 329ce5850adSLoGin 3303bc96fa4SLoGin impl InnerIrqCommonData { irqd_insert(&mut self, status: IrqStatus)331e2841179SLoGin pub fn irqd_insert(&mut self, status: IrqStatus) { 3323bc96fa4SLoGin self.state.insert(status); 3333bc96fa4SLoGin } 3343bc96fa4SLoGin irqd_clear(&mut self, status: IrqStatus)3353bc96fa4SLoGin pub fn irqd_clear(&mut self, status: IrqStatus) { 3363bc96fa4SLoGin self.state.remove(status); 3373bc96fa4SLoGin } 338338f6903SLoGin 339338f6903SLoGin #[allow(dead_code)] set_handler_data(&mut self, handler_data: Option<Arc<dyn IrqHandlerData>>)340338f6903SLoGin pub fn set_handler_data(&mut self, handler_data: Option<Arc<dyn IrqHandlerData>>) { 341338f6903SLoGin self.handler_data = handler_data; 342338f6903SLoGin } 343338f6903SLoGin 344338f6903SLoGin #[allow(dead_code)] handler_data(&self) -> Option<Arc<dyn IrqHandlerData>>345338f6903SLoGin pub fn handler_data(&self) -> Option<Arc<dyn IrqHandlerData>> { 346338f6903SLoGin self.handler_data.clone() 347338f6903SLoGin } 348*0102d69fSLoGin effective_affinity(&self) -> &CpuMask349*0102d69fSLoGin pub fn effective_affinity(&self) -> &CpuMask { 350*0102d69fSLoGin &self.effective_affinity 351*0102d69fSLoGin } 3523bc96fa4SLoGin } 3533bc96fa4SLoGin 354e2841179SLoGin /// 中断处理函数传入的数据 355e2841179SLoGin pub trait IrqHandlerData: Send + Sync + Any + Debug + CastFromSync {} 356ce5850adSLoGin 357ce5850adSLoGin bitflags! { 358ce5850adSLoGin /// 中断线状态 359ce5850adSLoGin /// https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h?fi=IRQ_TYPE_PROBE#77 360b5b571e0SLoGin #[allow(clippy::bad_bit_mask)] 361ce5850adSLoGin pub struct IrqLineStatus: u32 { 362ce5850adSLoGin /// 默认,未指明类型 363ce5850adSLoGin const IRQ_TYPE_NONE = 0x00000000; 364ce5850adSLoGin /// 上升沿触发 365ce5850adSLoGin const IRQ_TYPE_EDGE_RISING = 0x00000001; 366ce5850adSLoGin /// 下降沿触发 367ce5850adSLoGin const IRQ_TYPE_EDGE_FALLING = 0x00000002; 368ce5850adSLoGin /// 上升沿和下降沿触发 369ce5850adSLoGin const IRQ_TYPE_EDGE_BOTH = Self::IRQ_TYPE_EDGE_RISING.bits | Self::IRQ_TYPE_EDGE_FALLING.bits; 370ce5850adSLoGin /// 高电平触发 371ce5850adSLoGin const IRQ_TYPE_LEVEL_HIGH = 0x00000004; 372ce5850adSLoGin /// 低电平触发 373ce5850adSLoGin const IRQ_TYPE_LEVEL_LOW = 0x00000008; 374ce5850adSLoGin /// 过滤掉电平位的掩码 375ce5850adSLoGin const IRQ_TYPE_LEVEL_MASK = Self::IRQ_TYPE_LEVEL_LOW.bits | Self::IRQ_TYPE_LEVEL_HIGH.bits; 376ce5850adSLoGin /// 上述位掩码的掩码 377ce5850adSLoGin const IRQ_TYPE_SENSE_MASK = 0x0000000f; 378ce5850adSLoGin /// 某些PICs使用此类型要求 `IrqChip::irq_set_type()` 设置硬件到一个合理的默认值 379ce5850adSLoGin /// (由irqdomain的map()回调使用,以便为新分配的描述符同步硬件状态和软件标志位)。 380ce5850adSLoGin const IRQ_TYPE_DEFAULT = Self::IRQ_TYPE_SENSE_MASK.bits; 381ce5850adSLoGin 382ce5850adSLoGin /// 特定于探测的过程中的特殊标志 383ce5850adSLoGin const IRQ_TYPE_PROBE = 0x00000010; 384ce5850adSLoGin 385ce5850adSLoGin /// 中断是电平类型。当上述触发位通过`IrqChip::irq_set_type()` 修改时,也会在代码中更新 386ce5850adSLoGin const IRQ_LEVEL = 1 << 8; 387ce5850adSLoGin /// 标记一个PER_CPU的中断。将保护其免受亲和性设置的影响 388ce5850adSLoGin const IRQ_PER_CPU = 1 << 9; 389ce5850adSLoGin /// 中断不能被自动探测 390ce5850adSLoGin const IRQ_NOPROBE = 1 << 10; 391ce5850adSLoGin /// 中断不能通过request_irq()请求 392ce5850adSLoGin const IRQ_NOREQUEST = 1 << 11; 393ce5850adSLoGin /// 中断在request/setup_irq()中不会自动启用 394ce5850adSLoGin const IRQ_NOAUTOEN = 1 << 12; 395ce5850adSLoGin /// 中断不能被平衡(亲和性设置) 396ce5850adSLoGin const IRQ_NO_BALANCING = 1 << 13; 397ce5850adSLoGin /// 中断可以从进程上下文中迁移 398ce5850adSLoGin const IRQ_MOVE_PCNTXT = 1 << 14; 399ce5850adSLoGin /// 中断嵌套在另一个线程中 400ce5850adSLoGin const IRQ_NESTED_THREAD = 1 << 15; 401ce5850adSLoGin /// 中断不能被线程化 402ce5850adSLoGin const IRQ_NOTHREAD = 1 << 16; 403ce5850adSLoGin /// Dev_id是一个per-CPU变量 404ce5850adSLoGin const IRQ_PER_CPU_DEVID = 1 << 17; 405ce5850adSLoGin /// 总是由另一个中断轮询。将其从错误的中断检测机制和核心侧轮询中排除 406ce5850adSLoGin const IRQ_IS_POLLED = 1 << 18; 407ce5850adSLoGin /// 禁用延迟的中断禁用 (Disable lazy irq disable) 408ce5850adSLoGin const IRQ_DISABLE_UNLAZY = 1 << 19; 409ce5850adSLoGin /// 在/proc/interrupts中不显示 410ce5850adSLoGin const IRQ_HIDDEN = 1 << 20; 411ce5850adSLoGin /// 从note_interrupt()调试中排除 412ce5850adSLoGin const IRQ_NO_DEBUG = 1 << 21; 413ce5850adSLoGin } 414ce5850adSLoGin 415ce5850adSLoGin 416ce5850adSLoGin 417ce5850adSLoGin } 418e2841179SLoGin 419e2841179SLoGin impl IrqLineStatus { trigger_bits(&self) -> u32420e2841179SLoGin pub const fn trigger_bits(&self) -> u32 { 421e2841179SLoGin self.bits & Self::IRQ_TYPE_SENSE_MASK.bits 422e2841179SLoGin } 423e2841179SLoGin trigger_type(&self) -> Self424e2841179SLoGin pub fn trigger_type(&self) -> Self { 425e2841179SLoGin *self & Self::IRQ_TYPE_SENSE_MASK 426e2841179SLoGin } 427e2841179SLoGin is_level_type(&self) -> bool428e2841179SLoGin pub fn is_level_type(&self) -> bool { 429e2841179SLoGin self.contains(Self::IRQ_LEVEL) 430e2841179SLoGin } 431e2841179SLoGin 432e2841179SLoGin /// 是否为高电平触发 433e2841179SLoGin /// 434e2841179SLoGin /// ## 返回 435e2841179SLoGin /// 436e2841179SLoGin /// - 如果不是电平触发类型,则返回None 437e2841179SLoGin /// - 如果是电平触发类型,则返回Some(bool),当为true时表示高电平触发 438f049d1afSLoGin #[allow(dead_code)] is_level_high(&self) -> Option<bool>439e2841179SLoGin pub fn is_level_high(&self) -> Option<bool> { 440e2841179SLoGin if !self.is_level_type() { 441e2841179SLoGin return None; 442e2841179SLoGin } 443e2841179SLoGin return Some(self.contains(Self::IRQ_TYPE_LEVEL_HIGH)); 444e2841179SLoGin } 445338f6903SLoGin 446338f6903SLoGin #[allow(dead_code)] is_per_cpu_devid(&self) -> bool447338f6903SLoGin pub fn is_per_cpu_devid(&self) -> bool { 448338f6903SLoGin self.contains(Self::IRQ_PER_CPU_DEVID) 449338f6903SLoGin } 450e2841179SLoGin } 451b5b571e0SLoGin 452ce5850adSLoGin bitflags! { 453ce5850adSLoGin /// 中断状态(存储在IrqCommonData) 454ce5850adSLoGin /// 455ce5850adSLoGin /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h#227 456b5b571e0SLoGin #[allow(clippy::bad_bit_mask)] 457ce5850adSLoGin pub struct IrqStatus: u32 { 458e2841179SLoGin const IRQD_TRIGGER_NONE = IrqLineStatus::IRQ_TYPE_NONE.bits(); 459e2841179SLoGin const IRQD_TRIGGER_RISING = IrqLineStatus::IRQ_TYPE_EDGE_RISING.bits(); 460e2841179SLoGin const IRQD_TRIGGER_FALLING = IrqLineStatus::IRQ_TYPE_EDGE_FALLING.bits(); 461e2841179SLoGin const IRQD_TRIGGER_HIGH = IrqLineStatus::IRQ_TYPE_LEVEL_HIGH.bits(); 462e2841179SLoGin const IRQD_TRIGGER_LOW = IrqLineStatus::IRQ_TYPE_LEVEL_LOW.bits(); 463e2841179SLoGin 464ce5850adSLoGin /// 触发类型位的掩码 465ce5850adSLoGin const IRQD_TRIGGER_MASK = 0xf; 466ce5850adSLoGin /// 亲和性设置待处理 467ce5850adSLoGin const IRQD_SETAFFINITY_PENDING = 1 << 8; 468ce5850adSLoGin /// 中断已激活 469ce5850adSLoGin const IRQD_ACTIVATED = 1 << 9; 470ce5850adSLoGin /// 对此IRQ禁用平衡 471ce5850adSLoGin const IRQD_NO_BALANCING = 1 << 10; 472ce5850adSLoGin /// 中断是每个CPU特定的 473ce5850adSLoGin const IRQD_PER_CPU = 1 << 11; 474ce5850adSLoGin /// 中断亲和性已设置 475ce5850adSLoGin const IRQD_AFFINITY_SET = 1 << 12; 476ce5850adSLoGin /// 中断是电平触发 477ce5850adSLoGin const IRQD_LEVEL = 1 << 13; 478ce5850adSLoGin /// 中断配置为从挂起状态唤醒 479ce5850adSLoGin const IRQD_WAKEUP_STATE = 1 << 14; 480ce5850adSLoGin /// 中断可以在进程上下文中移动 481ce5850adSLoGin const IRQD_MOVE_PCNTXT = 1 << 15; 482ce5850adSLoGin /// 中断被禁用 483ce5850adSLoGin const IRQD_IRQ_DISABLED = 1 << 16; 484ce5850adSLoGin /// 中断被屏蔽 485ce5850adSLoGin const IRQD_IRQ_MASKED = 1 << 17; 486ce5850adSLoGin /// 中断正在处理中 487ce5850adSLoGin const IRQD_IRQ_INPROGRESS = 1 << 18; 488ce5850adSLoGin /// 唤醒模式已准备就绪 489ce5850adSLoGin const IRQD_WAKEUP_ARMED = 1 << 19; 490ce5850adSLoGin /// 中断被转发到一个虚拟CPU 491ce5850adSLoGin const IRQD_FORWARDED_TO_VCPU = 1 << 20; 492ce5850adSLoGin /// 亲和性由内核自动管理 493ce5850adSLoGin const IRQD_AFFINITY_MANAGED = 1 << 21; 494ce5850adSLoGin /// 中断已启动 495ce5850adSLoGin const IRQD_IRQ_STARTED = 1 << 22; 496ce5850adSLoGin /// 由于空亲和性掩码而关闭的中断。仅适用于亲和性管理的中断。 497ce5850adSLoGin const IRQD_MANAGED_SHUTDOWN = 1 << 23; 498ce5850adSLoGin /// IRQ只允许单个亲和性目标 499ce5850adSLoGin const IRQD_SINGLE_TARGET = 1 << 24; 500e2841179SLoGin /// 默认的触发器已设置 501ce5850adSLoGin const IRQD_DEFAULT_TRIGGER_SET = 1 << 25; 502ce5850adSLoGin /// 可以使用保留模式 503ce5850adSLoGin const IRQD_CAN_RESERVE = 1 << 26; 504ce5850adSLoGin /// Non-maskable MSI quirk for affinity change required 505ce5850adSLoGin const IRQD_MSI_NOMASK_QUIRK = 1 << 27; 506ce5850adSLoGin /// 强制要求`handle_irq_()`只能在真实的中断上下文中调用 507ce5850adSLoGin const IRQD_HANDLE_ENFORCE_IRQCTX = 1 << 28; 508ce5850adSLoGin /// 激活时设置亲和性。在禁用时不要调用irq_chip::irq_set_affinity()。 509ce5850adSLoGin const IRQD_AFFINITY_ON_ACTIVATE = 1 << 29; 510ce5850adSLoGin /// 如果irqpm具有标志 IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND,则在挂起时中断被启用。 511ce5850adSLoGin const IRQD_IRQ_ENABLED_ON_SUSPEND = 1 << 30; 512ce5850adSLoGin } 513ce5850adSLoGin } 514ce5850adSLoGin 515ce5850adSLoGin #[allow(dead_code)] 516ce5850adSLoGin impl IrqStatus { is_set_affinity_pending(&self) -> bool517ce5850adSLoGin pub const fn is_set_affinity_pending(&self) -> bool { 518ce5850adSLoGin self.contains(Self::IRQD_SETAFFINITY_PENDING) 519ce5850adSLoGin } 520ce5850adSLoGin is_per_cpu(&self) -> bool521ce5850adSLoGin pub const fn is_per_cpu(&self) -> bool { 522ce5850adSLoGin self.contains(Self::IRQD_PER_CPU) 523ce5850adSLoGin } 524ce5850adSLoGin can_balance(&self) -> bool525ce5850adSLoGin pub const fn can_balance(&self) -> bool { 526b5b571e0SLoGin (self.bits & (Self::IRQD_PER_CPU.bits | Self::IRQD_NO_BALANCING.bits)) == 0 527ce5850adSLoGin } 528ce5850adSLoGin affinity_was_set(&self) -> bool529ce5850adSLoGin pub const fn affinity_was_set(&self) -> bool { 530ce5850adSLoGin self.contains(Self::IRQD_AFFINITY_SET) 531ce5850adSLoGin } 532ce5850adSLoGin masked(&self) -> bool533e2841179SLoGin pub fn masked(&self) -> bool { 534e2841179SLoGin self.contains(Self::IRQD_IRQ_MASKED) 535e2841179SLoGin } 536e2841179SLoGin disabled(&self) -> bool537e2841179SLoGin pub fn disabled(&self) -> bool { 538e2841179SLoGin self.contains(Self::IRQD_IRQ_DISABLED) 539e2841179SLoGin } 540e2841179SLoGin mark_affinity_set(&mut self)541ce5850adSLoGin pub fn mark_affinity_set(&mut self) { 542ce5850adSLoGin self.insert(Self::IRQD_AFFINITY_SET); 543ce5850adSLoGin } 544ce5850adSLoGin trigger_type_was_set(&self) -> bool545ce5850adSLoGin pub const fn trigger_type_was_set(&self) -> bool { 546ce5850adSLoGin self.contains(Self::IRQD_DEFAULT_TRIGGER_SET) 547ce5850adSLoGin } 548ce5850adSLoGin mark_trigger_type_set(&mut self)549ce5850adSLoGin pub fn mark_trigger_type_set(&mut self) { 550ce5850adSLoGin self.insert(Self::IRQD_DEFAULT_TRIGGER_SET); 551ce5850adSLoGin } 552ce5850adSLoGin trigger_type(&self) -> IrqLineStatus553ce5850adSLoGin pub const fn trigger_type(&self) -> IrqLineStatus { 554ce5850adSLoGin IrqLineStatus::from_bits_truncate(self.bits & Self::IRQD_TRIGGER_MASK.bits) 555ce5850adSLoGin } 556ce5850adSLoGin 557ce5850adSLoGin /// Must only be called inside irq_chip.irq_set_type() functions or 558ce5850adSLoGin /// from the DT/ACPI setup code. set_trigger_type(&mut self, trigger: IrqLineStatus)559ce5850adSLoGin pub const fn set_trigger_type(&mut self, trigger: IrqLineStatus) { 560ce5850adSLoGin self.bits &= !Self::IRQD_TRIGGER_MASK.bits; 561ce5850adSLoGin self.bits |= trigger.bits & Self::IRQD_TRIGGER_MASK.bits; 562ce5850adSLoGin 563ce5850adSLoGin self.bits |= Self::IRQD_DEFAULT_TRIGGER_SET.bits; 564ce5850adSLoGin } 565ce5850adSLoGin is_level_type(&self) -> bool566ce5850adSLoGin pub const fn is_level_type(&self) -> bool { 567ce5850adSLoGin self.contains(Self::IRQD_LEVEL) 568ce5850adSLoGin } 569ce5850adSLoGin 570ce5850adSLoGin /// Must only be called of irqchip.irq_set_affinity() or low level 571ce5850adSLoGin /// hierarchy domain allocation functions. set_single_target(&mut self)572ce5850adSLoGin pub fn set_single_target(&mut self) { 573ce5850adSLoGin self.insert(Self::IRQD_SINGLE_TARGET); 574ce5850adSLoGin } 575ce5850adSLoGin is_single_target(&self) -> bool576ce5850adSLoGin pub const fn is_single_target(&self) -> bool { 577ce5850adSLoGin self.contains(Self::IRQD_SINGLE_TARGET) 578ce5850adSLoGin } 579ce5850adSLoGin set_handle_enforce_irqctx(&mut self)580ce5850adSLoGin pub fn set_handle_enforce_irqctx(&mut self) { 581ce5850adSLoGin self.insert(Self::IRQD_HANDLE_ENFORCE_IRQCTX); 582ce5850adSLoGin } 583ce5850adSLoGin is_handle_enforce_irqctx(&self) -> bool584ce5850adSLoGin pub const fn is_handle_enforce_irqctx(&self) -> bool { 585ce5850adSLoGin self.contains(Self::IRQD_HANDLE_ENFORCE_IRQCTX) 586ce5850adSLoGin } 587ce5850adSLoGin is_enabled_on_suspend(&self) -> bool588ce5850adSLoGin pub const fn is_enabled_on_suspend(&self) -> bool { 589ce5850adSLoGin self.contains(Self::IRQD_IRQ_ENABLED_ON_SUSPEND) 590ce5850adSLoGin } 591ce5850adSLoGin is_wakeup_set(&self) -> bool592ce5850adSLoGin pub const fn is_wakeup_set(&self) -> bool { 593ce5850adSLoGin self.contains(Self::IRQD_WAKEUP_STATE) 594ce5850adSLoGin } 595ce5850adSLoGin can_move_in_process_context(&self) -> bool596ce5850adSLoGin pub const fn can_move_in_process_context(&self) -> bool { 597ce5850adSLoGin self.contains(Self::IRQD_MOVE_PCNTXT) 598ce5850adSLoGin } 599ce5850adSLoGin is_irq_in_progress(&self) -> bool600ce5850adSLoGin pub const fn is_irq_in_progress(&self) -> bool { 601ce5850adSLoGin self.contains(Self::IRQD_IRQ_INPROGRESS) 602ce5850adSLoGin } 603ce5850adSLoGin is_wakeup_armed(&self) -> bool604ce5850adSLoGin pub const fn is_wakeup_armed(&self) -> bool { 605ce5850adSLoGin self.contains(Self::IRQD_WAKEUP_ARMED) 606ce5850adSLoGin } 607ce5850adSLoGin is_forwarded_to_vcpu(&self) -> bool608ce5850adSLoGin pub const fn is_forwarded_to_vcpu(&self) -> bool { 609ce5850adSLoGin self.contains(Self::IRQD_FORWARDED_TO_VCPU) 610ce5850adSLoGin } 611ce5850adSLoGin set_forwarded_to_vcpu(&mut self)612ce5850adSLoGin pub fn set_forwarded_to_vcpu(&mut self) { 613ce5850adSLoGin self.insert(Self::IRQD_FORWARDED_TO_VCPU); 614ce5850adSLoGin } 615ce5850adSLoGin affinity_managed(&self) -> bool616e2841179SLoGin pub const fn affinity_managed(&self) -> bool { 617ce5850adSLoGin self.contains(Self::IRQD_AFFINITY_MANAGED) 618ce5850adSLoGin } 619ce5850adSLoGin is_activated(&self) -> bool620ce5850adSLoGin pub const fn is_activated(&self) -> bool { 621ce5850adSLoGin self.contains(Self::IRQD_ACTIVATED) 622ce5850adSLoGin } 623ce5850adSLoGin set_activated(&mut self)624ce5850adSLoGin pub fn set_activated(&mut self) { 625ce5850adSLoGin self.insert(Self::IRQD_ACTIVATED); 626ce5850adSLoGin } 627ce5850adSLoGin clear_activated(&mut self)628ce5850adSLoGin pub fn clear_activated(&mut self) { 629ce5850adSLoGin self.remove(Self::IRQD_ACTIVATED); 630ce5850adSLoGin } 631ce5850adSLoGin is_started(&self) -> bool632ce5850adSLoGin pub const fn is_started(&self) -> bool { 633ce5850adSLoGin self.contains(Self::IRQD_IRQ_STARTED) 634ce5850adSLoGin } 635ce5850adSLoGin is_managed_and_shutdown(&self) -> bool636ce5850adSLoGin pub const fn is_managed_and_shutdown(&self) -> bool { 637ce5850adSLoGin self.contains(Self::IRQD_MANAGED_SHUTDOWN) 638ce5850adSLoGin } 639ce5850adSLoGin set_can_reserve(&mut self)640ce5850adSLoGin pub fn set_can_reserve(&mut self) { 641ce5850adSLoGin self.insert(Self::IRQD_CAN_RESERVE); 642ce5850adSLoGin } 643ce5850adSLoGin can_reserve(&self) -> bool644ce5850adSLoGin pub const fn can_reserve(&self) -> bool { 645ce5850adSLoGin self.contains(Self::IRQD_CAN_RESERVE) 646ce5850adSLoGin } 647ce5850adSLoGin clear_can_reserve(&mut self)648ce5850adSLoGin pub fn clear_can_reserve(&mut self) { 649ce5850adSLoGin self.remove(Self::IRQD_CAN_RESERVE); 650ce5850adSLoGin } 651ce5850adSLoGin set_msi_nomask_quirk(&mut self)652ce5850adSLoGin pub fn set_msi_nomask_quirk(&mut self) { 653ce5850adSLoGin self.insert(Self::IRQD_MSI_NOMASK_QUIRK); 654ce5850adSLoGin } 655ce5850adSLoGin clear_msi_nomask_quirk(&mut self)656ce5850adSLoGin pub fn clear_msi_nomask_quirk(&mut self) { 657ce5850adSLoGin self.remove(Self::IRQD_MSI_NOMASK_QUIRK); 658ce5850adSLoGin } 659ce5850adSLoGin is_msi_nomask_quirk(&self) -> bool660ce5850adSLoGin pub const fn is_msi_nomask_quirk(&self) -> bool { 661ce5850adSLoGin self.contains(Self::IRQD_MSI_NOMASK_QUIRK) 662ce5850adSLoGin } 663ce5850adSLoGin set_affinity_on_activate(&mut self)664ce5850adSLoGin pub fn set_affinity_on_activate(&mut self) { 665ce5850adSLoGin self.insert(Self::IRQD_AFFINITY_ON_ACTIVATE); 666ce5850adSLoGin } 667ce5850adSLoGin is_affinity_on_activate(&self) -> bool668ce5850adSLoGin pub const fn is_affinity_on_activate(&self) -> bool { 669ce5850adSLoGin self.contains(Self::IRQD_AFFINITY_ON_ACTIVATE) 670ce5850adSLoGin } 671e2841179SLoGin started(&self) -> bool672e2841179SLoGin pub const fn started(&self) -> bool { 673e2841179SLoGin self.contains(Self::IRQD_IRQ_STARTED) 674e2841179SLoGin } 675ce5850adSLoGin } 676