kernel/interrupt/
controllers.rs

1//! Interrupt controller trait definitions
2//! 
3//! This module defines the basic traits for local and external interrupt controllers.
4
5use crate::interrupt::InterruptError;
6
7use super::{InterruptId, CpuId, Priority, InterruptResult};
8use alloc::boxed::Box;
9
10/// Trait for local interrupt controllers (like CLINT)
11/// 
12/// Local interrupt controllers manage CPU-local interrupts such as timer interrupts
13/// and software interrupts.
14pub trait LocalInterruptController: Send + Sync {
15    /// Initialize the local interrupt controller for a specific CPU
16    fn init(&mut self, cpu_id: CpuId) -> InterruptResult<()>;
17
18    /// Enable a specific local interrupt type for a CPU
19    fn enable_interrupt(&mut self, cpu_id: CpuId, interrupt_type: LocalInterruptType) -> InterruptResult<()>;
20
21    /// Disable a specific local interrupt type for a CPU
22    fn disable_interrupt(&mut self, cpu_id: CpuId, interrupt_type: LocalInterruptType) -> InterruptResult<()>;
23
24    /// Check if a specific local interrupt type is pending for a CPU
25    fn is_pending(&self, cpu_id: CpuId, interrupt_type: LocalInterruptType) -> bool;
26
27    /// Clear a pending local interrupt for a CPU
28    fn clear_interrupt(&mut self, cpu_id: CpuId, interrupt_type: LocalInterruptType) -> InterruptResult<()>;
29
30    /// Send a software interrupt to a specific CPU
31    fn send_software_interrupt(&mut self, target_cpu: CpuId) -> InterruptResult<()>;
32
33    /// Clear a software interrupt for a specific CPU
34    fn clear_software_interrupt(&mut self, cpu_id: CpuId) -> InterruptResult<()>;
35
36    /// Set timer interrupt for a specific CPU
37    fn set_timer(&mut self, cpu_id: CpuId, time: u64) -> InterruptResult<()>;
38
39    /// Get current timer value
40    fn get_time(&self) -> u64;
41}
42
43/// Trait for external interrupt controllers (like PLIC)
44/// 
45/// External interrupt controllers manage interrupts from external devices
46/// and can route them to different CPUs with priority support.
47pub trait ExternalInterruptController: Send + Sync {
48    /// Initialize the external interrupt controller
49    fn init(&mut self) -> InterruptResult<()>;
50
51    /// Enable a specific interrupt for a CPU
52    fn enable_interrupt(&mut self, interrupt_id: InterruptId, cpu_id: CpuId) -> InterruptResult<()>;
53
54    /// Disable a specific interrupt for a CPU
55    fn disable_interrupt(&mut self, interrupt_id: InterruptId, cpu_id: CpuId) -> InterruptResult<()>;
56
57    /// Set priority for a specific interrupt
58    fn set_priority(&mut self, interrupt_id: InterruptId, priority: Priority) -> InterruptResult<()>;
59
60    /// Get priority for a specific interrupt
61    fn get_priority(&self, interrupt_id: InterruptId) -> InterruptResult<Priority>;
62
63    /// Set priority threshold for a CPU
64    fn set_threshold(&mut self, cpu_id: CpuId, threshold: Priority) -> InterruptResult<()>;
65
66    /// Get priority threshold for a CPU
67    fn get_threshold(&self, cpu_id: CpuId) -> InterruptResult<Priority>;
68
69    /// Claim an interrupt (acknowledge and get the interrupt ID)
70    fn claim_interrupt(&mut self, cpu_id: CpuId) -> InterruptResult<Option<InterruptId>>;
71
72    /// Complete an interrupt (signal that handling is finished)
73    fn complete_interrupt(&mut self, cpu_id: CpuId, interrupt_id: InterruptId) -> InterruptResult<()>;
74
75    /// Check if a specific interrupt is pending
76    fn is_pending(&self, interrupt_id: InterruptId) -> bool;
77
78    /// Get the maximum number of interrupts supported
79    fn max_interrupts(&self) -> InterruptId;
80
81    /// Get the number of CPUs supported
82    fn max_cpus(&self) -> CpuId;
83}
84
85/// Types of local interrupts
86#[derive(Debug, Clone, Copy, PartialEq, Eq)]
87pub enum LocalInterruptType {
88    /// Timer interrupt
89    Timer,
90    /// Software interrupt
91    Software,
92    /// External interrupt (from PLIC)
93    External,
94}
95
96/// Interrupt controller registry
97/// 
98/// This struct maintains references to the active interrupt controllers
99/// and provides a unified interface for interrupt management.
100/// Supports multiple local interrupt controllers for different CPU groups.
101pub 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>, // CPU ID -> controller index
105}
106
107unsafe impl Send for InterruptControllers {}
108unsafe impl Sync for InterruptControllers {}
109
110impl InterruptControllers {
111    /// Create a new interrupt controller registry
112    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    /// Register a local interrupt controller for specific CPUs
121    /// Returns the controller index
122    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        // Map CPUs to this controller
127        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    /// Register a local interrupt controller for a single CPU
135    /// Returns the controller index
136    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    /// Register a local interrupt controller for a CPU range (convenience function)
141    /// Returns the controller index
142    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    /// Register an external interrupt controller
148    pub fn register_external_controller(&mut self, controller: Box<dyn ExternalInterruptController>) {
149        self.external_controller = Some(controller);
150    }
151
152    /// Get a mutable reference to the local interrupt controller for a specific CPU
153    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    /// Get a mutable reference to a specific local interrupt controller by index
159    pub fn local_controller_mut(&mut self, index: usize) -> Option<&mut Box<dyn LocalInterruptController>> {
160        self.local_controllers.get_mut(index)
161    }
162
163    /// Get a mutable reference to the external interrupt controller
164    pub fn external_controller_mut(&mut self) -> Option<&mut Box<dyn ExternalInterruptController>> {
165        self.external_controller.as_mut()
166    }
167
168    /// Initialize all local controllers for their respective CPUs
169    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    /// Initialize the external controller
181    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    /// Check if local controller is available for a specific CPU
191    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    /// Check if any local controller is available
196    pub fn has_local_controller(&self) -> bool {
197        !self.local_controllers.is_empty()
198    }
199
200    /// Check if external controller is available
201    pub fn has_external_controller(&self) -> bool {
202        self.external_controller.is_some()
203    }
204
205    /// Get the number of registered local controllers
206    pub fn local_controller_count(&self) -> usize {
207        self.local_controllers.len()
208    }
209
210    /// Get CPU IDs managed by a specific local controller
211    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}