Commit db785dad authored by Stefan Lankes's avatar Stefan Lankes
Browse files

remove polling state within the network driver

- move interrupt handler to net/mod.rs
parent 3c9be4c8
......@@ -11,6 +11,13 @@ pub mod uhyve;
use alloc::boxed::Box;
use synch::semaphore::*;
#[cfg(target_arch = "x86_64")]
use arch::x86_64::kernel::apic;
#[cfg(target_arch = "x86_64")]
use arch::x86_64::kernel::irq::*;
#[cfg(target_arch = "x86_64")]
use arch::x86_64::kernel::percore::core_scheduler;
static mut NIC: Option<Box<dyn NetworkInterface>> = None;
static NET_SEM: Semaphore = Semaphore::new(0);
......@@ -26,43 +33,30 @@ pub fn init() -> Result<(), ()> {
}
pub trait NetworkInterface {
/// check if the driver in polling mode
fn is_polling(&self) -> bool;
/// set driver in polling/non-polling mode
fn set_polling(&mut self, mode: bool);
/// get mac address
fn get_mac_address(&self) -> [u8; 6];
}
#[no_mangle]
pub fn uhyve_is_polling() -> bool {
unsafe {
match &NIC {
Some(nic) => nic.is_polling(),
None => false,
}
}
}
#[no_mangle]
pub fn uhyve_set_polling(mode: bool) {
unsafe {
match &mut NIC {
Some(nic) => nic.set_polling(mode),
None => {}
}
}
pub fn uhyve_netwakeup() {
NET_SEM.release();
}
#[no_mangle]
pub fn uhyve_netwait(millis: Option<u64>) {
if uhyve_is_polling() == false {
let wakeup_time = match millis {
Some(ms) => Some(::arch::processor::get_timer_ticks() + ms * 1000),
None => None,
};
NET_SEM.acquire(wakeup_time);
}
match millis {
Some(ms) => {
if ms > 0 {
let delay = Some(::arch::processor::get_timer_ticks() + ms * 1000);
NET_SEM.acquire(delay);
} else {
NET_SEM.try_acquire();
}
}
_ => {
NET_SEM.acquire(None);
}
};
}
#[no_mangle]
......@@ -74,3 +68,11 @@ pub fn uhyve_get_mac_address() -> [u8; 6] {
}
}
}
#[cfg(target_arch = "x86_64")]
extern "x86-interrupt" fn network_irqhandler(_stack_frame: &mut ExceptionStackFrame) {
debug!("Receive network interrupt");
apic::eoi();
uhyve_netwakeup();
core_scheduler().scheduler();
}
......@@ -7,16 +7,11 @@
use alloc::boxed::Box;
use arch::irq;
use core::sync::atomic::{AtomicBool, Ordering};
use drivers::net::{NetworkInterface, NET_SEM};
use drivers::net::NetworkInterface;
#[cfg(target_arch = "x86_64")]
use arch::x86_64::kernel::apic;
#[cfg(target_arch = "x86_64")]
use arch::x86_64::kernel::irq::*;
#[cfg(target_arch = "x86_64")]
use arch::x86_64::kernel::percore::core_scheduler;
#[cfg(target_arch = "x86_64")]
use arch::x86_64::kernel::uhyve_get_ip;
#[cfg(target_arch = "x86_64")]
use arch::x86_64::mm::paging::virt_to_phys;
......@@ -37,31 +32,15 @@ struct UhyveNetinfo {
pub struct UhyveNetwork {
/// mac address
mac: [u8; 6],
/// is NIC in polling mode?
polling: AtomicBool,
}
impl UhyveNetwork {
pub const fn new(mac: &[u8; 6]) -> Self {
UhyveNetwork {
mac: *mac,
polling: AtomicBool::new(true),
}
UhyveNetwork { mac: *mac }
}
}
impl NetworkInterface for UhyveNetwork {
fn is_polling(&self) -> bool {
self.polling.load(Ordering::SeqCst)
}
fn set_polling(&mut self, mode: bool) {
self.polling.store(mode, Ordering::SeqCst);
if mode {
NET_SEM.release();
}
}
fn get_mac_address(&self) -> [u8; 6] {
self.mac
}
......@@ -92,17 +71,12 @@ pub fn init() -> Result<Box<dyn NetworkInterface>, ()> {
};
// Install interrupt handler
irq_install_handler(UHYVE_IRQ_NET, uhyve_irqhandler as usize);
irq_install_handler(
UHYVE_IRQ_NET,
crate::drivers::net::network_irqhandler as usize,
);
irq::enable();
Ok(nic)
}
#[cfg(target_arch = "x86_64")]
extern "x86-interrupt" fn uhyve_irqhandler(_stack_frame: &mut ExceptionStackFrame) {
debug!("Receive network interrupt from uhyve");
crate::drivers::net::uhyve_set_polling(true);
apic::eoi();
core_scheduler().scheduler();
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment