Redesign NetDriver trait and update drivers

master
Jiajie Chen 6 years ago
parent 36292e6fcd
commit 71336aca5c

@ -72,7 +72,7 @@ pub fn backtrace() {
// Kernel stack at 0x0000_57ac_0000_0000 (defined in bootloader crate)
// size = 512 pages
current_fp = *(current_fp as *const usize).offset(0);
if (current_fp >= 0x0000_57ac_0000_0000 + 512 * PAGE_SIZE - size_of::<usize>()) {
if current_fp >= 0x0000_57ac_0000_0000 + 512 * PAGE_SIZE - size_of::<usize>() {
break;
}
current_pc = *(current_fp as *const usize).offset(1);

@ -1,9 +1,7 @@
use alloc::prelude::*;
use alloc::sync::Arc;
use alloc::vec;
use core::cmp::min;
use core::fmt;
use core::mem::{size_of, zeroed};
use core::mem::{size_of};
use core::slice;
use bitflags::*;
@ -16,7 +14,6 @@ use volatile::Volatile;
use rcore_fs::dev::BlockDevice;
use crate::arch::cpu;
use crate::memory::active_table;
use crate::sync::SpinNoIrqLock as Mutex;

@ -1,6 +1,4 @@
use crate::drivers::net::e1000;
use crate::logging::*;
use core::slice;
use x86_64::instructions::port::Port;
const VENDOR: u32 = 0x00;
@ -67,7 +65,7 @@ impl PciTag {
pci_addr.write(0);
let ret = d >> (rsh * 8);
let m = if (width < 4) {
let m = if width < 4 {
(1 << (8 * width)) - 1
} else {
0xffffffff
@ -109,13 +107,13 @@ impl PciTag {
base = base & PCI_BASE_ADDRESS_MEM_MASK;
max_base = max_base & PCI_BASE_ADDRESS_MEM_MASK;
if (max_base == 0) {
if max_base == 0 {
return None;
}
// linux/drivers/pci/probe.c pci_size
let mut size = PCI_BASE_ADDRESS_MEM_MASK & max_base;
if (size == 0) {
if size == 0 {
return None;
}
size = (size & !(size - 1)) - 1;

@ -12,7 +12,6 @@ use rcore_memory::PAGE_SIZE;
use rcore_memory::paging::PageTable;
use volatile::{ReadOnly, Volatile, WriteOnly};
use crate::arch::memory;
use crate::HEAP_ALLOCATOR;
use crate::memory::active_table;
use crate::arch::consts::{KERNEL_OFFSET, MEMORY_OFFSET};

@ -1,6 +1,5 @@
use alloc::alloc::{GlobalAlloc, Layout};
use alloc::prelude::*;
use core::mem::size_of;
use core::slice;
use bitflags::*;

@ -3,6 +3,7 @@ use core::any::Any;
use lazy_static::lazy_static;
use smoltcp::wire::EthernetAddress;
use smoltcp::socket::SocketSet;
use crate::sync::SpinNoIrqLock;
@ -29,12 +30,14 @@ pub trait Driver : Send + AsAny {
fn device_type(&self) -> DeviceType;
}
pub trait NetDriver: Driver {
pub trait NetDriver : Send {
// get mac address for this device
fn get_mac(&self) -> EthernetAddress;
// get interface name for this device
fn get_ifname(&self) -> String;
fn poll(&mut self, socket: &mut SocketSet) -> Option<bool>;
}
// little hack, see https://users.rust-lang.org/t/how-to-downcast-from-a-trait-any-to-a-struct/11219/3

@ -6,10 +6,7 @@ use core::mem::size_of;
use core::slice;
use core::sync::atomic::{fence, Ordering};
use crate::arch::consts::{KERNEL_OFFSET, MEMORY_OFFSET};
use bitflags::*;
use device_tree::util::SliceRead;
use device_tree::Node;
use log::*;
use rcore_memory::paging::PageTable;
use rcore_memory::PAGE_SIZE;
@ -17,14 +14,17 @@ use smoltcp::phy::{self, DeviceCapabilities};
use smoltcp::time::Instant;
use smoltcp::wire::EthernetAddress;
use smoltcp::Result;
use volatile::{ReadOnly, Volatile};
use smoltcp::wire::*;
use smoltcp::iface::*;
use smoltcp::socket::*;
use alloc::collections::BTreeMap;
use volatile::{Volatile};
use crate::arch::cpu;
use crate::memory::active_table;
use crate::sync::SpinNoIrqLock as Mutex;
use crate::HEAP_ALLOCATOR;
use super::super::{DeviceType, Driver, NetDriver, DRIVERS, NET_DRIVERS};
use super::super::{DeviceType, Driver, NetDriver, NET_DRIVERS};
pub struct E1000 {
header: usize,
@ -56,6 +56,10 @@ const E1000_MTA: usize = 0x5200 / 4;
const E1000_RAL: usize = 0x5400 / 4;
const E1000_RAH: usize = 0x5404 / 4;
pub struct E1000Interface {
iface: EthernetInterface<'static, 'static, 'static, E1000Driver>
}
#[derive(Clone)]
pub struct E1000Driver(Arc<Mutex<E1000>>);
@ -118,14 +122,27 @@ impl E1000 {
}
}
impl NetDriver for E1000Driver {
impl NetDriver for E1000Interface {
fn get_mac(&self) -> EthernetAddress {
self.0.lock().mac
self.iface.ethernet_addr()
}
fn get_ifname(&self) -> String {
format!("e1000")
}
fn poll(&mut self, sockets: &mut SocketSet) -> Option<bool> {
let timestamp = Instant::from_millis(unsafe { crate::trap::TICK as i64 });
match self.iface.poll(sockets, timestamp) {
Ok(update) => {
Some(update)
}
Err(err) => {
debug!("poll got err {}", err);
None
}
}
}
}
#[repr(C)]
@ -407,6 +424,19 @@ pub fn e1000_init(header: usize, size: usize) {
let net_driver = E1000Driver(Arc::new(Mutex::new(driver)));
DRIVERS.lock().push(Box::new(net_driver.clone()));
NET_DRIVERS.lock().push(Box::new(net_driver));
let ethernet_addr = EthernetAddress::from_bytes(&mac);
let ip_addrs = [IpCidr::new(IpAddress::v4(10,0,0,2), 24)];
let neighbor_cache = NeighborCache::new(BTreeMap::new());
let iface = EthernetInterfaceBuilder::new(net_driver)
.ethernet_addr(ethernet_addr)
.ip_addrs(ip_addrs)
.neighbor_cache(neighbor_cache)
.finalize();
let e1000_iface = E1000Interface {
iface,
};
//DRIVERS.lock().push(Box::new(net_driver.clone()));
NET_DRIVERS.lock().push(Box::new(e1000_iface));
}

@ -4,7 +4,6 @@ use alloc::prelude::*;
use alloc::sync::Arc;
use core::mem::size_of;
use core::slice;
use core::sync::atomic::{fence, Ordering};
use bitflags::*;
use device_tree::Node;
@ -16,9 +15,9 @@ use smoltcp::phy::{self, DeviceCapabilities};
use smoltcp::Result;
use smoltcp::time::Instant;
use smoltcp::wire::EthernetAddress;
use smoltcp::socket::SocketSet;
use volatile::{ReadOnly, Volatile};
use crate::arch::cpu;
use crate::HEAP_ALLOCATOR;
use crate::memory::active_table;
use crate::sync::SpinNoIrqLock as Mutex;
@ -86,6 +85,9 @@ impl NetDriver for VirtIONetDriver {
format!("virtio{}", self.0.lock().interrupt)
}
fn poll(&mut self, sockets: &mut SocketSet) -> Option<bool> {
unimplemented!()
}
}
pub struct VirtIONetRxToken(VirtIONetDriver);

@ -7,7 +7,6 @@ use rcore_fs_sfs::SimpleFileSystem;
#[cfg(target_arch = "x86_64")]
use crate::arch::driver::ide;
use crate::drivers::{self, AsAny};
use crate::drivers::block::virtio_blk::VirtIOBlkDriver;
pub use self::file::*;

@ -1,14 +1,8 @@
use crate::thread;
use crate::drivers::NET_DRIVERS;
use smoltcp::wire::*;
use smoltcp::iface::*;
use smoltcp::socket::*;
use alloc::collections::BTreeMap;
use crate::drivers::NetDriver;
use crate::drivers::net::virtio_net::VirtIONetDriver;
use crate::drivers::net::e1000::E1000Driver;
use alloc::vec;
use smoltcp::time::Instant;
use core::fmt::Write;
pub extern fn server(_arg: usize) -> ! {
@ -18,20 +12,6 @@ pub extern fn server(_arg: usize) -> ! {
}
}
let driver = {
let ref_driver = &mut *NET_DRIVERS.lock()[0];
// TODO: support multiple net drivers here
ref_driver.as_any().downcast_ref::<E1000Driver>().unwrap().clone()
};
let ethernet_addr = driver.get_mac();
let ip_addrs = [IpCidr::new(IpAddress::v4(10,0,0,2), 24)];
let neighbor_cache = NeighborCache::new(BTreeMap::new());
let mut iface = EthernetInterfaceBuilder::new(driver.clone())
.ethernet_addr(ethernet_addr)
.ip_addrs(ip_addrs)
.neighbor_cache(neighbor_cache)
.finalize();
let udp_rx_buffer = UdpSocketBuffer::new(vec![UdpPacketMetadata::EMPTY], vec![0; 64]);
let udp_tx_buffer = UdpSocketBuffer::new(vec![UdpPacketMetadata::EMPTY], vec![0; 128]);
let udp_socket = UdpSocket::new(udp_rx_buffer, udp_tx_buffer);
@ -51,15 +31,15 @@ pub extern fn server(_arg: usize) -> ! {
loop {
{
let timestamp = Instant::from_millis(unsafe { crate::trap::TICK as i64 });
match iface.poll(&mut sockets, timestamp) {
Ok(event) => {
if (!event) {
let iface = &mut *NET_DRIVERS.lock()[0];
match iface.poll(&mut sockets) {
Some(event) => {
if !event {
continue;
}
},
Err(e) => {
println!("poll error: {}", e);
None => {
continue
}
}

@ -172,6 +172,12 @@ impl Thread {
}
}
impl Process {
pub fn get_free_inode(&self) -> usize {
(0..).find(|i| !self.files.contains_key(i)).unwrap()
}
}
/// Generate a MemorySet according to the ELF file.
/// Also return the real entry point address.

@ -89,7 +89,7 @@ pub fn sys_open(path: *const u8, flags: usize, mode: usize) -> SysResult {
}
};
let fd = (3..).find(|i| !proc.files.contains_key(i)).unwrap();
let fd = proc.get_free_inode();
let file = FileHandle::new(inode, flags.to_options());
proc.files.insert(fd, file);

@ -18,12 +18,14 @@ use self::mem::*;
use self::proc::*;
use self::time::*;
use self::ctrl::*;
use self::net::*;
mod fs;
mod mem;
mod proc;
mod time;
mod ctrl;
mod net;
/// System call dispatcher
pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
@ -48,7 +50,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
035 => sys_sleep(args[0]), // TODO: nanosleep
039 => sys_getpid(),
// 040 => sys_getppid(),
// 041 => sys_socket(),
041 => sys_socket(args[0], args[1], args[2]),
// 042 => sys_connect(),
// 043 => sys_accept(),
// 044 => sys_sendto(),

@ -0,0 +1,29 @@
//! Syscalls for networking
use super::*;
const AF_INET: usize = 2;
const SOCK_STREAM: usize = 1;
pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> SysResult {
info!("socket: domain: {}, socket_type: {:?}, protocol: {:#x}", domain, socket_type, protocol);
let mut proc = process();
match domain {
AF_INET => {
return match socket_type {
SOCK_STREAM => {
let fd = proc.get_free_inode();
Ok(fd as isize)
}
_ => {
Err(SysError::Inval)
}
}
}
_ => {
return Err(SysError::Inval);
}
}
}
Loading…
Cancel
Save