Skip to content

Commit

Permalink
refactor(virtio/mmio): migrate MmioRegisterLayout to virtio-spec
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Kröning <martin.kroening@eonerc.rwth-aachen.de>
  • Loading branch information
mkroening committed May 29, 2024
1 parent 2669df8 commit edbf1df
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 223 deletions.
20 changes: 14 additions & 6 deletions src/arch/riscv64/kernel/devicetree.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
#[cfg(all(feature = "tcp", not(feature = "pci")))]
use core::ptr::NonNull;

use fdt::Fdt;
#[cfg(all(feature = "tcp", not(feature = "pci")))]
use virtio_spec::mmio::{DeviceRegisterVolatileFieldAccess, DeviceRegisters};
#[cfg(all(feature = "tcp", not(feature = "pci")))]
use volatile::VolatileRef;

#[cfg(feature = "gem-net")]
use crate::arch::mm::VirtAddr;
Expand All @@ -9,11 +16,11 @@ use crate::arch::riscv64::kernel::mmio::MmioDriver;
use crate::arch::riscv64::mm::{paging, PhysAddr};
#[cfg(feature = "gem-net")]
use crate::drivers::net::gem;
#[cfg(all(feature = "tcp", not(feature = "pci")))]
use crate::drivers::virtio::transport::mmio::DevId;
#[cfg(all(feature = "tcp", not(feature = "pci"), not(feature = "gem-net")))]
use crate::drivers::virtio::transport::mmio::{self as mmio_virtio, VirtioDriver};
#[cfg(all(feature = "tcp", not(feature = "pci")))]
use crate::drivers::virtio::transport::mmio::{DevId, MmioRegisterLayout};
#[cfg(all(feature = "tcp", not(feature = "pci")))]
use crate::kernel::mmio::register_driver;

static mut PLATFORM_MODEL: Model = Model::Unknown;
Expand Down Expand Up @@ -184,10 +191,11 @@ pub fn init_drivers() {
);

// Verify the first register value to find out if this is really an MMIO magic-value.
let mmio = &mut *(virtio_region.starting_address as *mut MmioRegisterLayout);
let ptr = virtio_region.starting_address as *mut DeviceRegisters;
let mmio = VolatileRef::new(NonNull::new(ptr).unwrap());

let magic = mmio.get_magic_value();
let version = mmio.get_version();
let magic = mmio.as_ptr().magic_value().read().to_ne();
let version = mmio.as_ptr().version().read().to_ne();

const MMIO_MAGIC_VALUE: u32 = 0x74726976;
if magic != MMIO_MAGIC_VALUE {
Expand All @@ -201,7 +209,7 @@ pub fn init_drivers() {
trace!("Found a MMIO-device at {mmio:p}");

// Verify the device-ID to find the network card
let id = mmio.get_device_id();
let id = DevId::from(mmio.as_ptr().device_id().read().to_ne());

if id != DevId::VIRTIO_DEV_ID_NET {
debug!("It's not a network card at {mmio:p}");
Expand Down
21 changes: 12 additions & 9 deletions src/arch/x86_64/kernel/mmio.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
use alloc::string::String;
use alloc::vec::Vec;
use core::ptr::NonNull;
use core::{ptr, str};

use align_address::Align;
use hermit_sync::{without_interrupts, InterruptTicketMutex};
use virtio_spec::mmio::{DeviceRegisterVolatileFieldAccess, DeviceRegisters};
use volatile::VolatileRef;

use crate::arch::x86_64::mm::paging::{
BasePageSize, PageSize, PageTableEntryFlags, PageTableEntryFlagsExt,
};
use crate::arch::x86_64::mm::{paging, PhysAddr};
use crate::drivers::net::virtio_net::VirtioNetDriver;
use crate::drivers::virtio::transport::mmio as mmio_virtio;
use crate::drivers::virtio::transport::mmio::{DevId, MmioRegisterLayout, VirtioDriver};
use crate::drivers::virtio::transport::mmio::{DevId, VirtioDriver};
use crate::env;

pub const MAGIC_VALUE: u32 = 0x74726976;
Expand All @@ -36,12 +39,12 @@ impl MmioDriver {
}
}

unsafe fn check_ptr(ptr: *mut u8) -> Option<&'static mut MmioRegisterLayout> {
unsafe fn check_ptr(ptr: *mut u8) -> Option<VolatileRef<'static, DeviceRegisters>> {
// Verify the first register value to find out if this is really an MMIO magic-value.
let mmio = unsafe { ptr.cast::<MmioRegisterLayout>().as_mut().unwrap() };
let mmio = unsafe { VolatileRef::new(NonNull::new(ptr.cast::<DeviceRegisters>()).unwrap()) };

let magic = mmio.get_magic_value();
let version = mmio.get_version();
let magic = mmio.as_ptr().magic_value().read().to_ne();
let version = mmio.as_ptr().version().read().to_ne();

if magic != MAGIC_VALUE {
trace!("It's not a MMIO-device at {mmio:p}");
Expand All @@ -57,7 +60,7 @@ unsafe fn check_ptr(ptr: *mut u8) -> Option<&'static mut MmioRegisterLayout> {
trace!("Found a MMIO-device at {mmio:p}");

// Verify the device-ID to find the network card
let id = mmio.get_device_id();
let id = DevId::from(mmio.as_ptr().device_id().read().to_ne());

if id != DevId::VIRTIO_DEV_ID_NET {
trace!("It's not a network card at {mmio:p}");
Expand All @@ -69,7 +72,7 @@ unsafe fn check_ptr(ptr: *mut u8) -> Option<&'static mut MmioRegisterLayout> {

fn check_linux_args(
linux_mmio: &'static [String],
) -> Result<(&'static mut MmioRegisterLayout, u8), &'static str> {
) -> Result<(VolatileRef<'static, DeviceRegisters>, u8), &'static str> {
let virtual_address =
crate::arch::mm::virtualmem::allocate(BasePageSize::SIZE as usize).unwrap();

Expand Down Expand Up @@ -123,7 +126,7 @@ fn check_linux_args(
Err("Network card not found!")
}

fn guess_device() -> Result<(&'static mut MmioRegisterLayout, u8), &'static str> {
fn guess_device() -> Result<(VolatileRef<'static, DeviceRegisters>, u8), &'static str> {
// Trigger page mapping in the first iteration!
let mut current_page = 0;
let virtual_address =
Expand Down Expand Up @@ -175,7 +178,7 @@ fn guess_device() -> Result<(&'static mut MmioRegisterLayout, u8), &'static str>

/// Tries to find the network device within the specified address range.
/// Returns a reference to it within the Ok() if successful or an Err() on failure.
fn detect_network() -> Result<(&'static mut MmioRegisterLayout, u8), &'static str> {
fn detect_network() -> Result<(VolatileRef<'static, DeviceRegisters>, u8), &'static str> {
let linux_mmio = env::mmio();

if !linux_mmio.is_empty() {
Expand Down
24 changes: 16 additions & 8 deletions src/drivers/net/virtio_mmio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@

use alloc::rc::Rc;
use alloc::vec::Vec;
use core::ptr;
use core::ptr::read_volatile;
use core::str::FromStr;
use core::sync::atomic::{fence, Ordering};

use smoltcp::phy::ChecksumCapabilities;
use virtio_spec::mmio::{DeviceRegisterVolatileFieldAccess, DeviceRegisters};
use volatile::VolatileRef;

use crate::drivers::net::virtio_net::constants::Status;
use crate::drivers::net::virtio_net::{CtrlQueue, NetDevCfg, RxQueues, TxQueues, VirtioNetDriver};
use crate::drivers::virtio::error::{VirtioError, VirtioNetError};
use crate::drivers::virtio::transport::mmio::{ComCfg, IsrStatus, MmioRegisterLayout, NotifCfg};
use crate::drivers::virtio::transport::mmio::{ComCfg, IsrStatus, NotifCfg};
use crate::drivers::virtio::virtqueue::Virtq;

/// Virtio's network device configuration structure.
Expand Down Expand Up @@ -110,18 +111,25 @@ impl NetDevCfgRaw {
impl VirtioNetDriver {
pub fn new(
dev_id: u16,
registers: &'static mut MmioRegisterLayout,
mut registers: VolatileRef<'static, DeviceRegisters>,
irq: u8,
) -> Result<Self, VirtioNetError> {
let dev_cfg_raw: &'static NetDevCfgRaw =
unsafe { &*(ptr::with_exposed_provenance(ptr::from_ref(registers).addr() + 0xFC)) };
let dev_cfg_raw: &'static NetDevCfgRaw = unsafe {
&*registers
.borrow_mut()
.as_mut_ptr()
.config_generation()
.as_raw_ptr()
.cast::<NetDevCfgRaw>()
.as_ptr()
};
let dev_cfg = NetDevCfg {
raw: dev_cfg_raw,
dev_id,
features: virtio_spec::net::F::empty(),
};
let isr_stat = IsrStatus::new(registers);
let notif_cfg = NotifCfg::new(registers);
let isr_stat = IsrStatus::new(registers.borrow_mut());
let notif_cfg = NotifCfg::new(registers.borrow_mut());

let mtu = if let Some(my_mtu) = hermit_var!("HERMIT_MTU") {
u16::from_str(&my_mtu).unwrap()
Expand Down Expand Up @@ -159,7 +167,7 @@ impl VirtioNetDriver {
/// [VirtioNetDriver](structs.virtionetdriver.html) or an [VirtioError](enums.virtioerror.html).
pub fn init(
dev_id: u16,
registers: &'static mut MmioRegisterLayout,
registers: VolatileRef<'static, DeviceRegisters>,
irq_no: u8,
) -> Result<VirtioNetDriver, VirtioError> {
if let Ok(mut drv) = VirtioNetDriver::new(dev_id, registers, irq_no) {
Expand Down
Loading

0 comments on commit edbf1df

Please sign in to comment.