From 44e4fd8b75888cf2ee467dc3a83a1d717bff10ba Mon Sep 17 00:00:00 2001 From: Andrew Walbran Date: Wed, 31 Jul 2024 14:08:12 +0100 Subject: [PATCH] Add SomeTransport, an enum wrapping either an MMIO or PCI transport. --- src/transport/mod.rs | 2 + src/transport/some.rs | 139 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 src/transport/some.rs diff --git a/src/transport/mod.rs b/src/transport/mod.rs index f166ac3c..b258d15c 100644 --- a/src/transport/mod.rs +++ b/src/transport/mod.rs @@ -4,11 +4,13 @@ pub mod fake; pub mod mmio; pub mod pci; +mod some; use crate::{PhysAddr, Result, PAGE_SIZE}; use bitflags::{bitflags, Flags}; use core::{fmt::Debug, ops::BitAnd}; use log::debug; +pub use some::SomeTransport; use zerocopy::{FromBytes, IntoBytes}; /// A VirtIO transport layer. diff --git a/src/transport/some.rs b/src/transport/some.rs new file mode 100644 index 00000000..4806dfce --- /dev/null +++ b/src/transport/some.rs @@ -0,0 +1,139 @@ +use zerocopy::{FromBytes, IntoBytes}; + +use super::{mmio::MmioTransport, pci::PciTransport, DeviceStatus, DeviceType, Transport}; +use crate::{PhysAddr, Result}; + +/// A wrapper for an arbitrary VirtIO transport, either MMIO or PCI. +#[derive(Debug)] +pub enum SomeTransport { + /// An MMIO transport. + Mmio(MmioTransport), + /// A PCI transport. + Pci(PciTransport), +} + +impl From for SomeTransport { + fn from(mmio: MmioTransport) -> Self { + Self::Mmio(mmio) + } +} + +impl From for SomeTransport { + fn from(pci: PciTransport) -> Self { + Self::Pci(pci) + } +} + +impl Transport for SomeTransport { + fn device_type(&self) -> DeviceType { + match self { + Self::Mmio(mmio) => mmio.device_type(), + Self::Pci(pci) => pci.device_type(), + } + } + + fn read_device_features(&mut self) -> u64 { + match self { + Self::Mmio(mmio) => mmio.read_device_features(), + Self::Pci(pci) => pci.read_device_features(), + } + } + + fn write_driver_features(&mut self, driver_features: u64) { + match self { + Self::Mmio(mmio) => mmio.write_driver_features(driver_features), + Self::Pci(pci) => pci.write_driver_features(driver_features), + } + } + + fn max_queue_size(&mut self, queue: u16) -> u32 { + match self { + Self::Mmio(mmio) => mmio.max_queue_size(queue), + Self::Pci(pci) => pci.max_queue_size(queue), + } + } + + fn notify(&mut self, queue: u16) { + match self { + Self::Mmio(mmio) => mmio.notify(queue), + Self::Pci(pci) => pci.notify(queue), + } + } + + fn get_status(&self) -> DeviceStatus { + match self { + Self::Mmio(mmio) => mmio.get_status(), + Self::Pci(pci) => pci.get_status(), + } + } + + fn set_status(&mut self, status: DeviceStatus) { + match self { + Self::Mmio(mmio) => mmio.set_status(status), + Self::Pci(pci) => pci.set_status(status), + } + } + + fn set_guest_page_size(&mut self, guest_page_size: u32) { + match self { + Self::Mmio(mmio) => mmio.set_guest_page_size(guest_page_size), + Self::Pci(pci) => pci.set_guest_page_size(guest_page_size), + } + } + + fn requires_legacy_layout(&self) -> bool { + match self { + Self::Mmio(mmio) => mmio.requires_legacy_layout(), + Self::Pci(pci) => pci.requires_legacy_layout(), + } + } + + fn queue_set( + &mut self, + queue: u16, + size: u32, + descriptors: PhysAddr, + driver_area: PhysAddr, + device_area: PhysAddr, + ) { + match self { + Self::Mmio(mmio) => mmio.queue_set(queue, size, descriptors, driver_area, device_area), + Self::Pci(pci) => pci.queue_set(queue, size, descriptors, driver_area, device_area), + } + } + + fn queue_unset(&mut self, queue: u16) { + match self { + Self::Mmio(mmio) => mmio.queue_unset(queue), + Self::Pci(pci) => pci.queue_unset(queue), + } + } + + fn queue_used(&mut self, queue: u16) -> bool { + match self { + Self::Mmio(mmio) => mmio.queue_used(queue), + Self::Pci(pci) => pci.queue_used(queue), + } + } + + fn ack_interrupt(&mut self) -> bool { + match self { + Self::Mmio(mmio) => mmio.ack_interrupt(), + Self::Pci(pci) => pci.ack_interrupt(), + } + } + + fn read_config_space(&self, offset: usize) -> Result { + match self { + Self::Mmio(mmio) => mmio.read_config_space(offset), + Self::Pci(pci) => pci.read_config_space(offset), + } + } + + fn write_config_space(&mut self, offset: usize, value: T) -> Result<()> { + match self { + Self::Mmio(mmio) => mmio.write_config_space(offset, value), + Self::Pci(pci) => pci.write_config_space(offset, value), + } + } +}