driver_interface/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#![no_std]

use core::{fmt::Display, ptr::NonNull};

use alloc::{
    string::{String, ToString},
    sync::Arc,
    vec::Vec,
};

extern crate alloc;

pub use futures::future::BoxFuture;
use futures::future::LocalBoxFuture;
use irq::Trigger;

pub mod io;
pub mod irq;
pub mod timer;
pub mod uart;

pub type DriverResult<T = ()> = Result<T, DriverError>;

pub trait DriverGeneric: Send + Sync + 'static {}

#[derive(Clone)]
pub struct Register {
    pub name: String,
    pub compatible: Vec<&'static str>,
    pub kind: DriverKind,
    pub probe: Arc<dyn Probe>,
}
impl Register {
    pub fn new(
        name: &str,
        compatible: Vec<&'static str>,
        kind: DriverKind,
        probe: impl Probe,
    ) -> Self {
        Register {
            name: name.to_string(),
            compatible,
            kind,
            probe: Arc::new(probe),
        }
    }

    pub fn compatible_matched(&self, compatible: &str) -> bool {
        self.compatible.contains(&compatible)
    }
}

#[derive(Default, Clone)]
pub struct ProbeConfig {
    pub id: DeviceId,
    pub reg: Vec<NonNull<u8>>,
    pub irq: Vec<IrqProbeConfig>,
    pub clock_freq: Vec<u64>,
}

#[derive(Clone)]
pub struct IrqProbeConfig {
    pub irq: usize,
    pub trigger: Trigger,
}

pub trait Probe: Send + Sync + 'static {
    fn probe<'a>(&self, config: ProbeConfig) -> LocalBoxFuture<'a, DriverResult<DriverSpecific>>;
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum DriverKind {
    InteruptChip,
    Uart,
    Timer,
}

pub enum DriverSpecific {
    Uart(uart::BoxDriver),
    InteruptChip(irq::BoxDriver),
    Timer(timer::BoxDriver),
}

#[derive(Debug)]
pub enum DriverError {
    Init(String),
    NotFound,
    NoMemory,
}

#[repr(transparent)]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct DeviceId(u64);

impl Into<u64> for DeviceId {
    fn into(self) -> u64 {
        self.0
    }
}

impl From<u64> for DeviceId {
    fn from(value: u64) -> Self {
        Self(value)
    }
}

impl Display for DeviceId {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}", self.0)
    }
}