Skip to content

Commit

Permalink
Merge pull request #1334 from hermit-os/virtio-spec-refactor
Browse files Browse the repository at this point in the history
refactor(virtio-spec): feature-gate transport modules
  • Loading branch information
mkroening authored Jul 23, 2024
2 parents 12f2261 + 7238203 commit 54c4bf5
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 97 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand All @@ -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 }
Expand Down
3 changes: 3 additions & 0 deletions src/drivers/virtio/virtqueue/packed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions src/drivers/virtio/virtqueue/split.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down
4 changes: 3 additions & 1 deletion virtio-spec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ 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 }
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"]
83 changes: 83 additions & 0 deletions virtio-spec/src/driver_notifications.rs
Original file line number Diff line number Diff line change
@@ -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
///
/// <div class="warning">
///
/// This collides with [`Self::next_off`] and [`Self::next_wrap`].
///
/// </div>
///
/// 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
///
/// <div class="warning">
///
/// This collides with [`Self::with_next_off`] and [`Self::with_next_wrap`].
///
/// </div>
///
/// 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
///
/// <div class="warning">
///
/// This collides with [`Self::set_next_off`] and [`Self::set_next_wrap`].
///
/// </div>
///
/// Bits: 16..32
pub fn set_next_idx(&mut self, value: u16) {
*self = self.with_next_idx(value);
}
}
6 changes: 5 additions & 1 deletion virtio-spec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@ 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;

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};
Expand Down
5 changes: 2 additions & 3 deletions virtio-spec/src/mmio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
pub use crate::driver_notifications::NotificationData;
use crate::volatile::{OveralignedVolatilePtr, WideVolatilePtr};
use crate::{DeviceConfigSpace, DeviceStatus, Id};
use crate::{le16, le32, DeviceConfigSpace, DeviceStatus, Id};

/// MMIO Device Registers
#[repr(transparent)]
Expand Down
86 changes: 3 additions & 83 deletions virtio-spec/src/pci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

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;
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, DeviceConfigSpace, DeviceStatus};
use crate::{le16, le32, le64, DeviceConfigSpace, DeviceStatus, Le};

/// PCI Capability
///
Expand Down Expand Up @@ -461,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
///
/// <div class="warning">
///
/// This collides with [`Self::next_off`] and [`Self::next_wrap`].
///
/// </div>
///
/// 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
///
/// <div class="warning">
///
/// This collides with [`Self::with_next_off`] and [`Self::with_next_wrap`].
///
/// </div>
///
/// 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
///
/// <div class="warning">
///
/// This collides with [`Self::set_next_off`] and [`Self::set_next_wrap`].
///
/// </div>
///
/// Bits: 16..32
pub fn set_next_idx(&mut self, value: u16) {
*self = self.with_next_idx(value);
}
}
3 changes: 1 addition & 2 deletions virtio-spec/src/pvirtq.rs
Original file line number Diff line number Diff line change
@@ -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")]
Expand Down
2 changes: 1 addition & 1 deletion virtio-spec/src/virtq/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
9 changes: 5 additions & 4 deletions virtio-spec/src/volatile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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])*
Expand Down Expand Up @@ -283,7 +283,8 @@ impl OveralignedField<le32> for DeviceStatus {
}
}

impl OveralignedField<le32> for InterruptStatus {
#[cfg(feature = "mmio")]
impl OveralignedField<le32> for crate::mmio::InterruptStatus {
fn from_field(field: le32) -> Self {
Self::from_bits_retain(u8::from_field(field))
}
Expand All @@ -294,7 +295,6 @@ impl OveralignedField<le32> for InterruptStatus {
}

mod private {
use crate::mmio::InterruptStatus;
use crate::{le16, le32, DeviceStatus, Id};

pub trait Sealed<T> {}
Expand All @@ -304,5 +304,6 @@ mod private {
impl Sealed<le32> for le16 {}
impl Sealed<le32> for Id {}
impl Sealed<le32> for DeviceStatus {}
impl Sealed<le32> for InterruptStatus {}
#[cfg(feature = "mmio")]
impl Sealed<le32> for crate::mmio::InterruptStatus {}
}

0 comments on commit 54c4bf5

Please sign in to comment.