forked from rcore-os/zCore
Merge pull request #302 from elliott10/master
Enable PCI scan and e1000 driver in RISCV
This commit is contained in:
commit
d74dfad991
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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<T>(addr: usize, content: T) {
|
||||
let cell = (addr) as *mut T;
|
||||
unsafe {
|
||||
write_volatile(cell, content);
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn read<T>(addr: usize) -> T {
|
||||
let cell = (addr) as *const T;
|
||||
unsafe { read_volatile(cell) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<usize> {
|
||||
unsafe fn enable(loc: Location, paddr: u64) -> Option<usize> {
|
||||
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<usize> {
|
|||
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<usize> {
|
|||
assigned_irq
|
||||
}
|
||||
|
||||
pub fn init_driver(dev: &PCIDevice) {
|
||||
pub fn init_driver(dev: &PCIDevice, mapper: &Option<Arc<dyn IoMapper>>) -> DeviceResult<Device> {
|
||||
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<Arc<dyn IoMapper>>) -> DeviceResult<Vec<Device>> {
|
||||
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<Location> {
|
||||
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<Location> {
|
|||
}
|
||||
|
||||
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<BTreeMap<Location, Arc<dyn Driver>>> =
|
||||
Mutex::new(BTreeMap::new());
|
||||
}
|
||||
*/
|
||||
|
||||
// all devices stored in:AllDeviceList
|
||||
|
|
|
|||
|
|
@ -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<Mutex<E1000<ProviderImpl>>>);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct E1000Interface {
|
||||
iface: Arc<Mutex<Interface<'static, E1000Driver>>>,
|
||||
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<IpCidr> {
|
||||
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<usize> {
|
||||
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<usize> {
|
||||
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<u8>);
|
||||
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<Self::TxToken> {
|
||||
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<R, F>(mut self, _timestamp: Instant, f: F) -> Result<R>
|
||||
where
|
||||
F: FnOnce(&mut [u8]) -> Result<R>,
|
||||
{
|
||||
f(&mut self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl phy::TxToken for E1000TxToken {
|
||||
fn consume<R, F>(self, _timestamp: Instant, len: usize, f: F) -> Result<R>
|
||||
where
|
||||
F: FnOnce(&mut [u8]) -> Result<R>,
|
||||
{
|
||||
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<E1000Interface> {
|
||||
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)
|
||||
}
|
||||
|
|
@ -54,7 +54,7 @@ impl NetScheme for LoopbackInterface {
|
|||
fn get_ifname(&self) -> String {
|
||||
unimplemented!()
|
||||
}
|
||||
fn get_ip_addrrs(&self) -> Vec<IpCidr> {
|
||||
fn get_ip_address(&self) -> Vec<IpCidr> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -214,7 +214,6 @@ impl<P> RTL8211F<P>
|
|||
where
|
||||
P: Provider,
|
||||
{
|
||||
#[allow(clippy::clone_on_copy)]
|
||||
pub fn new(mac_addr: &[u8; 6]) -> Self {
|
||||
assert_eq!(size_of::<dma_desc>(), 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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ impl NetScheme for RTLxInterface {
|
|||
self.name.clone()
|
||||
}
|
||||
|
||||
fn get_ip_addrrs(&self) -> Vec<IpCidr> {
|
||||
fn get_ip_address(&self) -> Vec<IpCidr> {
|
||||
Vec::from(self.iface.lock().ip_addrs())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,6 @@ pub trait NetScheme: Scheme {
|
|||
fn send(&self, buf: &[u8]) -> DeviceResult<usize>;
|
||||
fn get_mac(&self) -> EthernetAddress;
|
||||
fn get_ifname(&self) -> String;
|
||||
fn get_ip_addrrs(&self) -> Vec<IpCidr>;
|
||||
fn get_ip_address(&self) -> Vec<IpCidr>;
|
||||
fn poll(&self) -> DeviceResult;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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")]
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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")]
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ impl TcpSocketState {
|
|||
|
||||
/// missing documentation
|
||||
pub async fn read(&self, data: &mut [u8]) -> (LxResult<usize>, 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<Endpoint>) -> SysResult {
|
||||
warn!("tcp write");
|
||||
info!("tcp write");
|
||||
let net_sockets = get_sockets();
|
||||
let mut sockets = net_sockets.lock();
|
||||
let mut socket = sockets.get::<TcpSocket>(self.handle.0);
|
||||
|
|
|
|||
|
|
@ -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<SocketHandle, Arc<Mutex<dyn Socket>>>,
|
||||
sockets: HashMap<usize, Arc<Mutex<dyn Socket>>>,
|
||||
}
|
||||
|
||||
#[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<Mutex<dyn Socket>>) -> LxResult<SocketHandle> {
|
||||
pub fn add_socket(&self, socket: Arc<Mutex<dyn Socket>>) -> LxResult<usize> {
|
||||
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<LinuxProcessInner>,
|
||||
fd: SocketHandle,
|
||||
fd: usize,
|
||||
socket: Arc<Mutex<dyn Socket>>,
|
||||
) -> LxResult<SocketHandle> {
|
||||
) -> LxResult<usize> {
|
||||
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<Arc<Mutex<dyn Socket>>> {
|
||||
pub fn get_socket(&self, fd: usize) -> LxResult<Arc<Mutex<dyn Socket>>> {
|
||||
// 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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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<SockAddr>,
|
||||
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<u8>,
|
||||
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<u8>,
|
||||
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<SockAddr>,
|
||||
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<SockAddr>,
|
||||
addr_len: UserInOutPtr<u32>,
|
||||
) -> 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)?;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue