From 2de4a526fb6158344647a766ef3b7c616eeed4a5 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 29 Aug 2019 20:16:48 -0600 Subject: [PATCH] Merge scheme handling in e1000d and rtl8168d --- e1000d/src/main.rs | 12 +-- rtl8168d/src/device.rs | 157 ++++++++++++++++++--------------- rtl8168d/src/main.rs | 196 +++++++++++++++++++++++++---------------- 3 files changed, 213 insertions(+), 152 deletions(-) diff --git a/e1000d/src/main.rs b/e1000d/src/main.rs index fb87503ef4..6518764fc2 100644 --- a/e1000d/src/main.rs +++ b/e1000d/src/main.rs @@ -71,10 +71,7 @@ fn main() { let irq_str = args.next().expect("e1000d: no irq provided"); let irq = irq_str.parse::().expect("e1000d: failed to parse irq"); - print!( - "{}", - format!(" + E1000 {} on: {:X} IRQ: {}\n", name, bar, irq) - ); + println!(" + E1000 {} on: {:X} IRQ: {}", name, bar, irq); // Daemonize if unsafe { syscall::clone(0).unwrap() } == 0 { @@ -87,8 +84,11 @@ fn main() { File::from_raw_fd(socket_fd as RawFd) })); - let mut irq_file = - File::open(format!("irq:{}", irq)).expect("e1000d: failed to open IRQ file"); + let irq_fd = syscall::open( + format!("irq:{}", irq), + syscall::O_RDWR | syscall::O_NONBLOCK + ).expect("e1000d: failed to open IRQ file"); + let mut irq_file = unsafe { File::from_raw_fd(irq_fd as RawFd) }; let address = unsafe { syscall::physmap(bar, 128 * 1024, PHYSMAP_WRITE | PHYSMAP_NO_CACHE) diff --git a/rtl8168d/src/device.rs b/rtl8168d/src/device.rs index 58830fedc7..906fdae221 100644 --- a/rtl8168d/src/device.rs +++ b/rtl8168d/src/device.rs @@ -5,7 +5,7 @@ use netutils::setcfg; use syscall::error::{Error, EACCES, EBADF, EINVAL, EWOULDBLOCK, Result}; use syscall::flag::O_NONBLOCK; use syscall::io::{Dma, Mmio, Io, ReadOnly}; -use syscall::scheme::SchemeMut; +use syscall::scheme::SchemeBlockMut; #[repr(packed)] struct Regs { @@ -79,18 +79,18 @@ pub struct Rtl8168 { pub handles: BTreeMap } -impl SchemeMut for Rtl8168 { - fn open(&mut self, _path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result { +impl SchemeBlockMut for Rtl8168 { + fn open(&mut self, _path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result> { if uid == 0 { self.next_id += 1; self.handles.insert(self.next_id, flags); - Ok(self.next_id) + Ok(Some(self.next_id)) } else { Err(Error::new(EACCES)) } } - fn dup(&mut self, id: usize, buf: &[u8]) -> Result { + fn dup(&mut self, id: usize, buf: &[u8]) -> Result> { if ! buf.is_empty() { return Err(Error::new(EINVAL)); } @@ -101,85 +101,97 @@ impl SchemeMut for Rtl8168 { }; self.next_id += 1; self.handles.insert(self.next_id, flags); - Ok(self.next_id) + Ok(Some(self.next_id)) } - fn read(&mut self, id: usize, buf: &mut [u8]) -> Result { - let flags = self.handles.get(&id).ok_or(Error::new(EBADF))?; + fn read(&mut self, id: usize, buf: &mut [u8]) -> Result> { + let mut inner = |buf: &mut [u8]| -> Result> { + let flags = self.handles.get(&id).ok_or(Error::new(EBADF))?; - if self.receive_i >= self.receive_ring.len() { - self.receive_i = 0; - } - - let rd = &mut self.receive_ring[self.receive_i]; - if ! rd.ctrl.readf(OWN) { - let rd_len = rd.ctrl.read() & 0x3FFF; - - let data = &self.receive_buffer[self.receive_i]; - - let mut i = 0; - while i < buf.len() && i < rd_len as usize { - buf[i] = data[i].read(); - i += 1; + if self.receive_i >= self.receive_ring.len() { + self.receive_i = 0; } - let eor = rd.ctrl.read() & EOR; - rd.ctrl.write(OWN | eor | data.len() as u32); + let rd = &mut self.receive_ring[self.receive_i]; + if ! rd.ctrl.readf(OWN) { + let rd_len = rd.ctrl.read() & 0x3FFF; - self.receive_i += 1; - - return Ok(i); - } - - if flags & O_NONBLOCK == O_NONBLOCK { - Ok(0) - } else { - Err(Error::new(EWOULDBLOCK)) - } - } - - fn write(&mut self, id: usize, buf: &[u8]) -> Result { - let _flags = self.handles.get(&id).ok_or(Error::new(EBADF))?; - - loop { - if self.transmit_i >= self.transmit_ring.len() { - self.transmit_i = 0; - } - - let td = &mut self.transmit_ring[self.transmit_i]; - if ! td.ctrl.readf(OWN) { - let data = &mut self.transmit_buffer[self.transmit_i]; + let data = &self.receive_buffer[self.receive_i]; let mut i = 0; - while i < buf.len() && i < data.len() { - data[i].write(buf[i]); + while i < buf.len() && i < rd_len as usize { + buf[i] = data[i].read(); i += 1; } - let eor = td.ctrl.read() & EOR; - td.ctrl.write(OWN | eor | FS | LS | i as u32); + let eor = rd.ctrl.read() & EOR; + rd.ctrl.write(OWN | eor | data.len() as u32); - self.regs.tppoll.writef(1 << 6, true); //Notify of normal priority packet + self.receive_i += 1; - while self.regs.tppoll.readf(1 << 6) { - unsafe { asm!("pause"); } + Ok(Some(i)) + } else if flags & O_NONBLOCK == O_NONBLOCK { + Err(Error::new(EWOULDBLOCK)) + } else { + Ok(None) + } + }; + + println!("rtl8168d read {}", buf.len()); + let res = inner(buf); + println!("rtl8168d read {} = {:?}", buf.len(), res); + res + } + + fn write(&mut self, id: usize, buf: &[u8]) -> Result> { + let mut inner = |buf: &[u8]| -> Result> { + let _flags = self.handles.get(&id).ok_or(Error::new(EBADF))?; + + loop { + if self.transmit_i >= self.transmit_ring.len() { + self.transmit_i = 0; } - self.transmit_i += 1; + let td = &mut self.transmit_ring[self.transmit_i]; + if ! td.ctrl.readf(OWN) { + let data = &mut self.transmit_buffer[self.transmit_i]; - return Ok(i); + let mut i = 0; + while i < buf.len() && i < data.len() { + data[i].write(buf[i]); + i += 1; + } + + let eor = td.ctrl.read() & EOR; + td.ctrl.write(OWN | eor | FS | LS | i as u32); + + self.regs.tppoll.writef(1 << 6, true); //Notify of normal priority packet + + while self.regs.tppoll.readf(1 << 6) { + unsafe { asm!("pause"); } + } + + self.transmit_i += 1; + + return Ok(Some(i)); + } + + unsafe { asm!("pause"); } } + }; - unsafe { asm!("pause"); } - } + println!("rtl8168d write {}", buf.len()); + let res = inner(buf); + println!("rtl8168d write {} = {:?}", buf.len(), res); + res } - fn fevent(&mut self, id: usize, _flags: usize) -> Result { + fn fevent(&mut self, id: usize, _flags: usize) -> Result> { let _flags = self.handles.get(&id).ok_or(Error::new(EBADF))?; - Ok(0) + Ok(Some(0)) } - fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result { + fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result> { let _flags = self.handles.get(&id).ok_or(Error::new(EBADF))?; let mut i = 0; @@ -188,17 +200,17 @@ impl SchemeMut for Rtl8168 { buf[i] = scheme_path[i]; i += 1; } - Ok(i) + Ok(Some(i)) } - fn fsync(&mut self, id: usize) -> Result { + fn fsync(&mut self, id: usize) -> Result> { let _flags = self.handles.get(&id).ok_or(Error::new(EBADF))?; - Ok(0) + Ok(Some(0)) } - fn close(&mut self, id: usize) -> Result { + fn close(&mut self, id: usize) -> Result> { self.handles.remove(&id).ok_or(Error::new(EBADF))?; - Ok(0) + Ok(Some(0)) } } @@ -254,12 +266,12 @@ impl Rtl8168 { Ok(module) } - pub unsafe fn irq(&mut self) -> u16 { + pub unsafe fn irq(&mut self) -> bool { // Read and then clear the ISR let isr = self.regs.isr.read(); self.regs.isr.write(isr); let imr = self.regs.imr.read(); - isr & imr + (isr & imr) != 0 } pub fn next_read(&self) -> usize { @@ -280,16 +292,18 @@ impl Rtl8168 { (mac_low >> 24) as u8, mac_high as u8, (mac_high >> 8) as u8]; - print!("{}", format!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); + println!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); let _ = setcfg("mac", &format!("{:>02X}-{:>02X}-{:>02X}-{:>02X}-{:>02X}-{:>02X}\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); // Reset - this will disable tx and rx, reinitialize FIFOs, and set the system buffer pointer to the initial value + println!(" - Reset"); self.regs.cmd.writef(1 << 4, true); while self.regs.cmd.readf(1 << 4) { asm!("pause"); } // Set up rx buffers + println!(" - Receive buffers"); for i in 0..self.receive_ring.len() { let rd = &mut self.receive_ring[i]; let data = &mut self.receive_buffer[i]; @@ -301,6 +315,7 @@ impl Rtl8168 { } // Set up normal priority tx buffers + println!(" - Transmit buffers (normal priority)"); for i in 0..self.transmit_ring.len() { self.transmit_ring[i].buffer.write(self.transmit_buffer[i].physical() as u64); } @@ -309,6 +324,7 @@ impl Rtl8168 { } // Set up high priority tx buffers + println!(" - Transmit buffers (high priority)"); for i in 0..self.transmit_ring_h.len() { self.transmit_ring_h[i].buffer.write(self.transmit_buffer_h[i].physical() as u64); } @@ -316,6 +332,7 @@ impl Rtl8168 { td.ctrl.writef(EOR, true); } + println!(" - Set config"); // Unlock config self.regs.cmd_9346.write(1 << 7 | 1 << 6); @@ -358,5 +375,7 @@ impl Rtl8168 { // Lock config self.regs.cmd_9346.write(0); + + println!(" - Complete!"); } } diff --git a/rtl8168d/src/main.rs b/rtl8168d/src/main.rs index e2cb2e51c1..9abaf31648 100644 --- a/rtl8168d/src/main.rs +++ b/rtl8168d/src/main.rs @@ -7,16 +7,58 @@ extern crate syscall; use std::cell::RefCell; use std::env; use std::fs::File; -use std::io::{self, Read, Write, Result}; +use std::io::{ErrorKind, Read, Result, Write}; use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; use std::sync::Arc; use event::EventQueue; -use syscall::{Packet, SchemeMut, PHYSMAP_NO_CACHE, PHYSMAP_WRITE}; -use syscall::error::EWOULDBLOCK; +use syscall::{Packet, SchemeBlockMut, PHYSMAP_NO_CACHE, PHYSMAP_WRITE}; pub mod device; +fn handle_update( + socket: &mut File, + device: &mut device::Rtl8168, + todo: &mut Vec, +) -> Result { + // Handle any blocked packets + let mut i = 0; + while i < todo.len() { + if let Some(a) = device.handle(&todo[i]) { + let mut packet = todo.remove(i); + packet.a = a; + socket.write(&packet)?; + } else { + i += 1; + } + } + + // Check that the socket is empty + loop { + let mut packet = Packet::default(); + match socket.read(&mut packet) { + Ok(0) => return Ok(true), + Ok(_) => (), + Err(err) => { + if err.kind() == ErrorKind::WouldBlock { + break; + } else { + return Err(err); + } + } + } + + if let Some(a) = device.handle(&packet) { + packet.a = a; + socket.write(&packet)?; + } else { + todo.push(packet); + } + } + + Ok(false) +} + fn main() { let mut args = env::args().skip(1); @@ -29,15 +71,18 @@ fn main() { let irq_str = args.next().expect("rtl8168d: no irq provided"); let irq = irq_str.parse::().expect("rtl8168d: failed to parse irq"); - print!("{}", format!(" + RTL8168 {} on: {:X}, IRQ: {}\n", name, bar, irq)); + println!(" + RTL8168 {} on: {:X}, IRQ: {}", name, bar, irq); // Daemonize if unsafe { syscall::clone(0).unwrap() } == 0 { let socket_fd = syscall::open( ":network", - syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK - ).expect("rtl8168d: failed to create network scheme"); - let socket = Arc::new(RefCell::new(unsafe { File::from_raw_fd(socket_fd as RawFd) })); + syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK, + ) + .expect("rtl8168d: failed to create network scheme"); + let socket = Arc::new(RefCell::new(unsafe { + File::from_raw_fd(socket_fd as RawFd) + })); let irq_fd = syscall::open( format!("irq:{}", irq), @@ -45,11 +90,17 @@ fn main() { ).expect("rtl8168d: failed to open IRQ file"); let mut irq_file = unsafe { File::from_raw_fd(irq_fd as RawFd) }; - let address = unsafe { syscall::physmap(bar, 256, PHYSMAP_WRITE | PHYSMAP_NO_CACHE).expect("rtl8168d: failed to map address") }; + let address = unsafe { + syscall::physmap(bar, 256, PHYSMAP_WRITE | PHYSMAP_NO_CACHE) + .expect("rtl8168d: failed to map address") + }; { - let device = Arc::new(RefCell::new(unsafe { device::Rtl8168::new(address).expect("rtl8168d: failed to allocate device") })); + let device = Arc::new(RefCell::new(unsafe { + device::Rtl8168::new(address).expect("rtl8168d: failed to allocate device") + })); - let mut event_queue = EventQueue::::new().expect("rtl8168d: failed to create event queue"); + let mut event_queue = + EventQueue::::new().expect("rtl8168d: failed to create event queue"); syscall::setrens(0, 0).expect("rtl8168d: failed to enter null namespace"); @@ -58,99 +109,90 @@ fn main() { let device_irq = device.clone(); let socket_irq = socket.clone(); let todo_irq = todo.clone(); - event_queue.add(irq_file.as_raw_fd(), move |_event| -> Result> { - let mut irq = [0; 8]; - irq_file.read(&mut irq)?; + event_queue + .add( + irq_file.as_raw_fd(), + move |_event| -> Result> { + let mut irq = [0; 8]; + irq_file.read(&mut irq)?; + if unsafe { device_irq.borrow_mut().irq() } { + irq_file.write(&mut irq)?; - let isr = unsafe { device_irq.borrow_mut().irq() }; - if isr != 0 { - irq_file.write(&mut irq)?; + if handle_update( + &mut socket_irq.borrow_mut(), + &mut device_irq.borrow_mut(), + &mut todo_irq.borrow_mut(), + )? { + return Ok(Some(0)); + } - let mut todo = todo_irq.borrow_mut(); - let mut i = 0; - while i < todo.len() { - let a = todo[i].a; - device_irq.borrow_mut().handle(&mut todo[i]); - if todo[i].a == (-EWOULDBLOCK) as usize { - todo[i].a = a; - i += 1; - } else { - socket_irq.borrow_mut().write(&mut todo[i])?; - todo.remove(i); + let next_read = device_irq.borrow().next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } } - } - - let next_read = device_irq.borrow().next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - } - Ok(None) - }).expect("rtl8168d: failed to catch events on IRQ file"); + Ok(None) + }, + ) + .expect("rtl8168d: failed to catch events on IRQ file"); let device_packet = device.clone(); let socket_packet = socket.clone(); - event_queue.add(socket_fd as RawFd, move |_event| -> Result> { - loop { - let mut packet = Packet::default(); - match socket_packet.borrow_mut().read(&mut packet) { - Ok(0) => return Ok(Some(0)), - Ok(_) => (), - Err(err) => if err.kind() == io::ErrorKind::WouldBlock { - break; - } else { - return Err(err); - } + event_queue + .add(socket_fd as RawFd, move |_event| -> Result> { + if handle_update( + &mut socket_packet.borrow_mut(), + &mut device_packet.borrow_mut(), + &mut todo.borrow_mut(), + )? { + return Ok(Some(0)); } - let a = packet.a; - device_packet.borrow_mut().handle(&mut packet); - if packet.a == (-EWOULDBLOCK) as usize { - packet.a = a; - todo.borrow_mut().push(packet); - } else { - socket_packet.borrow_mut().write(&mut packet)?; + let next_read = device_packet.borrow().next_read(); + if next_read > 0 { + return Ok(Some(next_read)); } - } - let next_read = device_packet.borrow().next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - - Ok(None) - }).expect("rtl8168d: failed to catch events on scheme file"); + Ok(None) + }) + .expect("rtl8168d: failed to catch events on scheme file"); let send_events = |event_count| { for (handle_id, _handle) in device.borrow().handles.iter() { - socket.borrow_mut().write(&Packet { - id: 0, - pid: 0, - uid: 0, - gid: 0, - a: syscall::number::SYS_FEVENT, - b: *handle_id, - c: syscall::flag::EVENT_READ, - d: event_count - }).expect("e1000d: failed to write event"); + socket + .borrow_mut() + .write(&Packet { + id: 0, + pid: 0, + uid: 0, + gid: 0, + a: syscall::number::SYS_FEVENT, + b: *handle_id, + c: syscall::flag::EVENT_READ, + d: event_count, + }) + .expect("rtl8168d: failed to write event"); } }; - for event_count in event_queue.trigger_all(event::Event { - fd: 0, - flags: 0, - }).expect("rtl8168d: failed to trigger events") { + for event_count in event_queue + .trigger_all(event::Event { fd: 0, flags: 0 }) + .expect("rtl8168d: failed to trigger events") + { send_events(event_count); } loop { let event_count = event_queue.run().expect("rtl8168d: failed to handle events"); if event_count == 0 { + //TODO: Handle todo break; } send_events(event_count); } } - unsafe { let _ = syscall::physunmap(address); } + unsafe { + let _ = syscall::physunmap(address); + } } }