2019-01-23 18:11:41 +04:00
|
|
|
use alloc::prelude::*;
|
|
|
|
use core::any::Any;
|
|
|
|
|
|
|
|
use lazy_static::lazy_static;
|
|
|
|
use smoltcp::wire::EthernetAddress;
|
2019-02-28 08:31:10 +04:00
|
|
|
use smoltcp::socket::SocketSet;
|
2019-01-23 18:11:41 +04:00
|
|
|
|
|
|
|
use crate::sync::SpinNoIrqLock;
|
|
|
|
|
|
|
|
mod device_tree;
|
|
|
|
pub mod bus;
|
|
|
|
pub mod net;
|
2019-01-25 06:28:38 +04:00
|
|
|
pub mod block;
|
2019-01-23 18:11:41 +04:00
|
|
|
mod gpu;
|
2019-01-25 06:28:38 +04:00
|
|
|
mod input;
|
2019-01-23 18:11:41 +04:00
|
|
|
|
|
|
|
pub enum DeviceType {
|
|
|
|
Net,
|
2019-01-25 06:28:38 +04:00
|
|
|
Gpu,
|
|
|
|
Input,
|
|
|
|
Block
|
2019-01-23 18:11:41 +04:00
|
|
|
}
|
|
|
|
|
2019-01-25 06:28:38 +04:00
|
|
|
pub trait Driver : Send + AsAny {
|
2019-01-23 18:11:41 +04:00
|
|
|
// if interrupt belongs to this driver, handle it and return true
|
|
|
|
// return false otherwise
|
|
|
|
fn try_handle_interrupt(&mut self) -> bool;
|
|
|
|
|
|
|
|
// return the correspondent device type, see DeviceType
|
|
|
|
fn device_type(&self) -> DeviceType;
|
|
|
|
}
|
|
|
|
|
2019-02-28 08:31:10 +04:00
|
|
|
pub trait NetDriver : Send {
|
2019-01-23 18:11:41 +04:00
|
|
|
// get mac address for this device
|
|
|
|
fn get_mac(&self) -> EthernetAddress;
|
|
|
|
|
|
|
|
// get interface name for this device
|
|
|
|
fn get_ifname(&self) -> String;
|
2019-02-28 08:31:10 +04:00
|
|
|
|
|
|
|
fn poll(&mut self, socket: &mut SocketSet) -> Option<bool>;
|
2019-01-23 18:11:41 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// little hack, see https://users.rust-lang.org/t/how-to-downcast-from-a-trait-any-to-a-struct/11219/3
|
|
|
|
pub trait AsAny {
|
|
|
|
fn as_any(&self) -> &Any;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Any> AsAny for T {
|
|
|
|
fn as_any(&self) -> &Any { self }
|
|
|
|
}
|
|
|
|
|
|
|
|
lazy_static! {
|
|
|
|
pub static ref DRIVERS: SpinNoIrqLock<Vec<Box<Driver>>> = SpinNoIrqLock::new(Vec::new());
|
|
|
|
}
|
|
|
|
|
|
|
|
lazy_static! {
|
|
|
|
pub static ref NET_DRIVERS: SpinNoIrqLock<Vec<Box<NetDriver>>> = SpinNoIrqLock::new(Vec::new());
|
|
|
|
}
|
|
|
|
|
2019-02-25 15:12:41 +04:00
|
|
|
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
|
2019-01-23 18:11:41 +04:00
|
|
|
pub fn init(dtb: usize) {
|
|
|
|
device_tree::init(dtb);
|
2019-02-25 15:12:41 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
|
pub fn init() {
|
|
|
|
bus::pci::init();
|
2019-01-23 18:11:41 +04:00
|
|
|
}
|