driver-interface 0.0.1

Sparreal OS kernel
Documentation
#![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)
    }
}