1extern 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
64pub type SharedDevice = Arc<dyn Device>;
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
69pub enum DriverPriority {
70 Critical = 0,
72 Core = 1,
74 Standard = 2,
76 Late = 3,
78}
79
80impl DriverPriority {
81 pub fn all() -> &'static [DriverPriority] {
83 &[
84 DriverPriority::Critical,
85 DriverPriority::Core,
86 DriverPriority::Standard,
87 DriverPriority::Late,
88 ]
89 }
90
91 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
104pub struct DeviceManager {
116 devices: Mutex<BTreeMap<usize, SharedDevice>>,
118 device_by_name: Mutex<BTreeMap<String, SharedDevice>>,
120 name_to_id: Mutex<BTreeMap<String, usize>>,
122 drivers: Mutex<BTreeMap<DriverPriority, Vec<Box<dyn DeviceDriver>>>>,
124 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), }
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 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 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 pub fn get_device(&self, id: usize) -> Option<SharedDevice> {
201 let devices = self.devices.lock();
202 devices.get(&id).cloned()
203 }
204
205 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 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 pub fn get_devices_count(&self) -> usize {
238 let devices = self.devices.lock();
239 devices.len()
240 }
241
242 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 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 pub fn populate_devices(&mut self) {
284 self.populate_devices_by_priority(None);
286 }
287
288 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 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 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 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; }
367 }
368 }
369 }
370 }
371 }
372
373 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 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}