kernel/device/
manager.rs

1//! # Device Manager Module
2//!
3//! This module provides functionality for managing hardware devices in the kernel.
4//!
5//! ## Overview
6//!
7//! The device manager is responsible for:
8//! - Tracking available device drivers with priority-based initialization
9//! - Device discovery and initialization through FDT
10//! - Managing device information and lifecycle
11//!
12//! ## Key Components
13//!
14//! - `DeviceManager`: The main device management system that handles all devices and drivers
15//! - `DriverPriority`: Priority levels for controlling driver initialization order
16//!
17//! ## Device Discovery
18//!
19//! Devices are discovered through the Flattened Device Tree (FDT). The manager:
20//! 1. Parses the device tree
21//! 2. Matches compatible devices with registered drivers based on priority
22//! 3. Probes devices with appropriate drivers in priority order
23//!
24//! ## Usage
25//!
26//! The device manager is implemented as a global singleton that can be accessed via:
27//! - `DeviceManager::get_manager()` - Immutable access
28//! - `DeviceManager::get_mut_manager()` - Mutable access
29//!
30//! ### Example: Registering a device driver
31//!
32//! ```
33//! use crate::device::manager::{DeviceManager, DriverPriority};
34//! 
35//! // Create a new device driver
36//! let my_driver = Box::new(MyDeviceDriver::new());
37//! 
38//! // Register with the device manager at Core priority
39//! DeviceManager::get_mut_manager().register_driver(my_driver, DriverPriority::Core);
40//! ```
41
42extern crate alloc;
43
44use core::sync::atomic::AtomicUsize;
45use core::sync::atomic::Ordering;
46
47use alloc::collections::btree_map::BTreeMap;
48use alloc::sync::Arc;
49use alloc::vec::Vec;
50use alloc::boxed::Box;
51use alloc::string::String;
52use spin::mutex::Mutex;
53
54use crate::device::platform::resource::PlatformDeviceResource;
55use crate::device::platform::resource::PlatformDeviceResourceType;
56use crate::device::platform::PlatformDeviceInfo;
57use crate::early_println;
58
59use super::fdt::FdtManager;
60use super::Device;
61use super::DeviceDriver;
62use super::DeviceInfo;
63
64/// Simplified shared device type
65pub type SharedDevice = Arc<dyn Device>;
66
67/// Driver priority levels for initialization order
68#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
69pub enum DriverPriority {
70    /// Critical infrastructure drivers (interrupt controllers, memory controllers)
71    Critical = 0,
72    /// Core system drivers (timers, basic I/O)
73    Core = 1,
74    /// Standard device drivers (network, storage)
75    Standard = 2,
76    /// Late initialization drivers (filesystems, user interface)
77    Late = 3,
78}
79
80impl DriverPriority {
81    /// Get all priority levels in order
82    pub fn all() -> &'static [DriverPriority] {
83        &[
84            DriverPriority::Critical,
85            DriverPriority::Core,
86            DriverPriority::Standard,
87            DriverPriority::Late,
88        ]
89    }
90
91    /// Get a human-readable description of the priority level
92    pub fn description(&self) -> &'static str {
93        match self {
94            DriverPriority::Critical => "Critical Infrastructure",
95            DriverPriority::Core => "Core System",
96            DriverPriority::Standard => "Standard Devices",
97            DriverPriority::Late => "Late Initialization",
98        }
99    }
100}
101
102static mut MANAGER: DeviceManager = DeviceManager::new();
103
104/// DeviceManager
105/// 
106/// This struct is the main device management system.
107/// It handles all devices and drivers with priority-based initialization.
108/// 
109/// # Fields
110/// - `devices`: A mutex-protected map of all registered devices by ID.
111/// - `device_by_name`: A mutex-protected map of devices by name.
112/// - `name_to_id`: A mutex-protected map from device name to device ID.
113/// - `drivers`: A mutex-protected map of device drivers organized by priority.
114/// - `next_device_id`: Atomic counter for generating unique device IDs.
115pub struct DeviceManager {
116    /* Devices stored by ID */
117    devices: Mutex<BTreeMap<usize, SharedDevice>>,
118    /* Devices stored by name */
119    device_by_name: Mutex<BTreeMap<String, SharedDevice>>,
120    /* Name to ID mapping */
121    name_to_id: Mutex<BTreeMap<String, usize>>,
122    /* Device drivers organized by priority */
123    drivers: Mutex<BTreeMap<DriverPriority, Vec<Box<dyn DeviceDriver>>>>,
124    /* Next device ID to assign */
125    next_device_id: AtomicUsize,
126}
127
128impl DeviceManager {
129    const fn new() -> Self {
130        DeviceManager {
131            devices: Mutex::new(BTreeMap::new()),
132            device_by_name: Mutex::new(BTreeMap::new()),
133            name_to_id: Mutex::new(BTreeMap::new()),
134            drivers: Mutex::new(BTreeMap::new()),
135            next_device_id: AtomicUsize::new(1), // Start from 1, reserve 0 for invalid
136        }
137    }
138
139    #[allow(static_mut_refs)]
140    pub fn get_manager() -> &'static DeviceManager {
141        unsafe { &MANAGER }
142    }
143
144    #[allow(static_mut_refs)]
145    pub fn get_mut_manager() -> &'static mut DeviceManager {
146        unsafe { &mut MANAGER }
147    }
148
149    /// Register a device with the manager
150    /// 
151    /// # Arguments
152    /// * `device`: The device to register.
153    /// 
154    /// # Returns
155    ///  * The id of the registered device.
156    /// 
157    /// # Example
158    /// 
159    /// ```rust
160    /// let device = Arc::new(MyDevice::new());
161    /// let id = DeviceManager::get_mut_manager().register_device(device);
162    /// ```
163    /// 
164    pub fn register_device(&self, device: Arc<dyn Device>) -> usize {
165        let mut devices = self.devices.lock();
166        let id = self.next_device_id.fetch_add(1, Ordering::SeqCst);
167        devices.insert(id, device);
168        id
169    }
170
171    /// Register a device with the manager by name
172    /// 
173    /// # Arguments
174    /// * `name`: The name of the device.
175    /// * `device`: The device to register.
176    /// 
177    /// # Returns
178    ///  * The id of the registered device.
179    /// 
180    pub fn register_device_with_name(&self, name: String, device: Arc<dyn Device>) -> usize {
181        let mut devices = self.devices.lock();
182        let mut device_by_name = self.device_by_name.lock();
183        let mut name_to_id = self.name_to_id.lock();
184        
185        let id = self.next_device_id.fetch_add(1, Ordering::SeqCst);
186        devices.insert(id, device.clone());
187        device_by_name.insert(name.clone(), device);
188        name_to_id.insert(name, id);
189        id
190    }
191
192    /// Get a device by ID
193    /// 
194    /// # Arguments
195    /// * `id`: The id of the device to get.
196    /// 
197    /// # Returns
198    /// * The device if found, or None if not found.
199    /// 
200    pub fn get_device(&self, id: usize) -> Option<SharedDevice> {
201        let devices = self.devices.lock();
202        devices.get(&id).cloned()
203    }
204
205    /// Get a device by name
206    /// 
207    /// # Arguments
208    /// * `name`: The name of the device to get.
209    /// 
210    /// # Returns
211    /// * The device if found, or None if not found.
212    /// 
213    pub fn get_device_by_name(&self, name: &str) -> Option<SharedDevice> {
214        let device_by_name = self.device_by_name.lock();
215        device_by_name.get(name).cloned()
216    }
217
218    /// Get a device ID by name
219    /// 
220    /// # Arguments
221    /// * `name`: The name of the device to find.
222    /// 
223    /// # Returns
224    /// * The device ID if found, or None if not found.
225    /// 
226    pub fn get_device_id_by_name(&self, name: &str) -> Option<usize> {
227        let name_to_id = self.name_to_id.lock();
228        name_to_id.get(name).cloned()
229    }
230
231    /// Get the number of devices
232    /// 
233    /// # Returns
234    /// 
235    /// The number of devices.
236    /// 
237    pub fn get_devices_count(&self) -> usize {
238        let devices = self.devices.lock();
239        devices.len()
240    }
241
242    /// Get the first device of a specific type
243    /// 
244    /// # Arguments
245    /// * `device_type`: The device type to find.
246    /// 
247    /// # Returns
248    /// * The first device ID of the specified type, or None if not found.
249    /// 
250    pub fn get_first_device_by_type(&self, device_type: super::DeviceType) -> Option<usize> {
251        let devices = self.devices.lock();
252        for (id, device) in devices.iter() {
253            if device.device_type() == device_type {
254                return Some(*id);
255            }
256        }
257        None
258    }
259
260    /// Get all devices registered by name
261    /// 
262    /// Returns an iterator over (name, device) pairs for all devices
263    /// that were registered with explicit names.
264    /// 
265    /// # Returns
266    /// 
267    /// Vector of (name, device) tuples
268    pub fn get_named_devices(&self) -> Vec<(String, SharedDevice)> {
269        let device_by_name = self.device_by_name.lock();
270        device_by_name.iter().map(|(name, device)| (name.clone(), device.clone())).collect()
271    }
272
273    pub fn borrow_drivers(&self) -> &Mutex<BTreeMap<DriverPriority, Vec<Box<dyn DeviceDriver>>>> {
274        &self.drivers
275    }
276
277    /// Populates devices from the FDT (Flattened Device Tree).
278    /// 
279    /// This function searches for the `/soc` node in the FDT and iterates through its children.
280    /// For each child node, it checks if there is a compatible driver registered.
281    /// If a matching driver is found, it probes the device using the driver's `probe` method.
282    /// If the probe is successful, the device is registered with the driver.
283    pub fn populate_devices(&mut self) {
284        // Use all priority levels in order
285        self.populate_devices_by_priority(None);
286    }
287
288    /// Populate devices using drivers of specific priority levels
289    /// 
290    /// # Arguments
291    /// 
292    /// * `priorities` - Optional slice of priority levels to use. If None, uses all priorities in order.
293    pub fn populate_devices_by_priority(&mut self, priorities: Option<&[DriverPriority]>) {
294        let fdt_manager = unsafe { FdtManager::get_mut_manager() };
295        let fdt = fdt_manager.get_fdt();
296        if fdt.is_none() {
297            early_println!("FDT not initialized");
298            return;
299        }
300        let fdt = fdt.unwrap();
301        
302        let priority_list = priorities.unwrap_or(DriverPriority::all());
303        
304        for &priority in priority_list {
305            early_println!("Populating devices with {} drivers from FDT...", priority.description());
306            
307            let soc = fdt.find_node("/soc");
308            if soc.is_none() {
309                early_println!("No /soc node found");
310                continue;
311            }
312
313            let soc = soc.unwrap();
314            let mut idx = 0;
315            for child in soc.children() {
316                let compatible = child.compatible();
317                if compatible.is_none() {
318                    continue;
319                }
320                let compatible = compatible.unwrap().all().collect::<Vec<_>>();
321                
322                // Get drivers for this priority level
323                let drivers = self.drivers.lock();
324                if let Some(driver_list) = drivers.get(&priority) {
325                    for driver in driver_list.iter() {
326                        if driver.match_table().iter().any(|&c| compatible.contains(&c)) {
327                            let mut resources = Vec::new();
328                            
329                            // Memory regions
330                            if let Some(regions) = child.reg() {
331                                for region in regions {
332                                    let res = PlatformDeviceResource {
333                                        res_type: PlatformDeviceResourceType::MEM,
334                                        start: region.starting_address as usize,
335                                        end: region.starting_address as usize + region.size.unwrap() - 1,
336                                    };
337                                    resources.push(res);
338                                }
339                            }
340
341                            // IRQs
342                            if let Some(irqs) = child.interrupts() {
343                                for irq in irqs {
344                                    let res = PlatformDeviceResource {
345                                        res_type: PlatformDeviceResourceType::IRQ,
346                                        start: irq,
347                                        end: irq,
348                                    };
349                                    resources.push(res);
350                                }
351                            }
352
353                            let device: Box<dyn DeviceInfo> = Box::new(PlatformDeviceInfo::new(
354                                child.name,
355                                idx,
356                                compatible.clone(),
357                                resources,
358                            ));
359                            if let Err(e) = driver.probe(&*device) {
360                                early_println!("Failed to probe {} device {}: {}", priority.description(), device.name(), e);
361                            } else {
362                                early_println!("Successfully probed {} device: {}", priority.description(), device.name());
363                                idx += 1;
364                            }
365                            break; // Found matching driver, move to next device
366                        }
367                    }
368                }
369            }
370        }
371    }
372
373    /// Registers a device driver with the device manager.
374    /// 
375    /// This function takes a boxed device driver and adds it to the list of registered drivers
376    /// at the specified priority level.
377    /// 
378    /// # Arguments
379    /// 
380    /// * `driver` - A boxed device driver that implements the `DeviceDriver` trait.
381    /// * `priority` - The priority level for this driver.
382    /// 
383    /// # Example
384    /// 
385    /// ```rust
386    /// let driver = Box::new(MyDeviceDriver::new());
387    /// DeviceManager::get_mut_manager().register_driver(driver, DriverPriority::Standard);
388    /// ```
389    pub fn register_driver(&mut self, driver: Box<dyn DeviceDriver>, priority: DriverPriority) {
390        let mut drivers = self.drivers.lock();
391        drivers.entry(priority).or_insert_with(Vec::new).push(driver);
392    }
393
394    /// Registers a device driver with default Standard priority.
395    /// 
396    /// This is a convenience method for backward compatibility.
397    /// 
398    /// # Arguments
399    /// 
400    /// * `driver` - A boxed device driver that implements the `DeviceDriver` trait.
401    pub fn register_driver_default(&mut self, driver: Box<dyn DeviceDriver>) {
402        self.register_driver(driver, DriverPriority::Standard);
403    }
404}
405
406#[cfg(test)]
407mod tests {
408    use alloc::vec;
409    use super::*;
410    use crate::device::{platform::*, GenericDevice};
411
412    #[test_case]
413    fn test_populate_driver() {
414        static mut TEST_RESULT: bool = false;
415        fn probe_fn(_device: &PlatformDeviceInfo) -> Result<(), &'static str> {      
416            unsafe {
417                TEST_RESULT = true;
418            }  
419            Ok(())
420        }
421
422        let driver = Box::new(PlatformDeviceDriver::new(
423            "test",
424            probe_fn,
425            |_device| Ok(()),
426            vec!["sifive,test0"]
427        ));
428        let mut manager = DeviceManager::new();
429        manager.register_driver(driver, DriverPriority::Standard);
430
431        manager.populate_devices();
432        let result = unsafe { TEST_RESULT };
433        assert_eq!(result, true);
434    }
435
436    #[test_case]
437    fn test_get_device_from_manager() {
438        let device = Arc::new(GenericDevice::new("test"));
439        let manager = DeviceManager::new();
440        let id = manager.register_device(device);
441        let retrieved_device = manager.get_device(id);
442        assert!(retrieved_device.is_some());
443        let retrieved_device = retrieved_device.unwrap();
444        assert_eq!(retrieved_device.name(), "test");
445    }
446
447    #[test_case]
448    fn test_get_device_by_name() {
449        let device = Arc::new(GenericDevice::new("test_named"));
450        let manager = DeviceManager::new();
451        let _id = manager.register_device_with_name("test_device".into(), device);
452        let retrieved_device = manager.get_device_by_name("test_device");
453        assert!(retrieved_device.is_some());
454        let retrieved_device = retrieved_device.unwrap();
455        assert_eq!(retrieved_device.name(), "test_named");
456    }
457
458    #[test_case]
459    fn test_get_first_device_by_type() {
460        let device1 = Arc::new(GenericDevice::new("test_char"));
461        let device2 = Arc::new(GenericDevice::new("test_block"));
462        let manager = DeviceManager::new();
463        let _id1 = manager.register_device(device1);
464        let _id2 = manager.register_device(device2);
465        
466        let char_device_id = manager.get_first_device_by_type(crate::device::DeviceType::Generic);
467        assert!(char_device_id.is_some());
468        let char_device_id = char_device_id.unwrap();
469        let char_device = manager.get_device(char_device_id).unwrap();
470        assert_eq!(char_device.name(), "test_char");
471    }
472
473    #[test_case]
474    fn test_get_device_out_of_bounds() {
475        let manager = DeviceManager::new();
476        let device = manager.get_device(999);
477        assert!(device.is_none());
478    }
479
480    #[test_case]
481    fn test_get_device_by_name_not_found() {
482        let manager = DeviceManager::new();
483        let device = manager.get_device_by_name("non_existent");
484        assert!(device.is_none());
485    }
486}