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}, 14ce5850adSLoGin irqdomain::IrqDomain, 15ce5850adSLoGin msi::MsiDesc, 16ce5850adSLoGin HardwareIrqNumber, IrqNumber, 17ce5850adSLoGin }; 18ce5850adSLoGin 19ce5850adSLoGin /// per irq chip data passed down to chip functions 20ce5850adSLoGin /// 21ce5850adSLoGin /// 该结构体用于表示每个Irq的私有数据,且与具体的中断芯片绑定 22ce5850adSLoGin /// 23ce5850adSLoGin /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h#179 24ce5850adSLoGin #[allow(dead_code)] 25ce5850adSLoGin #[derive(Debug)] 26ce5850adSLoGin pub struct IrqData { 27ce5850adSLoGin /// 中断号, 用于表示软件逻辑视角的中断号,全局唯一 28ce5850adSLoGin irq: IrqNumber, 293bc96fa4SLoGin inner: SpinLock<InnerIrqData>, 30e2841179SLoGin 31e2841179SLoGin chip_info: RwLock<InnerIrqChipInfo>, 323bc96fa4SLoGin } 333bc96fa4SLoGin 343bc96fa4SLoGin impl IrqData { 353bc96fa4SLoGin pub fn new( 363bc96fa4SLoGin irq: IrqNumber, 373bc96fa4SLoGin hwirq: HardwareIrqNumber, 383bc96fa4SLoGin common_data: Arc<IrqCommonData>, 393bc96fa4SLoGin chip: Arc<dyn IrqChip>, 403bc96fa4SLoGin ) -> Self { 413bc96fa4SLoGin return IrqData { 423bc96fa4SLoGin irq, 433bc96fa4SLoGin inner: SpinLock::new(InnerIrqData { 443bc96fa4SLoGin hwirq, 453bc96fa4SLoGin common_data, 46e2841179SLoGin 473bc96fa4SLoGin domain: None, 483bc96fa4SLoGin parent_data: None, 493bc96fa4SLoGin }), 50e2841179SLoGin chip_info: RwLock::new(InnerIrqChipInfo { 51e2841179SLoGin chip: Some(chip), 52e2841179SLoGin chip_data: None, 53e2841179SLoGin }), 543bc96fa4SLoGin }; 553bc96fa4SLoGin } 563bc96fa4SLoGin 573bc96fa4SLoGin pub fn irqd_set(&self, status: IrqStatus) { 583bc96fa4SLoGin // clone是为了释放inner锁 59e2841179SLoGin let common_data = self.inner.lock_irqsave().common_data.clone(); 60e2841179SLoGin common_data.insert_status(status); 613bc96fa4SLoGin } 623bc96fa4SLoGin 633bc96fa4SLoGin #[allow(dead_code)] 643bc96fa4SLoGin pub fn irqd_clear(&self, status: IrqStatus) { 653bc96fa4SLoGin // clone是为了释放inner锁 66e2841179SLoGin let common_data = self.inner.lock_irqsave().common_data.clone(); 67e2841179SLoGin common_data.clear_status(status); 683bc96fa4SLoGin } 693bc96fa4SLoGin 703bc96fa4SLoGin pub fn irq(&self) -> IrqNumber { 713bc96fa4SLoGin self.irq 723bc96fa4SLoGin } 73196b75dcSLoGin 74196b75dcSLoGin pub fn hardware_irq(&self) -> HardwareIrqNumber { 75196b75dcSLoGin self.inner.lock_irqsave().hwirq 76196b75dcSLoGin } 77196b75dcSLoGin 78196b75dcSLoGin /// 是否为电平触发 79196b75dcSLoGin pub fn is_level_type(&self) -> bool { 80196b75dcSLoGin self.inner 81196b75dcSLoGin .lock_irqsave() 82196b75dcSLoGin .common_data 83196b75dcSLoGin .inner 84e2841179SLoGin .lock_irqsave() 85196b75dcSLoGin .state 86196b75dcSLoGin .is_level_type() 87196b75dcSLoGin } 88196b75dcSLoGin 89196b75dcSLoGin pub fn is_wakeup_set(&self) -> bool { 90196b75dcSLoGin self.inner 91196b75dcSLoGin .lock_irqsave() 92196b75dcSLoGin .common_data 93196b75dcSLoGin .inner 94e2841179SLoGin .lock_irqsave() 95196b75dcSLoGin .state 96196b75dcSLoGin .is_wakeup_set() 97196b75dcSLoGin } 98e2841179SLoGin 99e2841179SLoGin pub fn common_data(&self) -> Arc<IrqCommonData> { 100e2841179SLoGin self.inner.lock_irqsave().common_data.clone() 101e2841179SLoGin } 102e2841179SLoGin 103e2841179SLoGin pub fn domain(&self) -> Option<Arc<IrqDomain>> { 104e2841179SLoGin self.inner.lock_irqsave().domain.clone() 105e2841179SLoGin } 106e2841179SLoGin 107e2841179SLoGin pub fn inner(&self) -> SpinLockGuard<InnerIrqData> { 108e2841179SLoGin self.inner.lock_irqsave() 109e2841179SLoGin } 110e2841179SLoGin 111e2841179SLoGin pub fn chip_info_read(&self) -> RwLockReadGuard<InnerIrqChipInfo> { 112e2841179SLoGin self.chip_info.read() 113e2841179SLoGin } 114e2841179SLoGin 115e2841179SLoGin pub fn chip_info_read_irqsave(&self) -> RwLockReadGuard<InnerIrqChipInfo> { 116e2841179SLoGin self.chip_info.read_irqsave() 117e2841179SLoGin } 118e2841179SLoGin 119e2841179SLoGin pub fn chip_info_write_irqsave(&self) -> RwLockWriteGuard<InnerIrqChipInfo> { 120e2841179SLoGin self.chip_info.write_irqsave() 121e2841179SLoGin } 122e2841179SLoGin 123e2841179SLoGin pub fn parent_data(&self) -> Option<Weak<IrqData>> { 124e2841179SLoGin self.inner.lock_irqsave().parent_data.clone() 125e2841179SLoGin } 1263bc96fa4SLoGin } 1273bc96fa4SLoGin 1283bc96fa4SLoGin #[allow(dead_code)] 1293bc96fa4SLoGin #[derive(Debug)] 130e2841179SLoGin pub struct InnerIrqData { 131ce5850adSLoGin /// 硬件中断号, 用于表示在某个IrqDomain中的中断号 132ce5850adSLoGin hwirq: HardwareIrqNumber, 133ce5850adSLoGin /// 涉及的所有irqchip之间共享的数据 134ce5850adSLoGin common_data: Arc<IrqCommonData>, 135e2841179SLoGin 136ce5850adSLoGin /// 中断域 1373bc96fa4SLoGin domain: Option<Arc<IrqDomain>>, 138ce5850adSLoGin /// 中断的父中断(如果具有中断域继承的话) 139ce5850adSLoGin parent_data: Option<Weak<IrqData>>, 140ce5850adSLoGin } 141ce5850adSLoGin 142e2841179SLoGin impl InnerIrqData { 143e2841179SLoGin pub fn set_hwirq(&mut self, hwirq: HardwareIrqNumber) { 144e2841179SLoGin self.hwirq = hwirq; 145e2841179SLoGin } 146e2841179SLoGin 147e2841179SLoGin #[allow(dead_code)] 148e2841179SLoGin pub fn domain(&self) -> Option<Arc<IrqDomain>> { 149e2841179SLoGin self.domain.clone() 150e2841179SLoGin } 151e2841179SLoGin 152e2841179SLoGin pub fn set_domain(&mut self, domain: Option<Arc<IrqDomain>>) { 153e2841179SLoGin self.domain = domain; 154e2841179SLoGin } 155e2841179SLoGin } 156e2841179SLoGin 157e2841179SLoGin #[derive(Debug)] 158e2841179SLoGin pub struct InnerIrqChipInfo { 159e2841179SLoGin /// 绑定到的中断芯片 160e2841179SLoGin chip: Option<Arc<dyn IrqChip>>, 161e2841179SLoGin /// 中断芯片的私有数据(与当前irq相关) 162e2841179SLoGin chip_data: Option<Arc<dyn IrqChipData>>, 163e2841179SLoGin } 164e2841179SLoGin 165e2841179SLoGin impl InnerIrqChipInfo { 166e2841179SLoGin pub fn set_chip(&mut self, chip: Option<Arc<dyn IrqChip>>) { 167e2841179SLoGin self.chip = chip; 168e2841179SLoGin } 169e2841179SLoGin 170e2841179SLoGin pub fn set_chip_data(&mut self, chip_data: Option<Arc<dyn IrqChipData>>) { 171e2841179SLoGin self.chip_data = chip_data; 172e2841179SLoGin } 173e2841179SLoGin 174e2841179SLoGin pub fn chip(&self) -> Arc<dyn IrqChip> { 175e2841179SLoGin self.chip.clone().unwrap() 176e2841179SLoGin } 177e2841179SLoGin 178e2841179SLoGin pub fn chip_data(&self) -> Option<Arc<dyn IrqChipData>> { 179e2841179SLoGin self.chip_data.clone() 180e2841179SLoGin } 181e2841179SLoGin } 182e2841179SLoGin 183ce5850adSLoGin /// per irq data shared by all irqchips 184ce5850adSLoGin /// 185ce5850adSLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h#147 186ce5850adSLoGin #[derive(Debug)] 187ce5850adSLoGin pub struct IrqCommonData { 188ce5850adSLoGin inner: SpinLock<InnerIrqCommonData>, 189ce5850adSLoGin } 190ce5850adSLoGin 1913bc96fa4SLoGin impl IrqCommonData { 1923bc96fa4SLoGin pub fn new() -> Self { 1933bc96fa4SLoGin let inner = InnerIrqCommonData { 1943bc96fa4SLoGin state: IrqStatus::empty(), 1953bc96fa4SLoGin handler_data: None, 1963bc96fa4SLoGin msi_desc: None, 197e2841179SLoGin affinity: CpuMask::new(), 1983bc96fa4SLoGin }; 1993bc96fa4SLoGin return IrqCommonData { 2003bc96fa4SLoGin inner: SpinLock::new(inner), 2013bc96fa4SLoGin }; 2023bc96fa4SLoGin } 2033bc96fa4SLoGin 204e2841179SLoGin pub fn insert_status(&self, status: IrqStatus) { 205e2841179SLoGin self.inner.lock_irqsave().irqd_insert(status); 2063bc96fa4SLoGin } 2073bc96fa4SLoGin 208e2841179SLoGin pub fn clear_status(&self, status: IrqStatus) { 2093bc96fa4SLoGin self.inner.lock_irqsave().irqd_clear(status); 2103bc96fa4SLoGin } 211e2841179SLoGin 212e2841179SLoGin pub fn clear_managed_shutdown(&self) { 213e2841179SLoGin self.inner 214e2841179SLoGin .lock_irqsave() 215e2841179SLoGin .state 216e2841179SLoGin .remove(IrqStatus::IRQD_MANAGED_SHUTDOWN); 217e2841179SLoGin } 218e2841179SLoGin 219e2841179SLoGin #[allow(dead_code)] 220e2841179SLoGin pub fn masked(&self) -> bool { 221e2841179SLoGin self.inner.lock_irqsave().state.masked() 222e2841179SLoGin } 223e2841179SLoGin 224e2841179SLoGin pub fn set_masked(&self) { 225e2841179SLoGin self.inner 226e2841179SLoGin .lock_irqsave() 227e2841179SLoGin .state 228e2841179SLoGin .insert(IrqStatus::IRQD_IRQ_MASKED); 229e2841179SLoGin } 230e2841179SLoGin 231e2841179SLoGin pub fn clear_masked(&self) { 232e2841179SLoGin self.clear_status(IrqStatus::IRQD_IRQ_MASKED); 233e2841179SLoGin } 234e2841179SLoGin 235e2841179SLoGin pub fn set_inprogress(&self) { 236e2841179SLoGin self.inner 237e2841179SLoGin .lock_irqsave() 238e2841179SLoGin .state 239e2841179SLoGin .insert(IrqStatus::IRQD_IRQ_INPROGRESS); 240e2841179SLoGin } 241e2841179SLoGin 242e2841179SLoGin pub fn clear_inprogress(&self) { 243e2841179SLoGin self.inner 244e2841179SLoGin .lock_irqsave() 245e2841179SLoGin .state 246e2841179SLoGin .remove(IrqStatus::IRQD_IRQ_INPROGRESS); 247e2841179SLoGin } 248e2841179SLoGin 249e2841179SLoGin pub fn disabled(&self) -> bool { 250e2841179SLoGin self.inner.lock_irqsave().state.disabled() 251e2841179SLoGin } 252e2841179SLoGin 253e2841179SLoGin #[allow(dead_code)] 254e2841179SLoGin pub fn set_disabled(&self) { 255e2841179SLoGin self.inner 256e2841179SLoGin .lock_irqsave() 257e2841179SLoGin .state 258e2841179SLoGin .insert(IrqStatus::IRQD_IRQ_DISABLED); 259e2841179SLoGin } 260e2841179SLoGin 261e2841179SLoGin pub fn clear_disabled(&self) { 262e2841179SLoGin self.clear_status(IrqStatus::IRQD_IRQ_DISABLED); 263e2841179SLoGin } 264e2841179SLoGin 265e2841179SLoGin pub fn status(&self) -> IrqStatus { 266e2841179SLoGin self.inner.lock_irqsave().state 267e2841179SLoGin } 268e2841179SLoGin 269e2841179SLoGin pub fn trigger_type(&self) -> IrqLineStatus { 270e2841179SLoGin self.inner.lock_irqsave().state.trigger_type() 271e2841179SLoGin } 272e2841179SLoGin 273e2841179SLoGin pub fn set_trigger_type(&self, trigger: IrqLineStatus) { 274e2841179SLoGin self.inner.lock_irqsave().state.set_trigger_type(trigger); 275e2841179SLoGin } 276e2841179SLoGin 277e2841179SLoGin pub fn set_started(&self) { 278e2841179SLoGin self.inner 279e2841179SLoGin .lock_irqsave() 280e2841179SLoGin .state 281e2841179SLoGin .insert(IrqStatus::IRQD_IRQ_STARTED); 282e2841179SLoGin } 283e2841179SLoGin 284e2841179SLoGin pub fn affinity(&self) -> CpuMask { 285e2841179SLoGin self.inner.lock_irqsave().affinity.clone() 286e2841179SLoGin } 287e2841179SLoGin 288e2841179SLoGin pub fn set_affinity(&self, affinity: CpuMask) { 289e2841179SLoGin self.inner.lock_irqsave().affinity = affinity; 290e2841179SLoGin } 291338f6903SLoGin 292338f6903SLoGin pub fn inner(&self) -> SpinLockGuard<InnerIrqCommonData> { 293338f6903SLoGin self.inner.lock_irqsave() 294338f6903SLoGin } 2953bc96fa4SLoGin } 2963bc96fa4SLoGin 297ce5850adSLoGin #[allow(dead_code)] 298ce5850adSLoGin #[derive(Debug)] 299338f6903SLoGin pub struct InnerIrqCommonData { 300ce5850adSLoGin /// status information for irq chip functions. 301ce5850adSLoGin state: IrqStatus, 302ce5850adSLoGin /// per-IRQ data for the irq_chip methods 303ce5850adSLoGin handler_data: Option<Arc<dyn IrqHandlerData>>, 304ce5850adSLoGin msi_desc: Option<Arc<MsiDesc>>, 305e2841179SLoGin affinity: CpuMask, 306ce5850adSLoGin } 307ce5850adSLoGin 3083bc96fa4SLoGin impl InnerIrqCommonData { 309e2841179SLoGin pub fn irqd_insert(&mut self, status: IrqStatus) { 3103bc96fa4SLoGin self.state.insert(status); 3113bc96fa4SLoGin } 3123bc96fa4SLoGin 3133bc96fa4SLoGin pub fn irqd_clear(&mut self, status: IrqStatus) { 3143bc96fa4SLoGin self.state.remove(status); 3153bc96fa4SLoGin } 316338f6903SLoGin 317338f6903SLoGin #[allow(dead_code)] 318338f6903SLoGin pub fn set_handler_data(&mut self, handler_data: Option<Arc<dyn IrqHandlerData>>) { 319338f6903SLoGin self.handler_data = handler_data; 320338f6903SLoGin } 321338f6903SLoGin 322338f6903SLoGin #[allow(dead_code)] 323338f6903SLoGin pub fn handler_data(&self) -> Option<Arc<dyn IrqHandlerData>> { 324338f6903SLoGin self.handler_data.clone() 325338f6903SLoGin } 3263bc96fa4SLoGin } 3273bc96fa4SLoGin 328e2841179SLoGin /// 中断处理函数传入的数据 329e2841179SLoGin pub trait IrqHandlerData: Send + Sync + Any + Debug + CastFromSync {} 330ce5850adSLoGin 331ce5850adSLoGin bitflags! { 332ce5850adSLoGin /// 中断线状态 333ce5850adSLoGin /// https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h?fi=IRQ_TYPE_PROBE#77 334*b5b571e0SLoGin #[allow(clippy::bad_bit_mask)] 335ce5850adSLoGin pub struct IrqLineStatus: u32 { 336ce5850adSLoGin /// 默认,未指明类型 337ce5850adSLoGin const IRQ_TYPE_NONE = 0x00000000; 338ce5850adSLoGin /// 上升沿触发 339ce5850adSLoGin const IRQ_TYPE_EDGE_RISING = 0x00000001; 340ce5850adSLoGin /// 下降沿触发 341ce5850adSLoGin const IRQ_TYPE_EDGE_FALLING = 0x00000002; 342ce5850adSLoGin /// 上升沿和下降沿触发 343ce5850adSLoGin const IRQ_TYPE_EDGE_BOTH = Self::IRQ_TYPE_EDGE_RISING.bits | Self::IRQ_TYPE_EDGE_FALLING.bits; 344ce5850adSLoGin /// 高电平触发 345ce5850adSLoGin const IRQ_TYPE_LEVEL_HIGH = 0x00000004; 346ce5850adSLoGin /// 低电平触发 347ce5850adSLoGin const IRQ_TYPE_LEVEL_LOW = 0x00000008; 348ce5850adSLoGin /// 过滤掉电平位的掩码 349ce5850adSLoGin const IRQ_TYPE_LEVEL_MASK = Self::IRQ_TYPE_LEVEL_LOW.bits | Self::IRQ_TYPE_LEVEL_HIGH.bits; 350ce5850adSLoGin /// 上述位掩码的掩码 351ce5850adSLoGin const IRQ_TYPE_SENSE_MASK = 0x0000000f; 352ce5850adSLoGin /// 某些PICs使用此类型要求 `IrqChip::irq_set_type()` 设置硬件到一个合理的默认值 353ce5850adSLoGin /// (由irqdomain的map()回调使用,以便为新分配的描述符同步硬件状态和软件标志位)。 354ce5850adSLoGin const IRQ_TYPE_DEFAULT = Self::IRQ_TYPE_SENSE_MASK.bits; 355ce5850adSLoGin 356ce5850adSLoGin /// 特定于探测的过程中的特殊标志 357ce5850adSLoGin const IRQ_TYPE_PROBE = 0x00000010; 358ce5850adSLoGin 359ce5850adSLoGin /// 中断是电平类型。当上述触发位通过`IrqChip::irq_set_type()` 修改时,也会在代码中更新 360ce5850adSLoGin const IRQ_LEVEL = 1 << 8; 361ce5850adSLoGin /// 标记一个PER_CPU的中断。将保护其免受亲和性设置的影响 362ce5850adSLoGin const IRQ_PER_CPU = 1 << 9; 363ce5850adSLoGin /// 中断不能被自动探测 364ce5850adSLoGin const IRQ_NOPROBE = 1 << 10; 365ce5850adSLoGin /// 中断不能通过request_irq()请求 366ce5850adSLoGin const IRQ_NOREQUEST = 1 << 11; 367ce5850adSLoGin /// 中断在request/setup_irq()中不会自动启用 368ce5850adSLoGin const IRQ_NOAUTOEN = 1 << 12; 369ce5850adSLoGin /// 中断不能被平衡(亲和性设置) 370ce5850adSLoGin const IRQ_NO_BALANCING = 1 << 13; 371ce5850adSLoGin /// 中断可以从进程上下文中迁移 372ce5850adSLoGin const IRQ_MOVE_PCNTXT = 1 << 14; 373ce5850adSLoGin /// 中断嵌套在另一个线程中 374ce5850adSLoGin const IRQ_NESTED_THREAD = 1 << 15; 375ce5850adSLoGin /// 中断不能被线程化 376ce5850adSLoGin const IRQ_NOTHREAD = 1 << 16; 377ce5850adSLoGin /// Dev_id是一个per-CPU变量 378ce5850adSLoGin const IRQ_PER_CPU_DEVID = 1 << 17; 379ce5850adSLoGin /// 总是由另一个中断轮询。将其从错误的中断检测机制和核心侧轮询中排除 380ce5850adSLoGin const IRQ_IS_POLLED = 1 << 18; 381ce5850adSLoGin /// 禁用延迟的中断禁用 (Disable lazy irq disable) 382ce5850adSLoGin const IRQ_DISABLE_UNLAZY = 1 << 19; 383ce5850adSLoGin /// 在/proc/interrupts中不显示 384ce5850adSLoGin const IRQ_HIDDEN = 1 << 20; 385ce5850adSLoGin /// 从note_interrupt()调试中排除 386ce5850adSLoGin const IRQ_NO_DEBUG = 1 << 21; 387ce5850adSLoGin } 388ce5850adSLoGin 389ce5850adSLoGin 390ce5850adSLoGin 391ce5850adSLoGin } 392e2841179SLoGin 393e2841179SLoGin impl IrqLineStatus { 394e2841179SLoGin pub const fn trigger_bits(&self) -> u32 { 395e2841179SLoGin self.bits & Self::IRQ_TYPE_SENSE_MASK.bits 396e2841179SLoGin } 397e2841179SLoGin 398e2841179SLoGin pub fn trigger_type(&self) -> Self { 399e2841179SLoGin *self & Self::IRQ_TYPE_SENSE_MASK 400e2841179SLoGin } 401e2841179SLoGin 402e2841179SLoGin pub fn is_level_type(&self) -> bool { 403e2841179SLoGin self.contains(Self::IRQ_LEVEL) 404e2841179SLoGin } 405e2841179SLoGin 406e2841179SLoGin /// 是否为高电平触发 407e2841179SLoGin /// 408e2841179SLoGin /// ## 返回 409e2841179SLoGin /// 410e2841179SLoGin /// - 如果不是电平触发类型,则返回None 411e2841179SLoGin /// - 如果是电平触发类型,则返回Some(bool),当为true时表示高电平触发 412e2841179SLoGin pub fn is_level_high(&self) -> Option<bool> { 413e2841179SLoGin if !self.is_level_type() { 414e2841179SLoGin return None; 415e2841179SLoGin } 416e2841179SLoGin return Some(self.contains(Self::IRQ_TYPE_LEVEL_HIGH)); 417e2841179SLoGin } 418338f6903SLoGin 419338f6903SLoGin #[allow(dead_code)] 420338f6903SLoGin pub fn is_per_cpu_devid(&self) -> bool { 421338f6903SLoGin self.contains(Self::IRQ_PER_CPU_DEVID) 422338f6903SLoGin } 423e2841179SLoGin } 424*b5b571e0SLoGin 425ce5850adSLoGin bitflags! { 426ce5850adSLoGin /// 中断状态(存储在IrqCommonData) 427ce5850adSLoGin /// 428ce5850adSLoGin /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h#227 429*b5b571e0SLoGin #[allow(clippy::bad_bit_mask)] 430ce5850adSLoGin pub struct IrqStatus: u32 { 431e2841179SLoGin const IRQD_TRIGGER_NONE = IrqLineStatus::IRQ_TYPE_NONE.bits(); 432e2841179SLoGin const IRQD_TRIGGER_RISING = IrqLineStatus::IRQ_TYPE_EDGE_RISING.bits(); 433e2841179SLoGin const IRQD_TRIGGER_FALLING = IrqLineStatus::IRQ_TYPE_EDGE_FALLING.bits(); 434e2841179SLoGin const IRQD_TRIGGER_HIGH = IrqLineStatus::IRQ_TYPE_LEVEL_HIGH.bits(); 435e2841179SLoGin const IRQD_TRIGGER_LOW = IrqLineStatus::IRQ_TYPE_LEVEL_LOW.bits(); 436e2841179SLoGin 437ce5850adSLoGin /// 触发类型位的掩码 438ce5850adSLoGin const IRQD_TRIGGER_MASK = 0xf; 439ce5850adSLoGin /// 亲和性设置待处理 440ce5850adSLoGin const IRQD_SETAFFINITY_PENDING = 1 << 8; 441ce5850adSLoGin /// 中断已激活 442ce5850adSLoGin const IRQD_ACTIVATED = 1 << 9; 443ce5850adSLoGin /// 对此IRQ禁用平衡 444ce5850adSLoGin const IRQD_NO_BALANCING = 1 << 10; 445ce5850adSLoGin /// 中断是每个CPU特定的 446ce5850adSLoGin const IRQD_PER_CPU = 1 << 11; 447ce5850adSLoGin /// 中断亲和性已设置 448ce5850adSLoGin const IRQD_AFFINITY_SET = 1 << 12; 449ce5850adSLoGin /// 中断是电平触发 450ce5850adSLoGin const IRQD_LEVEL = 1 << 13; 451ce5850adSLoGin /// 中断配置为从挂起状态唤醒 452ce5850adSLoGin const IRQD_WAKEUP_STATE = 1 << 14; 453ce5850adSLoGin /// 中断可以在进程上下文中移动 454ce5850adSLoGin const IRQD_MOVE_PCNTXT = 1 << 15; 455ce5850adSLoGin /// 中断被禁用 456ce5850adSLoGin const IRQD_IRQ_DISABLED = 1 << 16; 457ce5850adSLoGin /// 中断被屏蔽 458ce5850adSLoGin const IRQD_IRQ_MASKED = 1 << 17; 459ce5850adSLoGin /// 中断正在处理中 460ce5850adSLoGin const IRQD_IRQ_INPROGRESS = 1 << 18; 461ce5850adSLoGin /// 唤醒模式已准备就绪 462ce5850adSLoGin const IRQD_WAKEUP_ARMED = 1 << 19; 463ce5850adSLoGin /// 中断被转发到一个虚拟CPU 464ce5850adSLoGin const IRQD_FORWARDED_TO_VCPU = 1 << 20; 465ce5850adSLoGin /// 亲和性由内核自动管理 466ce5850adSLoGin const IRQD_AFFINITY_MANAGED = 1 << 21; 467ce5850adSLoGin /// 中断已启动 468ce5850adSLoGin const IRQD_IRQ_STARTED = 1 << 22; 469ce5850adSLoGin /// 由于空亲和性掩码而关闭的中断。仅适用于亲和性管理的中断。 470ce5850adSLoGin const IRQD_MANAGED_SHUTDOWN = 1 << 23; 471ce5850adSLoGin /// IRQ只允许单个亲和性目标 472ce5850adSLoGin const IRQD_SINGLE_TARGET = 1 << 24; 473e2841179SLoGin /// 默认的触发器已设置 474ce5850adSLoGin const IRQD_DEFAULT_TRIGGER_SET = 1 << 25; 475ce5850adSLoGin /// 可以使用保留模式 476ce5850adSLoGin const IRQD_CAN_RESERVE = 1 << 26; 477ce5850adSLoGin /// Non-maskable MSI quirk for affinity change required 478ce5850adSLoGin const IRQD_MSI_NOMASK_QUIRK = 1 << 27; 479ce5850adSLoGin /// 强制要求`handle_irq_()`只能在真实的中断上下文中调用 480ce5850adSLoGin const IRQD_HANDLE_ENFORCE_IRQCTX = 1 << 28; 481ce5850adSLoGin /// 激活时设置亲和性。在禁用时不要调用irq_chip::irq_set_affinity()。 482ce5850adSLoGin const IRQD_AFFINITY_ON_ACTIVATE = 1 << 29; 483ce5850adSLoGin /// 如果irqpm具有标志 IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND,则在挂起时中断被启用。 484ce5850adSLoGin const IRQD_IRQ_ENABLED_ON_SUSPEND = 1 << 30; 485ce5850adSLoGin } 486ce5850adSLoGin } 487ce5850adSLoGin 488ce5850adSLoGin #[allow(dead_code)] 489ce5850adSLoGin impl IrqStatus { 490ce5850adSLoGin pub const fn is_set_affinity_pending(&self) -> bool { 491ce5850adSLoGin self.contains(Self::IRQD_SETAFFINITY_PENDING) 492ce5850adSLoGin } 493ce5850adSLoGin 494ce5850adSLoGin pub const fn is_per_cpu(&self) -> bool { 495ce5850adSLoGin self.contains(Self::IRQD_PER_CPU) 496ce5850adSLoGin } 497ce5850adSLoGin 498ce5850adSLoGin pub const fn can_balance(&self) -> bool { 499*b5b571e0SLoGin (self.bits & (Self::IRQD_PER_CPU.bits | Self::IRQD_NO_BALANCING.bits)) == 0 500ce5850adSLoGin } 501ce5850adSLoGin 502ce5850adSLoGin pub const fn affinity_was_set(&self) -> bool { 503ce5850adSLoGin self.contains(Self::IRQD_AFFINITY_SET) 504ce5850adSLoGin } 505ce5850adSLoGin 506e2841179SLoGin pub fn masked(&self) -> bool { 507e2841179SLoGin self.contains(Self::IRQD_IRQ_MASKED) 508e2841179SLoGin } 509e2841179SLoGin 510e2841179SLoGin pub fn disabled(&self) -> bool { 511e2841179SLoGin self.contains(Self::IRQD_IRQ_DISABLED) 512e2841179SLoGin } 513e2841179SLoGin 514ce5850adSLoGin pub fn mark_affinity_set(&mut self) { 515ce5850adSLoGin self.insert(Self::IRQD_AFFINITY_SET); 516ce5850adSLoGin } 517ce5850adSLoGin 518ce5850adSLoGin pub const fn trigger_type_was_set(&self) -> bool { 519ce5850adSLoGin self.contains(Self::IRQD_DEFAULT_TRIGGER_SET) 520ce5850adSLoGin } 521ce5850adSLoGin 522ce5850adSLoGin pub fn mark_trigger_type_set(&mut self) { 523ce5850adSLoGin self.insert(Self::IRQD_DEFAULT_TRIGGER_SET); 524ce5850adSLoGin } 525ce5850adSLoGin 526ce5850adSLoGin pub const fn trigger_type(&self) -> IrqLineStatus { 527ce5850adSLoGin IrqLineStatus::from_bits_truncate(self.bits & Self::IRQD_TRIGGER_MASK.bits) 528ce5850adSLoGin } 529ce5850adSLoGin 530ce5850adSLoGin /// Must only be called inside irq_chip.irq_set_type() functions or 531ce5850adSLoGin /// from the DT/ACPI setup code. 532ce5850adSLoGin pub const fn set_trigger_type(&mut self, trigger: IrqLineStatus) { 533ce5850adSLoGin self.bits &= !Self::IRQD_TRIGGER_MASK.bits; 534ce5850adSLoGin self.bits |= trigger.bits & Self::IRQD_TRIGGER_MASK.bits; 535ce5850adSLoGin 536ce5850adSLoGin self.bits |= Self::IRQD_DEFAULT_TRIGGER_SET.bits; 537ce5850adSLoGin } 538ce5850adSLoGin 539ce5850adSLoGin pub const fn is_level_type(&self) -> bool { 540ce5850adSLoGin self.contains(Self::IRQD_LEVEL) 541ce5850adSLoGin } 542ce5850adSLoGin 543ce5850adSLoGin /// Must only be called of irqchip.irq_set_affinity() or low level 544ce5850adSLoGin /// hierarchy domain allocation functions. 545ce5850adSLoGin pub fn set_single_target(&mut self) { 546ce5850adSLoGin self.insert(Self::IRQD_SINGLE_TARGET); 547ce5850adSLoGin } 548ce5850adSLoGin 549ce5850adSLoGin pub const fn is_single_target(&self) -> bool { 550ce5850adSLoGin self.contains(Self::IRQD_SINGLE_TARGET) 551ce5850adSLoGin } 552ce5850adSLoGin 553ce5850adSLoGin pub fn set_handle_enforce_irqctx(&mut self) { 554ce5850adSLoGin self.insert(Self::IRQD_HANDLE_ENFORCE_IRQCTX); 555ce5850adSLoGin } 556ce5850adSLoGin 557ce5850adSLoGin pub const fn is_handle_enforce_irqctx(&self) -> bool { 558ce5850adSLoGin self.contains(Self::IRQD_HANDLE_ENFORCE_IRQCTX) 559ce5850adSLoGin } 560ce5850adSLoGin 561ce5850adSLoGin pub const fn is_enabled_on_suspend(&self) -> bool { 562ce5850adSLoGin self.contains(Self::IRQD_IRQ_ENABLED_ON_SUSPEND) 563ce5850adSLoGin } 564ce5850adSLoGin 565ce5850adSLoGin pub const fn is_wakeup_set(&self) -> bool { 566ce5850adSLoGin self.contains(Self::IRQD_WAKEUP_STATE) 567ce5850adSLoGin } 568ce5850adSLoGin 569ce5850adSLoGin pub const fn can_move_in_process_context(&self) -> bool { 570ce5850adSLoGin self.contains(Self::IRQD_MOVE_PCNTXT) 571ce5850adSLoGin } 572ce5850adSLoGin 573ce5850adSLoGin pub const fn is_irq_in_progress(&self) -> bool { 574ce5850adSLoGin self.contains(Self::IRQD_IRQ_INPROGRESS) 575ce5850adSLoGin } 576ce5850adSLoGin 577ce5850adSLoGin pub const fn is_wakeup_armed(&self) -> bool { 578ce5850adSLoGin self.contains(Self::IRQD_WAKEUP_ARMED) 579ce5850adSLoGin } 580ce5850adSLoGin 581ce5850adSLoGin pub const fn is_forwarded_to_vcpu(&self) -> bool { 582ce5850adSLoGin self.contains(Self::IRQD_FORWARDED_TO_VCPU) 583ce5850adSLoGin } 584ce5850adSLoGin 585ce5850adSLoGin pub fn set_forwarded_to_vcpu(&mut self) { 586ce5850adSLoGin self.insert(Self::IRQD_FORWARDED_TO_VCPU); 587ce5850adSLoGin } 588ce5850adSLoGin 589e2841179SLoGin pub const fn affinity_managed(&self) -> bool { 590ce5850adSLoGin self.contains(Self::IRQD_AFFINITY_MANAGED) 591ce5850adSLoGin } 592ce5850adSLoGin 593ce5850adSLoGin pub const fn is_activated(&self) -> bool { 594ce5850adSLoGin self.contains(Self::IRQD_ACTIVATED) 595ce5850adSLoGin } 596ce5850adSLoGin 597ce5850adSLoGin pub fn set_activated(&mut self) { 598ce5850adSLoGin self.insert(Self::IRQD_ACTIVATED); 599ce5850adSLoGin } 600ce5850adSLoGin 601ce5850adSLoGin pub fn clear_activated(&mut self) { 602ce5850adSLoGin self.remove(Self::IRQD_ACTIVATED); 603ce5850adSLoGin } 604ce5850adSLoGin 605ce5850adSLoGin pub const fn is_started(&self) -> bool { 606ce5850adSLoGin self.contains(Self::IRQD_IRQ_STARTED) 607ce5850adSLoGin } 608ce5850adSLoGin 609ce5850adSLoGin pub const fn is_managed_and_shutdown(&self) -> bool { 610ce5850adSLoGin self.contains(Self::IRQD_MANAGED_SHUTDOWN) 611ce5850adSLoGin } 612ce5850adSLoGin 613ce5850adSLoGin pub fn set_can_reserve(&mut self) { 614ce5850adSLoGin self.insert(Self::IRQD_CAN_RESERVE); 615ce5850adSLoGin } 616ce5850adSLoGin 617ce5850adSLoGin pub const fn can_reserve(&self) -> bool { 618ce5850adSLoGin self.contains(Self::IRQD_CAN_RESERVE) 619ce5850adSLoGin } 620ce5850adSLoGin 621ce5850adSLoGin pub fn clear_can_reserve(&mut self) { 622ce5850adSLoGin self.remove(Self::IRQD_CAN_RESERVE); 623ce5850adSLoGin } 624ce5850adSLoGin 625ce5850adSLoGin pub fn set_msi_nomask_quirk(&mut self) { 626ce5850adSLoGin self.insert(Self::IRQD_MSI_NOMASK_QUIRK); 627ce5850adSLoGin } 628ce5850adSLoGin 629ce5850adSLoGin pub fn clear_msi_nomask_quirk(&mut self) { 630ce5850adSLoGin self.remove(Self::IRQD_MSI_NOMASK_QUIRK); 631ce5850adSLoGin } 632ce5850adSLoGin 633ce5850adSLoGin pub const fn is_msi_nomask_quirk(&self) -> bool { 634ce5850adSLoGin self.contains(Self::IRQD_MSI_NOMASK_QUIRK) 635ce5850adSLoGin } 636ce5850adSLoGin 637ce5850adSLoGin pub fn set_affinity_on_activate(&mut self) { 638ce5850adSLoGin self.insert(Self::IRQD_AFFINITY_ON_ACTIVATE); 639ce5850adSLoGin } 640ce5850adSLoGin 641ce5850adSLoGin pub const fn is_affinity_on_activate(&self) -> bool { 642ce5850adSLoGin self.contains(Self::IRQD_AFFINITY_ON_ACTIVATE) 643ce5850adSLoGin } 644e2841179SLoGin 645e2841179SLoGin pub const fn started(&self) -> bool { 646e2841179SLoGin self.contains(Self::IRQD_IRQ_STARTED) 647e2841179SLoGin } 648ce5850adSLoGin } 649