From 01a16bd27302aab475f114e6ad93be76384949d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Wed, 29 May 2024 16:08:11 +0200 Subject: [PATCH 1/2] feat(virtio-spec): add `mmio::InterruptStatus` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- virtio-spec/src/mmio.rs | 28 +++++++++++++++++----------- virtio-spec/src/volatile.rs | 13 +++++++++++++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/virtio-spec/src/mmio.rs b/virtio-spec/src/mmio.rs index 52138f977b..f627de90d9 100644 --- a/virtio-spec/src/mmio.rs +++ b/virtio-spec/src/mmio.rs @@ -272,19 +272,10 @@ device_register_impl! { /// /// Reading from this register returns a bit mask of events that /// caused the device interrupt to be asserted. - /// The following events are possible: - /// - /// - Used Buffer Notification - /// - bit 0 - the interrupt was asserted - /// because the device has used a buffer - /// in at least one of the active virtual queues. - /// - Configuration Change Notification - /// - bit 1 - the interrupt was - /// asserted because the configuration of the device has changed. #[doc(alias = "InterruptStatus")] #[offset(0x060)] #[access(ReadOnly)] - interrupt_status: le32, + interrupt_status: InterruptStatus, /// Interrupt acknowledge /// @@ -294,7 +285,7 @@ device_register_impl! { #[doc(alias = "InterruptACK")] #[offset(0x064)] #[access(WriteOnly)] - interrupt_ack: le32, + interrupt_ack: InterruptStatus, /// Device status /// @@ -528,3 +519,18 @@ impl_wide_field_access! { shm_base: shm_base_low, shm_base_high; } } + +virtio_bitflags! { + /// Interrupt Status + pub struct InterruptStatus: u8 { + /// Used Buffer Notification + /// + /// The interrupt was asserted because the device has used a buffer in at least one of the active virtual queues. + const USED_BUFFER_NOTIFICATION = 1 << 0; + + /// Configuration Change Notification + /// + /// The interrupt was asserted because the configuration of the device has changed. + const CONFIGURATION_CHANGE_NOTIFICATION = 1 << 1; + } +} diff --git a/virtio-spec/src/volatile.rs b/virtio-spec/src/volatile.rs index d5d9757d32..634abe75a8 100644 --- a/virtio-spec/src/volatile.rs +++ b/virtio-spec/src/volatile.rs @@ -5,6 +5,7 @@ use core::marker::PhantomData; use volatile::access::{Readable, Writable}; use volatile::VolatilePtr; +use crate::mmio::InterruptStatus; use crate::{be32, be64, le16, le32, le64, DeviceStatus}; /// A wide volatile pointer for 64-bit fields. @@ -272,7 +273,18 @@ impl OveralignedField for DeviceStatus { } } +impl OveralignedField for InterruptStatus { + fn from_field(field: le32) -> Self { + Self::from_bits_retain(u8::from_field(field)) + } + + fn into_field(self) -> le32 { + self.bits().into_field() + } +} + mod private { + use crate::mmio::InterruptStatus; use crate::{le16, le32, DeviceStatus}; pub trait Sealed {} @@ -281,4 +293,5 @@ mod private { impl Sealed for u8 {} impl Sealed for le16 {} impl Sealed for DeviceStatus {} + impl Sealed for InterruptStatus {} } From 0472c8bce02e206fbb865eeef293c19933464840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Wed, 29 May 2024 16:11:57 +0200 Subject: [PATCH 2/2] refactor(virtio/mmio): migrate `IsrStatusRaw` to `virtio-spec` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/drivers/virtio/transport/mmio.rs | 52 ++++++++++++---------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/src/drivers/virtio/transport/mmio.rs b/src/drivers/virtio/transport/mmio.rs index 9a75eeb8ad..421e4a89e7 100644 --- a/src/drivers/virtio/transport/mmio.rs +++ b/src/drivers/virtio/transport/mmio.rs @@ -3,11 +3,12 @@ //! The module contains ... #![allow(dead_code)] -use core::ptr::{read_volatile, write_volatile}; +use core::mem; use core::sync::atomic::{fence, Ordering}; use virtio_spec::mmio::{ DeviceRegisterVolatileFieldAccess, DeviceRegisterVolatileWideFieldAccess, DeviceRegisters, + InterruptStatus, }; use virtio_spec::DeviceStatus; use volatile::VolatileRef; @@ -380,56 +381,47 @@ impl NotifCtrl { } } -/// Wraps a [IsrStatusRaw] in order to preserve +/// Wraps a [`DeviceRegisters`] in order to preserve /// the original structure and allow interaction with the device via /// the structure. /// /// Provides a safe API for Raw structure and allows interaction with the device via /// the structure. pub struct IsrStatus { - raw: &'static mut IsrStatusRaw, + // FIXME: integrate into device register struct + raw: VolatileRef<'static, DeviceRegisters>, } impl IsrStatus { - pub fn new(mut registers: VolatileRef<'_, DeviceRegisters>) -> Self { - let ptr = registers - .as_mut_ptr() - .interrupt_status() - .as_raw_ptr() - .as_ptr(); - let raw: &'static mut IsrStatusRaw = unsafe { &mut *(ptr as *mut IsrStatusRaw) }; - - IsrStatus { raw } + pub fn new(registers: VolatileRef<'_, DeviceRegisters>) -> Self { + let raw = + unsafe { mem::transmute::, VolatileRef<'static, _>>(registers) }; + Self { raw } } pub fn is_interrupt(&self) -> bool { - unsafe { - let status = read_volatile(&self.raw.interrupt_status); - status & 0x1 == 0x1 - } + self.raw + .as_ptr() + .interrupt_status() + .read() + .contains(InterruptStatus::USED_BUFFER_NOTIFICATION) } pub fn is_cfg_change(&self) -> bool { - unsafe { - let status = read_volatile(&self.raw.interrupt_status); - status & 0x2 == 0x2 - } + self.raw + .as_ptr() + .interrupt_status() + .read() + .contains(InterruptStatus::CONFIGURATION_CHANGE_NOTIFICATION) } pub fn acknowledge(&mut self) { - unsafe { - let status = read_volatile(&self.raw.interrupt_status); - write_volatile(&mut self.raw.interrupt_ack, status); - } + let ptr = self.raw.as_mut_ptr(); + let status = ptr.interrupt_status().read(); + ptr.interrupt_ack().write(status); } } -#[repr(C)] -struct IsrStatusRaw { - interrupt_status: u32, - interrupt_ack: u32, -} - pub(crate) enum VirtioDriver { #[cfg(any(feature = "tcp", feature = "udp"))] Network(VirtioNetDriver),