xref: /DragonOS/kernel/src/exception/irqdata.rs (revision b5b571e02693d91eb6918d3b7561e088c3e7ee81)
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