1use core::fmt;
7use hashbrown::HashMap;
8
9use crate::arch::{self, interrupt::enable_external_interrupts};
10
11pub mod controllers;
12
13pub type InterruptId = u32;
15
16pub type CpuId = u32;
18
19pub type Priority = u32;
21
22
23pub struct InterruptHandle<'a> {
28 interrupt_id: InterruptId,
29 cpu_id: CpuId,
30 completed: bool,
31 manager: &'a mut InterruptManager,
32}
33
34impl<'a> InterruptHandle<'a> {
35 pub fn new(interrupt_id: InterruptId, cpu_id: CpuId, manager: &'a mut InterruptManager) -> Self {
37 Self {
38 interrupt_id,
39 cpu_id,
40 completed: false,
41 manager,
42 }
43 }
44
45 pub fn interrupt_id(&self) -> InterruptId {
47 self.interrupt_id
48 }
49
50 pub fn cpu_id(&self) -> CpuId {
52 self.cpu_id
53 }
54
55 pub fn complete(&mut self) -> InterruptResult<()> {
59 if self.completed {
60 return Err(InterruptError::InvalidOperation);
61 }
62
63 self.manager.complete_external_interrupt(self.cpu_id, self.interrupt_id)?;
64 self.completed = true;
65 Ok(())
66 }
67
68 pub fn is_completed(&self) -> bool {
70 self.completed
71 }
72
73 pub fn enable_interrupt(&mut self, target_interrupt: InterruptId) -> InterruptResult<()> {
75 self.manager.enable_external_interrupt(target_interrupt, self.cpu_id)
76 }
77
78 pub fn disable_interrupt(&mut self, target_interrupt: InterruptId) -> InterruptResult<()> {
80 self.manager.disable_external_interrupt(target_interrupt, self.cpu_id)
81 }
82}
83
84impl<'a> Drop for InterruptHandle<'a> {
85 fn drop(&mut self) {
86 if !self.completed {
87 let _ = self.complete();
89 }
90 }
91}
92
93pub type InterruptResult<T = ()> = Result<T, InterruptError>;
95
96#[derive(Debug, Clone, Copy, PartialEq, Eq)]
98pub enum InterruptError {
99 InvalidInterruptId,
101 InvalidCpuId,
103 ControllerNotFound,
105 HandlerAlreadyRegistered,
107 HandlerNotFound,
109 InvalidPriority,
111 NotSupported,
113 HardwareError,
115 InvalidOperation,
117}
118
119impl fmt::Display for InterruptError {
120 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121 match self {
122 InterruptError::InvalidInterruptId => write!(f, "Invalid interrupt ID"),
123 InterruptError::InvalidCpuId => write!(f, "Invalid CPU ID"),
124 InterruptError::ControllerNotFound => write!(f, "Controller not found"),
125 InterruptError::HandlerAlreadyRegistered => write!(f, "Handler already registered"),
126 InterruptError::HandlerNotFound => write!(f, "Handler not found"),
127 InterruptError::InvalidPriority => write!(f, "Invalid priority"),
128 InterruptError::NotSupported => write!(f, "Operation not supported"),
129 InterruptError::HardwareError => write!(f, "Hardware error"),
130 InterruptError::InvalidOperation => write!(f, "Invalid operation"),
131 }
132 }
133}
134
135pub fn enable_interrupts() {
137 arch::interrupt::enable_interrupts();
138}
139
140pub fn disable_interrupts() {
142 arch::interrupt::disable_interrupts();
143}
144
145pub fn with_interrupts_disabled<F, R>(f: F) -> R
147where
148 F: FnOnce() -> R,
149{
150 arch::interrupt::with_interrupts_disabled(f)
151}
152
153pub fn are_interrupts_enabled() -> bool {
155 arch::interrupt::are_interrupts_enabled()
156}
157
158pub struct InterruptManager {
162 controllers: controllers::InterruptControllers,
163 external_handlers: spin::Mutex<HashMap<InterruptId, ExternalInterruptHandler>>,
164 interrupt_devices: spin::Mutex<HashMap<InterruptId, alloc::sync::Arc<dyn crate::device::events::InterruptCapableDevice>>>,
165}
166
167impl InterruptManager {
168
169 pub fn new() -> Self {
171 Self {
172 controllers: controllers::InterruptControllers::new(),
173 external_handlers: spin::Mutex::new(HashMap::new()),
174 interrupt_devices: spin::Mutex::new(HashMap::new()),
175 }
176 }
177
178 pub fn global() -> &'static spin::Mutex<InterruptManager> {
180 static INTERRUPT_MANAGER: spin::Once<spin::Mutex<InterruptManager>> = spin::Once::new();
181 INTERRUPT_MANAGER.call_once(|| spin::Mutex::new(InterruptManager::new()))
182 }
183
184 pub fn get_manager() -> spin::MutexGuard<'static, InterruptManager> {
189 Self::global().lock()
190 }
191
192 pub fn with_manager<F, R>(f: F) -> R
196 where
197 F: FnOnce(&mut InterruptManager) -> R,
198 {
199 f(&mut Self::global().lock())
200 }
201
202 pub fn init(&mut self) {
203 match self.controllers.init_local_controllers() {
205 Ok(()) => {}
206 Err(e) => {
207 crate::early_println!("Failed to initialize local controllers: {}", e);
208 }
209 }
210
211 match self.controllers.init_external_controller() {
213 Ok(()) => {}
214 Err(e) => {
215 crate::early_println!("Failed to initialize external controller: {}", e);
216 }
217 }
218
219
220 enable_external_interrupts(); enable_interrupts(); }
224
225 pub fn handle_external_interrupt(&mut self, interrupt_id: InterruptId, cpu_id: CpuId) -> InterruptResult<()> {
227 let device = {
229 let devices = self.interrupt_devices.lock();
230 devices.get(&interrupt_id).cloned()
231 };
232
233 if let Some(device) = device {
234 device.handle_interrupt()?;
236 self.complete_external_interrupt(cpu_id, interrupt_id)
237 } else {
238 let handler = {
240 let handlers = self.external_handlers.lock();
241 handlers.get(&interrupt_id).copied()
242 };
243
244 if let Some(handler_fn) = handler {
245 let mut handle = InterruptHandle::new(interrupt_id, cpu_id, self);
246 handler_fn(&mut handle)
247 } else {
248 self.complete_external_interrupt(cpu_id, interrupt_id)
250 }
251 }
252 }
253
254 pub fn claim_and_handle_external_interrupt(&mut self, cpu_id: CpuId) -> InterruptResult<Option<InterruptId>> {
256 let interrupt_id = if let Some(ref mut controller) = self.controllers.external_controller_mut() {
257 controller.claim_interrupt(cpu_id)?
258 } else {
259 return Err(InterruptError::ControllerNotFound);
260 };
261
262 if let Some(id) = interrupt_id {
263 self.handle_external_interrupt(id, cpu_id)?;
264 Ok(Some(id))
265 } else {
266 Ok(None)
267 }
268 }
269
270 pub fn enable_local_interrupt(&mut self, cpu_id: CpuId, interrupt_type: controllers::LocalInterruptType) -> InterruptResult<()> {
272 if let Some(ref mut controller) = self.controllers.local_controller_mut_for_cpu(cpu_id) {
273 controller.enable_interrupt(cpu_id, interrupt_type)
274 } else {
275 Err(InterruptError::ControllerNotFound)
276 }
277 }
278
279 pub fn disable_local_interrupt(&mut self, cpu_id: CpuId, interrupt_type: controllers::LocalInterruptType) -> InterruptResult<()> {
281 if let Some(ref mut controller) = self.controllers.local_controller_mut_for_cpu(cpu_id) {
282 controller.disable_interrupt(cpu_id, interrupt_type)
283 } else {
284 Err(InterruptError::ControllerNotFound)
285 }
286 }
287
288 pub fn send_software_interrupt(&mut self, target_cpu: CpuId) -> InterruptResult<()> {
290 if let Some(ref mut controller) = self.controllers.local_controller_mut_for_cpu(target_cpu) {
291 controller.send_software_interrupt(target_cpu)
292 } else {
293 Err(InterruptError::ControllerNotFound)
294 }
295 }
296
297 pub fn set_timer(&mut self, cpu_id: CpuId, time: u64) -> InterruptResult<()> {
299 if let Some(ref mut controller) = self.controllers.local_controller_mut_for_cpu(cpu_id) {
300 controller.set_timer(cpu_id, time)
301 } else {
302 Err(InterruptError::ControllerNotFound)
303 }
304 }
305
306 pub fn register_local_controller(&mut self, controller: alloc::boxed::Box<dyn controllers::LocalInterruptController>, cpu_ids: &[CpuId]) -> InterruptResult<usize> {
308 Ok(self.controllers.register_local_controller(controller, cpu_ids))
309 }
310
311 pub fn register_local_controller_for_range(&mut self, controller: alloc::boxed::Box<dyn controllers::LocalInterruptController>, cpu_range: core::ops::Range<CpuId>) -> InterruptResult<usize> {
313 Ok(self.controllers.register_local_controller_for_range(controller, cpu_range))
314 }
315
316 pub fn register_local_controller_for_cpu(&mut self, controller: alloc::boxed::Box<dyn controllers::LocalInterruptController>, cpu_id: CpuId) -> InterruptResult<usize> {
318 Ok(self.controllers.register_local_controller_for_cpu(controller, cpu_id))
319 }
320
321 pub fn register_external_controller(&mut self, controller: alloc::boxed::Box<dyn controllers::ExternalInterruptController>) -> InterruptResult<()> {
323 if self.controllers.has_external_controller() {
324 return Err(InterruptError::HardwareError);
325 }
326 self.controllers.register_external_controller(controller);
327 Ok(())
328 }
329
330 pub fn register_external_handler(&mut self, interrupt_id: InterruptId, handler: ExternalInterruptHandler) -> InterruptResult<()> {
332 let mut handlers = self.external_handlers.lock();
333 if handlers.contains_key(&interrupt_id) {
334 return Err(InterruptError::HandlerAlreadyRegistered);
335 }
336 handlers.insert(interrupt_id, handler);
337 Ok(())
338 }
339
340 pub fn register_interrupt_device(&mut self, interrupt_id: InterruptId, device: alloc::sync::Arc<dyn crate::device::events::InterruptCapableDevice>) -> InterruptResult<()> {
342 let mut devices = self.interrupt_devices.lock();
343 if devices.contains_key(&interrupt_id) {
344 return Err(InterruptError::HandlerAlreadyRegistered);
345 }
346 devices.insert(interrupt_id, device);
347 Ok(())
348 }
349
350 pub fn complete_external_interrupt(&mut self, cpu_id: CpuId, interrupt_id: InterruptId) -> InterruptResult<()> {
352 if let Some(ref mut controller) = self.controllers.external_controller_mut() {
353 controller.complete_interrupt(cpu_id, interrupt_id)
354 } else {
355 Err(InterruptError::ControllerNotFound)
356 }
357 }
358
359 pub fn enable_external_interrupt(&mut self, interrupt_id: InterruptId, cpu_id: CpuId) -> InterruptResult<()> {
361 if let Some(ref mut controller) = self.controllers.external_controller_mut() {
362 controller.enable_interrupt(interrupt_id, cpu_id)
363 } else {
364 Err(InterruptError::ControllerNotFound)
365 }
366 }
367
368 pub fn disable_external_interrupt(&mut self, interrupt_id: InterruptId, cpu_id: CpuId) -> InterruptResult<()> {
370 if let Some(ref mut controller) = self.controllers.external_controller_mut() {
371 controller.disable_interrupt(interrupt_id, cpu_id)
372 } else {
373 Err(InterruptError::ControllerNotFound)
374 }
375 }
376
377 pub fn has_local_controller(&self) -> bool {
379 self.controllers.has_local_controller()
380 }
381
382 pub fn has_external_controller(&self) -> bool {
384 self.controllers.has_external_controller()
385 }
386}
387
388pub type ExternalInterruptHandler = fn(&mut InterruptHandle) -> InterruptResult<()>;
390
391pub type LocalInterruptHandler = fn(cpu_id: CpuId, interrupt_type: controllers::LocalInterruptType) -> InterruptResult<()>;