From 45612fc14d58fa050647bb00a3b30d4d2820eb6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Tue, 23 Jul 2024 11:42:35 +0200 Subject: [PATCH 1/3] refactor(virtio-spec): import endian-num types from crate root MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- virtio-spec/src/lib.rs | 2 +- virtio-spec/src/mmio.rs | 3 +-- virtio-spec/src/pci.rs | 3 +-- virtio-spec/src/pvirtq.rs | 3 +-- virtio-spec/src/virtq/mod.rs | 2 +- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/virtio-spec/src/lib.rs b/virtio-spec/src/lib.rs index 79b41de2c1..9dbafd2d16 100644 --- a/virtio-spec/src/lib.rs +++ b/virtio-spec/src/lib.rs @@ -21,7 +21,7 @@ pub mod pci; pub mod pvirtq; pub mod virtq; -pub use endian_num::{be128, be16, be32, be64, le128, le16, le32, le64}; +pub use endian_num::{be128, be16, be32, be64, le128, le16, le32, le64, Be, Le}; use num_enum::{FromPrimitive, IntoPrimitive, TryFromPrimitive}; pub use self::features::{FeatureBits, F}; diff --git a/virtio-spec/src/mmio.rs b/virtio-spec/src/mmio.rs index fe2f3fcbf5..327b219b54 100644 --- a/virtio-spec/src/mmio.rs +++ b/virtio-spec/src/mmio.rs @@ -2,14 +2,13 @@ use core::mem; -use endian_num::{le16, le32}; use volatile::access::{ReadOnly, ReadWrite, Readable, RestrictAccess, WriteOnly}; use volatile::VolatilePtr; #[doc(inline)] pub use super::pci::NotificationData; use crate::volatile::{OveralignedVolatilePtr, WideVolatilePtr}; -use crate::{DeviceConfigSpace, DeviceStatus, Id}; +use crate::{le16, le32, DeviceConfigSpace, DeviceStatus, Id}; /// MMIO Device Registers #[repr(transparent)] diff --git a/virtio-spec/src/pci.rs b/virtio-spec/src/pci.rs index c69aa6e1ae..394f03e73c 100644 --- a/virtio-spec/src/pci.rs +++ b/virtio-spec/src/pci.rs @@ -3,7 +3,6 @@ use core::mem; use bitfield_struct::bitfield; -use endian_num::{le64, Le}; use num_enum::{FromPrimitive, IntoPrimitive}; use pci_types::capability::PciCapabilityAddress; use pci_types::ConfigRegionAccess; @@ -12,7 +11,7 @@ use volatile::VolatilePtr; use volatile_macro::VolatileFieldAccess; use crate::volatile::WideVolatilePtr; -use crate::{le16, le32, DeviceConfigSpace, DeviceStatus}; +use crate::{le16, le32, le64, DeviceConfigSpace, DeviceStatus, Le}; /// PCI Capability /// diff --git a/virtio-spec/src/pvirtq.rs b/virtio-spec/src/pvirtq.rs index 968b0a5ec1..a9a677441e 100644 --- a/virtio-spec/src/pvirtq.rs +++ b/virtio-spec/src/pvirtq.rs @@ -1,9 +1,8 @@ //! Packed virtqueue definitions use bitfield_struct::bitfield; -use endian_num::{le16, le32, le64}; -use crate::{virtq, RingEventFlags}; +use crate::{le16, le32, le64, virtq, RingEventFlags}; /// Packed Virtqueue Descriptor #[doc(alias = "pvirtq_desc")] diff --git a/virtio-spec/src/virtq/mod.rs b/virtio-spec/src/virtq/mod.rs index ecc3813a34..60ca82d12b 100644 --- a/virtio-spec/src/virtq/mod.rs +++ b/virtio-spec/src/virtq/mod.rs @@ -7,7 +7,7 @@ use core::alloc::Layout; use core::ptr::{addr_of_mut, NonNull}; use core::{mem, ptr}; -use endian_num::{le16, le32, le64}; +use crate::{le16, le32, le64}; /// Split Virtqueue Descriptor #[doc(alias = "virtq_desc")] From f564b4ed7a5b3ae9d8549c98beddde4eaab474d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Tue, 23 Jul 2024 11:46:59 +0200 Subject: [PATCH 2/3] refactor(virtio-spec): move NotificationData into separate module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- virtio-spec/src/driver_notifications.rs | 83 +++++++++++++++++++++++++ virtio-spec/src/lib.rs | 1 + virtio-spec/src/mmio.rs | 2 +- virtio-spec/src/pci.rs | 83 +------------------------ 4 files changed, 87 insertions(+), 82 deletions(-) create mode 100644 virtio-spec/src/driver_notifications.rs diff --git a/virtio-spec/src/driver_notifications.rs b/virtio-spec/src/driver_notifications.rs new file mode 100644 index 0000000000..4ad12f793a --- /dev/null +++ b/virtio-spec/src/driver_notifications.rs @@ -0,0 +1,83 @@ +use bitfield_struct::bitfield; + +use crate::le32; + +/// Notification Data. +#[bitfield(u32, repr = le32, from = le32::from_ne, into = le32::to_ne)] +pub struct NotificationData { + /// VQ number to be notified. + pub vqn: u16, + + /// Offset + /// within the ring where the next available ring entry + /// will be written. + /// When [`VIRTIO_F_RING_PACKED`] has not been negotiated this refers to the + /// 15 least significant bits of the available index. + /// When `VIRTIO_F_RING_PACKED` has been negotiated this refers to the offset + /// (in units of descriptor entries) + /// within the descriptor ring where the next available + /// descriptor will be written. + /// + /// [`VIRTIO_F_RING_PACKED`]: F::RING_PACKED + #[bits(15)] + pub next_off: u16, + + /// Wrap Counter. + /// With [`VIRTIO_F_RING_PACKED`] this is the wrap counter + /// referring to the next available descriptor. + /// Without `VIRTIO_F_RING_PACKED` this is the most significant bit + /// (bit 15) of the available index. + /// + /// [`VIRTIO_F_RING_PACKED`]: F::RING_PACKED + #[bits(1)] + pub next_wrap: u8, +} + +impl NotificationData { + const NEXT_IDX_BITS: usize = 16; + const NEXT_IDX_OFFSET: usize = 16; + + /// Available index + /// + ///
+ /// + /// This collides with [`Self::next_off`] and [`Self::next_wrap`]. + /// + ///
+ /// + /// Bits: 16..32 + pub const fn next_idx(&self) -> u16 { + let mask = u32::MAX >> (u32::BITS - Self::NEXT_IDX_BITS as u32); + let this = (le32::to_ne(self.0) >> Self::NEXT_IDX_OFFSET) & mask; + this as u16 + } + + /// Available index + /// + ///
+ /// + /// This collides with [`Self::with_next_off`] and [`Self::with_next_wrap`]. + /// + ///
+ /// + /// Bits: 16..32 + pub const fn with_next_idx(self, value: u16) -> Self { + let mask = u32::MAX >> (u32::BITS - Self::NEXT_IDX_BITS as u32); + let bits = le32::to_ne(self.0) & !(mask << Self::NEXT_IDX_OFFSET) + | (value as u32 & mask) << Self::NEXT_IDX_OFFSET; + Self(le32::from_ne(bits)) + } + + /// Available index + /// + ///
+ /// + /// This collides with [`Self::set_next_off`] and [`Self::set_next_wrap`]. + /// + ///
+ /// + /// Bits: 16..32 + pub fn set_next_idx(&mut self, value: u16) { + *self = self.with_next_idx(value); + } +} diff --git a/virtio-spec/src/lib.rs b/virtio-spec/src/lib.rs index 9dbafd2d16..a6344190b8 100644 --- a/virtio-spec/src/lib.rs +++ b/virtio-spec/src/lib.rs @@ -13,6 +13,7 @@ extern crate alloc; mod bitflags; #[macro_use] pub mod volatile; +mod driver_notifications; mod features; pub mod fs; pub mod mmio; diff --git a/virtio-spec/src/mmio.rs b/virtio-spec/src/mmio.rs index 327b219b54..899b1e7706 100644 --- a/virtio-spec/src/mmio.rs +++ b/virtio-spec/src/mmio.rs @@ -6,7 +6,7 @@ use volatile::access::{ReadOnly, ReadWrite, Readable, RestrictAccess, WriteOnly} use volatile::VolatilePtr; #[doc(inline)] -pub use super::pci::NotificationData; +pub use crate::driver_notifications::NotificationData; use crate::volatile::{OveralignedVolatilePtr, WideVolatilePtr}; use crate::{le16, le32, DeviceConfigSpace, DeviceStatus, Id}; diff --git a/virtio-spec/src/pci.rs b/virtio-spec/src/pci.rs index 394f03e73c..38d3eb0ad6 100644 --- a/virtio-spec/src/pci.rs +++ b/virtio-spec/src/pci.rs @@ -2,7 +2,6 @@ use core::mem; -use bitfield_struct::bitfield; use num_enum::{FromPrimitive, IntoPrimitive}; use pci_types::capability::PciCapabilityAddress; use pci_types::ConfigRegionAccess; @@ -10,6 +9,8 @@ use volatile::access::{ReadOnly, ReadWrite, Readable, RestrictAccess}; use volatile::VolatilePtr; use volatile_macro::VolatileFieldAccess; +#[doc(inline)] +pub use crate::driver_notifications::NotificationData; use crate::volatile::WideVolatilePtr; use crate::{le16, le32, le64, DeviceConfigSpace, DeviceStatus, Le}; @@ -460,83 +461,3 @@ virtio_bitflags! { const DEVICE_CONFIGURATION_INTERRUPT = 1 << 1; } } - -/// Notification Data. -#[bitfield(u32, repr = le32, from = le32::from_ne, into = le32::to_ne)] -pub struct NotificationData { - /// VQ number to be notified. - pub vqn: u16, - - /// Offset - /// within the ring where the next available ring entry - /// will be written. - /// When [`VIRTIO_F_RING_PACKED`] has not been negotiated this refers to the - /// 15 least significant bits of the available index. - /// When `VIRTIO_F_RING_PACKED` has been negotiated this refers to the offset - /// (in units of descriptor entries) - /// within the descriptor ring where the next available - /// descriptor will be written. - /// - /// [`VIRTIO_F_RING_PACKED`]: F::RING_PACKED - #[bits(15)] - pub next_off: u16, - - /// Wrap Counter. - /// With [`VIRTIO_F_RING_PACKED`] this is the wrap counter - /// referring to the next available descriptor. - /// Without `VIRTIO_F_RING_PACKED` this is the most significant bit - /// (bit 15) of the available index. - /// - /// [`VIRTIO_F_RING_PACKED`]: F::RING_PACKED - #[bits(1)] - pub next_wrap: u8, -} - -impl NotificationData { - const NEXT_IDX_BITS: usize = 16; - const NEXT_IDX_OFFSET: usize = 16; - - /// Available index - /// - ///
- /// - /// This collides with [`Self::next_off`] and [`Self::next_wrap`]. - /// - ///
- /// - /// Bits: 16..32 - pub const fn next_idx(&self) -> u16 { - let mask = u32::MAX >> (u32::BITS - Self::NEXT_IDX_BITS as u32); - let this = (le32::to_ne(self.0) >> Self::NEXT_IDX_OFFSET) & mask; - this as u16 - } - - /// Available index - /// - ///
- /// - /// This collides with [`Self::with_next_off`] and [`Self::with_next_wrap`]. - /// - ///
- /// - /// Bits: 16..32 - pub const fn with_next_idx(self, value: u16) -> Self { - let mask = u32::MAX >> (u32::BITS - Self::NEXT_IDX_BITS as u32); - let bits = le32::to_ne(self.0) & !(mask << Self::NEXT_IDX_OFFSET) - | (value as u32 & mask) << Self::NEXT_IDX_OFFSET; - Self(le32::from_ne(bits)) - } - - /// Available index - /// - ///
- /// - /// This collides with [`Self::set_next_off`] and [`Self::set_next_wrap`]. - /// - ///
- /// - /// Bits: 16..32 - pub fn set_next_idx(&mut self, value: u16) { - *self = self.with_next_idx(value); - } -} From 72382032b72e87926cc92e0846aaa92bc1bdbcce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Tue, 23 Jul 2024 11:51:17 +0200 Subject: [PATCH 3/3] refactor(virtio-spec): feature-gate transport modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- Cargo.toml | 4 ++-- src/drivers/virtio/virtqueue/packed.rs | 3 +++ src/drivers/virtio/virtqueue/split.rs | 3 +++ virtio-spec/Cargo.toml | 4 +++- virtio-spec/src/lib.rs | 3 +++ virtio-spec/src/volatile.rs | 9 +++++---- 6 files changed, 19 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c51ddbe1f0..c5d89e8483 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ fuse = ["pci", "dep:fuse-abi", "fuse-abi/num_enum"] fsgsbase = [] gem-net = ["tcp", "dep:tock-registers"] newlib = [] -pci = [] +pci = ["virtio/pci"] rtl8139 = ["tcp", "pci"] smp = [] tcp = ["smoltcp", "smoltcp/socket-tcp"] @@ -74,7 +74,7 @@ mmap = [] [dependencies] hermit-macro = { path = "hermit-macro" } -virtio = { package = "virtio-spec", path = "virtio-spec", features = ["alloc", "nightly", "zerocopy"] } +virtio = { package = "virtio-spec", path = "virtio-spec", features = ["alloc", "mmio", "nightly", "zerocopy"] } ahash = { version = "0.8", default-features = false } align-address = "0.3" anstyle = { version = "1", default-features = false } diff --git a/src/drivers/virtio/virtqueue/packed.rs b/src/drivers/virtio/virtqueue/packed.rs index 3587b335b9..53f079febc 100644 --- a/src/drivers/virtio/virtqueue/packed.rs +++ b/src/drivers/virtio/virtqueue/packed.rs @@ -9,6 +9,9 @@ use core::sync::atomic::{fence, Ordering}; use core::{iter, mem, ops, ptr}; use align_address::Align; +#[cfg(not(feature = "pci"))] +use virtio::mmio::NotificationData; +#[cfg(feature = "pci")] use virtio::pci::NotificationData; use virtio::pvirtq::{EventSuppressDesc, EventSuppressFlags}; use virtio::virtq::DescF; diff --git a/src/drivers/virtio/virtqueue/split.rs b/src/drivers/virtio/virtqueue/split.rs index 79170a4218..c03ba970d4 100644 --- a/src/drivers/virtio/virtqueue/split.rs +++ b/src/drivers/virtio/virtqueue/split.rs @@ -7,6 +7,9 @@ use core::cell::{RefCell, UnsafeCell}; use core::mem::{self, MaybeUninit}; use core::{iter, ptr}; +#[cfg(not(feature = "pci"))] +use virtio::mmio::NotificationData; +#[cfg(feature = "pci")] use virtio::pci::NotificationData; use virtio::{le16, virtq}; diff --git a/virtio-spec/Cargo.toml b/virtio-spec/Cargo.toml index d08d861ec8..fabfd5d0fb 100644 --- a/virtio-spec/Cargo.toml +++ b/virtio-spec/Cargo.toml @@ -14,7 +14,7 @@ bitfield-struct = "0.8" bitflags = "2" endian-num = { version = "0.1", features = ["bitflags", "linux-types"] } num_enum = { version = "0.7", default-features = false } -pci_types = "0.10" +pci_types = { version = "0.10", optional = true } volatile = "0.6" volatile-macro = "0.6" zerocopy = { version = "0.7", optional = true, default-features = false } @@ -22,5 +22,7 @@ zerocopy-derive = { version = "0.7", optional = true } [features] alloc = ["dep:allocator-api2"] +mmio = [] nightly = ["allocator-api2/nightly"] +pci = ["dep:pci_types"] zerocopy = ["dep:zerocopy", "dep:zerocopy-derive", "endian-num/zerocopy"] diff --git a/virtio-spec/src/lib.rs b/virtio-spec/src/lib.rs index a6344190b8..865c86744d 100644 --- a/virtio-spec/src/lib.rs +++ b/virtio-spec/src/lib.rs @@ -13,11 +13,14 @@ extern crate alloc; mod bitflags; #[macro_use] pub mod volatile; +#[cfg(any(feature = "mmio", feature = "pci"))] mod driver_notifications; mod features; pub mod fs; +#[cfg(feature = "mmio")] pub mod mmio; pub mod net; +#[cfg(feature = "pci")] pub mod pci; pub mod pvirtq; pub mod virtq; diff --git a/virtio-spec/src/volatile.rs b/virtio-spec/src/volatile.rs index f0dfa31164..468e68e355 100644 --- a/virtio-spec/src/volatile.rs +++ b/virtio-spec/src/volatile.rs @@ -5,7 +5,6 @@ use core::marker::PhantomData; use volatile::access::{Readable, Writable}; use volatile::VolatilePtr; -use crate::mmio::InterruptStatus; use crate::{be32, be64, le16, le32, le64, DeviceStatus, Id}; /// A wide volatile pointer for 64-bit fields. @@ -112,6 +111,7 @@ impl<'a, A> WideVolatilePtr<'a, be32, A> { } } +#[cfg(any(feature = "mmio", feature = "pci"))] macro_rules! impl_wide_field_access { ( $(#[$outer:meta])* @@ -283,7 +283,8 @@ impl OveralignedField for DeviceStatus { } } -impl OveralignedField for InterruptStatus { +#[cfg(feature = "mmio")] +impl OveralignedField for crate::mmio::InterruptStatus { fn from_field(field: le32) -> Self { Self::from_bits_retain(u8::from_field(field)) } @@ -294,7 +295,6 @@ impl OveralignedField for InterruptStatus { } mod private { - use crate::mmio::InterruptStatus; use crate::{le16, le32, DeviceStatus, Id}; pub trait Sealed {} @@ -304,5 +304,6 @@ mod private { impl Sealed for le16 {} impl Sealed for Id {} impl Sealed for DeviceStatus {} - impl Sealed for InterruptStatus {} + #[cfg(feature = "mmio")] + impl Sealed for crate::mmio::InterruptStatus {} }