diff --git a/drivers/Cargo.toml b/drivers/Cargo.toml index 77f1d757..5d99dba5 100644 --- a/drivers/Cargo.toml +++ b/drivers/Cargo.toml @@ -21,23 +21,12 @@ lazy_static = "1.4" numeric-enum-macro = "0.2" device_tree = { git = "https://github.com/rcore-os/device_tree-rs", rev = "2f2e55f" } bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev = "88e871a5" } -pci = { git = "https://github.com/rcore-os/pci-rs", rev = "a4e7cea6" } +pci = { git = "https://github.com/elliott10/pci-rs", rev = "8f33774b" } virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "2aaf7d6", optional = true } rcore-console = { git = "https://github.com/rcore-os/rcore-console", default-features = false, rev = "ca5b1bc", optional = true } lock = { git = "https://github.com/DeathWish5/kernel-sync", rev = "01b2e70" } -# smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp", rev = "35e833e3", default-features = false, features = ["log", "alloc", "verbose", "proto-ipv4", "proto-ipv6", "proto-igmp", "medium-ip", "medium-ethernet", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp"] } -smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev = "043eb60", default-features = false, features = [ - "alloc", - "log", - "async", - "medium-ethernet", - "proto-ipv4", - "proto-igmp", - "socket-icmp", - "socket-udp", - "socket-tcp", - "socket-raw", -] } +isomorphic_drivers = { git = "https://github.com/rcore-os/isomorphic_drivers", rev = "f7cd97a8", features = ["log"] } +smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp", rev = "35e833e3", default-features = false, features = ["log", "alloc", "verbose", "proto-ipv4", "proto-ipv6", "proto-igmp", "medium-ip", "medium-ethernet", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp", "async"] } # LibOS mode [target.'cfg(not(target_os = "none"))'.dependencies] diff --git a/drivers/src/bus/mod.rs b/drivers/src/bus/mod.rs index 9e67d9bf..6f31fd1d 100644 --- a/drivers/src/bus/mod.rs +++ b/drivers/src/bus/mod.rs @@ -1,6 +1,6 @@ #![allow(unused)] -#[cfg(target_arch = "x86_64")] +#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] pub mod pci; pub fn phys_to_virt(paddr: PhysAddr) -> VirtAddr { @@ -22,3 +22,17 @@ pub const PAGE_SIZE: usize = 4096; type VirtAddr = usize; type PhysAddr = usize; + +use core::ptr::{read_volatile, write_volatile}; +#[inline(always)] +pub fn write(addr: usize, content: T) { + let cell = (addr) as *mut T; + unsafe { + write_volatile(cell, content); + } +} +#[inline(always)] +pub fn read(addr: usize) -> T { + let cell = (addr) as *const T; + unsafe { read_volatile(cell) } +} diff --git a/drivers/src/bus/pci.rs b/drivers/src/bus/pci.rs index eba115c2..fabd5f99 100644 --- a/drivers/src/bus/pci.rs +++ b/drivers/src/bus/pci.rs @@ -1,11 +1,12 @@ -//use crate::drivers::{Driver, DRIVERS, NET_DRIVERS}; use super::{phys_to_virt, PAGE_SIZE}; -use alloc::{collections::BTreeMap, format, sync::Arc}; -use lazy_static::lazy_static; +use crate::builder::IoMapper; +use crate::{Device, DeviceError, DeviceResult, VirtAddr}; +use alloc::{collections::BTreeMap, format, sync::Arc, vec::Vec}; use pci::*; use spin::Mutex; const PCI_COMMAND: u16 = 0x04; +const BAR0: u16 = 0x10; const PCI_CAP_PTR: u16 = 0x34; const PCI_INTERRUPT_LINE: u16 = 0x3c; const PCI_INTERRUPT_PIN: u16 = 0x3d; @@ -31,8 +32,8 @@ impl PortOps for PortOpsImpl { unsafe fn read16(&self, port: u16) -> u16 { Port::new(port).read() } - unsafe fn read32(&self, port: u16) -> u32 { - Port::new(port).read() + unsafe fn read32(&self, port: u32) -> u32 { + Port::new(port as u16).read() } unsafe fn write8(&self, port: u16, val: u8) { Port::new(port).write(val); @@ -40,43 +41,70 @@ impl PortOps for PortOpsImpl { unsafe fn write16(&self, port: u16, val: u16) { Port::new(port).write(val); } - unsafe fn write32(&self, port: u16, val: u32) { - Port::new(port).write(val); + unsafe fn write32(&self, port: u32, val: u32) { + Port::new(port as u16).write(val); } } -#[cfg(target_arch = "mips")] -use crate::util::{read, write}; +#[cfg(target_arch = "x86_64")] +const PCI_BASE: usize = 0; //Fix me + +#[cfg(any(target_arch = "mips", target_arch = "riscv64"))] +use super::{read, write}; + #[cfg(feature = "board_malta")] const PCI_BASE: usize = 0xbbe00000; -#[cfg(target_arch = "mips")] +#[cfg(target_arch = "riscv64")] +const PCI_BASE: usize = 0x30000000; +#[cfg(target_arch = "riscv64")] +const E1000_BASE: usize = 0x40000000; +// riscv64 Qemu + +#[cfg(target_arch = "x86_64")] +const PCI_ACCESS: CSpaceAccessMethod = CSpaceAccessMethod::IO; +#[cfg(not(target_arch = "x86_64"))] +const PCI_ACCESS: CSpaceAccessMethod = CSpaceAccessMethod::MemoryMapped(PCI_BASE as *mut u8); + +#[cfg(any(target_arch = "mips", target_arch = "riscv64"))] impl PortOps for PortOpsImpl { unsafe fn read8(&self, port: u16) -> u8 { - read(PCI_BASE + port as usize) + read(phys_to_virt(PCI_BASE) + port as usize) } unsafe fn read16(&self, port: u16) -> u16 { - read(PCI_BASE + port as usize) + read(phys_to_virt(PCI_BASE) + port as usize) } - unsafe fn read32(&self, port: u16) -> u32 { - read(PCI_BASE + port as usize) + unsafe fn read32(&self, port: u32) -> u32 { + read(phys_to_virt(PCI_BASE) + port as usize) } unsafe fn write8(&self, port: u16, val: u8) { - write(PCI_BASE + port as usize, val); + write(phys_to_virt(PCI_BASE) + port as usize, val); } unsafe fn write16(&self, port: u16, val: u16) { - write(PCI_BASE + port as usize, val); + write(phys_to_virt(PCI_BASE) + port as usize, val); } - unsafe fn write32(&self, port: u16, val: u32) { - write(PCI_BASE + port as usize, val); + unsafe fn write32(&self, port: u32, val: u32) { + write(phys_to_virt(PCI_BASE) + port as usize, val); } } /// Enable the pci device and its interrupt /// Return assigned MSI interrupt number when applicable -unsafe fn enable(loc: Location) -> Option { +unsafe fn enable(loc: Location, paddr: u64) -> Option { let ops = &PortOpsImpl; - let am = CSpaceAccessMethod::IO; + //let am = CSpaceAccessMethod::IO; + let am = PCI_ACCESS; + + if paddr != 0 { + // reveal PCI regs by setting paddr + let bar0_raw = am.read32(ops, loc, BAR0); + am.write32(ops, loc, BAR0, (paddr & !0xfff) as u32); //Only for 32-bit decoding + debug!( + "BAR0 set from {:#x} to {:#x}", + bar0_raw, + am.read32(ops, loc, BAR0) + ); + } // 23 and lower are used static mut MSI_IRQ: u32 = 23; @@ -94,7 +122,8 @@ unsafe fn enable(loc: Location) -> Option { if cap_id == PCI_CAP_ID_MSI { let orig_ctrl = am.read32(ops, loc, cap_ptr + PCI_MSI_CTRL_CAP); // The manual Volume 3 Chapter 10.11 Message Signalled Interrupts - // 0 is (usually) the apic id of the bsp. Write "0xfee00000 | (0 << 12)" + // 0 is (usually) the apic id of the bsp. + //am.write32(ops, loc, cap_ptr + PCI_MSI_ADDR, 0xfee00000 | (0 << 12)); am.write32(ops, loc, cap_ptr + PCI_MSI_ADDR, 0xfee00000); MSI_IRQ += 1; let irq = MSI_IRQ; @@ -133,7 +162,7 @@ unsafe fn enable(loc: Location) -> Option { assigned_irq } -pub fn init_driver(dev: &PCIDevice) { +pub fn init_driver(dev: &PCIDevice, mapper: &Option>) -> DeviceResult { let name = format!("enp{}s{}f{}", dev.loc.bus, dev.loc.device, dev.loc.function); match (dev.id.vendor_id, dev.id.device_id) { (0x8086, 0x100e) | (0x8086, 0x100f) | (0x8086, 0x10d3) => { @@ -143,21 +172,31 @@ pub fn init_driver(dev: &PCIDevice) { // 82545EM Gigabit Ethernet Controller (Copper) // 0x10d3 // 82574L Gigabit Network Connection + // (e1000e 8086:10d3) if let Some(BAR::Memory(addr, len, _, _)) = dev.bars[0] { - let irq = unsafe { enable(dev.loc) }; + info!("Found e1000e dev {:?} BAR0 {:#x?}", dev, addr); + #[cfg(target_arch = "riscv64")] + let addr = if addr == 0 { E1000_BASE as u64 } else { addr }; + + if let Some(m) = mapper { + m.query_or_map(addr as usize, PAGE_SIZE * 8); + } + let irq = unsafe { enable(dev.loc, addr) }; let vaddr = phys_to_virt(addr as usize); - info!("Found E1000 dev {:#x}, irq: {:?}", vaddr, irq); - /* - let index = NET_DRIVERS.read().len(); - e1000::init(name, irq, vaddr, len as usize, index); - */ - return; + let dev = Device::Net(Arc::new(crate::net::e1000::init( + name, + irq.unwrap_or(0), + vaddr, + len as usize, + 0, + )?)); + return Ok(dev); } } (0x8086, 0x10fb) => { // 82599ES 10-Gigabit SFI/SFP+ Network Connection if let Some(BAR::Memory(addr, len, _, _)) = dev.bars[0] { - let irq = unsafe { enable(dev.loc) }; + let irq = unsafe { enable(dev.loc, 0) }; let vaddr = phys_to_virt(addr as usize); info!("Found ixgbe dev {:#x}, irq: {:?}", vaddr, irq); /* @@ -167,7 +206,14 @@ pub fn init_driver(dev: &PCIDevice) { ixgbe::ixgbe_init(name, irq, vaddr, len as usize, index), ); */ - return; + return Err(DeviceError::NotSupported); + } + } + (0x8086, 0x1533) => { + if let Some(BAR::Memory(addr, len, _, _)) = dev.bars[0] { + info!("Intel Corporation I210 Gigabit Network Connection"); + info!("DEV: {:?}, BAR0: {:#x}", dev, addr); + return Err(DeviceError::NotSupported); } } (0x8086, 0x1539) => { @@ -176,17 +222,7 @@ pub fn init_driver(dev: &PCIDevice) { "Found Intel I211 ethernet controller dev {:?}, addr: {:x?}", dev, addr ); - /* - let irq = unsafe { enable(dev.loc) }; - let vaddr = phys_to_virt(addr as usize); - info!("Found ixgbe dev {:#x}, irq: {:?}", vaddr, irq); - let index = NET_DRIVERS.read().len(); - PCI_DRIVERS.lock().insert( - dev.loc, - ixgbe::ixgbe_init(name, irq, vaddr, len as usize, index), - ); - */ - return; + return Err(DeviceError::NotSupported); } } _ => {} @@ -204,8 +240,11 @@ pub fn init_driver(dev: &PCIDevice) { PCI_DRIVERS.lock().insert(dev.loc, driver); } */ + return Err(DeviceError::NotSupported); } } + + Err(DeviceError::NoResources) } pub fn detach_driver(loc: &Location) -> bool { @@ -226,11 +265,21 @@ pub fn detach_driver(loc: &Location) -> bool { false } -pub fn init() { - let pci_iter = unsafe { scan_bus(&PortOpsImpl, CSpaceAccessMethod::IO) }; +pub fn init(mapper: Option>) -> DeviceResult> { + let mapper_driver = if let Some(m) = mapper { + m.query_or_map(PCI_BASE, PAGE_SIZE * 256 * 32 * 8); + Some(m) + } else { + None + }; + + let mut dev_list = Vec::new(); + let pci_iter = unsafe { scan_bus(&PortOpsImpl, PCI_ACCESS) }; + info!(""); + info!("--------- PCI bus:device:function ---------"); for dev in pci_iter { info!( - "pci: {:02x}:{:02x}.{} {:#x} {:#x} ({} {}) irq: {}:{:?}", + "pci: {}:{}:{} {:04x}:{:04x} ({} {}) irq: {}:{:?}", dev.loc.bus, dev.loc.device, dev.loc.function, @@ -241,12 +290,23 @@ pub fn init() { dev.pic_interrupt_line, dev.interrupt_pin, ); - init_driver(&dev); + let res = init_driver(&dev, &mapper_driver); + match res { + Ok(d) => dev_list.push(d), + Err(e) => warn!( + "{:?}, failed to initialize PCI device: {:04x}:{:04x}", + e, dev.id.vendor_id, dev.id.device_id + ), + } } + info!("---------"); + info!(""); + + Ok(dev_list) } pub fn find_device(vendor: u16, product: u16) -> Option { - let pci_iter = unsafe { scan_bus(&PortOpsImpl, CSpaceAccessMethod::IO) }; + let pci_iter = unsafe { scan_bus(&PortOpsImpl, PCI_ACCESS) }; for dev in pci_iter { if dev.id.vendor_id == vendor && dev.id.device_id == product { return Some(dev.loc); @@ -256,7 +316,7 @@ pub fn find_device(vendor: u16, product: u16) -> Option { } pub fn get_bar0_mem(loc: Location) -> Option<(usize, usize)> { - unsafe { probe_function(&PortOpsImpl, loc, CSpaceAccessMethod::IO) } + unsafe { probe_function(&PortOpsImpl, loc, PCI_ACCESS) } .and_then(|dev| dev.bars[0]) .map(|bar| match bar { BAR::Memory(addr, len, _, _) => (addr as usize, len as usize), @@ -264,11 +324,4 @@ pub fn get_bar0_mem(loc: Location) -> Option<(usize, usize)> { }) } -/* -lazy_static! { - pub static ref PCI_DRIVERS: Mutex>> = - Mutex::new(BTreeMap::new()); -} -*/ - // all devices stored in:AllDeviceList diff --git a/drivers/src/net/e1000.rs b/drivers/src/net/e1000.rs new file mode 100644 index 00000000..1ff7d7ea --- /dev/null +++ b/drivers/src/net/e1000.rs @@ -0,0 +1,218 @@ +//! 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::collections::BTreeMap; +use alloc::string::String; +use alloc::sync::Arc; +use alloc::vec::Vec; + +use smoltcp::iface::*; +use smoltcp::phy::{self, DeviceCapabilities}; +use smoltcp::time::Instant; +use smoltcp::wire::*; +use smoltcp::Result; + +use super::ProviderImpl; +use super::PAGE_SIZE; +use crate::net::get_sockets; +use crate::scheme::{NetScheme, Scheme}; +use crate::{DeviceError, DeviceResult}; +use isomorphic_drivers::net::ethernet::intel::e1000::E1000; +use isomorphic_drivers::net::ethernet::structs::EthernetAddress as DriverEthernetAddress; +use lock::Mutex; + +#[derive(Clone)] +pub struct E1000Driver(Arc>>); + +#[derive(Clone)] +pub struct E1000Interface { + iface: Arc>>, + driver: E1000Driver, + name: String, + irq: usize, +} + +impl Scheme for E1000Interface { + fn name(&self) -> &str { + "e1000" + } + + fn handle_irq(&self, irq: usize) { + if irq != self.irq { + // not ours, skip it + return; + } + + let data = self.driver.0.lock().handle_interrupt(); + + if data { + //let timestamp = Instant::from_millis(crate::trap::uptime_msec() as i64); + // Fix me + let timestamp = Instant::from_millis(0); + let sockets = get_sockets(); + let mut sockets = sockets.lock(); + match self.iface.lock().poll(&mut sockets, timestamp) { + Ok(p) => { + //SOCKET_ACTIVITY.notify_all(); + info!("e1000 try_handle_interrupt poll: {:?}", p); + } + Err(err) => { + warn!("poll got err {}", err); + } + } + } + } +} + +impl NetScheme for E1000Interface { + fn get_mac(&self) -> EthernetAddress { + self.iface.lock().ethernet_addr() + } + + fn get_ifname(&self) -> String { + self.name.clone() + } + + // get ip addresses + fn get_ip_address(&self) -> Vec { + Vec::from(self.iface.lock().ip_addrs()) + } + + fn poll(&self) -> DeviceResult { + //let timestamp = Instant::from_millis(crate::trap::uptime_msec() as i64); + let timestamp = Instant::from_millis(0); + let sockets = get_sockets(); + let mut sockets = sockets.lock(); + match self.iface.lock().poll(&mut sockets, timestamp) { + Ok(p) => { + //SOCKET_ACTIVITY.notify_all(); + info!("e1000 NetScheme poll: {:?}", p); + Ok(()) + } + Err(err) => { + warn!("poll got err {}", err); + Err(DeviceError::IoError) + } + } + } + + fn recv(&self, buf: &mut [u8]) -> DeviceResult { + if let Some(vec_recv) = self.driver.0.lock().receive() { + buf.copy_from_slice(&vec_recv); + Ok(vec_recv.len()) + } else { + Err(DeviceError::NotReady) + } + } + + fn send(&self, data: &[u8]) -> DeviceResult { + if self.driver.0.lock().can_send() { + let mut driver = self.driver.0.lock(); + driver.send(data); + Ok(data.len()) + } else { + Err(DeviceError::NotReady) + } + } +} + +pub struct E1000RxToken(Vec); +pub struct E1000TxToken(E1000Driver); + +impl phy::Device<'_> for E1000Driver { + type RxToken = E1000RxToken; + type TxToken = E1000TxToken; + + fn receive(&mut self) -> Option<(Self::RxToken, Self::TxToken)> { + self.0 + .lock() + .receive() + .map(|vec| (E1000RxToken(vec), E1000TxToken(self.clone()))) + } + + fn transmit(&mut self) -> Option { + if self.0.lock().can_send() { + Some(E1000TxToken(self.clone())) + } else { + None + } + } + + fn capabilities(&self) -> DeviceCapabilities { + let mut caps = DeviceCapabilities::default(); + caps.max_transmission_unit = 1536; + caps.max_burst_size = Some(64); + caps + } +} + +impl phy::RxToken for E1000RxToken { + fn consume(mut self, _timestamp: Instant, f: F) -> Result + where + F: FnOnce(&mut [u8]) -> Result, + { + f(&mut self.0) + } +} + +impl phy::TxToken for E1000TxToken { + fn consume(self, _timestamp: Instant, len: usize, f: F) -> Result + where + F: FnOnce(&mut [u8]) -> Result, + { + let mut buffer = [0u8; PAGE_SIZE]; + let result = f(&mut buffer[..len]); + + let mut driver = (self.0).0.lock(); + driver.send(&buffer); + + result + } +} + +// JudgeDuck-OS/kern/e1000.c +pub fn init( + name: String, + irq: usize, + header: usize, + size: usize, + index: usize, +) -> DeviceResult { + info!("Probing e1000 {}", name); + + // randomly generated + let mac: [u8; 6] = [0x54, 0x51, 0x9F, 0x71, 0xC0, index as u8]; + + let e1000 = E1000::new(header, size, DriverEthernetAddress::from_bytes(&mac)); + + let net_driver = E1000Driver(Arc::new(Mutex::new(e1000))); + + let ethernet_addr = EthernetAddress::from_bytes(&mac); + let ip_addrs = [IpCidr::new(IpAddress::v4(10, 0, 2, (15 + index) as u8), 24)]; + let default_v4_gw = Ipv4Address::new(10, 0, 2, 2); //Qemu user network gateway: 10.0.2.2 + static mut ROUTES_STORAGE: [Option<(IpCidr, Route)>; 1] = [None; 1]; + let mut routes = unsafe { Routes::new(&mut ROUTES_STORAGE[..]) }; + routes.add_default_ipv4_route(default_v4_gw).unwrap(); + + let neighbor_cache = NeighborCache::new(BTreeMap::new()); + let iface = InterfaceBuilder::new(net_driver.clone()) + .ethernet_addr(ethernet_addr) + .neighbor_cache(neighbor_cache) + .ip_addrs(ip_addrs) + .routes(routes) + .finalize(); + + info!( + "e1000 interface {} up with addr 10.0.2.{}/24", + name, + 15 + index + ); + let e1000_iface = E1000Interface { + iface: Arc::new(Mutex::new(iface)), + driver: net_driver, + name, + irq, + }; + + Ok(e1000_iface) +} diff --git a/drivers/src/net/loopback.rs b/drivers/src/net/loopback.rs index cb6d7c74..7d4be190 100644 --- a/drivers/src/net/loopback.rs +++ b/drivers/src/net/loopback.rs @@ -54,7 +54,7 @@ impl NetScheme for LoopbackInterface { fn get_ifname(&self) -> String { unimplemented!() } - fn get_ip_addrrs(&self) -> Vec { + fn get_ip_address(&self) -> Vec { unimplemented!() } } diff --git a/drivers/src/net/mod.rs b/drivers/src/net/mod.rs index a5ec4dc3..85ef7c91 100644 --- a/drivers/src/net/mod.rs +++ b/drivers/src/net/mod.rs @@ -1,5 +1,6 @@ //! LAN driver, only for Realtek currently. +pub mod e1000; cfg_if::cfg_if! { if #[cfg(target_arch = "riscv64")] { mod realtek; @@ -9,6 +10,7 @@ pub use rtlx::*; } } +/* /// External functions that drivers must use pub trait Provider { /// Page size (usually 4K) @@ -22,6 +24,8 @@ pub trait Provider { /// Deallocate DMA fn dealloc_dma(vaddr: usize, size: usize); } +*/ +pub use isomorphic_drivers::provider::Provider; pub struct ProviderImpl; diff --git a/drivers/src/net/realtek/rtl8211f.rs b/drivers/src/net/realtek/rtl8211f.rs index 548fe1b9..88d01a53 100644 --- a/drivers/src/net/realtek/rtl8211f.rs +++ b/drivers/src/net/realtek/rtl8211f.rs @@ -214,7 +214,6 @@ impl

RTL8211F

where P: Provider, { - #[allow(clippy::clone_on_copy)] pub fn new(mac_addr: &[u8; 6]) -> Self { assert_eq!(size_of::(), 16); @@ -1142,11 +1141,9 @@ where status = tx_dma_irq_status::tx_hard_error as i32; } - #[allow(clippy::collapsible_if)] /* 正常的 TX/RX NORMAL interrupts */ - if (intr_status & (TX_INT | RX_INT | RX_EARLY_INT | TX_UA_INT)) != 0 - && (intr_status & (TX_INT | RX_INT)) != 0 - { + // (intr_status & (TX_INT | RX_INT | RX_EARLY_INT | TX_UA_INT)) != 0 + if (intr_status & (TX_INT | RX_INT)) != 0 { status = tx_dma_irq_status::handle_tx_rx as i32; } /* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */ @@ -1434,14 +1431,6 @@ where match speed { 1000 => ctrl &= !0x0C, - 100 | 10 => { - ctrl |= 0x08; - if (speed == 100) { - ctrl |= 0x04; - } else { - ctrl &= !0x04; - } - } _ => { ctrl |= 0x08; if (speed == 100) { diff --git a/drivers/src/net/realtek/utils.rs b/drivers/src/net/realtek/utils.rs index 9e89f319..3b031e59 100644 --- a/drivers/src/net/realtek/utils.rs +++ b/drivers/src/net/realtek/utils.rs @@ -1,6 +1,6 @@ +// c906 use core::arch::asm; -// c906 const FREQUENCY: u64 = 24_000_000; // C906: 24_000_000, Qemu: 10_000_000 const MMIO_MTIMECMP0: *mut u64 = 0x0200_4000usize as *mut u64; const MMIO_MTIME: *const u64 = 0x0200_BFF8 as *const u64; diff --git a/drivers/src/net/rtlx.rs b/drivers/src/net/rtlx.rs index 33be17f7..0e0a611e 100644 --- a/drivers/src/net/rtlx.rs +++ b/drivers/src/net/rtlx.rs @@ -76,7 +76,7 @@ impl NetScheme for RTLxInterface { self.name.clone() } - fn get_ip_addrrs(&self) -> Vec { + fn get_ip_address(&self) -> Vec { Vec::from(self.iface.lock().ip_addrs()) } diff --git a/drivers/src/scheme/net.rs b/drivers/src/scheme/net.rs index 6a51f15b..52463112 100644 --- a/drivers/src/scheme/net.rs +++ b/drivers/src/scheme/net.rs @@ -9,6 +9,6 @@ pub trait NetScheme: Scheme { fn send(&self, buf: &[u8]) -> DeviceResult; fn get_mac(&self) -> EthernetAddress; fn get_ifname(&self) -> String; - fn get_ip_addrrs(&self) -> Vec; + fn get_ip_address(&self) -> Vec; fn poll(&self) -> DeviceResult; } diff --git a/kernel-hal/Cargo.toml b/kernel-hal/Cargo.toml index 3b848263..4edddcbe 100644 --- a/kernel-hal/Cargo.toml +++ b/kernel-hal/Cargo.toml @@ -35,18 +35,7 @@ numeric-enum-macro = "0.2" lazy_static = { version = "1.4", features = ["spin_no_std"] } zcore-drivers = { path = "../drivers", features = ["virtio"] } lock = { git = "https://github.com/DeathWish5/kernel-sync", rev = "01b2e70" } -smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev = "043eb60", default-features = false, features = [ - "alloc", - "log", - "async", - "medium-ethernet", - "proto-ipv4", - "proto-igmp", - "socket-icmp", - "socket-udp", - "socket-tcp", - "socket-raw", -] } +smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp", rev = "35e833e3", default-features = false, features = ["log", "alloc", "verbose", "proto-ipv4", "proto-ipv6", "proto-igmp", "medium-ip", "medium-ethernet", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp", "async"] } # LibOS mode [target.'cfg(not(target_os = "none"))'.dependencies] diff --git a/kernel-hal/src/bare/arch/riscv/drivers.rs b/kernel-hal/src/bare/arch/riscv/drivers.rs index 3ccf4f4d..7a7779df 100644 --- a/kernel-hal/src/bare/arch/riscv/drivers.rs +++ b/kernel-hal/src/bare/arch/riscv/drivers.rs @@ -62,6 +62,16 @@ pub(super) fn init() -> DeviceResult { } } + #[cfg(not(feature = "loopback"))] + { + use alloc::sync::Arc; + use zcore_drivers::bus::pci; + let pci_devs = pci::init(Some(Arc::new(IoMapperImpl)))?; + for d in pci_devs.into_iter() { + drivers::add_device(d); + } + } + intc_init()?; #[cfg(feature = "graphic")] diff --git a/kernel-hal/src/bare/arch/riscv/trap.rs b/kernel-hal/src/bare/arch/riscv/trap.rs index 8271fc0b..105696ab 100644 --- a/kernel-hal/src/bare/arch/riscv/trap.rs +++ b/kernel-hal/src/bare/arch/riscv/trap.rs @@ -26,8 +26,8 @@ pub(super) fn super_soft() { #[no_mangle] pub extern "C" fn trap_handler(tf: &mut TrapFrame) { let scause = scause::read(); - debug!("kernel trap happened: {:?}", TrapReason::from(scause)); - debug!( + trace!("kernel trap happened: {:?}", TrapReason::from(scause)); + trace!( "sepc = 0x{:x} pgtoken = 0x{:x}", tf.sepc, crate::vm::current_vmtoken() diff --git a/kernel-hal/src/bare/arch/x86_64/drivers.rs b/kernel-hal/src/bare/arch/x86_64/drivers.rs index 76c652a7..ebc5ac9f 100644 --- a/kernel-hal/src/bare/arch/x86_64/drivers.rs +++ b/kernel-hal/src/bare/arch/x86_64/drivers.rs @@ -1,6 +1,5 @@ use alloc::{boxed::Box, sync::Arc}; -use zcore_drivers::bus::pci; use zcore_drivers::irq::x86::Apic; use zcore_drivers::scheme::IrqScheme; use zcore_drivers::uart::{BufferedUart, Uart16550Pmio}; @@ -48,8 +47,15 @@ pub(super) fn init() -> DeviceResult { drivers::add_device(Device::Irq(irq)); - // PCI scan - pci::init(); + #[cfg(not(feature = "loopback"))] + { + // PCI scan + use zcore_drivers::bus::pci; + let pci_devs = pci::init(None)?; + for d in pci_devs.into_iter() { + drivers::add_device(d); + } + } #[cfg(feature = "graphic")] { diff --git a/kernel-hal/src/bare/arch/x86_64/trap.rs b/kernel-hal/src/bare/arch/x86_64/trap.rs index fb7b9a28..f5a66a29 100644 --- a/kernel-hal/src/bare/arch/x86_64/trap.rs +++ b/kernel-hal/src/bare/arch/x86_64/trap.rs @@ -30,7 +30,7 @@ pub(super) fn super_timer() { #[no_mangle] pub extern "C" fn trap_handler(tf: &mut TrapFrame) { - debug!( + trace!( "Interrupt: {:#x} @ CPU{}", tf.trap_num, super::cpu::cpu_id() diff --git a/linux-object/Cargo.toml b/linux-object/Cargo.toml index 7d7b6b0f..304ae4d3 100644 --- a/linux-object/Cargo.toml +++ b/linux-object/Cargo.toml @@ -25,20 +25,9 @@ rcore-fs-ramfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b" rcore-fs-mountfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b" } rcore-fs-devfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b" } cfg-if = "1.0" -smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev = "043eb60", default-features = false, features = [ - "alloc", - "log", - "async", - "medium-ethernet", - "proto-ipv4", - "proto-igmp", - "socket-icmp", - "socket-udp", - "socket-tcp", - "socket-raw", -] } zcore-drivers = { path = "../drivers", features = ["virtio"] } lock = { git = "https://github.com/DeathWish5/kernel-sync", rev = "01b2e70" } +smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp", rev = "35e833e3", default-features = false, features = ["log", "alloc", "verbose", "proto-ipv4", "proto-ipv6", "proto-igmp", "medium-ip", "medium-ethernet", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp", "async"] } # LibOS mode [target.'cfg(not(target_os = "none"))'.dependencies] diff --git a/linux-object/src/net/tcp.rs b/linux-object/src/net/tcp.rs index e51201dd..abfeec05 100644 --- a/linux-object/src/net/tcp.rs +++ b/linux-object/src/net/tcp.rs @@ -70,7 +70,7 @@ impl TcpSocketState { /// missing documentation pub async fn read(&self, data: &mut [u8]) -> (LxResult, Endpoint) { - warn!("tcp read"); + info!("tcp read"); loop { poll_ifaces(); let net_sockets = get_sockets(); @@ -98,7 +98,7 @@ impl TcpSocketState { /// missing documentation pub fn write(&self, data: &[u8], _sendto_endpoint: Option) -> SysResult { - warn!("tcp write"); + info!("tcp write"); let net_sockets = get_sockets(); let mut sockets = net_sockets.lock(); let mut socket = sockets.get::(self.handle.0); diff --git a/linux-object/src/process.rs b/linux-object/src/process.rs index 124d5b5f..7362e5c6 100644 --- a/linux-object/src/process.rs +++ b/linux-object/src/process.rs @@ -17,7 +17,6 @@ use core::sync::atomic::AtomicI32; use hashbrown::HashMap; use kernel_hal::VirtAddr; use rcore_fs::vfs::{FileSystem, INode}; -use smoltcp::socket::SocketHandle; use spin::{Mutex, MutexGuard}; use zircon_object::{ @@ -170,7 +169,7 @@ struct LinuxProcessInner { /// Signal actions signal_actions: SignalActions, /// Sockets - sockets: HashMap>>, + sockets: HashMap>>, } #[derive(Clone)] @@ -332,9 +331,9 @@ impl LinuxProcess { } /// Add a socket to the socket set at given `SocketHandle`. - pub fn add_socket(&self, socket: Arc>) -> LxResult { + pub fn add_socket(&self, socket: Arc>) -> LxResult { let inner = self.inner.lock(); - let fd = inner.get_free_hd(); + let fd = inner.get_free_socket_fd(); self.insert_socket(inner, fd, socket) // unimplemented!() } @@ -343,9 +342,9 @@ impl LinuxProcess { fn insert_socket( &self, mut inner: MutexGuard, - fd: SocketHandle, + fd: usize, socket: Arc>, - ) -> LxResult { + ) -> LxResult { if inner.sockets.len() < inner.file_limit.cur as usize { inner.sockets.insert(fd, socket); Ok(fd) @@ -355,7 +354,7 @@ impl LinuxProcess { } /// Get the `Socket` with given `fd`. - pub fn get_socket(&self, fd: SocketHandle) -> LxResult>> { + pub fn get_socket(&self, fd: usize) -> LxResult>> { // unimplemented!() let inner = self.inner.lock(); let socket = inner.sockets.get(&fd).cloned().ok_or(LxError::EBADF); @@ -363,7 +362,7 @@ impl LinuxProcess { } /// Close file descriptor `fd`. - pub fn close_socket(&self, fd: SocketHandle) -> LxResult { + pub fn close_socket(&self, fd: usize) -> LxResult { let mut inner = self.inner.lock(); inner.sockets.remove(&fd).map(|_| ()).ok_or(LxError::EBADF) } @@ -507,9 +506,8 @@ impl LinuxProcessInner { .unwrap() } - fn get_free_hd(&self) -> SocketHandle { + fn get_free_socket_fd(&self) -> usize { (SOCKET_FD..) - .map(|i| i.into()) .find(|fd| !self.sockets.contains_key(fd)) .unwrap() } diff --git a/linux-syscall/src/file/file.rs b/linux-syscall/src/file/file.rs index 695f5ea4..bab11060 100644 --- a/linux-syscall/src/file/file.rs +++ b/linux-syscall/src/file/file.rs @@ -25,7 +25,7 @@ impl Syscall<'_> { // TODO wait a new struct to refactor if usize::from(fd) >= SOCKET_FD { let x = usize::from(fd); - let socket = proc.get_socket(x.into())?; + let socket = proc.get_socket(x)?; let mut buf = vec![0u8; len]; let (len, _) = socket.lock().read(&mut buf).await; let len = len.unwrap_or(0); @@ -108,7 +108,7 @@ impl Syscall<'_> { // TODO wait a new struct to refactor if usize::from(fd) >= SOCKET_FD { let x = usize::from(fd); - let socket = proc.get_socket(x.into())?; + let socket = proc.get_socket(x)?; let mut buf = vec![0u8; iovs.total_len()]; let (len, _) = socket.lock().read(&mut buf).await; let len = len.unwrap(); @@ -143,7 +143,7 @@ impl Syscall<'_> { // TODO wait a new struct to refactor if usize::from(fd) >= SOCKET_FD { let x = usize::from(fd); - let socket = proc.get_socket(x.into())?; + let socket = proc.get_socket(x)?; let len = socket.lock().write(&buf, None)?; Ok(len) } else { @@ -323,7 +323,7 @@ impl Syscall<'_> { // TODO wait a new struct to refactor if usize::from(fd) >= SOCKET_FD { let f = usize::from(fd); - let socket = proc.get_socket(f.into())?; + let socket = proc.get_socket(f)?; let x = socket.lock(); x.ioctl(request, arg1, arg2, arg3) } else { @@ -342,7 +342,7 @@ impl Syscall<'_> { // TODO wait a new struct to refactor if usize::from(fd) >= SOCKET_FD { let f = usize::from(fd); - let socket = proc.get_socket(f.into())?; + let socket = proc.get_socket(f)?; let x = socket.lock(); x.fcntl(cmd, arg) } else { diff --git a/linux-syscall/src/net.rs b/linux-syscall/src/net.rs index 84415c35..9d532530 100644 --- a/linux-syscall/src/net.rs +++ b/linux-syscall/src/net.rs @@ -11,7 +11,7 @@ use spin::Mutex; impl Syscall<'_> { /// net socket pub fn sys_socket(&mut self, domain: usize, socket_type: usize, protocol: usize) -> SysResult { - warn!( + info!( "sys_socket: domain: {:?}, socket_type: {:?}, protocol: {}", domain, socket_type, protocol ); @@ -43,7 +43,7 @@ impl Syscall<'_> { }; // socket let fd = proc.add_socket(socket)?; - Ok(fd.into()) + Ok(fd) } /// net sys_connect @@ -53,7 +53,7 @@ impl Syscall<'_> { addr: UserInPtr, addr_len: usize, ) -> SysResult { - warn!( + info!( "sys_connect: fd: {}, addr: {:?}, addr_len: {}", fd, addr, addr_len ); @@ -62,7 +62,7 @@ impl Syscall<'_> { let sa: SockAddr = addr.read()?; let endpoint = sockaddr_to_endpoint(sa, addr_len)?; - let socket = _proc.get_socket(fd.into())?; + let socket = _proc.get_socket(fd)?; let x = socket.lock(); x.connect(endpoint).await?; Ok(0) @@ -77,14 +77,15 @@ impl Syscall<'_> { optval: UserInPtr, optlen: usize, ) -> SysResult { - warn!( + info!( "sys_setsockopt : sockfd : {:?}, level : {:?}, optname : {:?}, optval : {:?} , optlen : {:?}", sockfd, level, optname,optval,optlen ); - self.linux_process() - .get_socket(sockfd.into())? - .lock() - .setsockopt(level, optname, optval.as_slice(optlen)?) + self.linux_process().get_socket(sockfd)?.lock().setsockopt( + level, + optname, + optval.as_slice(optlen)?, + ) } /// net getsockopt @@ -96,7 +97,7 @@ impl Syscall<'_> { optval: UserOutPtr, optlen: usize, ) -> SysResult { - warn!( + info!( "sys_getsockopt : sockfd : {:?}, level : {:?}, optname : {:?}, optval : {:?} , optlen : {:?}", sockfd, level, optname,optval,optlen ); @@ -113,7 +114,7 @@ impl Syscall<'_> { dest_addr: UserInPtr, addrlen: usize, ) -> SysResult { - warn!( + info!( "sys_sendto : sockfd : {:?}, buffer : {:?}, length : {:?}, flags : {:?} , optlen : {:?}, addrlen : {:?}", sockfd,buffer,length,flags,dest_addr,addrlen ); @@ -125,7 +126,7 @@ impl Syscall<'_> { Some(endpoint) }; let proc = self.linux_process(); - let socket = proc.get_socket(sockfd.into())?; + let socket = proc.get_socket(sockfd)?; let len = socket.lock().write(buffer.as_slice(length)?, endpoint)?; Ok(len) } @@ -146,7 +147,7 @@ impl Syscall<'_> { ); let proc = self.linux_process(); let mut data = vec![0u8; length]; - let socket = proc.get_socket(sockfd.into())?; + let socket = proc.get_socket(sockfd)?; let x = socket.lock(); let (result, endpoint) = x.read(&mut data).await; if result.is_ok() && !addr.is_null() { @@ -165,7 +166,7 @@ impl Syscall<'_> { let endpoint = sockaddr_to_endpoint(sa, addr_len)?; info!("sys_bind: fd={:?} bind to {:?}", fd, endpoint); - let socket = proc.get_socket(fd.into())?; + let socket = proc.get_socket(fd)?; let mut x = socket.lock(); x.bind(endpoint) } @@ -177,7 +178,7 @@ impl Syscall<'_> { // open multiple sockets for each connection let proc = self.linux_process(); - let socket = proc.get_socket(fd.into())?; + let socket = proc.get_socket(fd)?; let mut x = socket.lock(); x.listen() } @@ -187,7 +188,7 @@ impl Syscall<'_> { info!("sys_shutdown: fd={:?} how={}", fd, how); let proc = self.linux_process(); - let socket = proc.get_socket(fd.into())?; + let socket = proc.get_socket(fd)?; let x = socket.lock(); x.shutdown() } @@ -199,7 +200,7 @@ impl Syscall<'_> { addr: UserOutPtr, addr_len: UserInOutPtr, ) -> SysResult { - warn!( + info!( "sys_accept: fd={:?} addr={:?} addr_len={:?}", fd, addr, addr_len ); @@ -207,7 +208,7 @@ impl Syscall<'_> { // open multiple sockets for each connection let proc = self.linux_process(); - let socket = proc.get_socket(fd.into())?; + let socket = proc.get_socket(fd)?; let (new_socket, remote_endpoint) = socket.lock().accept().await?; let new_fd = proc.add_socket(new_socket)?; @@ -215,7 +216,7 @@ impl Syscall<'_> { let sockaddr_in = SockAddr::from(remote_endpoint); sockaddr_in.write_to(addr, addr_len)?; } - Ok(new_fd.into()) + Ok(new_fd) } /// net getsocknames @@ -236,7 +237,7 @@ impl Syscall<'_> { return Err(LxError::EINVAL); } - let socket = proc.get_socket(fd.into())?; + let socket = proc.get_socket(fd)?; let endpoint = socket.lock().endpoint().ok_or(LxError::EINVAL)?; let sockaddr_in = SockAddr::from(endpoint); sockaddr_in.write_to(addr, addr_len)?; @@ -263,7 +264,7 @@ impl Syscall<'_> { return Err(LxError::EINVAL); } - let socket = proc.get_socket(fd.into())?; + let socket = proc.get_socket(fd)?; let remote_endpoint = socket.lock().remote_endpoint().ok_or(LxError::EINVAL)?; let sockaddr_in = SockAddr::from(remote_endpoint); sockaddr_in.write_to(addr, addr_len)?; diff --git a/zCore/Makefile b/zCore/Makefile index 49cad1cc..7089bd88 100644 --- a/zCore/Makefile +++ b/zCore/Makefile @@ -166,6 +166,10 @@ else ifeq ($(ARCH), riscv64) -append "$(CMDLINE)" endif +qemu_opts += \ + -netdev user,id=net1,hostfwd=tcp::8000-:80,hostfwd=tcp::2222-:2222,hostfwd=udp::6969-:6969 \ + -device e1000e,netdev=net1 + ifeq ($(DISK), on) ifeq ($(ARCH), x86_64) qemu_opts += -device ide-hd,bus=ahci.0,drive=userdisk