kernel/interrupt/
controllers.rs1use crate::interrupt::InterruptError;
6
7use super::{InterruptId, CpuId, Priority, InterruptResult};
8use alloc::boxed::Box;
9
10pub trait LocalInterruptController: Send + Sync {
15 fn init(&mut self, cpu_id: CpuId) -> InterruptResult<()>;
17
18 fn enable_interrupt(&mut self, cpu_id: CpuId, interrupt_type: LocalInterruptType) -> InterruptResult<()>;
20
21 fn disable_interrupt(&mut self, cpu_id: CpuId, interrupt_type: LocalInterruptType) -> InterruptResult<()>;
23
24 fn is_pending(&self, cpu_id: CpuId, interrupt_type: LocalInterruptType) -> bool;
26
27 fn clear_interrupt(&mut self, cpu_id: CpuId, interrupt_type: LocalInterruptType) -> InterruptResult<()>;
29
30 fn send_software_interrupt(&mut self, target_cpu: CpuId) -> InterruptResult<()>;
32
33 fn clear_software_interrupt(&mut self, cpu_id: CpuId) -> InterruptResult<()>;
35
36 fn set_timer(&mut self, cpu_id: CpuId, time: u64) -> InterruptResult<()>;
38
39 fn get_time(&self) -> u64;
41}
42
43pub trait ExternalInterruptController: Send + Sync {
48 fn init(&mut self) -> InterruptResult<()>;
50
51 fn enable_interrupt(&mut self, interrupt_id: InterruptId, cpu_id: CpuId) -> InterruptResult<()>;
53
54 fn disable_interrupt(&mut self, interrupt_id: InterruptId, cpu_id: CpuId) -> InterruptResult<()>;
56
57 fn set_priority(&mut self, interrupt_id: InterruptId, priority: Priority) -> InterruptResult<()>;
59
60 fn get_priority(&self, interrupt_id: InterruptId) -> InterruptResult<Priority>;
62
63 fn set_threshold(&mut self, cpu_id: CpuId, threshold: Priority) -> InterruptResult<()>;
65
66 fn get_threshold(&self, cpu_id: CpuId) -> InterruptResult<Priority>;
68
69 fn claim_interrupt(&mut self, cpu_id: CpuId) -> InterruptResult<Option<InterruptId>>;
71
72 fn complete_interrupt(&mut self, cpu_id: CpuId, interrupt_id: InterruptId) -> InterruptResult<()>;
74
75 fn is_pending(&self, interrupt_id: InterruptId) -> bool;
77
78 fn max_interrupts(&self) -> InterruptId;
80
81 fn max_cpus(&self) -> CpuId;
83}
84
85#[derive(Debug, Clone, Copy, PartialEq, Eq)]
87pub enum LocalInterruptType {
88 Timer,
90 Software,
92 External,
94}
95
96pub struct InterruptControllers {
102 local_controllers: alloc::vec::Vec<Box<dyn LocalInterruptController>>,
103 external_controller: Option<Box<dyn ExternalInterruptController>>,
104 cpu_to_local_controller: alloc::collections::BTreeMap<CpuId, usize>, }
106
107unsafe impl Send for InterruptControllers {}
108unsafe impl Sync for InterruptControllers {}
109
110impl InterruptControllers {
111 pub fn new() -> Self {
113 Self {
114 local_controllers: alloc::vec::Vec::new(),
115 external_controller: None,
116 cpu_to_local_controller: alloc::collections::BTreeMap::new(),
117 }
118 }
119
120 pub fn register_local_controller(&mut self, controller: Box<dyn LocalInterruptController>, cpu_ids: &[CpuId]) -> usize {
123 let controller_index = self.local_controllers.len();
124 self.local_controllers.push(controller);
125
126 for &cpu_id in cpu_ids {
128 self.cpu_to_local_controller.insert(cpu_id, controller_index);
129 }
130
131 controller_index
132 }
133
134 pub fn register_local_controller_for_cpu(&mut self, controller: Box<dyn LocalInterruptController>, cpu_id: CpuId) -> usize {
137 self.register_local_controller(controller, &[cpu_id])
138 }
139
140 pub fn register_local_controller_for_range(&mut self, controller: Box<dyn LocalInterruptController>, cpu_range: core::ops::Range<CpuId>) -> usize {
143 let cpu_ids: alloc::vec::Vec<CpuId> = cpu_range.collect();
144 self.register_local_controller(controller, &cpu_ids)
145 }
146
147 pub fn register_external_controller(&mut self, controller: Box<dyn ExternalInterruptController>) {
149 self.external_controller = Some(controller);
150 }
151
152 pub fn local_controller_mut_for_cpu(&mut self, cpu_id: CpuId) -> Option<&mut Box<dyn LocalInterruptController>> {
154 let controller_index = self.cpu_to_local_controller.get(&cpu_id)?;
155 self.local_controllers.get_mut(*controller_index)
156 }
157
158 pub fn local_controller_mut(&mut self, index: usize) -> Option<&mut Box<dyn LocalInterruptController>> {
160 self.local_controllers.get_mut(index)
161 }
162
163 pub fn external_controller_mut(&mut self) -> Option<&mut Box<dyn ExternalInterruptController>> {
165 self.external_controller.as_mut()
166 }
167
168 pub fn init_local_controllers(&mut self) -> InterruptResult<()> {
170 for (cpu_id, &controller_index) in &self.cpu_to_local_controller {
171 if let Some(controller) = self.local_controllers.get_mut(controller_index) {
172 controller.init(*cpu_id)?;
173 } else {
174 return Err(InterruptError::ControllerNotFound);
175 }
176 }
177 Ok(())
178 }
179
180 pub fn init_external_controller(&mut self) -> InterruptResult<()> {
182 if let Some(controller) = self.external_controller.as_mut() {
183 controller.init()?;
184 Ok(())
185 } else {
186 Err(InterruptError::ControllerNotFound)
187 }
188 }
189
190 pub fn has_local_controller_for_cpu(&self, cpu_id: CpuId) -> bool {
192 self.cpu_to_local_controller.contains_key(&cpu_id)
193 }
194
195 pub fn has_local_controller(&self) -> bool {
197 !self.local_controllers.is_empty()
198 }
199
200 pub fn has_external_controller(&self) -> bool {
202 self.external_controller.is_some()
203 }
204
205 pub fn local_controller_count(&self) -> usize {
207 self.local_controllers.len()
208 }
209
210 pub fn cpus_for_controller(&self, controller_index: usize) -> alloc::vec::Vec<CpuId> {
212 self.cpu_to_local_controller
213 .iter()
214 .filter_map(|(cpu_id, &index)| {
215 if index == controller_index {
216 Some(*cpu_id)
217 } else {
218 None
219 }
220 })
221 .collect()
222 }
223}