hermit/drivers/
mod.rs

1//! A module containing hermit-rs driver, hermit-rs driver trait and driver specific errors.
2
3#[cfg(feature = "fuse")]
4pub mod fs;
5#[cfg(not(feature = "pci"))]
6pub mod mmio;
7#[cfg(any(feature = "tcp", feature = "udp"))]
8pub mod net;
9#[cfg(feature = "pci")]
10pub mod pci;
11#[cfg(any(
12	all(any(feature = "tcp", feature = "udp"), not(feature = "rtl8139")),
13	feature = "fuse",
14	feature = "vsock"
15))]
16pub mod virtio;
17#[cfg(feature = "vsock")]
18pub mod vsock;
19
20use alloc::collections::VecDeque;
21
22#[cfg(feature = "pci")]
23pub(crate) use pci_types::InterruptLine;
24#[cfg(not(feature = "pci"))]
25pub(crate) type InterruptLine = u8;
26
27pub(crate) type InterruptHandlerQueue = VecDeque<fn()>;
28
29/// A common error module for drivers.
30/// [DriverError](error::DriverError) values will be
31/// passed on to higher layers.
32pub mod error {
33	use core::fmt;
34
35	#[cfg(all(target_arch = "riscv64", feature = "gem-net"))]
36	use crate::drivers::net::gem::GEMError;
37	#[cfg(all(target_arch = "x86_64", feature = "rtl8139"))]
38	use crate::drivers::net::rtl8139::RTL8139Error;
39	#[cfg(any(
40		all(any(feature = "tcp", feature = "udp"), not(feature = "rtl8139")),
41		feature = "fuse",
42		feature = "vsock"
43	))]
44	use crate::drivers::virtio::error::VirtioError;
45
46	#[derive(Debug)]
47	pub enum DriverError {
48		#[cfg(any(
49			all(any(feature = "tcp", feature = "udp"), not(feature = "rtl8139")),
50			feature = "fuse",
51			feature = "vsock"
52		))]
53		InitVirtioDevFail(VirtioError),
54		#[cfg(all(target_arch = "x86_64", feature = "rtl8139"))]
55		InitRTL8139DevFail(RTL8139Error),
56		#[cfg(all(target_arch = "riscv64", feature = "gem-net"))]
57		InitGEMDevFail(GEMError),
58	}
59
60	#[cfg(any(
61		all(any(feature = "tcp", feature = "udp"), not(feature = "rtl8139")),
62		feature = "fuse",
63		feature = "vsock"
64	))]
65	impl From<VirtioError> for DriverError {
66		fn from(err: VirtioError) -> Self {
67			DriverError::InitVirtioDevFail(err)
68		}
69	}
70
71	#[cfg(all(target_arch = "x86_64", feature = "rtl8139"))]
72	impl From<RTL8139Error> for DriverError {
73		fn from(err: RTL8139Error) -> Self {
74			DriverError::InitRTL8139DevFail(err)
75		}
76	}
77
78	#[cfg(all(target_arch = "riscv64", feature = "gem-net"))]
79	impl From<GEMError> for DriverError {
80		fn from(err: GEMError) -> Self {
81			DriverError::InitGEMDevFail(err)
82		}
83	}
84
85	impl fmt::Display for DriverError {
86		#[allow(unused_variables)]
87		fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88			match *self {
89				#[cfg(any(
90					all(any(feature = "tcp", feature = "udp"), not(feature = "rtl8139")),
91					feature = "fuse",
92					feature = "vsock"
93				))]
94				DriverError::InitVirtioDevFail(ref err) => {
95					write!(f, "Virtio driver failed: {err:?}")
96				}
97				#[cfg(all(target_arch = "x86_64", feature = "rtl8139"))]
98				DriverError::InitRTL8139DevFail(ref err) => {
99					write!(f, "RTL8139 driver failed: {err:?}")
100				}
101				#[cfg(all(target_arch = "riscv64", feature = "gem-net"))]
102				DriverError::InitGEMDevFail(ref err) => {
103					write!(f, "GEM driver failed: {err:?}")
104				}
105			}
106		}
107	}
108}
109
110/// A trait to determine general driver information
111#[allow(dead_code)]
112pub(crate) trait Driver {
113	/// Returns the interrupt number of the device
114	fn get_interrupt_number(&self) -> InterruptLine;
115
116	/// Returns the device driver name
117	fn get_name(&self) -> &'static str;
118}
119
120pub(crate) fn init() {
121	// Initialize PCI Drivers
122	#[cfg(feature = "pci")]
123	crate::drivers::pci::init();
124	#[cfg(all(
125		not(feature = "pci"),
126		target_arch = "x86_64",
127		any(feature = "tcp", feature = "udp")
128	))]
129	crate::arch::x86_64::kernel::mmio::init_drivers();
130
131	#[cfg(target_arch = "riscv64")]
132	crate::arch::riscv64::kernel::init_drivers();
133
134	crate::arch::interrupts::install_handlers();
135}