From d967453222b30241c5edabdc39f5f3e55e3953bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Thu, 23 May 2024 15:15:46 +0200 Subject: [PATCH 1/4] style(virtio-spec): expand glob import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- virtio-spec/src/pci.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virtio-spec/src/pci.rs b/virtio-spec/src/pci.rs index 443c3142ff..25fef9aaf9 100644 --- a/virtio-spec/src/pci.rs +++ b/virtio-spec/src/pci.rs @@ -3,7 +3,7 @@ use volatile::access::{ReadOnly, ReadWrite, RestrictAccess}; use volatile::{VolatileFieldAccess, VolatilePtr}; -use crate::num::*; +use crate::num::{le16, le32}; use crate::{DeviceStatus, WideVolatilePtr}; /// Common configuration structure From 2084aae6644e324b51267d82cb92a3512dcabc75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Thu, 23 May 2024 15:16:42 +0200 Subject: [PATCH 2/4] style(virtio-spec): explicitly refer to current 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/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/virtio-spec/src/lib.rs b/virtio-spec/src/lib.rs index e53b739d46..06a4a9b715 100644 --- a/virtio-spec/src/lib.rs +++ b/virtio-spec/src/lib.rs @@ -14,8 +14,8 @@ pub mod net; pub mod num; pub mod pci; -pub use features::{FeatureBits, F}; -pub use volatile::WideVolatilePtr; +pub use self::features::{FeatureBits, F}; +pub use self::volatile::WideVolatilePtr; pub mod fs { //! File System Device From 3c3fd8623c11d09e149eb8464d366ecde3214b63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Thu, 23 May 2024 15:18:03 +0200 Subject: [PATCH 3/4] feat(virtio-spec): export 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 --- src/drivers/virtio/virtqueue/split.rs | 2 +- virtio-spec/src/features.rs | 6 +++--- virtio-spec/src/lib.rs | 3 ++- virtio-spec/src/net.rs | 2 +- virtio-spec/src/pci.rs | 3 +-- virtio-spec/src/volatile.rs | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/drivers/virtio/virtqueue/split.rs b/src/drivers/virtio/virtqueue/split.rs index 3eb49be836..a2072a1abd 100644 --- a/src/drivers/virtio/virtqueue/split.rs +++ b/src/drivers/virtio/virtqueue/split.rs @@ -10,7 +10,7 @@ use core::cell::{RefCell, UnsafeCell}; use core::mem::{size_of, MaybeUninit}; use core::ptr::{self, NonNull}; -use virtio_spec::num::{le16, le32, le64}; +use virtio_spec::{le16, le32, le64}; use volatile::access::ReadOnly; use volatile::{map_field, VolatilePtr, VolatileRef}; diff --git a/virtio-spec/src/features.rs b/virtio-spec/src/features.rs index 7c49442e36..d95a8d105d 100644 --- a/virtio-spec/src/features.rs +++ b/virtio-spec/src/features.rs @@ -1,6 +1,6 @@ //! Feature Bits -use crate::num::le128; +use crate::le128; /// Feature Bits #[doc(alias = "VIRTIO_F")] @@ -290,7 +290,7 @@ macro_rules! feature_bits { } pub mod net { - use crate::num::le128; + use crate::le128; feature_bits! { /// Network Device Feature Bits @@ -460,7 +460,7 @@ pub mod net { } pub mod fs { - use crate::num::le128; + use crate::le128; feature_bits! { /// File System Device Feature Bits diff --git a/virtio-spec/src/lib.rs b/virtio-spec/src/lib.rs index 06a4a9b715..b747cf711b 100644 --- a/virtio-spec/src/lib.rs +++ b/virtio-spec/src/lib.rs @@ -11,10 +11,11 @@ mod bitflags; mod volatile; mod features; pub mod net; -pub mod num; +mod num; pub mod pci; pub use self::features::{FeatureBits, F}; +pub use self::num::{be128, be16, be32, be64, le128, le16, le32, le64}; pub use self::volatile::WideVolatilePtr; pub mod fs { diff --git a/virtio-spec/src/net.rs b/virtio-spec/src/net.rs index ea94fc0eac..39355468c5 100644 --- a/virtio-spec/src/net.rs +++ b/virtio-spec/src/net.rs @@ -1,7 +1,7 @@ //! Network Device pub use super::features::net::F; -use crate::num::{le16, le32}; +use crate::{le16, le32}; virtio_bitflags! { /// Network Device Header Flags diff --git a/virtio-spec/src/pci.rs b/virtio-spec/src/pci.rs index 25fef9aaf9..f73d67ab23 100644 --- a/virtio-spec/src/pci.rs +++ b/virtio-spec/src/pci.rs @@ -3,8 +3,7 @@ use volatile::access::{ReadOnly, ReadWrite, RestrictAccess}; use volatile::{VolatileFieldAccess, VolatilePtr}; -use crate::num::{le16, le32}; -use crate::{DeviceStatus, WideVolatilePtr}; +use crate::{le16, le32, DeviceStatus, WideVolatilePtr}; /// Common configuration structure /// diff --git a/virtio-spec/src/volatile.rs b/virtio-spec/src/volatile.rs index 1537de2239..e054b7e41f 100644 --- a/virtio-spec/src/volatile.rs +++ b/virtio-spec/src/volatile.rs @@ -3,7 +3,7 @@ use volatile::access::{Readable, Writable}; use volatile::VolatilePtr; -use crate::num::{be32, be64, le32, le64}; +use crate::{be32, be64, le32, le64}; /// A wide volatile pointer for 64-bit fields. /// From 3756022cc6774649510cebe2c6d4c29949fc9ce3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Fri, 24 May 2024 15:19:09 +0200 Subject: [PATCH 4/4] feat(virtio-spec): migrate to endian-num crate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- Cargo.lock | 12 ++ src/drivers/net/virtio_net.rs | 2 +- src/drivers/virtio/transport/mmio.rs | 2 +- src/drivers/virtio/transport/pci.rs | 14 +- src/drivers/virtio/virtqueue/split.rs | 18 +- virtio-spec/Cargo.toml | 3 +- virtio-spec/src/bitflags.rs | 20 +- virtio-spec/src/features.rs | 22 +-- virtio-spec/src/lib.rs | 4 +- virtio-spec/src/num.rs | 273 -------------------------- virtio-spec/src/volatile.rs | 8 +- 11 files changed, 60 insertions(+), 318 deletions(-) delete mode 100644 virtio-spec/src/num.rs diff --git a/Cargo.lock b/Cargo.lock index 2f6e0149c2..044927f4fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -414,6 +414,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +[[package]] +name = "endian-num" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0df1568147123f2170d703aada73a9f2e73a1464f93c8fb5e44ffbb7695134b9" +dependencies = [ + "bitflags 2.5.0", + "zerocopy", + "zerocopy-derive", +] + [[package]] name = "event-listener" version = "4.0.3" @@ -1505,6 +1516,7 @@ name = "virtio-spec" version = "0.0.0" dependencies = [ "bitflags 2.5.0", + "endian-num", "volatile 0.5.4", "zerocopy", "zerocopy-derive", diff --git a/src/drivers/net/virtio_net.rs b/src/drivers/net/virtio_net.rs index 2e05c0ece0..2525b2277d 100644 --- a/src/drivers/net/virtio_net.rs +++ b/src/drivers/net/virtio_net.rs @@ -558,7 +558,7 @@ impl NetworkDriver for VirtioNetDriver { num_buffers }; - for _ in 1..num_buffers.get() { + for _ in 1..num_buffers.to_ne() { let transfer = match RxQueues::post_processing(self.recv_vqs.get_next().unwrap()) { Ok(trf) => trf, diff --git a/src/drivers/virtio/transport/mmio.rs b/src/drivers/virtio/transport/mmio.rs index 504969c298..4915dd7f4d 100644 --- a/src/drivers/virtio/transport/mmio.rs +++ b/src/drivers/virtio/transport/mmio.rs @@ -563,7 +563,7 @@ impl MmioRegisterLayout { /// Write selected features into driver_select field. pub fn set_drv_features(&mut self, features: virtio_spec::F) { - let features = features.bits().get() as u64; + let features = features.bits().to_ne() as u64; let high: u32 = (features >> 32) as u32; let low: u32 = features as u32; diff --git a/src/drivers/virtio/transport/pci.rs b/src/drivers/virtio/transport/pci.rs index 961d25e093..871bfc2e14 100644 --- a/src/drivers/virtio/transport/pci.rs +++ b/src/drivers/virtio/transport/pci.rs @@ -452,11 +452,11 @@ impl<'a> VqCfgHandler<'a> { self.select_queue(); let queue_size = self.raw.as_mut_ptr().queue_size(); - if queue_size.read().get() >= size { + if queue_size.read().to_ne() >= size { queue_size.write(size.into()); } - queue_size.read().get() + queue_size.read().to_ne() } pub fn set_ring_addr(&mut self, addr: PhysAddr) { @@ -485,7 +485,7 @@ impl<'a> VqCfgHandler<'a> { pub fn notif_off(&mut self) -> u16 { self.select_queue(); - self.raw.as_mut_ptr().queue_notify_off().read().get() + self.raw.as_mut_ptr().queue_notify_off().read().to_ne() } pub fn enable_queue(&mut self) { @@ -503,7 +503,7 @@ impl ComCfg { pub fn select_vq(&mut self, index: u16) -> Option> { self.com_cfg.as_mut_ptr().queue_select().write(index.into()); - if self.com_cfg.as_mut_ptr().queue_size().read().get() == 0 { + if self.com_cfg.as_mut_ptr().queue_size().read().to_ne() == 0 { None } else { Some(VqCfgHandler { @@ -608,7 +608,7 @@ impl ComCfg { memory_barrier(); // read high 32 bits of device features - let mut device_features = u64::from(device_feature.read().get()) << 32; + let mut device_features = u64::from(device_feature.read().to_ne()) << 32; // Indicate device to show low 32 bits in device_feature field. // See Virtio specification v1.1. - 4.1.4.3 @@ -616,14 +616,14 @@ impl ComCfg { memory_barrier(); // read low 32 bits of device features - device_features |= u64::from(device_feature.read().get()); + device_features |= u64::from(device_feature.read().to_ne()); virtio_spec::F::from_bits_retain(u128::from(device_features).into()) } /// Write selected features into driver_select field. pub fn set_drv_features(&mut self, features: virtio_spec::F) { - let features = features.bits().get() as u64; + let features = features.bits().to_ne() as u64; let com_cfg = self.com_cfg.as_mut_ptr(); let driver_feature_select = com_cfg.driver_feature_select(); let driver_feature = com_cfg.driver_feature(); diff --git a/src/drivers/virtio/virtqueue/split.rs b/src/drivers/virtio/virtqueue/split.rs index a2072a1abd..4bf9f62add 100644 --- a/src/drivers/virtio/virtqueue/split.rs +++ b/src/drivers/virtio/virtqueue/split.rs @@ -264,13 +264,13 @@ impl DescrRing { let len = self.token_ring.len(); let mut avail_ring_ref = self.avail_ring_ref(); let avail_ring = avail_ring_ref.as_mut_ptr(); - let idx = map_field!(avail_ring.index).read().get(); + let idx = map_field!(avail_ring.index).read().to_ne(); AvailRing::ring_ptr(avail_ring) .index(idx as usize % len) .write(MaybeUninit::new((index as u16).into())); memory_barrier(); - map_field!(avail_ring.index).update(|val| (val.get().wrapping_add(1)).into()); + map_field!(avail_ring.index).update(|val| (val.to_ne().wrapping_add(1)).into()); (0, 0) } @@ -284,7 +284,7 @@ impl DescrRing { { let used_ring_ref = self.used_ring_ref(); let used_ring = used_ring_ref.as_ptr(); - if self.read_idx == map_field!(used_ring.index).read().get() { + if self.read_idx == map_field!(used_ring.index).read().to_ne() { break; } else { let cur_ring_index = self.read_idx as usize % self.token_ring.len(); @@ -292,15 +292,17 @@ impl DescrRing { } } - let mut tkn = self.token_ring[used_elem.id.get() as usize].take().expect( - "The buff_id is incorrect or the reference to the TransferToken was misplaced.", - ); + let mut tkn = self.token_ring[used_elem.id.to_ne() as usize] + .take() + .expect( + "The buff_id is incorrect or the reference to the TransferToken was misplaced.", + ); if tkn.buff_tkn.as_ref().unwrap().recv_buff.as_ref().is_some() { tkn.buff_tkn .as_mut() .unwrap() - .restr_size(None, Some(used_elem.len.get() as usize)) + .restr_size(None, Some(used_elem.len.to_ne() as usize)) .unwrap(); } if let Some(queue) = tkn.await_queue.take() { @@ -326,7 +328,7 @@ impl DescrRing { fn dev_is_notif(&self) -> bool { let used_ring_ref = self.used_ring_ref(); let used_ring = used_ring_ref.as_ptr(); - map_field!(used_ring.flags).read().get() & 1 == 0 + map_field!(used_ring.flags).read().to_ne() & 1 == 0 } } diff --git a/virtio-spec/Cargo.toml b/virtio-spec/Cargo.toml index 5e8bf89ba8..02e0970862 100644 --- a/virtio-spec/Cargo.toml +++ b/virtio-spec/Cargo.toml @@ -10,9 +10,10 @@ categories = ["no-std", "no-std::no-alloc"] [dependencies] bitflags = "2" +endian-num = { version = "0.1", features = ["bitflags", "linux-types"] } volatile = { version = "0.5.3", features = ["derive"] } zerocopy = { version = "0.7", optional = true, default-features = false } zerocopy-derive = { version = "0.7", optional = true } [features] -zerocopy = ["dep:zerocopy", "dep:zerocopy-derive"] +zerocopy = ["dep:zerocopy", "dep:zerocopy-derive", "endian-num/zerocopy"] diff --git a/virtio-spec/src/bitflags.rs b/virtio-spec/src/bitflags.rs index 4de014dccb..02f535b261 100644 --- a/virtio-spec/src/bitflags.rs +++ b/virtio-spec/src/bitflags.rs @@ -110,7 +110,7 @@ macro_rules! endian_bitflags { impl $BitFlags { $( $(#[$inner $($args)*])* - pub const $Flag: Self = Self(<$T>::new($value)); + pub const $Flag: Self = Self(<$T>::from_ne($value)); )* } @@ -186,25 +186,25 @@ macro_rules! endian_bitflags { /// Whether all bits in this flags value are unset. #[inline] pub const fn is_empty(&self) -> bool { - self.bits().get() == <$T as ::bitflags::Bits>::EMPTY.get() + self.bits().to_ne() == <$T as ::bitflags::Bits>::EMPTY.to_ne() } /// Whether all known bits in this flags value are set. #[inline] pub const fn is_all(&self) -> bool { - Self::all().bits().get() | self.bits().get() == self.bits().get() + Self::all().bits().to_ne() | self.bits().to_ne() == self.bits().to_ne() } /// Whether any set bits in a source flags value are also set in a target flags value. #[inline] pub const fn intersects(&self, other: Self) -> bool { - self.bits().get() & other.bits().get() != <$T as ::bitflags::Bits>::EMPTY.get() + self.bits().to_ne() & other.bits().to_ne() != <$T as ::bitflags::Bits>::EMPTY.to_ne() } /// Whether all set bits in a source flags value are also set in a target flags value. #[inline] pub const fn contains(&self, other: Self) -> bool { - self.bits().get() & other.bits().get() == other.bits().get() + self.bits().to_ne() & other.bits().to_ne() == other.bits().to_ne() } /// The bitwise or (`|`) of the bits in two flags values. @@ -242,14 +242,14 @@ macro_rules! endian_bitflags { #[inline] #[must_use] pub const fn intersection(self, other: Self) -> Self { - Self::from_bits_retain(<$T>::new(self.bits().get() & other.bits().get())) + Self::from_bits_retain(<$T>::from_ne(self.bits().to_ne() & other.bits().to_ne())) } /// The bitwise or (`|`) of the bits in two flags values. #[inline] #[must_use] pub const fn union(self, other: Self) -> Self { - Self::from_bits_retain(<$T>::new(self.bits().get() | other.bits().get())) + Self::from_bits_retain(<$T>::from_ne(self.bits().to_ne() | other.bits().to_ne())) } /// The intersection of a source flags value with the complement of a target flags value (`&!`). @@ -259,21 +259,21 @@ macro_rules! endian_bitflags { #[inline] #[must_use] pub const fn difference(self, other: Self) -> Self { - Self::from_bits_retain(<$T>::new(self.bits().get() & !other.bits().get())) + Self::from_bits_retain(<$T>::from_ne(self.bits().to_ne() & !other.bits().to_ne())) } /// The bitwise exclusive-or (`^`) of the bits in two flags values. #[inline] #[must_use] pub const fn symmetric_difference(self, other: Self) -> Self { - Self::from_bits_retain(<$T>::new(self.bits().get() ^ other.bits().get())) + Self::from_bits_retain(<$T>::from_ne(self.bits().to_ne() ^ other.bits().to_ne())) } /// The bitwise negation (`!`) of the bits in a flags value, truncating the result. #[inline] #[must_use] pub const fn complement(self) -> Self { - Self::from_bits_truncate(<$T>::new(!self.bits().get())) + Self::from_bits_truncate(<$T>::from_ne(!self.bits().to_ne())) } } diff --git a/virtio-spec/src/features.rs b/virtio-spec/src/features.rs index d95a8d105d..a0459589b6 100644 --- a/virtio-spec/src/features.rs +++ b/virtio-spec/src/features.rs @@ -209,37 +209,37 @@ macro_rules! feature_bits { )* /// Device-independent Bit. See [`virtio_spec::F::INDIRECT_DESC`](crate::F::INDIRECT_DESC). - const INDIRECT_DESC = $crate::F::INDIRECT_DESC.bits().get(); + const INDIRECT_DESC = $crate::F::INDIRECT_DESC.bits().to_ne(); /// Device-independent Bit. See [`virtio_spec::F::EVENT_IDX`](crate::F::EVENT_IDX). - const EVENT_IDX = $crate::F::EVENT_IDX.bits().get(); + const EVENT_IDX = $crate::F::EVENT_IDX.bits().to_ne(); /// Device-independent Bit. See [`virtio_spec::F::VERSION_1`](crate::F::VERSION_1). - const VERSION_1 = $crate::F::VERSION_1.bits().get(); + const VERSION_1 = $crate::F::VERSION_1.bits().to_ne(); /// Device-independent Bit. See [`virtio_spec::F::ACCESS_PLATFORM`](crate::F::ACCESS_PLATFORM). - const ACCESS_PLATFORM = $crate::F::ACCESS_PLATFORM.bits().get(); + const ACCESS_PLATFORM = $crate::F::ACCESS_PLATFORM.bits().to_ne(); /// Device-independent Bit. See [`virtio_spec::F::RING_PACKED`](crate::F::RING_PACKED). - const RING_PACKED = $crate::F::RING_PACKED.bits().get(); + const RING_PACKED = $crate::F::RING_PACKED.bits().to_ne(); /// Device-independent Bit. See [`virtio_spec::F::IN_ORDER`](crate::F::IN_ORDER). - const IN_ORDER = $crate::F::IN_ORDER.bits().get(); + const IN_ORDER = $crate::F::IN_ORDER.bits().to_ne(); /// Device-independent Bit. See [`virtio_spec::F::ORDER_PLATFORM`](crate::F::ORDER_PLATFORM). - const ORDER_PLATFORM = $crate::F::ORDER_PLATFORM.bits().get(); + const ORDER_PLATFORM = $crate::F::ORDER_PLATFORM.bits().to_ne(); /// Device-independent Bit. See [`virtio_spec::F::SR_IOV`](crate::F::SR_IOV). - const SR_IOV = $crate::F::SR_IOV.bits().get(); + const SR_IOV = $crate::F::SR_IOV.bits().to_ne(); /// Device-independent Bit. See [`virtio_spec::F::NOTIFICATION_DATA`](crate::F::NOTIFICATION_DATA). - const NOTIFICATION_DATA = $crate::F::NOTIFICATION_DATA.bits().get(); + const NOTIFICATION_DATA = $crate::F::NOTIFICATION_DATA.bits().to_ne(); /// Device-independent Bit. See [`virtio_spec::F::NOTIF_CONFIG_DATA`](crate::F::NOTIF_CONFIG_DATA). - const NOTIF_CONFIG_DATA = $crate::F::NOTIF_CONFIG_DATA.bits().get(); + const NOTIF_CONFIG_DATA = $crate::F::NOTIF_CONFIG_DATA.bits().to_ne(); /// Device-independent Bit. See [`virtio_spec::F::RING_RESET`](crate::F::RING_RESET). - const RING_RESET = $crate::F::RING_RESET.bits().get(); + const RING_RESET = $crate::F::RING_RESET.bits().to_ne(); } } diff --git a/virtio-spec/src/lib.rs b/virtio-spec/src/lib.rs index b747cf711b..cea4366df1 100644 --- a/virtio-spec/src/lib.rs +++ b/virtio-spec/src/lib.rs @@ -11,11 +11,11 @@ mod bitflags; mod volatile; mod features; pub mod net; -mod num; pub mod pci; +pub use endian_num::{be128, be16, be32, be64, le128, le16, le32, le64}; + pub use self::features::{FeatureBits, F}; -pub use self::num::{be128, be16, be32, be64, le128, le16, le32, le64}; pub use self::volatile::WideVolatilePtr; pub mod fs { diff --git a/virtio-spec/src/num.rs b/virtio-spec/src/num.rs deleted file mode 100644 index cf2c55a94d..0000000000 --- a/virtio-spec/src/num.rs +++ /dev/null @@ -1,273 +0,0 @@ -//! Byte order-aware numeric primitives. - -use core::cmp::Ordering; -use core::{fmt, mem, ops}; - -use bitflags::parser::{ParseError, ParseHex, WriteHex}; -use bitflags::Bits; - -/// An unsigned integer stored in big-endian byte order. -#[cfg_attr( - feature = "zerocopy", - derive( - zerocopy_derive::FromZeroes, - zerocopy_derive::FromBytes, - zerocopy_derive::AsBytes - ) -)] -#[derive(Default, Hash, PartialEq, Eq, Clone, Copy)] -#[repr(transparent)] -pub struct Be(T); - -/// An unsigned integer stored in little-endian byte order. -#[cfg_attr( - feature = "zerocopy", - derive( - zerocopy_derive::FromZeroes, - zerocopy_derive::FromBytes, - zerocopy_derive::AsBytes - ) -)] -#[derive(Default, Hash, PartialEq, Eq, Clone, Copy)] -#[repr(transparent)] -pub struct Le(T); - -macro_rules! endian_impl { - ($SelfT:ident, $ActualT:ty, $alias:ident, $to:ident, $from:ident, $bits:expr, $order:expr) => { - #[doc = concat!("A ", stringify!($bits), "-bit unsigned integer stored in ", $order, " byte order.")] - #[allow(non_camel_case_types)] - pub type $alias = $SelfT<$ActualT>; - - impl $SelfT<$ActualT> { - /// The smallest value that can be represented by this integer type. - pub const MIN: Self = Self::new(<$ActualT>::MIN); - - /// The largest value that can be represented by this integer type - #[doc = concat!("(2", $bits, " − 1", ").")] - pub const MAX: Self = Self::new(<$ActualT>::MAX); - - /// The size of this integer type in bits. - pub const BITS: u32 = $bits; - - #[doc = concat!("Creates a new ", $order, " integer from native-endian byte order.")] - #[inline] - pub const fn new(n: $ActualT) -> Self { - Self(n.$to()) - } - - /// Returns the integer in native-endian byte order. - #[inline] - pub const fn get(self) -> $ActualT { - <$ActualT>::$from(self.0) - } - } - - impl From<$ActualT> for $SelfT<$ActualT> { - #[inline] - fn from(value: $ActualT) -> Self { - Self::new(value) - } - } - - impl From<$SelfT<$ActualT>> for $ActualT { - #[inline] - fn from(value: $SelfT<$ActualT>) -> Self { - value.get() - } - } - - impl Bits for $SelfT<$ActualT> { - const EMPTY: Self = Self::MIN; - - const ALL: Self = Self::MAX; - } - }; -} - -endian_impl!(Be, u16, be16, to_be, from_be, 16, "big-endian"); -endian_impl!(Be, u32, be32, to_be, from_be, 32, "big-endian"); -endian_impl!(Be, u64, be64, to_be, from_be, 64, "big-endian"); -endian_impl!(Be, u128, be128, to_be, from_be, 128, "big-endian"); -endian_impl!(Le, u16, le16, to_le, from_le, 16, "little-endian"); -endian_impl!(Le, u32, le32, to_le, from_le, 32, "little-endian"); -endian_impl!(Le, u64, le64, to_le, from_le, 64, "little-endian"); -endian_impl!(Le, u128, le128, to_le, from_le, 128, "little-endian"); - -macro_rules! impl_fmt { - ($Trait:ident, $SelfT:ident) => { - impl fmt::$Trait for $SelfT - where - Self: Copy + Into, - T: fmt::$Trait, - { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (*self).into().fmt(f) - } - } - }; -} - -macro_rules! impl_binary_op { - ($Trait:ident, $op:ident, $TraitAssign:ident, $op_assign:ident, $SelfT:ident) => { - impl ops::$Trait for $SelfT - where - Self: Into, - T: ops::$Trait + Into, - { - type Output = Self; - - #[inline] - fn $op(self, rhs: Self) -> Self::Output { - self.into().$op(rhs.into()).into() - } - } - - impl ops::$TraitAssign for $SelfT - where - Self: Copy + ops::$Trait, - { - #[inline] - fn $op_assign(&mut self, rhs: Self) { - use ops::$Trait; - - *self = self.$op(rhs) - } - } - }; -} - -macro_rules! impl_traits { - ($SelfT:ident) => { - impl_fmt!(Debug, $SelfT); - impl_fmt!(Display, $SelfT); - impl_fmt!(Binary, $SelfT); - impl_fmt!(Octal, $SelfT); - impl_fmt!(LowerHex, $SelfT); - impl_fmt!(UpperHex, $SelfT); - - impl_binary_op!(Add, add, AddAssign, add_assign, $SelfT); - impl_binary_op!(BitAnd, bitand, BitAndAssign, bitand_assign, $SelfT); - impl_binary_op!(BitOr, bitor, BitOrAssign, bitor_assign, $SelfT); - impl_binary_op!(BitXor, bitxor, BitXorAssign, bitxor_assign, $SelfT); - impl_binary_op!(Div, div, DivAssign, div_assign, $SelfT); - impl_binary_op!(Mul, mul, MulAssign, mul_assign, $SelfT); - impl_binary_op!(Rem, rem, RemAssign, rem_assign, $SelfT); - impl_binary_op!(Shl, shl, ShlAssign, shl_assign, $SelfT); - impl_binary_op!(Shr, shr, ShrAssign, shr_assign, $SelfT); - impl_binary_op!(Sub, sub, SubAssign, sub_assign, $SelfT); - - impl ParseHex for $SelfT - where - T: ParseHex + Into, - { - fn parse_hex(input: &str) -> Result { - T::parse_hex(input).map(Into::into) - } - } - - impl WriteHex for $SelfT - where - Self: Copy + Into, - T: WriteHex, - { - fn write_hex(&self, writer: W) -> fmt::Result { - (*self).into().write_hex(writer) - } - } - - impl ops::Not for $SelfT - where - Self: Into, - T: ops::Not + Into, - { - type Output = Self; - - #[inline] - fn not(self) -> Self::Output { - self.into().not().into() - } - } - - impl PartialOrd for $SelfT - where - Self: Copy + Into, - T: Ord, - { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } - } - - impl Ord for $SelfT - where - Self: Copy + Into, - T: Ord, - { - #[inline] - fn cmp(&self, other: &Self) -> Ordering { - (*self).into().cmp(&(*other).into()) - } - } - }; -} - -impl_traits!(Be); -impl_traits!(Le); - -impl Be { - /// Create an integer from its representation as a [`Be`] array in big endian. - #[inline] - pub const fn from_be_parts(parts: [Be; 2]) -> Self { - unsafe { mem::transmute(parts) } - } - - /// Return the memory representation of this integer as a [`Be`] array in big-endian (network) byte order. - #[inline] - pub const fn to_be_parts(self) -> [Be; 2] { - unsafe { mem::transmute(self) } - } -} - -impl Le { - /// Create an integer from its representation as a [`Le`] array in little endian. - #[inline] - pub const fn from_le_parts(parts: [Le; 2]) -> Self { - unsafe { mem::transmute(parts) } - } - - /// Return the memory representation of this integer as a [`Le`] array in little-endian byte order. - #[inline] - pub const fn to_le_parts(self) -> [Le; 2] { - unsafe { mem::transmute(self) } - } -} - -impl Be { - /// Create an integer from its representation as a [`Be`] array in big endian. - #[inline] - pub const fn from_be_parts(parts: [Be; 4]) -> Self { - unsafe { mem::transmute(parts) } - } - - /// Return the memory representation of this integer as a [`Be`] array in big-endian (network) byte order. - #[inline] - pub const fn to_be_parts(self) -> [Be; 4] { - unsafe { mem::transmute(self) } - } -} - -impl Le { - /// Create an integer from its representation as a [`Le`] array in little endian. - #[inline] - pub const fn from_le_parts(parts: [Le; 4]) -> Self { - unsafe { mem::transmute(parts) } - } - - /// Return the memory representation of this integer as a [`Le`] array in little-endian byte order. - #[inline] - pub const fn to_le_parts(self) -> [Le; 4] { - unsafe { mem::transmute(self) } - } -} diff --git a/virtio-spec/src/volatile.rs b/virtio-spec/src/volatile.rs index e054b7e41f..025aeda6b7 100644 --- a/virtio-spec/src/volatile.rs +++ b/virtio-spec/src/volatile.rs @@ -31,7 +31,7 @@ impl<'a, A> WideVolatilePtr<'a, le32, A> { { let low = self.low.read(); let high = self.high.read(); - le64::from_le_parts([low, high]) + le64::from([low, high]) } /// Performs a volatile write, setting the contained value to the given `value`. @@ -41,7 +41,7 @@ impl<'a, A> WideVolatilePtr<'a, le32, A> { where A: Writable, { - let [low, high] = value.to_le_parts(); + let [low, high] = value.into(); self.low.write(low); self.high.write(high); } @@ -57,7 +57,7 @@ impl<'a, A> WideVolatilePtr<'a, be32, A> { { let low = self.low.read(); let high = self.high.read(); - be64::from_be_parts([low, high]) + be64::from([low, high]) } /// Performs a volatile write, setting the contained value to the given `value`. @@ -67,7 +67,7 @@ impl<'a, A> WideVolatilePtr<'a, be32, A> { where A: Writable, { - let [low, high] = value.to_be_parts(); + let [low, high] = value.into(); self.low.write(low); self.high.write(high); }