Skip to content

Commit

Permalink
Merge pull request #1262 from hermit-os/notif-calc
Browse files Browse the repository at this point in the history
refactor(virtio/transport): move notification location calculation into `NotifCfg`
  • Loading branch information
mkroening authored Jun 6, 2024
2 parents d450c15 + 5628e9e commit 8436ca0
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 48 deletions.
34 changes: 8 additions & 26 deletions src/drivers/virtio/transport/mmio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use virtio_spec::mmio::{
DeviceRegisterVolatileFieldAccess, DeviceRegisterVolatileWideFieldAccess, DeviceRegisters,
InterruptStatus,
};
use virtio_spec::DeviceStatus;
use virtio_spec::{le32, DeviceStatus};
use volatile::VolatileRef;

#[cfg(any(feature = "tcp", feature = "udp"))]
Expand Down Expand Up @@ -69,11 +69,6 @@ impl<'a> VqCfgHandler<'a> {
self.raw.as_mut_ptr().queue_device().write(addr.0.into());
}

pub fn notif_off(&mut self) -> u16 {
// we don't need an offset
0
}

pub fn enable_queue(&mut self) {
self.select_queue();

Expand Down Expand Up @@ -267,31 +262,18 @@ impl ComCfg {
/// See Virtio specification v1.1 - 4.1.4.4
pub struct NotifCfg {
/// Start addr, from where the notification addresses for the virtqueues are computed
queue_notify: *mut u32,
queue_notify: *mut le32,
}

impl NotifCfg {
pub fn new(mut registers: VolatileRef<'_, DeviceRegisters>) -> Self {
let raw = registers
.as_mut_ptr()
.queue_notify()
.as_raw_ptr()
.as_ptr()
.cast();
let raw = registers.as_mut_ptr().queue_notify().as_raw_ptr().as_ptr();

NotifCfg { queue_notify: raw }
}

/// Returns base address of notification area as an usize
pub fn base(&self) -> usize {
self.queue_notify as usize
}

/// Returns the multiplier, needed in order to calculate the
/// notification address for a specific queue.
pub fn multiplier(&self) -> u32 {
// we don't need a multiplier
0
pub fn notification_location(&self, _vq_cfg_handler: &mut VqCfgHandler<'_>) -> *mut le32 {
self.queue_notify
}
}

Expand All @@ -301,16 +283,16 @@ pub struct NotifCtrl {
/// Indicates if VIRTIO_F_NOTIFICATION_DATA has been negotiated
f_notif_data: bool,
/// Where to write notification
notif_addr: *mut u32,
notif_addr: *mut le32,
}

impl NotifCtrl {
/// Returns a new controller. By default MSI-X capabilities and VIRTIO_F_NOTIFICATION_DATA
/// are disabled.
pub fn new(notif_addr: *mut usize) -> Self {
pub fn new(notif_addr: *mut le32) -> Self {
NotifCtrl {
f_notif_data: false,
notif_addr: notif_addr as *mut u32,
notif_addr,
}
}

Expand Down
19 changes: 7 additions & 12 deletions src/drivers/virtio/transport/pci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use virtio_spec::pci::{
CommonCfg, CommonCfgVolatileFieldAccess, CommonCfgVolatileWideFieldAccess,
IsrStatus as IsrStatusRaw,
};
use virtio_spec::DeviceStatus;
use virtio_spec::{le32, DeviceStatus};
use volatile::VolatileRef;

#[cfg(all(not(feature = "rtl8139"), any(feature = "tcp", feature = "udp")))]
Expand Down Expand Up @@ -617,15 +617,10 @@ impl NotifCfg {
})
}

/// Returns base address of notification area as an usize
pub fn base(&self) -> usize {
usize::from(self.base_addr)
}

/// Returns the multiplier, needed in order to calculate the
/// notification address for a specific queue.
pub fn multiplier(&self) -> u32 {
self.notify_off_multiplier
pub fn notification_location(&self, vq_cfg_handler: &mut VqCfgHandler<'_>) -> *mut le32 {
let addend = u32::from(vq_cfg_handler.notif_off()) * self.notify_off_multiplier;
let addr = usize::from(self.base_addr) + usize::try_from(addend).unwrap();
ptr::with_exposed_provenance_mut(addr)
}
}

Expand All @@ -635,13 +630,13 @@ pub struct NotifCtrl {
/// Indicates if VIRTIO_F_NOTIFICATION_DATA has been negotiated
f_notif_data: bool,
/// Where to write notification
notif_addr: *mut usize,
notif_addr: *mut le32,
}

impl NotifCtrl {
/// Returns a new controller. By default MSI-X capabilities and VIRTIO_F_NOTIFICATION_DATA
/// are disabled.
pub fn new(notif_addr: *mut usize) -> Self {
pub fn new(notif_addr: *mut le32) -> Self {
NotifCtrl {
f_notif_data: false,
notif_addr,
Expand Down
6 changes: 1 addition & 5 deletions src/drivers/virtio/virtqueue/packed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1131,11 +1131,7 @@ impl Virtq for PackedVq {
raw: dev_event,
};

let mut notif_ctrl = NotifCtrl::new(ptr::with_exposed_provenance_mut(
notif_cfg.base()
+ usize::from(vq_handler.notif_off())
* usize::try_from(notif_cfg.multiplier()).unwrap(),
));
let mut notif_ctrl = NotifCtrl::new(notif_cfg.notification_location(&mut vq_handler));

if features.contains(virtio_spec::F::NOTIFICATION_DATA) {
notif_ctrl.enable_notif_data();
Expand Down
6 changes: 1 addition & 5 deletions src/drivers/virtio/virtqueue/split.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,11 +494,7 @@ impl Virtq for SplitVq {
used_ring_cell,
};

let mut notif_ctrl = NotifCtrl::new(ptr::with_exposed_provenance_mut(
notif_cfg.base()
+ usize::from(vq_handler.notif_off())
* usize::try_from(notif_cfg.multiplier()).unwrap(),
));
let mut notif_ctrl = NotifCtrl::new(notif_cfg.notification_location(&mut vq_handler));

if features.contains(virtio_spec::F::NOTIFICATION_DATA) {
notif_ctrl.enable_notif_data();
Expand Down

0 comments on commit 8436ca0

Please sign in to comment.