1use alloc::{
6 collections::btree_map::{BTreeMap, Entry},
7 sync::Arc,
8 vec::Vec,
9};
10
11pub mod plic;
12
13use crate::{arch::intr::enable_irq, device::Driver};
14
15pub struct IrqManager {
17 root: bool,
19 mapping: BTreeMap<usize, Vec<Arc<dyn Driver>>>,
22 all: Vec<Arc<dyn Driver>>,
25}
26
27impl IrqManager {
28 pub fn new(root: bool) -> IrqManager {
34 IrqManager {
35 root,
36 mapping: BTreeMap::new(),
37 all: Vec::new(),
38 }
39 }
40
41 pub fn register_irq(&mut self, irq: usize, driver: Arc<dyn Driver>) {
46 if self.root {
49 enable_irq(irq);
50 }
51 match self.mapping.entry(irq) {
52 Entry::Occupied(mut e) => {
53 e.get_mut().push(driver);
54 }
55 Entry::Vacant(e) => {
56 let mut v = Vec::new();
57 v.push(driver);
58 e.insert(v);
59 }
60 }
61 }
62
63 pub fn register_all(&mut self, driver: Arc<dyn Driver>) {
67 self.all.push(driver);
68 }
69
70 pub fn register_opt(&mut self, irq_opt: Option<usize>, driver: Arc<dyn Driver>) {
75 if let Some(irq) = irq_opt {
76 self.register_irq(irq, driver);
77 } else {
78 self.register_all(driver);
79 }
80 }
81
82 pub fn deregister_irq(&mut self, irq: usize, driver: Arc<dyn Driver>) {
87 if let Some(e) = self.mapping.get_mut(&irq) {
88 e.retain(|d| !Arc::ptr_eq(d, &driver));
89 }
90 }
91
92 pub fn deregister_all(&mut self, driver: Arc<dyn Driver>) {
96 self.all.retain(|d| !Arc::ptr_eq(d, &driver));
97 }
98
99 pub fn try_handle_interrupt(&self, irq_opt: Option<usize>) -> bool {
105 if let Some(irq) = irq_opt {
106 if let Some(e) = self.mapping.get(&irq) {
107 for dri in e.iter() {
108 if dri.try_handle_interrupt(Some(irq)) {
109 return true;
110 }
111 }
112 }
113 }
114
115 for dri in self.all.iter() {
116 if dri.try_handle_interrupt(irq_opt) {
117 return true;
118 }
119 }
120 false
121 }
122}
123
124pub trait IntcDriver: Driver {
126 fn register_local_irq(&self, irq: usize, driver: Arc<dyn Driver>);
131}