Skip to content

Commit bf1ad94

Browse files
committed
refactor(mmio): use a simpler approach for static dispatch
1 parent e8a3932 commit bf1ad94

2 files changed

Lines changed: 40 additions & 81 deletions

File tree

src/arch/x86_64/kernel/mmio.rs

Lines changed: 40 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use alloc::boxed::Box;
12
use alloc::string::String;
23
use alloc::vec::Vec;
34
use core::ptr::NonNull;
@@ -135,23 +136,10 @@ unsafe fn check_ptr(
135136
Some(mmio)
136137
}
137138

138-
trait MmioIterator: Iterator<Item = (VolatileRef<'static, DeviceRegisters>, u8)> {}
139-
140-
impl<
141-
I: Iterator,
142-
U: IntoIterator<Item = (VolatileRef<'static, DeviceRegisters>, u8)>,
143-
F: FnMut(I::Item) -> U,
144-
> MmioIterator for core::iter::FlatMap<I, U, F>
145-
{
146-
}
147-
148-
type LinuxArgsMmioIterator = impl MmioIterator;
149-
150-
#[define_opaque(LinuxArgsMmioIterator)]
151139
fn check_linux_args(
152140
linux_mmio: &'static [String],
153141
virtual_address: VirtAddr,
154-
) -> LinuxArgsMmioIterator {
142+
) -> impl Iterator<Item = (VolatileRef<'static, DeviceRegisters>, u8)> {
155143
linux_mmio
156144
.iter()
157145
.inspect(|arg| trace!("check linux parameter: {arg}"))
@@ -169,17 +157,9 @@ fn check_linux_args(
169157
})
170158
}
171159

172-
impl<
173-
I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
174-
U: Iterator<Item = (VolatileRef<'static, DeviceRegisters>, u8)>,
175-
> MmioIterator for core::iter::Flatten<I>
176-
{
177-
}
178-
179-
type GuessMmioIterator = impl MmioIterator;
180-
181-
#[define_opaque(GuessMmioIterator)]
182-
fn guess_device(virtual_address: VirtAddr) -> GuessMmioIterator {
160+
fn guess_device(
161+
virtual_address: VirtAddr,
162+
) -> impl Iterator<Item = (VolatileRef<'static, DeviceRegisters>, u8)> {
183163
// Look for the device-ID in all possible 64-byte aligned addresses within this range.
184164
(MMIO_START..MMIO_END)
185165
.step_by(512)
@@ -202,37 +182,6 @@ fn guess_device(virtual_address: VirtAddr) -> GuessMmioIterator {
202182
.flatten()
203183
}
204184

205-
#[enum_dispatch::enum_dispatch(MmioIterator)]
206-
enum MmioIteratorEnum {
207-
LinuxArgsMmioIterator,
208-
GuessMmioIterator,
209-
}
210-
211-
impl Iterator for MmioIteratorEnum {
212-
type Item = (VolatileRef<'static, DeviceRegisters>, u8);
213-
214-
fn next(&mut self) -> Option<Self::Item> {
215-
match self {
216-
MmioIteratorEnum::LinuxArgsMmioIterator(iter) => iter.next(),
217-
MmioIteratorEnum::GuessMmioIterator(iter) => iter.next(),
218-
}
219-
}
220-
}
221-
222-
fn detect_devices() -> MmioIteratorEnum {
223-
let layout = PageLayout::from_size(BasePageSize::SIZE as usize).unwrap();
224-
let page_range = PageBox::new(layout).unwrap();
225-
let virtual_address = VirtAddr::from(page_range.start());
226-
227-
let linux_mmio = env::mmio();
228-
229-
if linux_mmio.is_empty() {
230-
MmioIteratorEnum::GuessMmioIterator(guess_device(virtual_address))
231-
} else {
232-
MmioIteratorEnum::LinuxArgsMmioIterator(check_linux_args(linux_mmio, virtual_address))
233-
}
234-
}
235-
236185
#[cfg(any(
237186
feature = "virtio-console",
238187
feature = "virtio-fs",
@@ -269,29 +218,43 @@ pub(crate) fn get_vsock_driver() -> Option<&'static InterruptTicketMutex<VirtioV
269218
.find_map(|drv| drv.get_vsock_driver())
270219
}
271220

221+
fn register_mmio(mmio: VolatileRef<'static, DeviceRegisters>, irq: u8) {
222+
match mmio_virtio::init_device(mmio, irq) {
223+
#[cfg(feature = "virtio-console")]
224+
Ok(VirtioDriver::Console(drv)) => {
225+
register_driver(MmioDriver::VirtioConsole(InterruptTicketMutex::new(*drv)));
226+
}
227+
#[cfg(feature = "virtio-fs")]
228+
Ok(VirtioDriver::Fs(drv)) => {
229+
register_driver(MmioDriver::VirtioFs(InterruptTicketMutex::new(*drv)));
230+
}
231+
#[cfg(feature = "virtio-net")]
232+
Ok(VirtioDriver::Net(drv)) => {
233+
*NETWORK_DEVICE.lock() = Some(*drv);
234+
}
235+
#[cfg(feature = "virtio-vsock")]
236+
Ok(VirtioDriver::Vsock(drv)) => {
237+
register_driver(MmioDriver::VirtioVsock(InterruptTicketMutex::new(*drv)));
238+
}
239+
Err(err) => error!("Could not initialize virtio-mmio device: {err}"),
240+
}
241+
}
242+
272243
pub(crate) fn init_drivers() {
273244
without_interrupts(|| {
274-
let devices = detect_devices();
275-
276-
for (mmio, irq) in devices {
277-
match mmio_virtio::init_device(mmio, irq) {
278-
#[cfg(feature = "virtio-console")]
279-
Ok(VirtioDriver::Console(drv)) => {
280-
register_driver(MmioDriver::VirtioConsole(InterruptTicketMutex::new(*drv)));
281-
}
282-
#[cfg(feature = "virtio-fs")]
283-
Ok(VirtioDriver::Fs(drv)) => {
284-
register_driver(MmioDriver::VirtioFs(InterruptTicketMutex::new(*drv)));
285-
}
286-
#[cfg(feature = "virtio-net")]
287-
Ok(VirtioDriver::Net(drv)) => {
288-
*NETWORK_DEVICE.lock() = Some(*drv);
289-
}
290-
#[cfg(feature = "virtio-vsock")]
291-
Ok(VirtioDriver::Vsock(drv)) => {
292-
register_driver(MmioDriver::VirtioVsock(InterruptTicketMutex::new(*drv)));
293-
}
294-
Err(err) => error!("Could not initialize virtio-mmio device: {err}"),
245+
let layout = PageLayout::from_size(BasePageSize::SIZE as usize).unwrap();
246+
let page_range = PageBox::new(layout).unwrap();
247+
let virtual_address = VirtAddr::from(page_range.start());
248+
249+
let linux_mmio = env::mmio();
250+
251+
if linux_mmio.is_empty() {
252+
for (mmio, irq) in guess_device(virtual_address) {
253+
register_mmio(mmio, irq);
254+
}
255+
} else {
256+
for (mmio, irq) in check_linux_args(linux_mmio, virtual_address) {
257+
register_mmio(mmio, irq);
295258
}
296259
}
297260

src/lib.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,6 @@
7676
#![cfg_attr(all(target_os = "none", test), no_main)]
7777
// FIXME: move this to `Cargo.toml` once stable
7878
#![feature(strict_provenance_lints)]
79-
#![cfg_attr(
80-
all(not(feature = "pci"), feature = "virtio"),
81-
feature(type_alias_impl_trait)
82-
)]
8379
#![warn(fuzzy_provenance_casts)]
8480
#![warn(lossy_provenance_casts)]
8581

0 commit comments

Comments
 (0)