xref: /DragonOS/kernel/src/exception/dummychip.rs (revision a8753f8fffb992e4d3bbd21eda431081b395af6b)
1 use alloc::sync::Arc;
2 use system_error::SystemError;
3 
4 use crate::arch::CurrentIrqArch;
5 
6 use super::{
7     irqchip::{IrqChip, IrqChipFlags},
8     irqdata::IrqData,
9     InterruptArch,
10 };
11 
12 static mut NO_IRQ_CHIP: Option<Arc<NoIrqChip>> = None;
13 static mut DUMMY_IRQ_CHIP: Option<Arc<DummyIrqChip>> = None;
14 
15 #[inline(never)]
16 pub fn no_irq_chip() -> Arc<dyn IrqChip> {
17     unsafe { NO_IRQ_CHIP.as_ref().unwrap().clone() }
18 }
19 
20 #[allow(dead_code)]
21 #[inline(never)]
22 pub fn dummy_irq_chip() -> Arc<dyn IrqChip> {
23     unsafe { DUMMY_IRQ_CHIP.as_ref().unwrap().clone() }
24 }
25 
26 fn ack_bad(irq_data: &Arc<IrqData>) {
27     // todo: print_irq_desc
28     CurrentIrqArch::ack_bad_irq(irq_data.irq());
29 }
30 
31 #[derive(Debug)]
32 struct NoIrqChip;
33 
34 impl NoIrqChip {
35     pub const fn new() -> Self {
36         NoIrqChip
37     }
38 }
39 
40 impl IrqChip for NoIrqChip {
41     fn name(&self) -> &'static str {
42         "none"
43     }
44 
45     fn can_mask_ack(&self) -> bool {
46         false
47     }
48 
49     fn irq_enable(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
50         Ok(())
51     }
52 
53     fn can_set_affinity(&self) -> bool {
54         false
55     }
56 
57     fn can_set_flow_type(&self) -> bool {
58         false
59     }
60 
61     fn irq_disable(&self, _irq: &Arc<IrqData>) {}
62 
63     fn irq_ack(&self, irq: &Arc<IrqData>) {
64         ack_bad(irq);
65     }
66 
67     fn irq_startup(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
68         Ok(())
69     }
70 
71     fn irq_shutdown(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
72         Ok(())
73     }
74 
75     fn flags(&self) -> IrqChipFlags {
76         IrqChipFlags::IRQCHIP_SKIP_SET_WAKE
77     }
78 }
79 
80 #[derive(Debug)]
81 struct DummyIrqChip;
82 
83 impl DummyIrqChip {
84     pub const fn new() -> Self {
85         DummyIrqChip
86     }
87 }
88 
89 impl IrqChip for DummyIrqChip {
90     fn name(&self) -> &'static str {
91         "dummy"
92     }
93 
94     fn can_mask_ack(&self) -> bool {
95         false
96     }
97 
98     fn irq_enable(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
99         Ok(())
100     }
101 
102     fn can_set_flow_type(&self) -> bool {
103         false
104     }
105 
106     fn can_set_affinity(&self) -> bool {
107         false
108     }
109 
110     fn irq_disable(&self, _irq: &Arc<IrqData>) {}
111 
112     fn irq_ack(&self, _irq: &Arc<IrqData>) {}
113 
114     fn irq_startup(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
115         Ok(())
116     }
117 
118     fn irq_shutdown(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
119         Ok(())
120     }
121 
122     fn flags(&self) -> IrqChipFlags {
123         IrqChipFlags::IRQCHIP_SKIP_SET_WAKE
124     }
125 }
126 
127 #[inline(never)]
128 pub fn dummy_chip_init() {
129     unsafe {
130         NO_IRQ_CHIP = Some(Arc::new(NoIrqChip::new()));
131         DUMMY_IRQ_CHIP = Some(Arc::new(DummyIrqChip::new()));
132     }
133 }
134