kernel/interrupt/
mod.rs

1//! Interrupt management system
2//! 
3//! This module provides a comprehensive interrupt management system for the Scarlet kernel.
4//! It supports both local interrupts (via CLINT) and external interrupts (via PLIC) on RISC-V architecture.
5
6use core::fmt;
7use hashbrown::HashMap;
8
9use crate::arch::{self, interrupt::enable_external_interrupts};
10
11pub mod controllers;
12
13/// Interrupt ID type
14pub type InterruptId = u32;
15
16/// CPU ID type
17pub type CpuId = u32;
18
19/// Priority level for interrupts
20pub type Priority = u32;
21
22
23/// Handle for managing interrupt processing
24/// 
25/// This provides a safe interface for interrupt handlers to interact with
26/// the interrupt controller without direct access.
27pub 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    /// Create a new interrupt handle
36    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    /// Get the interrupt ID
46    pub fn interrupt_id(&self) -> InterruptId {
47        self.interrupt_id
48    }
49
50    /// Get the CPU ID
51    pub fn cpu_id(&self) -> CpuId {
52        self.cpu_id
53    }
54
55    /// Mark the interrupt as completed
56    /// 
57    /// This should be called when the handler has finished processing the interrupt.
58    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    /// Check if the interrupt has been completed
69    pub fn is_completed(&self) -> bool {
70        self.completed
71    }
72
73    /// Enable another interrupt
74    pub fn enable_interrupt(&mut self, target_interrupt: InterruptId) -> InterruptResult<()> {
75        self.manager.enable_external_interrupt(target_interrupt, self.cpu_id)
76    }
77
78    /// Disable another interrupt
79    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            // Auto-complete if not manually completed
88            let _ = self.complete();
89        }
90    }
91}
92
93/// Result type for interrupt operations
94pub type InterruptResult<T = ()> = Result<T, InterruptError>;
95
96/// Errors that can occur during interrupt management
97#[derive(Debug, Clone, Copy, PartialEq, Eq)]
98pub enum InterruptError {
99    /// Invalid interrupt ID
100    InvalidInterruptId,
101    /// Invalid CPU ID
102    InvalidCpuId,
103    /// Controller not found
104    ControllerNotFound,
105    /// Handler already registered
106    HandlerAlreadyRegistered,
107    /// Handler not found
108    HandlerNotFound,
109    /// Invalid priority
110    InvalidPriority,
111    /// Operation not supported
112    NotSupported,
113    /// Hardware error
114    HardwareError,
115    /// Invalid operation
116    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
135/// Enable interrupts globally
136pub fn enable_interrupts() {
137    arch::interrupt::enable_interrupts();
138}
139
140/// Disable interrupts globally
141pub fn disable_interrupts() {
142    arch::interrupt::disable_interrupts();
143}
144
145/// Execute a closure with interrupts disabled
146pub fn with_interrupts_disabled<F, R>(f: F) -> R
147where
148    F: FnOnce() -> R,
149{
150    arch::interrupt::with_interrupts_disabled(f)
151}
152
153/// Check if interrupts are currently enabled
154pub fn are_interrupts_enabled() -> bool {
155    arch::interrupt::are_interrupts_enabled()
156}
157
158/// Unified interrupt manager
159/// 
160/// This manages both local and external interrupts in a single structure.
161pub 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    /// Create a new interrupt manager
170    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    /// Get a reference to the global interrupt manager
179    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    /// Get a mutable reference to the global interrupt manager (convenience method)
185    /// 
186    /// This method locks the global manager and returns a guard.
187    /// Use this when you need to perform multiple operations atomically.
188    pub fn get_manager() -> spin::MutexGuard<'static, InterruptManager> {
189        Self::global().lock()
190    }
191
192    /// Execute a closure with mutable access to the global interrupt manager
193    /// 
194    /// This is a convenience method that automatically handles locking and unlocking.
195    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        // Initialize local controllers (e.g., CLINT)
204        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        // Initialize external controller (e.g., PLIC)
212        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 external interrupts
221        // Timer interrupts are disabled by default, enable them if needed by scheduler or other components
222        enable_interrupts(); // Enable interrupts globally
223    }
224
225    /// Handle an external interrupt
226    pub fn handle_external_interrupt(&mut self, interrupt_id: InterruptId, cpu_id: CpuId) -> InterruptResult<()> {
227        // First, check for device-based handlers
228        let device = {
229            let devices = self.interrupt_devices.lock();
230            devices.get(&interrupt_id).cloned()
231        };
232        
233        if let Some(device) = device {
234            // Call device's interrupt handler
235            device.handle_interrupt()?;
236            self.complete_external_interrupt(cpu_id, interrupt_id)
237        } else {
238            // Fall back to function-based handlers
239            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                // No handler registered - just complete the interrupt
249                self.complete_external_interrupt(cpu_id, interrupt_id)
250            }
251        }
252    }
253
254    /// Claim and handle the next pending external interrupt
255    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    /// Enable a local interrupt type for a CPU
271    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    /// Disable a local interrupt type for a CPU
280    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    /// Send a software interrupt to a specific CPU
289    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    /// Set timer interrupt for a specific CPU
298    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    /// Register a local interrupt controller (e.g., CLINT) for specific CPUs
307    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    /// Register a local interrupt controller for a CPU range
312    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    /// Register a local interrupt controller for a single CPU
317    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    /// Register an external interrupt controller (e.g., PLIC)
322    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    /// Register a handler for a specific external interrupt
331    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    /// Register a device-based handler for a specific external interrupt
341    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    /// Complete an external interrupt
351    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    /// Enable an external interrupt for a specific CPU
360    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    /// Disable an external interrupt for a specific CPU
369    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    /// Check if local interrupt controller is registered
378    pub fn has_local_controller(&self) -> bool {
379        self.controllers.has_local_controller()
380    }
381
382    /// Check if external interrupt controller is registered
383    pub fn has_external_controller(&self) -> bool {
384        self.controllers.has_external_controller()
385    }
386}
387
388/// Handler function type for external interrupts
389pub type ExternalInterruptHandler = fn(&mut InterruptHandle) -> InterruptResult<()>;
390
391/// Handler function type for local interrupts (timer, software)
392pub type LocalInterruptHandler = fn(cpu_id: CpuId, interrupt_type: controllers::LocalInterruptType) -> InterruptResult<()>;