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	#[cfg(all(target_arch = "riscv64", feature = "gem-net"))]
34	use crate::drivers::net::gem::GEMError;
35	#[cfg(all(target_arch = "x86_64", feature = "rtl8139"))]
36	use crate::drivers::net::rtl8139::RTL8139Error;
37	#[cfg(any(
38		all(any(feature = "tcp", feature = "udp"), not(feature = "rtl8139")),
39		feature = "fuse",
40		feature = "vsock"
41	))]
42	use crate::drivers::virtio::error::VirtioError;
43
44	#[cfg(any(feature = "tcp", feature = "udp", feature = "fuse", feature = "vsock"))]
45	#[derive(Debug)]
46	pub enum DriverError {
47		#[cfg(any(
48			all(any(feature = "tcp", feature = "udp"), not(feature = "rtl8139")),
49			feature = "fuse",
50			feature = "vsock"
51		))]
52		InitVirtioDevFail(VirtioError),
53		#[cfg(all(target_arch = "x86_64", feature = "rtl8139"))]
54		InitRTL8139DevFail(RTL8139Error),
55		#[cfg(all(target_arch = "riscv64", feature = "gem-net"))]
56		InitGEMDevFail(GEMError),
57	}
58
59	#[cfg(any(
60		all(any(feature = "tcp", feature = "udp"), not(feature = "rtl8139")),
61		feature = "fuse",
62		feature = "vsock"
63	))]
64	impl From<VirtioError> for DriverError {
65		fn from(err: VirtioError) -> Self {
66			DriverError::InitVirtioDevFail(err)
67		}
68	}
69
70	#[cfg(all(target_arch = "x86_64", feature = "rtl8139"))]
71	impl From<RTL8139Error> for DriverError {
72		fn from(err: RTL8139Error) -> Self {
73			DriverError::InitRTL8139DevFail(err)
74		}
75	}
76
77	#[cfg(all(target_arch = "riscv64", feature = "gem-net"))]
78	impl From<GEMError> for DriverError {
79		fn from(err: GEMError) -> Self {
80			DriverError::InitGEMDevFail(err)
81		}
82	}
83
84	#[cfg(any(feature = "tcp", feature = "udp", feature = "fuse", feature = "vsock"))]
85	impl core::fmt::Display for DriverError {
86		#[allow(unused_variables)]
87		fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::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	#[cfg(all(
131		not(feature = "pci"),
132		target_arch = "aarch64",
133		any(feature = "tcp", feature = "udp")
134	))]
135	crate::arch::aarch64::kernel::mmio::init_drivers();
136
137	#[cfg(target_arch = "riscv64")]
138	crate::arch::riscv64::kernel::init_drivers();
139
140	crate::arch::interrupts::install_handlers();
141}