Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 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,32 +191,30 @@ 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 {
error!("It's not a MMIO-device at {:#X}", mmio as *const _ as usize);
error!("It's not a MMIO-device at {mmio:p}");
}

if version != 2 {
warn!("Found a leagacy device, which isn't supported");
} else {
// We found a MMIO-device (whose 512-bit address in this structure).
trace!("Found a MMIO-device at {:#X}", mmio as *const _ as usize);
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 {:#X}",
mmio as *const _ as usize
);
debug!("It's not a network card at {mmio:p}");
} else {
info!("Found network card at {:#X}", mmio as *const _ as usize);
info!("Found network card at {mmio:p}");

// crate::arch::mm::physicalmem::reserve(
// PhysAddr::from(current_address.align_down(BasePageSize::SIZE as usize)),
Expand Down
111 changes: 48 additions & 63 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,9 +39,40 @@ impl MmioDriver {
}
}

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 { VolatileRef::new(NonNull::new(ptr.cast::<DeviceRegisters>()).unwrap()) };

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}");
return None;
}

if version != 2 {
trace!("Found a legacy device, which isn't supported");
return None;
}

// We found a MMIO-device (whose 512-bit address in this structure).
trace!("Found a MMIO-device at {mmio:p}");

// Verify the device-ID to find the network card
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}");
return None;
}

Some(mmio)
}

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 @@ -66,37 +100,12 @@ fn check_linux_args(
flags,
);

// Verify the first register value to find out if this is really an MMIO magic-value.
let mmio = unsafe {
&mut *(ptr::with_exposed_provenance_mut::<MmioRegisterLayout>(
virtual_address.as_usize()
| (current_address & (BasePageSize::SIZE as usize - 1)),
))
};

let magic = mmio.get_magic_value();
let version = mmio.get_version();

if magic != MAGIC_VALUE {
trace!("It's not a MMIO-device at {mmio:p}");
continue;
}

if version != 2 {
trace!("Found a legacy device, which isn't supported");
continue;
}

// We found a MMIO-device (whose 512-bit address in this structure).
trace!("Found a MMIO-device at {mmio:p}");

// Verify the device-ID to find the network card
let id = mmio.get_device_id();

if id != DevId::VIRTIO_DEV_ID_NET {
trace!("It's not a network card at {mmio:p}");
let addr = virtual_address.as_usize()
| (current_address & (BasePageSize::SIZE as usize - 1));
let ptr = ptr::with_exposed_provenance_mut(addr);
let Some(mmio) = (unsafe { check_ptr(ptr) }) else {
continue;
}
};

crate::arch::mm::physicalmem::reserve(
PhysAddr::from(current_address.align_down(BasePageSize::SIZE as usize)),
Expand All @@ -117,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 All @@ -144,36 +153,12 @@ fn guess_device() -> Result<(&'static mut MmioRegisterLayout, u8), &'static str>
current_page = current_address / BasePageSize::SIZE as usize;
}

// Verify the first register value to find out if this is really an MMIO magic-value.
let mmio = unsafe {
&mut *(ptr::with_exposed_provenance_mut::<MmioRegisterLayout>(
virtual_address.as_usize() | (current_address & (BasePageSize::SIZE as usize - 1)),
))
};

let magic = mmio.get_magic_value();
let version = mmio.get_version();

if magic != MAGIC_VALUE {
trace!("It's not a MMIO-device at {mmio:p}");
let addr =
virtual_address.as_usize() | (current_address & (BasePageSize::SIZE as usize - 1));
let ptr = ptr::with_exposed_provenance_mut(addr);
let Some(mmio) = (unsafe { check_ptr(ptr) }) else {
continue;
}

if version != 2 {
trace!("Found a legacy device, which isn't supported");
continue;
}

// We found a MMIO-device (whose 512-bit address in this structure).
trace!("Found a MMIO-device at {mmio:p}");

// Verify the device-ID to find the network card
let id = mmio.get_device_id();

if id != DevId::VIRTIO_DEV_ID_NET {
trace!("It's not a network card at {mmio:p}");
continue;
}
};

info!("Found network card at {mmio:p}");

Expand All @@ -193,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