Skip to content

Commit

Permalink
network drivers create directly TxToken / RxToken for smoltcp
Browse files Browse the repository at this point in the history
For this purpose, it was necessary to avoid the creation of dynamic objects of the driver. This means that during compilation it must be defined which network interface is used. If the feature `rtl8139` is activated, the driver for Realtek 8139 will be used. Otherwise the Virtio network interface will be used.

using a exponential backoff to check the network device

if exponential backoff has completed, the task will be blocked
and waits for an network interrupt

poll device before the device checks the future

remove obsolete code

network drivers create directly TxToken / RxToken for smoltcp

For this purpose, it was necessary to avoid the creation of dynamic
objects of the driver. This means that during compilation it must
be defined which network interface is used. If the feature `rtl8139`
is activated, the driver for Realtek 8139 will be used. Otherwise the
Virtio network interface will be used.

build Virtio network driver only if the feature `tcp` is set

feature `tcp` must be activated to support any network interface

remove compiler warnings

remove compiler warnings

remove compiler warnings

use polling mode for read / write operations on a socket

idle task enables network interrupt, while the read function disable
it

enable network interrupts, if a socket is blocking

add missing import

check device driver only, if the device is available

remove compiler warnings

add mmio support

add dummy network interface for aarch64

add missing file for mmio support

add check if the feature tcp is available

revert block_on to the original version

revise CI workflow to support the feature rtl8139
  • Loading branch information
stlankes authored and mkroening committed Aug 2, 2023
1 parent 226ba62 commit a6d81f6
Show file tree
Hide file tree
Showing 28 changed files with 298 additions and 428 deletions.
14 changes: 10 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,9 @@ jobs:
-device vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=root \
-object memory-backend-file,id=mem,size=1G,mem-path=/dev/shm,share=on -numa node,memdev=mem \
-initrd target/x86_64-unknown-hermit/release/rusty_demo
- name: Build httpd with DHCP support (debug)
- name: Build httpd with DHCP support (debug, rtl8139)
run:
cargo build -Zbuild-std=std,panic_abort --target x86_64-unknown-hermit --package httpd --features ci,dhcpv4
cargo build -Zbuild-std=std,panic_abort --target x86_64-unknown-hermit --package httpd --features ci,dhcpv4,rtl8139
- name: Test httpd with DHCP support (debug, rtl8139)
run: |
qemu-system-x86_64 -smp 1 -cpu qemu64,apic,fsgsbase,rdtscp,xsave,xsaveopt,fxsr,rdrand \
Expand All @@ -179,6 +179,9 @@ jobs:
sleep 5
curl http://127.0.0.1:9975/help
sleep 1
- name: Build httpd with DHCP support (debug, virtio-net)
run:
cargo build -Zbuild-std=std,panic_abort --target x86_64-unknown-hermit --package httpd --features ci,dhcpv4
- name: Test httpd with DHCP support (debug, virtio-net)
run: |
qemu-system-x86_64 -smp 1 -cpu qemu64,apic,fsgsbase,rdtscp,xsave,xsaveopt,fxsr,rdrand \
Expand All @@ -190,9 +193,9 @@ jobs:
sleep 5
curl http://127.0.0.1:9975/help
sleep 1
- name: Build httpd with DHCP support (release)
- name: Build httpd with DHCP support (release, rtl8139)
run:
cargo build -Zbuild-std=std,panic_abort --target x86_64-unknown-hermit --package httpd --release --features ci,dhcpv4
cargo build -Zbuild-std=std,panic_abort --target x86_64-unknown-hermit --package httpd --release --features ci,dhcpv4,rtl8139
- name: Test httpd with DHCP support (release, rtl8139)
run: |
qemu-system-x86_64 -smp 1 -cpu qemu64,apic,fsgsbase,rdtscp,xsave,xsaveopt,fxsr,rdrand \
Expand All @@ -204,6 +207,9 @@ jobs:
sleep 5
curl http://127.0.0.1:9975/help
sleep 1
- name: Build httpd with DHCP support (release, virtio-net)
run:
cargo build -Zbuild-std=std,panic_abort --target x86_64-unknown-hermit --package httpd --release --features ci,dhcpv4
- name: Test httpd with DHCP support (release, virtio-net)
run: |
qemu-system-x86_64 -smp 1 -cpu qemu64,apic,fsgsbase,rdtscp,xsave,xsaveopt,fxsr,rdrand \
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ acpi = []
smp = ["include-transformed"]
fsgsbase = []
trace = []
rtl8139 = ["tcp", "pci"]
tcp = [
"smoltcp",
]
Expand Down
11 changes: 7 additions & 4 deletions src/arch/aarch64/kernel/interrupts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const MAX_HANDLERS: usize = 256;
/// The ID of the first Private Peripheral Interrupt.
const PPI_START: u8 = 16;
/// The ID of the first Shared Peripheral Interrupt.
#[allow(dead_code)]
const SPI_START: u8 = 32;
/// Software-generated interrupt for rescheduling
pub(crate) const SGI_RESCHED: u8 = 1;
Expand Down Expand Up @@ -93,6 +94,7 @@ pub fn disable() {
}
}

#[allow(dead_code)]
pub(crate) fn irq_install_handler(irq_number: u8, handler: HandlerFunc) {
debug!("Install handler for interrupt {}", irq_number);
unsafe {
Expand Down Expand Up @@ -348,7 +350,8 @@ pub(crate) fn init() {
static IRQ_NAMES: InterruptTicketMutex<HashMap<u8, &'static str, RandomState>> =
InterruptTicketMutex::new(HashMap::with_hasher(RandomState::with_seeds(0, 0, 0, 0)));

pub fn add_irq_name(irq_number: u8, name: &'static str) {
#[allow(dead_code)]
pub(crate) fn add_irq_name(irq_number: u8, name: &'static str) {
debug!("Register name \"{}\" for interrupt {}", name, irq_number);
IRQ_NAMES.lock().insert(SPI_START + irq_number, name);
}
Expand All @@ -357,10 +360,10 @@ fn get_irq_name(irq_number: u8) -> Option<&'static str> {
IRQ_NAMES.lock().get(&irq_number).copied()
}

pub static IRQ_COUNTERS: InterruptSpinMutex<BTreeMap<CoreId, &IrqStatistics>> =
pub(crate) static IRQ_COUNTERS: InterruptSpinMutex<BTreeMap<CoreId, &IrqStatistics>> =
InterruptSpinMutex::new(BTreeMap::new());

pub struct IrqStatistics {
pub(crate) struct IrqStatistics {
pub counters: [AtomicU64; 256],
}

Expand All @@ -378,7 +381,7 @@ impl IrqStatistics {
}
}

pub fn print_statistics() {
pub(crate) fn print_statistics() {
info!("Number of interrupts");
for (core_id, irg_statistics) in IRQ_COUNTERS.lock().iter() {
for (i, counter) in irg_statistics.counters.iter().enumerate() {
Expand Down
4 changes: 2 additions & 2 deletions src/arch/aarch64/kernel/mmio.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use hermit_sync::InterruptTicketMutex;

use crate::drivers::net::NetworkInterface;
use crate::drivers::net::virtio_net::VirtioNetDriver;

pub fn get_network_driver() -> Option<&'static InterruptTicketMutex<dyn NetworkInterface>> {
pub(crate) fn get_network_driver() -> Option<&'static InterruptTicketMutex<VirtioNetDriver>> {
None
}
2 changes: 1 addition & 1 deletion src/arch/aarch64/kernel/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub mod core_local;
pub mod interrupts;
#[cfg(not(feature = "pci"))]
#[cfg(all(not(feature = "pci"), feature = "tcp"))]
pub mod mmio;
#[cfg(feature = "pci")]
pub mod pci;
Expand Down
2 changes: 1 addition & 1 deletion src/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,6 @@ pub fn init_drivers() {
// Initialize PCI Drivers for x86_64
#[cfg(feature = "pci")]
crate::drivers::pci::init_drivers();
#[cfg(all(target_arch = "x86_64", not(feature = "pci")))]
#[cfg(all(target_arch = "x86_64", not(feature = "pci"), feature = "tcp"))]
crate::arch::x86_64::kernel::mmio::init_drivers();
}
7 changes: 3 additions & 4 deletions src/arch/x86_64/kernel/mmio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use crate::arch::x86_64::mm::paging::{
};
use crate::arch::x86_64::mm::{paging, PhysAddr};
use crate::drivers::net::virtio_net::VirtioNetDriver;
use crate::drivers::net::NetworkInterface;
use crate::drivers::virtio::transport::mmio as mmio_virtio;
use crate::drivers::virtio::transport::mmio::{DevId, MmioRegisterLayout, VirtioDriver};

Expand All @@ -27,7 +26,7 @@ pub(crate) enum MmioDriver {

impl MmioDriver {
#[allow(unreachable_patterns)]
fn get_network_driver(&self) -> Option<&InterruptTicketMutex<dyn NetworkInterface>> {
fn get_network_driver(&self) -> Option<&InterruptTicketMutex<VirtioNetDriver>> {
match self {
Self::VirtioNet(drv) => Some(drv),
_ => None,
Expand Down Expand Up @@ -122,11 +121,11 @@ pub(crate) fn register_driver(drv: MmioDriver) {
}
}

pub fn get_network_driver() -> Option<&'static InterruptTicketMutex<dyn NetworkInterface>> {
pub(crate) fn get_network_driver() -> Option<&'static InterruptTicketMutex<VirtioNetDriver>> {
unsafe { MMIO_DRIVERS.iter().find_map(|drv| drv.get_network_driver()) }
}

pub fn init_drivers() {
pub(crate) fn init_drivers() {
// virtio: MMIO Device Discovery
without_interrupts(|| {
if let Ok(mmio) = detect_network() {
Expand Down
2 changes: 1 addition & 1 deletion src/arch/x86_64/kernel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub mod apic;
pub mod core_local;
pub mod gdt;
pub mod interrupts;
#[cfg(not(feature = "pci"))]
#[cfg(all(not(feature = "pci"), feature = "tcp"))]
pub mod mmio;
#[cfg(feature = "pci")]
pub mod pci;
Expand Down
1 change: 1 addition & 0 deletions src/arch/x86_64/mm/physicalmem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ pub fn deallocate(physical_address: PhysAddr, size: usize) {
.deallocate(physical_address.as_usize(), size);
}

#[allow(dead_code)]
#[cfg(not(feature = "pci"))]
pub fn reserve(physical_address: PhysAddr, size: usize) {
assert_eq!(
Expand Down
2 changes: 2 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ pub(crate) const DEFAULT_STACK_SIZE: usize = 65_536;

pub(crate) const USER_STACK_SIZE: usize = 1_048_576;

#[allow(dead_code)]
#[cfg(feature = "pci")]
pub(crate) const VIRTIO_MAX_QUEUE_SIZE: u16 = 2048;
#[allow(dead_code)]
#[cfg(not(feature = "pci"))]
pub(crate) const VIRTIO_MAX_QUEUE_SIZE: u16 = 1024;

Expand Down
2 changes: 2 additions & 0 deletions src/drivers/mmio.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#[cfg(feature = "tcp")]
pub(crate) use crate::arch::kernel::mmio::get_network_driver;
11 changes: 7 additions & 4 deletions src/drivers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! A module containing hermit-rs driver, hermit-rs driver trait and driver specific errors.

pub mod fs;
#[cfg(not(feature = "pci"))]
pub mod mmio;
#[cfg(feature = "tcp")]
pub mod net;
#[cfg(feature = "pci")]
pub mod pci;
Expand All @@ -12,14 +15,14 @@ pub mod virtio;
pub mod error {
use core::fmt;

#[cfg(all(feature = "pci", not(target_arch = "aarch64")))]
#[cfg(feature = "rtl8139")]
use crate::drivers::net::rtl8139::RTL8139Error;
use crate::drivers::virtio::error::VirtioError;

#[derive(Debug)]
pub enum DriverError {
InitVirtioDevFail(VirtioError),
#[cfg(all(feature = "pci", not(target_arch = "aarch64")))]
#[cfg(feature = "rtl8139")]
InitRTL8139DevFail(RTL8139Error),
}

Expand All @@ -29,7 +32,7 @@ pub mod error {
}
}

#[cfg(all(feature = "pci", not(target_arch = "aarch64")))]
#[cfg(feature = "rtl8139")]
impl From<RTL8139Error> for DriverError {
fn from(err: RTL8139Error) -> Self {
DriverError::InitRTL8139DevFail(err)
Expand All @@ -42,7 +45,7 @@ pub mod error {
DriverError::InitVirtioDevFail(ref err) => {
write!(f, "Virtio driver failed: {err:?}")
}
#[cfg(all(feature = "pci", not(target_arch = "aarch64")))]
#[cfg(feature = "rtl8139")]
DriverError::InitRTL8139DevFail(ref err) => {
write!(f, "RTL8139 driver failed: {err:?}")
}
Expand Down
26 changes: 12 additions & 14 deletions src/drivers/net/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#[cfg(all(feature = "pci", not(target_arch = "aarch64")))]
#[cfg(feature = "rtl8139")]
pub mod rtl8139;
#[cfg(not(feature = "pci"))]
#[cfg(all(not(feature = "pci"), not(feature = "rtl8139")))]
pub mod virtio_mmio;
#[cfg(not(feature = "rtl8139"))]
pub mod virtio_net;
#[cfg(feature = "pci")]
#[cfg(all(feature = "pci", not(feature = "rtl8139")))]
pub mod virtio_pci;

#[cfg(target_arch = "x86_64")]
Expand All @@ -18,25 +19,22 @@ use crate::arch::kernel::mmio as hardware;
use crate::arch::scheduler::State;
#[cfg(feature = "pci")]
use crate::drivers::pci as hardware;
use crate::executor::device::{RxToken, TxToken};

/// A trait for accessing the network interface
pub trait NetworkInterface {
pub(crate) trait NetworkDriver {
/// Returns the mac address of the device.
fn get_mac_address(&self) -> [u8; 6];
/// Returns the current MTU of the device.
fn get_mtu(&self) -> u16;
/// Get buffer to create a TX packet
///
/// This returns ownership of the TX buffer.
fn get_tx_buffer(&mut self, len: usize) -> Result<(*mut u8, usize), ()>;
/// Frees the TX buffer (takes ownership)
fn free_tx_buffer(&self, token: usize);
/// Send TC packets (takes TX buffer ownership)
fn send_tx_buffer(&mut self, tkn_handle: usize, len: usize) -> Result<(), ()>;
/// Get buffer with the received packet
fn receive_packet(&mut self) -> Option<(RxToken, TxToken)>;
/// Send packet with the size `len`
fn send_packet<R, F>(&mut self, len: usize, f: F) -> R
where
F: FnOnce(&mut [u8]) -> R;
/// Check if a packet is available
fn has_packet(&self) -> bool;
/// Get RX buffer with an received packet
fn receive_rx_buffer(&mut self, buffer: &mut [u8]) -> Result<usize, ()>;
/// Enable / disable the polling mode of the network interface
fn set_polling_mode(&mut self, value: bool);
/// Handle interrupt and check if a packet is available
Expand Down
Loading

0 comments on commit a6d81f6

Please sign in to comment.