diff --git a/README.md b/README.md index 34bbce4..a2b6d3d 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ Rust version of THU [uCore OS Plus](https://github.com/chyyuu/ucore_os_plus). Going to be the next generation teaching operating system. -Supported architectures: x86_64, RISCV32/64, AArch64 +Supported architectures: x86_64, RISCV32/64, AArch64, MIPS (planned) -Tested boards: QEMU, PC, Raspberry Pi 3B+ +Tested boards: QEMU, HiFive Unleashed, x86_64 PC (i5/i7), Raspberry Pi 3B+ [Dev docs](https://rucore.gitbook.io/rust-os-docs/) (in Chinese) @@ -24,20 +24,22 @@ Tested boards: QEMU, PC, Raspberry Pi 3B+ * [bootimage](https://github.com/rust-osdev/bootimage) (for x86_64) * [RISCV64 GNU toolchain](https://www.sifive.com/boards) (for riscv32/64) * [AArch64 GNU toolchain](https://cs140e.sergio.bz/assignments/0-blinky/) (for aarch64) +* [musl-cross-make](https://github.com/richfelker/musl-cross-make) (for userland musl) See [Travis script](./.travis.yml) for details. ### How to run ```bash -rustup component add rust-src -cargo install cargo-xbuild bootimage +$ rustup component add rust-src +$ cargo install cargo-xbuild bootimage ``` ```bash -git clone https://github.com/rcore-os/rCore.git --recursive -cd rCore/kernel -make run arch={riscv32,riscv64,x86_64,aarch64} +$ git clone https://github.com/rcore-os/rCore.git --recursive +$ cd rCore/kernel +$ make sfsimg arch={riscv32,riscv64,x86_64,aarch64} # requires musl-cross-make +$ make run arch={riscv32,riscv64,x86_64,aarch64} ``` ## History diff --git a/kernel/src/drivers/bus/mod.rs b/kernel/src/drivers/bus/mod.rs index c9d93c6..673e3ba 100644 --- a/kernel/src/drivers/bus/mod.rs +++ b/kernel/src/drivers/bus/mod.rs @@ -1,3 +1,3 @@ -pub mod virtio_mmio; #[cfg(target_arch = "x86_64")] -pub mod pci; \ No newline at end of file +pub mod pci; +pub mod virtio_mmio; diff --git a/kernel/src/drivers/bus/pci.rs b/kernel/src/drivers/bus/pci.rs index 3a9b9fc..2e3cfea 100644 --- a/kernel/src/drivers/bus/pci.rs +++ b/kernel/src/drivers/bus/pci.rs @@ -1,6 +1,11 @@ use crate::drivers::net::*; -use x86_64::instructions::port::Port; +use crate::drivers::{Driver, DRIVERS, NET_DRIVERS}; +use alloc::collections::BTreeMap; use alloc::string::String; +use alloc::sync::Arc; +use spin::Mutex; +use core::cmp::Ordering; +use x86_64::instructions::port::Port; const PCI_VENDOR: u32 = 0x00; const PCI_DEVICE: u32 = 0x02; @@ -39,6 +44,28 @@ const PCI_BASE_ADDRESS_MEM_MASK: u32 = 0xfffffff0; #[derive(Copy, Clone)] pub struct PciTag(u32); + +impl Ord for PciTag { + fn cmp(&self, other: &PciTag) -> Ordering { + self.0.cmp(&other.0) + } +} + +impl PartialOrd for PciTag { + fn partial_cmp(&self, other: &PciTag) -> Option { + Some(self.cmp(other)) + } +} + +impl Eq for PciTag { +} + +impl PartialEq for PciTag { + fn eq(&self, other: &PciTag) -> bool { + self.0 == other.0 + } +} + impl PciTag { pub fn new(bus: u32, dev: u32, func: u32) -> PciTag { assert!(bus < 256); @@ -135,10 +162,9 @@ impl PciTag { max_base |= (max_base_hi as usize) << 32; address_mark = !0; } - _ => unimplemented!("pci bar mem type") + _ => unimplemented!("pci bar mem type"), } - if max_base == 0 { return None; } @@ -191,7 +217,6 @@ impl PciTag { } } - /// Enable the pci tag and its interrupt /// Return assigned MSI interrupt number when applicable pub unsafe fn enable(&self) -> Option { @@ -221,11 +246,18 @@ impl PciTag { // enable MSI interrupt, assuming 64bit for now let orig_ctrl = self.read(cap_ptr + PCI_MSI_CTRL_CAP, 4); self.write(cap_ptr + PCI_MSI_CTRL_CAP, orig_ctrl | 0x10000); - debug!("MSI control {:#b}, enabling MSI interrupts", orig_ctrl >> 16); + debug!( + "MSI control {:#b}, enabling MSI interrupts", + orig_ctrl >> 16 + ); msi_found = true; break; } - debug!("PCI device has cap id {} at {:#X}", self.read(cap_ptr, 1), cap_ptr); + debug!( + "PCI device has cap id {} at {:#X}", + self.read(cap_ptr, 1), + cap_ptr + ); cap_ptr = self.read(cap_ptr + 1, 1); } @@ -235,7 +267,10 @@ impl PciTag { self.write(PCI_COMMAND, orig | 0xf); let line = self.read(PCI_INTERRUPT_LINE, 1); let pin = self.read(PCI_INTERRUPT_PIN, 1); - debug!("MSI not found, using PCI interrupt line {} pin {}", line, pin); + debug!( + "MSI not found, using PCI interrupt line {} pin {}", + line, pin + ); } assigned_irq @@ -260,15 +295,27 @@ pub fn init_driver(name: String, vid: u32, did: u32, tag: PciTag) { } else if did == 0x10fb { // 82599ES 10-Gigabit SFI/SFP+ Network Connection if let Some((addr, len)) = unsafe { tag.get_bar_mem(0) } { - let irq = unsafe { - tag.enable() - }; - ixgbe::ixgbe_init(name, irq, addr, len); + let irq = unsafe { tag.enable() }; + PCI_DRIVERS.lock() + .insert(tag, ixgbe::ixgbe_init(name, irq, addr, len)); } } } } +pub fn detach_driver(bus: u32, dev: u32, func: u32) -> bool { + match PCI_DRIVERS.lock().remove(&PciTag::new(bus, dev, func)) { + Some(driver) => { + DRIVERS.write().retain(|dri| !Arc::ptr_eq(&driver, dri)); + NET_DRIVERS.write().retain(|dri| !Arc::ptr_eq(&driver, dri)); + true + } + None => { + false + } + } +} + pub fn init() { for bus in 0..256 { for dev in 0..32 { @@ -312,4 +359,8 @@ pub fn find_device(vendor: u32, product: u32) -> Option { } } None -} \ No newline at end of file +} + +lazy_static! { + pub static ref PCI_DRIVERS: Arc>>> = Arc::new(Mutex::new(BTreeMap::new())); +} diff --git a/kernel/src/drivers/bus/virtio_mmio.rs b/kernel/src/drivers/bus/virtio_mmio.rs index 13ca1dd..0dbcbcf 100644 --- a/kernel/src/drivers/bus/virtio_mmio.rs +++ b/kernel/src/drivers/bus/virtio_mmio.rs @@ -1,20 +1,20 @@ -use alloc::{vec, vec::Vec}; use alloc::alloc::{GlobalAlloc, Layout}; +use alloc::{vec, vec::Vec}; use core::mem::size_of; use core::slice; use core::sync::atomic::{fence, Ordering}; use bitflags::*; -use device_tree::Node; use device_tree::util::SliceRead; +use device_tree::Node; use log::*; -use rcore_memory::PAGE_SIZE; use rcore_memory::paging::PageTable; +use rcore_memory::PAGE_SIZE; use volatile::{ReadOnly, Volatile, WriteOnly}; -use crate::HEAP_ALLOCATOR; -use crate::memory::active_table; use crate::arch::consts::{KERNEL_OFFSET, MEMORY_OFFSET}; +use crate::memory::active_table; +use crate::HEAP_ALLOCATOR; use super::super::block::virtio_blk; use super::super::gpu::virtio_gpu; @@ -25,28 +25,28 @@ use super::super::net::virtio_net; #[repr(C)] #[derive(Debug)] pub struct VirtIOHeader { - magic: ReadOnly, // 0x000 - version: ReadOnly, // 0x004 - device_id: ReadOnly, // 0x008 - vendor_id: ReadOnly, // 0x00c - pub device_features: ReadOnly, // 0x010 + magic: ReadOnly, // 0x000 + version: ReadOnly, // 0x004 + device_id: ReadOnly, // 0x008 + vendor_id: ReadOnly, // 0x00c + pub device_features: ReadOnly, // 0x010 pub device_features_sel: WriteOnly, // 0x014 - __r1: [ReadOnly; 2], - pub driver_features: WriteOnly, // 0x020 + __r1: [ReadOnly; 2], + pub driver_features: WriteOnly, // 0x020 pub driver_features_sel: WriteOnly, // 0x024 - pub guest_page_size: WriteOnly, // 0x028 + pub guest_page_size: WriteOnly, // 0x028 __r2: ReadOnly, - pub queue_sel: WriteOnly, // 0x030 + pub queue_sel: WriteOnly, // 0x030 pub queue_num_max: ReadOnly, // 0x034 - pub queue_num: WriteOnly, // 0x038 - pub queue_align: WriteOnly, // 0x03c - pub queue_pfn: Volatile, // 0x040 - queue_ready: Volatile, // new interface only + pub queue_num: WriteOnly, // 0x038 + pub queue_align: WriteOnly, // 0x03c + pub queue_pfn: Volatile, // 0x040 + queue_ready: Volatile, // new interface only __r3: [ReadOnly; 2], pub queue_notify: WriteOnly, // 0x050 __r4: [ReadOnly; 3], pub interrupt_status: ReadOnly, // 0x060 - pub interrupt_ack: WriteOnly, // 0x064 + pub interrupt_ack: WriteOnly, // 0x064 __r5: [ReadOnly; 2], pub status: Volatile, // 0x070 __r6: [ReadOnly; 3], @@ -59,7 +59,7 @@ pub struct VirtIOHeader { queue_used_low: WriteOnly, queue_used_high: WriteOnly, __r9: [ReadOnly; 21], - config_generation: ReadOnly + config_generation: ReadOnly, } #[repr(C)] @@ -68,9 +68,9 @@ pub struct VirtIOVirtqueue { queue_address: usize, queue_num: usize, queue: usize, - desc: usize, // *mut VirtIOVirtqueueDesc, + desc: usize, // *mut VirtIOVirtqueueDesc, avail: usize, // *mut VirtIOVirtqueueAvailableRing, - used: usize, // *mut VirtIOVirtqueueUsedRing, + used: usize, // *mut VirtIOVirtqueueUsedRing, desc_state: Vec, num_used: usize, free_head: usize, @@ -90,16 +90,19 @@ impl VirtIOVirtqueue { let size = virtqueue_size(queue_num, align); assert!(size % align == 0); // alloc continuous pages - let address = unsafe { - HEAP_ALLOCATOR.alloc_zeroed(Layout::from_size_align(size, align).unwrap()) - } as usize; + let address = + unsafe { HEAP_ALLOCATOR.alloc_zeroed(Layout::from_size_align(size, align).unwrap()) } + as usize; header.queue_num.write(queue_num as u32); header.queue_align.write(align as u32); - header.queue_pfn.write(((address - KERNEL_OFFSET + MEMORY_OFFSET) as u32) >> 12); + header + .queue_pfn + .write(((address - KERNEL_OFFSET + MEMORY_OFFSET) as u32) >> 12); // link desc together - let desc = unsafe { slice::from_raw_parts_mut(address as *mut VirtIOVirtqueueDesc, queue_num) }; + let desc = + unsafe { slice::from_raw_parts_mut(address as *mut VirtIOVirtqueueDesc, queue_num) }; for i in 0..(queue_num - 1) { desc[i].next.write((i + 1) as u16); } @@ -133,25 +136,35 @@ impl VirtIOVirtqueue { return false; } - let desc = unsafe { slice::from_raw_parts_mut(self.desc as *mut VirtIOVirtqueueDesc, self.queue_num) }; + let desc = unsafe { + slice::from_raw_parts_mut(self.desc as *mut VirtIOVirtqueueDesc, self.queue_num) + }; let head = self.free_head; let mut prev = 0; let mut cur = self.free_head; for i in 0..output.len() { desc[cur].flags.write(VirtIOVirtqueueFlag::NEXT.bits()); - desc[cur].addr.write(output[i].as_ptr() as u64 - KERNEL_OFFSET as u64 + MEMORY_OFFSET as u64); + desc[cur] + .addr + .write(output[i].as_ptr() as u64 - KERNEL_OFFSET as u64 + MEMORY_OFFSET as u64); desc[cur].len.write(output[i].len() as u32); prev = cur; cur = desc[cur].next.read() as usize; } for i in 0..input.len() { - desc[cur].flags.write((VirtIOVirtqueueFlag::NEXT | VirtIOVirtqueueFlag::WRITE).bits()); - desc[cur].addr.write(input[i].as_ptr() as u64 - KERNEL_OFFSET as u64 + MEMORY_OFFSET as u64); + desc[cur] + .flags + .write((VirtIOVirtqueueFlag::NEXT | VirtIOVirtqueueFlag::WRITE).bits()); + desc[cur] + .addr + .write(input[i].as_ptr() as u64 - KERNEL_OFFSET as u64 + MEMORY_OFFSET as u64); desc[cur].len.write(input[i].len() as u32); prev = cur; cur = desc[cur].next.read() as usize; } - desc[prev].flags.write(desc[prev].flags.read() & !(VirtIOVirtqueueFlag::NEXT.bits())); + desc[prev] + .flags + .write(desc[prev].flags.read() & !(VirtIOVirtqueueFlag::NEXT.bits())); self.num_used += input.len() + output.len(); self.free_head = cur; @@ -189,7 +202,7 @@ impl VirtIOVirtqueue { pub fn get(&mut self) -> Option<(Vec<&'static [u8]>, Vec<&'static [u8]>, usize, usize)> { let used = unsafe { &mut *(self.used as *mut VirtIOVirtqueueUsedRing) }; if self.last_used_idx == used.idx.read() { - return None + return None; } // read barrier fence(Ordering::SeqCst); @@ -202,13 +215,16 @@ impl VirtIOVirtqueue { self.desc_state[last_used_slot] = 0; let mut cur = index; - let desc = unsafe { slice::from_raw_parts_mut(self.desc as *mut VirtIOVirtqueueDesc, self.queue_num) }; + let desc = unsafe { + slice::from_raw_parts_mut(self.desc as *mut VirtIOVirtqueueDesc, self.queue_num) + }; let mut input = Vec::new(); let mut output = Vec::new(); loop { let flags = VirtIOVirtqueueFlag::from_bits_truncate(desc[cur].flags.read()); let addr = desc[cur].addr.read() as u64 - MEMORY_OFFSET as u64 + KERNEL_OFFSET as u64; - let buffer = unsafe { slice::from_raw_parts(addr as *const u8, desc[cur].len.read() as usize) }; + let buffer = + unsafe { slice::from_raw_parts(addr as *const u8, desc[cur].len.read() as usize) }; if flags.contains(VirtIOVirtqueueFlag::WRITE) { input.push(buffer); } else { @@ -221,7 +237,7 @@ impl VirtIOVirtqueue { } else { desc[cur].next.write(self.free_head as u16); self.num_used -= 1; - break + break; } } @@ -263,9 +279,11 @@ impl VirtIOHeader { pub fn write_driver_features(&mut self, driver_features: u64) { self.driver_features_sel.write(0); // driver features [0, 32) - self.driver_features.write((driver_features & 0xFFFFFFFF) as u32); + self.driver_features + .write((driver_features & 0xFFFFFFFF) as u32); self.driver_features_sel.write(1); // driver features [32, 64) - self.driver_features.write(((driver_features & 0xFFFFFFFF00000000) >> 32) as u32); + self.driver_features + .write(((driver_features & 0xFFFFFFFF00000000) >> 32) as u32); } } @@ -286,7 +304,7 @@ pub struct VirtIOVirtqueueDesc { pub addr: Volatile, pub len: Volatile, pub flags: Volatile, - pub next: Volatile + pub next: Volatile, } bitflags! { @@ -303,14 +321,14 @@ pub struct VirtIOVirtqueueAvailableRing { pub flags: Volatile, pub idx: Volatile, pub ring: [Volatile; 32], // actual size: queue_size - used_event: Volatile // unused + used_event: Volatile, // unused } #[repr(C)] #[derive(Debug)] pub struct VirtIOVirtqueueUsedElem { id: Volatile, - len: Volatile + len: Volatile, } #[repr(C)] @@ -319,17 +337,19 @@ pub struct VirtIOVirtqueueUsedRing { pub flags: Volatile, pub idx: Volatile, pub ring: [VirtIOVirtqueueUsedElem; 32], // actual size: queue_size - avail_event: Volatile // unused + avail_event: Volatile, // unused } // virtio 2.4.2 Legacy Interfaces: A Note on Virtqueue Layout pub fn virtqueue_size(num: usize, align: usize) -> usize { - (((size_of::() * num + size_of::() * (3 + num)) + align) & !(align-1)) + - (((size_of::() * 3 + size_of::() * num) + align) & !(align-1)) + (((size_of::() * num + size_of::() * (3 + num)) + align) + & !(align - 1)) + + (((size_of::() * 3 + size_of::() * num) + align) + & !(align - 1)) } pub fn virtqueue_used_elem_offset(num: usize, align: usize) -> usize { - ((size_of::() * num + size_of::() * (3 + num)) + align) & !(align-1) + ((size_of::() * num + size_of::() * (3 + num)) + align) & !(align - 1) } pub fn virtio_probe(node: &Node) { @@ -344,19 +364,27 @@ pub fn virtio_probe(node: &Node) { let version = header.version.read(); let device_id = header.device_id.read(); // only support legacy device - if magic == 0x74726976 && version == 1 && device_id != 0 { // "virt" magic - info!("Detected virtio device with vendor id {:#X}", header.vendor_id.read()); + if magic == 0x74726976 && version == 1 && device_id != 0 { + // "virt" magic + info!( + "Detected virtio device with vendor id {:#X}", + header.vendor_id.read() + ); info!("Device tree node {:?}", node); // virtio 3.1.1 Device Initialization header.status.write(0); header.status.write(VirtIODeviceStatus::ACKNOWLEDGE.bits()); - if device_id == 1 { // net device + if device_id == 1 { + // net device virtio_net::virtio_net_init(node); - } else if device_id == 2 { // blk device + } else if device_id == 2 { + // blk device virtio_blk::virtio_blk_init(node); - } else if device_id == 16 { // gpu device + } else if device_id == 16 { + // gpu device virtio_gpu::virtio_gpu_init(node); - } else if device_id == 18 { // input device + } else if device_id == 18 { + // input device virtio_input::virtio_input_init(node); } else { println!("Unrecognized virtio device {}", device_id); @@ -365,4 +393,4 @@ pub fn virtio_probe(node: &Node) { active_table().unmap(from as usize); } } -} \ No newline at end of file +} diff --git a/kernel/src/drivers/mod.rs b/kernel/src/drivers/mod.rs index b1eb9ec..2320951 100644 --- a/kernel/src/drivers/mod.rs +++ b/kernel/src/drivers/mod.rs @@ -38,27 +38,35 @@ pub trait Driver : Send + Sync { // return the correspondent device type, see DeviceType fn device_type(&self) -> DeviceType; -} -pub trait NetDriver : Driver { + // Rust trait is still too restricted... + // network related drivers should implement these // get mac address for this device - fn get_mac(&self) -> EthernetAddress; + fn get_mac(&self) -> EthernetAddress { + unimplemented!("not a net driver") + } // get interface name for this device - fn get_ifname(&self) -> String; + fn get_ifname(&self) -> String { + unimplemented!("not a net driver") + } // get ipv4 address - fn ipv4_address(&self) -> Option; + fn ipv4_address(&self) -> Option { + unimplemented!("not a net driver") + } // manually trigger a poll, use it after sending packets - fn poll(&self); + fn poll(&self) { + unimplemented!("not a net driver") + } } lazy_static! { // NOTE: RwLock only write when initializing drivers pub static ref DRIVERS: RwLock>> = RwLock::new(Vec::new()); - pub static ref NET_DRIVERS: RwLock>> = RwLock::new(Vec::new()); + pub static ref NET_DRIVERS: RwLock>> = RwLock::new(Vec::new()); pub static ref BLK_DRIVERS: RwLock>> = RwLock::new(Vec::new()); } diff --git a/kernel/src/drivers/net/e1000.rs b/kernel/src/drivers/net/e1000.rs index de8a7ae..b97b9af 100644 --- a/kernel/src/drivers/net/e1000.rs +++ b/kernel/src/drivers/net/e1000.rs @@ -1,4 +1,5 @@ //! Intel PRO/1000 Network Adapter i.e. e1000 network driver +//! Datasheet: https://www.intel.ca/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf use alloc::alloc::{GlobalAlloc, Layout}; use alloc::format; @@ -28,7 +29,7 @@ use crate::sync::SpinNoIrqLock as Mutex; use crate::sync::{MutexGuard, SpinNoIrq}; use crate::HEAP_ALLOCATOR; -use super::super::{DeviceType, Driver, NetDriver, DRIVERS, NET_DRIVERS, SOCKET_ACTIVITY}; +use super::super::{DeviceType, Driver, DRIVERS, NET_DRIVERS, SOCKET_ACTIVITY}; // At the beginning, all transmit descriptors have there status non-zero, // so we need to track whether we are using the descriptor for the first time. @@ -121,9 +122,7 @@ impl Driver for E1000Interface { fn device_type(&self) -> DeviceType { DeviceType::Net } -} -impl NetDriver for E1000Interface { fn get_mac(&self) -> EthernetAddress { self.iface.lock().ethernet_addr() } diff --git a/kernel/src/drivers/net/ixgbe.rs b/kernel/src/drivers/net/ixgbe.rs index 5dd8734..55e5869 100644 --- a/kernel/src/drivers/net/ixgbe.rs +++ b/kernel/src/drivers/net/ixgbe.rs @@ -1,4 +1,5 @@ //! Intel 10Gb Network Adapter 82599 i.e. ixgbe network driver +//! Datasheet: https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82599-10-gbe-controller-datasheet.pdf use alloc::alloc::{GlobalAlloc, Layout}; use alloc::prelude::*; @@ -27,7 +28,7 @@ use crate::sync::SpinNoIrqLock as Mutex; use crate::sync::{MutexGuard, SpinNoIrq}; use crate::HEAP_ALLOCATOR; -use super::super::{DeviceType, Driver, NetDriver, DRIVERS, NET_DRIVERS, SOCKET_ACTIVITY}; +use super::super::{DeviceType, Driver, DRIVERS, NET_DRIVERS, SOCKET_ACTIVITY}; // At the beginning, all transmit descriptors have there status non-zero, // so we need to track whether we are using the descriptor for the first time. @@ -215,9 +216,7 @@ impl Driver for IXGBEInterface { fn device_type(&self) -> DeviceType { DeviceType::Net } -} -impl NetDriver for IXGBEInterface { fn get_mac(&self) -> EthernetAddress { self.iface.lock().ethernet_addr() } @@ -360,7 +359,7 @@ impl<'a> phy::Device<'a> for IXGBEDriver { fn capabilities(&self) -> DeviceCapabilities { let mut caps = DeviceCapabilities::default(); caps.max_transmission_unit = IXGBE_MTU; // max MTU - caps.max_burst_size = Some(64); + caps.max_burst_size = Some(256); // IP Rx checksum is offloaded with RXCSUM caps.checksum.ipv4 = Checksum::Tx; caps @@ -442,7 +441,7 @@ bitflags! { } } -pub fn ixgbe_init(name: String, irq: Option, header: usize, size: usize) { +pub fn ixgbe_init(name: String, irq: Option, header: usize, size: usize) -> Arc { assert_eq!(size_of::(), 16); assert_eq!(size_of::(), 16); @@ -796,5 +795,21 @@ pub fn ixgbe_init(name: String, irq: Option, header: usize, size: usize) { let driver = Arc::new(ixgbe_iface); DRIVERS.write().push(driver.clone()); - NET_DRIVERS.write().push(driver); + NET_DRIVERS.write().push(driver.clone()); + driver } + +impl Drop for IXGBE { + fn drop(&mut self) { + unsafe { + HEAP_ALLOCATOR.dealloc(self.send_page as *mut u8, Layout::from_size_align(PAGE_SIZE, PAGE_SIZE).unwrap()); + HEAP_ALLOCATOR.dealloc(self.recv_page as *mut u8, Layout::from_size_align(PAGE_SIZE, PAGE_SIZE).unwrap()); + for send_buffer in self.send_buffers.iter() { + HEAP_ALLOCATOR.dealloc(*send_buffer as *mut u8, Layout::from_size_align(IXGBE_BUFFER_SIZE, PAGE_SIZE).unwrap()); + } + for recv_buffer in self.recv_buffers.iter() { + HEAP_ALLOCATOR.dealloc(*recv_buffer as *mut u8, Layout::from_size_align(IXGBE_BUFFER_SIZE, PAGE_SIZE).unwrap()); + } + } + } +} \ No newline at end of file diff --git a/kernel/src/drivers/net/virtio_net.rs b/kernel/src/drivers/net/virtio_net.rs index f2492fe..453d4e6 100644 --- a/kernel/src/drivers/net/virtio_net.rs +++ b/kernel/src/drivers/net/virtio_net.rs @@ -24,7 +24,7 @@ use crate::sync::{MutexGuard, SpinNoIrq}; use crate::HEAP_ALLOCATOR; use super::super::bus::virtio_mmio::*; -use super::super::{DeviceType, Driver, NetDriver, DRIVERS, NET_DRIVERS}; +use super::super::{DeviceType, Driver, DRIVERS, NET_DRIVERS}; pub struct VirtIONet { interrupt_parent: u32, @@ -64,19 +64,7 @@ impl Driver for VirtIONetDriver { fn device_type(&self) -> DeviceType { DeviceType::Net } -} - -impl VirtIONet { - fn transmit_available(&self) -> bool { - self.queues[VIRTIO_QUEUE_TRANSMIT].can_add(1, 0) - } - - fn receive_available(&self) -> bool { - self.queues[VIRTIO_QUEUE_RECEIVE].can_get() - } -} -impl NetDriver for VirtIONetDriver { fn get_mac(&self) -> EthernetAddress { self.0.lock().mac } @@ -94,6 +82,16 @@ impl NetDriver for VirtIONetDriver { } } +impl VirtIONet { + fn transmit_available(&self) -> bool { + self.queues[VIRTIO_QUEUE_TRANSMIT].can_add(1, 0) + } + + fn receive_available(&self) -> bool { + self.queues[VIRTIO_QUEUE_RECEIVE].can_get() + } +} + pub struct VirtIONetRxToken(VirtIONetDriver); pub struct VirtIONetTxToken(VirtIONetDriver); diff --git a/kernel/src/net/test.rs b/kernel/src/net/test.rs index ebfb007..ee40d1d 100644 --- a/kernel/src/net/test.rs +++ b/kernel/src/net/test.rs @@ -1,4 +1,4 @@ -use crate::drivers::NetDriver; +use crate::drivers::Driver; use crate::drivers::NET_DRIVERS; use crate::net::SOCKETS; use crate::thread; diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index 48921c0..06be2e0 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -11,7 +11,6 @@ use crate::arch::interrupt::{Context, TrapFrame}; use crate::memory::{ByFrame, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet}; use crate::fs::{FileHandle, OpenOptions}; use crate::sync::Condvar; -use crate::drivers::NET_DRIVERS; use crate::net::{SocketWrapper, SOCKETS}; use super::abi::{self, ProcInitInfo}; diff --git a/kernel/src/syscall/custom.rs b/kernel/src/syscall/custom.rs index e23f8e6..ece5c37 100644 --- a/kernel/src/syscall/custom.rs +++ b/kernel/src/syscall/custom.rs @@ -3,6 +3,8 @@ use rcore_memory::memory_set::handler::Linear; use rcore_memory::memory_set::MemoryAttr; use super::*; +/// Allocate this PCI device to user space +/// The kernel driver using the PCI device will be unloaded #[cfg(target_arch = "x86_64")] pub fn sys_map_pci_device(vendor: usize, product: usize) -> SysResult { use crate::drivers::bus::pci; diff --git a/kernel/src/syscall/net.rs b/kernel/src/syscall/net.rs index 7c506a1..bb6f8d1 100644 --- a/kernel/src/syscall/net.rs +++ b/kernel/src/syscall/net.rs @@ -1,7 +1,7 @@ //! Syscalls for networking use super::*; -use crate::drivers::{NET_DRIVERS, SOCKET_ACTIVITY}; +use crate::drivers::SOCKET_ACTIVITY; use crate::net::{ get_ephemeral_port, poll_ifaces, SocketType, SocketWrapper, TcpSocketState, UdpSocketState, SOCKETS,