Skip to content

Commit

Permalink
boards/qemu_rv32_virt: instantiate EthernetTapDriver for VirtIO Netwo…
Browse files Browse the repository at this point in the history
…rkCard
  • Loading branch information
lschuermann committed Feb 21, 2025
1 parent cac9392 commit 1c3c501
Showing 1 changed file with 59 additions and 14 deletions.
73 changes: 59 additions & 14 deletions boards/qemu_rv32_virt/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ struct QemuRv32VirtPlatform {
qemu_rv32_virt_chip::virtio::devices::virtio_rng::VirtIORng<'static, 'static>,
>,
>,
virtio_ethernet_tap: Option<
&'static capsules_extra::ethernet_tap::EthernetTapDriver<
'static,
qemu_rv32_virt_chip::virtio::devices::virtio_net::VirtIONet<'static>,
>,
>,
}

/// Mapping of integer syscalls to objects that implement syscalls.
Expand All @@ -101,6 +107,13 @@ impl SyscallDriverLookup for QemuRv32VirtPlatform {
f(None)
}
}
capsules_extra::ethernet_tap::DRIVER_NUM => {
if let Some(ethernet_tap_driver) = self.virtio_ethernet_tap {
f(Some(ethernet_tap_driver))
} else {
f(None)
}
}
kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
_ => f(None),
}
Expand Down Expand Up @@ -366,14 +379,16 @@ unsafe fn start() -> (
};

// If there is a VirtIO NetworkCard present, use the appropriate VirtIONet
// driver. Currently this is not used, as work on the userspace network
// driver and kernel network stack is in progress.
//
// A template dummy driver is provided to verify basic functionality of this
// interface.
let _virtio_net_if: Option<
&'static qemu_rv32_virt_chip::virtio::devices::virtio_net::VirtIONet<'static>,
// driver, and expose this device through the Ethernet Tap driver
// (forwarding raw Ethernet frames from and to userspace).
let virtio_ethernet_tap: Option<
&'static capsules_extra::ethernet_tap::EthernetTapDriver<
'static,
qemu_rv32_virt_chip::virtio::devices::virtio_net::VirtIONet<'static>,
>,
> = if let Some(net_idx) = virtio_net_idx {
use capsules_extra::ethernet_tap::EthernetTapDriver;
use kernel::hil::ethernet::EthernetAdapterDatapath;
use qemu_rv32_virt_chip::virtio::devices::virtio_net::VirtIONet;
use qemu_rv32_virt_chip::virtio::queues::split_queue::{
SplitVirtqueue, VirtqueueAvailableRing, VirtqueueDescriptors, VirtqueueUsedRing,
Expand Down Expand Up @@ -434,14 +449,28 @@ unsafe fn start() -> (
.initialize(virtio_net, mmio_queues)
.unwrap();

// Don't forget to enable RX once when integrating this into a
// proper Ethernet stack:
// virtio_net.enable_rx();
// Instantiate the userspace tap network driver over this device:
let virtio_ethernet_tap_tx_buffer = static_init!(
[u8; capsules_extra::ethernet_tap::MAX_MTU],
[0; capsules_extra::ethernet_tap::MAX_MTU],
);
let virtio_ethernet_tap = static_init!(
EthernetTapDriver<'static, VirtIONet<'static>>,
EthernetTapDriver::new(
virtio_net,
board_kernel.create_grant(
capsules_extra::ethernet_tap::DRIVER_NUM,
&memory_allocation_cap
),
virtio_ethernet_tap_tx_buffer,
),
);
virtio_net.set_client(virtio_ethernet_tap);

// TODO: When we have a proper Ethernet driver available for userspace,
// return that. For now, just return a reference to the raw VirtIONet
// driver:
Some(virtio_net as &'static VirtIONet)
// This enables reception on the underlying device:
virtio_ethernet_tap.initialize();

Some(virtio_ethernet_tap as &'static EthernetTapDriver<'static, VirtIONet<'static>>)
} else {
// No VirtIO NetworkCard discovered
None
Expand Down Expand Up @@ -520,6 +549,7 @@ unsafe fn start() -> (
scheduler,
scheduler_timer,
virtio_rng: virtio_rng_driver,
virtio_ethernet_tap,
ipc: kernel::ipc::IPC::new(
board_kernel,
kernel::ipc::DRIVER_NUM,
Expand All @@ -531,6 +561,21 @@ unsafe fn start() -> (
let _ = platform.pconsole.start();

debug!("QEMU RISC-V 32-bit \"virt\" machine, initialization complete.");

// This board dynamically discovers VirtIO devices like a randomness source
// or a network card. Print a message indicating whether or not each such
// device and corresponding userspace driver is present:
if virtio_rng_driver.is_some() {
debug!("- Found VirtIO EntropySource device, enabling RngDriver");
} else {
debug!("- VirtIO EntropySource device not found, disabling RngDriver");
}
if virtio_ethernet_tap.is_some() {
debug!("- Found VirtIO NetworkCard device, enabling EthernetTapDriver");
} else {
debug!("- VirtIO NetworkCard device not found, disabling EthernetTapDriver");
}

debug!("Entering main loop.");

// ---------- PROCESS LOADING, SCHEDULER LOOP ----------
Expand Down

0 comments on commit 1c3c501

Please sign in to comment.