xref: /DragonOS/kernel/src/exception/dummychip.rs (revision d2b28acb4d1f160779b25d76afca49ed60ad5d48)
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     fn irq_enable(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
45         Ok(())
46     }
47 
48     fn irq_disable(&self, _irq: &Arc<IrqData>) {}
49 
50     fn irq_ack(&self, irq: &Arc<IrqData>) {
51         ack_bad(irq);
52     }
53 
54     fn irq_startup(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
55         Ok(())
56     }
57 
58     fn irq_shutdown(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
59         Ok(())
60     }
61 
62     fn flags(&self) -> IrqChipFlags {
63         IrqChipFlags::IRQCHIP_SKIP_SET_WAKE
64     }
65 }
66 
67 #[derive(Debug)]
68 struct DummyIrqChip;
69 
70 impl DummyIrqChip {
71     pub const fn new() -> Self {
72         DummyIrqChip
73     }
74 }
75 
76 impl IrqChip for DummyIrqChip {
77     fn name(&self) -> &'static str {
78         "dummy"
79     }
80 
81     fn irq_enable(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
82         Ok(())
83     }
84 
85     fn irq_disable(&self, _irq: &Arc<IrqData>) {}
86 
87     fn irq_ack(&self, _irq: &Arc<IrqData>) {}
88 
89     fn irq_mask(&self, _irq: &Arc<IrqData>) {}
90     fn irq_unmask(&self, _irq: &Arc<IrqData>) {}
91 
92     fn irq_startup(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
93         Ok(())
94     }
95 
96     fn irq_shutdown(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
97         Ok(())
98     }
99 
100     fn flags(&self) -> IrqChipFlags {
101         IrqChipFlags::IRQCHIP_SKIP_SET_WAKE
102     }
103 }
104 
105 #[inline(never)]
106 pub fn dummy_chip_init() {
107     unsafe {
108         NO_IRQ_CHIP = Some(Arc::new(NoIrqChip::new()));
109         DUMMY_IRQ_CHIP = Some(Arc::new(DummyIrqChip::new()));
110     }
111 }
112