1#![no_std]
2
3extern crate alloc;
4
5use core::ptr::NonNull;
6pub use fdt_parser::Phandle;
7
8use register::DriverRegister;
9use spin::Mutex;
10
11mod device;
12pub mod error;
13mod id;
14mod manager;
15pub mod probe;
16pub mod register;
17pub use device::*;
18pub use manager::*;
19pub use probe::ProbeError;
20pub use rdif_base::{DriverGeneric, DriverResult, IrqId, io};
21
22static MANAGER: Mutex<Option<Manager>> = Mutex::new(None);
23
24#[derive(Debug, Clone)]
25pub enum DriverInfoKind {
26 Fdt { addr: NonNull<u8> },
27}
28
29unsafe impl Send for DriverInfoKind {}
30
31pub fn init(probe_kind: DriverInfoKind) {
32 MANAGER.lock().replace(Manager::new(probe_kind));
33}
34
35pub fn edit<F, T>(f: F) -> T
36where
37 F: FnOnce(&mut Manager) -> T,
38{
39 let mut g = MANAGER.lock();
40 f(g.as_mut().expect("manager not init"))
41}
42
43pub fn read<F, T>(f: F) -> T
44where
45 F: FnOnce(&Manager) -> T,
46{
47 let g = MANAGER.lock();
48 f(g.as_ref().expect("manager not init"))
49}
50
51pub fn register_add(register: DriverRegister) {
52 edit(|manager| manager.registers.add(register));
53}
54
55pub fn register_append(registers: &[DriverRegister]) {
56 edit(|manager| manager.registers.append(registers))
57}
58
59pub fn probe_pre_kernel() -> Result<(), ProbeError> {
60 edit(|manager| manager.probe_pre_kernel())
61}
62
63pub fn probe() -> Result<(), ProbeError> {
64 edit(|manager| manager.probe())
65}
66
67#[macro_export]
68macro_rules! dev_list {
69 ($k: ident) => {
70 $crate::read(|manager| {
71 manager
72 .dev_map
73 .iter()
74 .filter_map(|(_, v)| {
75 if let $crate::DeviceKind::$k(dev) = v {
76 Some(dev.weak())
77 } else {
78 None
79 }
80 })
81 .collect::<alloc::vec::Vec<_>>()
82 })
83 };
84}
85#[macro_export]
86macro_rules! get_dev {
87 ($k:ident) => {
88 $crate::read(|m| {
89 manager
90 .dev_map
91 .iter()
92 .filter_map(|(_, v)| {
93 if let $crate::DeviceKind::$k(dev) = v {
94 Some(dev.weak())
95 } else {
96 None
97 }
98 })
99 .next()
100 })
101 };
102 ($id:expr, $k:ident) => {
103 $crate::read(|m| {
104 let dev = m.dev_map.get(&$id)?;
105 if let $crate::DeviceKind::$k(dev) = dev {
106 Some(dev.weak())
107 } else {
108 None
109 }
110 })
111 };
112}