hermit/drivers/
mod.rs

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