From 03b924a48b9041989d96ce0f0731d8b8acef83e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Sat, 1 Jun 2024 22:39:06 +0200 Subject: [PATCH] refactor(virtio): move `notif_data` into 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 | 30 ++++++-------- src/drivers/virtio/transport/pci.rs | 25 ++++++------ src/drivers/virtio/virtqueue/packed.rs | 54 +++----------------------- src/drivers/virtio/virtqueue/split.rs | 18 +-------- 4 files changed, 32 insertions(+), 95 deletions(-) diff --git a/src/drivers/virtio/transport/mmio.rs b/src/drivers/virtio/transport/mmio.rs index 1bad406a68..90e33ace42 100644 --- a/src/drivers/virtio/transport/mmio.rs +++ b/src/drivers/virtio/transport/mmio.rs @@ -4,11 +4,10 @@ #![allow(dead_code)] use core::mem; -use core::sync::atomic::{fence, Ordering}; use virtio_spec::mmio::{ DeviceRegisterVolatileFieldAccess, DeviceRegisterVolatileWideFieldAccess, DeviceRegisters, - InterruptStatus, + InterruptStatus, NotificationData, }; use virtio_spec::{le32, DeviceStatus}; use volatile::VolatileRef; @@ -301,26 +300,21 @@ impl NotifCtrl { self.f_notif_data = true; } - pub fn notify_dev(&self, notif_data: &[u8]) { - fence(Ordering::Acquire); + pub fn notify_dev(&self, vqn: u16, next_off: u16, next_wrap: u8) { + let notification_data = NotificationData::new() + .with_vqn(vqn) + .with_next_off(next_off) + .with_next_wrap(next_wrap); - if self.f_notif_data { - let ptr = self.notif_addr as *mut [u8; 4]; - - unsafe { - ptr.write_volatile(notif_data[0..4].try_into().unwrap()); - } + let notification_data = if self.f_notif_data { + notification_data.into_bits() } else { - let mut data: [u8; 4] = [0, 0, 0, 0]; - data[0..2].copy_from_slice(¬if_data[0..2]); - let ptr = self.notif_addr as *mut [u8; 4]; + u32::from(notification_data.vqn()).into() + }; - unsafe { - ptr.write_volatile(data[0..4].try_into().unwrap()); - } + unsafe { + self.notif_addr.write_volatile(notification_data); } - - fence(Ordering::Release); } } diff --git a/src/drivers/virtio/transport/pci.rs b/src/drivers/virtio/transport/pci.rs index 4291fc85eb..0fb10ca82b 100644 --- a/src/drivers/virtio/transport/pci.rs +++ b/src/drivers/virtio/transport/pci.rs @@ -5,15 +5,14 @@ use alloc::vec::Vec; use core::ptr::NonNull; -use core::sync::atomic::{fence, Ordering}; use core::{mem, ptr}; use pci_types::capability::PciCapability; use virtio_spec::pci::{ CommonCfg, CommonCfgVolatileFieldAccess, CommonCfgVolatileWideFieldAccess, - IsrStatus as IsrStatusRaw, + IsrStatus as IsrStatusRaw, NotificationData, }; -use virtio_spec::{le32, DeviceStatus}; +use virtio_spec::{le16, le32, DeviceStatus}; use volatile::VolatileRef; #[cfg(all(not(feature = "rtl8139"), any(feature = "tcp", feature = "udp")))] @@ -648,28 +647,28 @@ impl NotifCtrl { self.f_notif_data = true; } - pub fn notify_dev(&self, notif_data: &[u8]) { + pub fn notify_dev(&self, vqn: u16, next_off: u16, next_wrap: u8) { // See Virtio specification v.1.1. - 4.1.5.2 // Depending in the feature negotiation, we write either only the // virtqueue index or the index and the next position inside the queue. - fence(Ordering::Acquire); + let notification_data = NotificationData::new() + .with_vqn(vqn) + .with_next_off(next_off) + .with_next_wrap(next_wrap); if self.f_notif_data { - let ptr = self.notif_addr as *mut [u8; 4]; - unsafe { - ptr.write_volatile(notif_data[0..4].try_into().unwrap()); + self.notif_addr + .write_volatile(notification_data.into_bits()); } } else { - let ptr = self.notif_addr as *mut [u8; 2]; - unsafe { - ptr.write_volatile(notif_data[0..2].try_into().unwrap()); + self.notif_addr + .cast::() + .write_volatile(notification_data.vqn().into()); } } - - fence(Ordering::Release); } } diff --git a/src/drivers/virtio/virtqueue/packed.rs b/src/drivers/virtio/virtqueue/packed.rs index f2e0dd0882..5eedb75a36 100644 --- a/src/drivers/virtio/virtqueue/packed.rs +++ b/src/drivers/virtio/virtqueue/packed.rs @@ -971,22 +971,8 @@ impl Virtq for PackedVq { } if self.dev_event.is_notif() | self.dev_event.is_notif_specfic(next_off, next_wrap) { - let index = self.index.0.to_le_bytes(); - let mut index = index.iter(); - let det_notif_data: u16 = next_off & !(1 << 15); - let flags = (det_notif_data | (u16::from(next_wrap) << 15)).to_le_bytes(); - let mut flags = flags.iter(); - let mut notif_data: [u8; 4] = [0, 0, 0, 0]; - - for (i, byte) in notif_data.iter_mut().enumerate() { - if i < 2 { - *byte = *index.next().unwrap(); - } else { - *byte = *flags.next().unwrap(); - } - } - - self.notif_ctrl.notify_dev(¬if_data) + self.notif_ctrl + .notify_dev(self.index.0, next_off, next_wrap); } } @@ -1013,22 +999,8 @@ impl Virtq for PackedVq { } if self.dev_event.is_notif() { - let index = self.index.0.to_le_bytes(); - let mut index = index.iter(); - let det_notif_data: u16 = next_off & !(1 << 15); - let flags = (det_notif_data | (u16::from(next_wrap) << 15)).to_le_bytes(); - let mut flags = flags.iter(); - let mut notif_data: [u8; 4] = [0, 0, 0, 0]; - - for (i, byte) in notif_data.iter_mut().enumerate() { - if i < 2 { - *byte = *index.next().unwrap(); - } else { - *byte = *flags.next().unwrap(); - } - } - - self.notif_ctrl.notify_dev(¬if_data) + self.notif_ctrl + .notify_dev(self.index.0, next_off, next_wrap); } } @@ -1042,22 +1014,8 @@ impl Virtq for PackedVq { } if self.dev_event.is_notif() { - let index = self.index.0.to_le_bytes(); - let mut index = index.iter(); - let det_notif_data: u16 = next_off & !(1 << 15); - let flags = (det_notif_data | (u16::from(next_wrap) << 15)).to_le_bytes(); - let mut flags = flags.iter(); - let mut notif_data: [u8; 4] = [0, 0, 0, 0]; - - for (i, byte) in notif_data.iter_mut().enumerate() { - if i < 2 { - *byte = *index.next().unwrap(); - } else { - *byte = *flags.next().unwrap(); - } - } - - self.notif_ctrl.notify_dev(¬if_data) + self.notif_ctrl + .notify_dev(self.index.0, next_off, next_wrap); } } diff --git a/src/drivers/virtio/virtqueue/split.rs b/src/drivers/virtio/virtqueue/split.rs index a379b8612d..5cafa70c49 100644 --- a/src/drivers/virtio/virtqueue/split.rs +++ b/src/drivers/virtio/virtqueue/split.rs @@ -378,22 +378,8 @@ impl Virtq for SplitVq { } if self.ring.borrow().dev_is_notif() { - let index = self.index.0.to_le_bytes(); - let mut index = index.iter(); - let det_notif_data: u16 = next_off & !(1 << 15); - let flags = (det_notif_data | (u16::from(next_wrap) << 15)).to_le_bytes(); - let mut flags = flags.iter(); - let mut notif_data: [u8; 4] = [0, 0, 0, 0]; - - for (i, byte) in notif_data.iter_mut().enumerate() { - if i < 2 { - *byte = *index.next().unwrap(); - } else { - *byte = *flags.next().unwrap(); - } - } - - self.notif_ctrl.notify_dev(¬if_data) + self.notif_ctrl + .notify_dev(self.index.0, next_off, next_wrap); } }