Merge branch 'redox-unix'

This commit is contained in:
Jeremy Soller
2019-08-26 17:16:39 -06:00
45 changed files with 1514 additions and 568 deletions
Generated
+283 -230
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -1,6 +1,7 @@
[package]
name = "ahcid"
version = "0.1.0"
edition = "2018"
[dependencies]
bitflags = "0.7"
+3 -3
View File
@@ -18,18 +18,18 @@ pub trait Disk {
fn block_length(&mut self) -> Result<u32>;
}
pub fn disks(base: usize, name: &str) -> (&'static mut HbaMem, Vec<Box<Disk>>) {
pub fn disks(base: usize, name: &str) -> (&'static mut HbaMem, Vec<Box<dyn Disk>>) {
let hba_mem = unsafe { &mut *(base as *mut HbaMem) };
hba_mem.init();
let pi = hba_mem.pi.read();
let disks: Vec<Box<Disk>> = (0..hba_mem.ports.len())
let disks: Vec<Box<dyn Disk>> = (0..hba_mem.ports.len())
.filter(|&i| pi & 1 << i as i32 == 1 << i as i32)
.filter_map(|i| {
let port = unsafe { &mut *hba_mem.ports.as_mut_ptr().add(i) };
let port_type = port.probe();
print!("{}", format!("{}-{}: {:?}\n", name, i, port_type));
let disk: Option<Box<Disk>> = match port_type {
let disk: Option<Box<dyn Disk>> = match port_type {
HbaPortType::SATA => {
match DiskATA::new(i, port) {
Ok(disk) => Some(Box::new(disk)),
+27 -10
View File
@@ -5,11 +5,11 @@ extern crate byteorder;
use std::{env, usize};
use std::fs::File;
use std::io::{Read, Write};
use std::os::unix::io::FromRawFd;
use syscall::{EVENT_READ, PHYSMAP_NO_CACHE, PHYSMAP_WRITE, Event, Packet, SchemeBlockMut};
use std::io::{ErrorKind, Read, Write};
use std::os::unix::io::{FromRawFd, RawFd};
use syscall::{ENODEV, EVENT_READ, PHYSMAP_NO_CACHE, PHYSMAP_WRITE, Error, Event, Packet, SchemeBlockMut};
use scheme::DiskScheme;
use crate::scheme::DiskScheme;
pub mod ahci;
pub mod scheme;
@@ -37,13 +37,13 @@ fn main() {
&format!(":{}", scheme_name),
syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK
).expect("ahcid: failed to create disk scheme");
let mut socket = unsafe { File::from_raw_fd(socket_fd) };
let mut socket = unsafe { File::from_raw_fd(socket_fd as RawFd) };
let irq_fd = syscall::open(
&format!("irq:{}", irq),
syscall::O_RDWR | syscall::O_NONBLOCK
).expect("ahcid: failed to open irq file");
let mut irq_file = unsafe { File::from_raw_fd(irq_fd) };
let mut irq_file = unsafe { File::from_raw_fd(irq_fd as RawFd) };
let mut event_file = File::open("event:").expect("ahcid: failed to open event file");
@@ -64,8 +64,9 @@ fn main() {
let (hba_mem, disks) = ahci::disks(address, &name);
let mut scheme = DiskScheme::new(scheme_name, hba_mem, disks);
let mut mounted = true;
let mut todo = Vec::new();
loop {
while mounted {
let mut event = Event::default();
if event_file.read(&mut event).expect("ahcid: failed to read event file") == 0 {
break;
@@ -73,8 +74,17 @@ fn main() {
if event.id == socket_fd {
loop {
let mut packet = Packet::default();
if socket.read(&mut packet).expect("ahcid: failed to read disk scheme") == 0 {
break;
match socket.read(&mut packet) {
Ok(0) => {
mounted = false;
break;
},
Ok(_) => (),
Err(err) => if err.kind() == ErrorKind::WouldBlock {
break;
} else {
panic!("ahcid: failed to read disk scheme: {}", err);
}
}
if let Some(a) = scheme.handle(&packet) {
@@ -113,11 +123,18 @@ fn main() {
if let Some(a) = scheme.handle(&todo[i]) {
let mut packet = todo.remove(i);
packet.a = a;
socket.write(&mut packet).expect("ahcid: failed to write disk scheme");
socket.write(&packet).expect("ahcid: failed to write disk scheme");
} else {
i += 1;
}
}
if ! mounted {
for mut packet in todo.drain(..) {
packet.a = Error::mux(Err(Error::new(ENODEV)));
socket.write(&packet).expect("ahcid: failed to write disk scheme");
}
}
}
}
unsafe { let _ = syscall::physunmap(address); }
+8 -8
View File
@@ -7,8 +7,8 @@ use syscall::{
Io, SchemeBlockMut, Stat, MODE_DIR, MODE_FILE, O_DIRECTORY,
O_STAT, SEEK_CUR, SEEK_END, SEEK_SET};
use ahci::Disk;
use ahci::hba::HbaMem;
use crate::ahci::Disk;
use crate::ahci::hba::HbaMem;
#[derive(Clone)]
enum Handle {
@@ -19,13 +19,13 @@ enum Handle {
pub struct DiskScheme {
scheme_name: String,
hba_mem: &'static mut HbaMem,
disks: Box<[Box<Disk>]>,
disks: Box<[Box<dyn Disk>]>,
handles: BTreeMap<usize, Handle>,
next_id: usize
}
impl DiskScheme {
pub fn new(scheme_name: String, hba_mem: &'static mut HbaMem, disks: Vec<Box<Disk>>) -> DiskScheme {
pub fn new(scheme_name: String, hba_mem: &'static mut HbaMem, disks: Vec<Box<dyn Disk>>) -> DiskScheme {
DiskScheme {
scheme_name: scheme_name,
hba_mem: hba_mem,
@@ -117,7 +117,7 @@ impl SchemeBlockMut for DiskScheme {
Ok(Some(0))
},
Handle::Disk(number, _) => {
let mut disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
stat.st_mode = MODE_FILE;
stat.st_size = disk.size();
Ok(Some(0))
@@ -168,7 +168,7 @@ impl SchemeBlockMut for DiskScheme {
Ok(Some(count))
},
Handle::Disk(number, ref mut size) => {
let mut disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
let blk_len = disk.block_length()?;
if let Some(count) = disk.read((*size as u64)/(blk_len as u64), buf)? {
*size += count;
@@ -186,7 +186,7 @@ impl SchemeBlockMut for DiskScheme {
Err(Error::new(EBADF))
},
Handle::Disk(number, ref mut size) => {
let mut disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
let blk_len = disk.block_length()?;
if let Some(count) = disk.write((*size as u64)/(blk_len as u64), buf)? {
*size += count;
@@ -212,7 +212,7 @@ impl SchemeBlockMut for DiskScheme {
Ok(Some(*size))
},
Handle::Disk(number, ref mut size) => {
let mut disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
let len = disk.size() as usize;
*size = match whence {
SEEK_SET => cmp::min(len, pos),
+2 -1
View File
@@ -1,9 +1,10 @@
[package]
name = "alxd"
version = "0.1.0"
edition = "2018"
[dependencies]
bitflags = "0.7"
netutils = { git = "https://gitlab.redox-os.org/redox-os/netutils.git" }
netutils = { git = "https://gitlab.redox-os.org/redox-os/netutils.git", branch = "redox-unix" }
redox_event = { git = "https://gitlab.redox-os.org/redox-os/event.git" }
redox_syscall = "0.1"
+3 -3
View File
@@ -1721,7 +1721,7 @@ impl Alx {
}
unsafe fn open(&mut self) -> usize {
let mut err: usize = 0;
let _err: usize = 0;
macro_rules! goto_out {
() => {{
@@ -1805,7 +1805,7 @@ impl scheme::SchemeMut for Alx {
Ok(id)
}
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
fn read(&mut self, id: usize, _buf: &mut [u8]) -> Result<usize> {
/*
let head = unsafe { self.read(RDH) };
let mut tail = unsafe { self.read(RDT) };
@@ -1842,7 +1842,7 @@ impl scheme::SchemeMut for Alx {
}
}
fn write(&mut self, _id: usize, buf: &[u8]) -> Result<usize> {
fn write(&mut self, _id: usize, _buf: &[u8]) -> Result<usize> {
/*
loop {
let head = unsafe { self.read(TDH) };
+3 -3
View File
@@ -12,7 +12,7 @@ use std::cell::RefCell;
use std::env;
use std::fs::File;
use std::io::{Read, Write, Result};
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::sync::Arc;
use event::EventQueue;
@@ -39,7 +39,7 @@ fn main() {
if unsafe { syscall::clone(0).unwrap() } == 0
{
let socket_fd = syscall::open(":network", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK).expect("alxd: failed to create network scheme");
let socket = Arc::new(RefCell::new(unsafe { File::from_raw_fd(socket_fd) }));
let socket = Arc::new(RefCell::new(unsafe { File::from_raw_fd(socket_fd as RawFd) }));
let mut irq_file = File::open(format!("irq:{}", irq)).expect("alxd: failed to open IRQ file");
@@ -85,7 +85,7 @@ fn main() {
}).expect("alxd: failed to catch events on IRQ file");
let socket_packet = socket.clone();
event_queue.add(socket_fd, move |_event| -> Result<Option<usize>> {
event_queue.add(socket_fd as RawFd, move |_event| -> Result<Option<usize>> {
loop {
let mut packet = Packet::default();
if socket_packet.borrow_mut().read(&mut packet)? == 0 {
+2 -1
View File
@@ -1,7 +1,8 @@
[package]
name = "bgad"
version = "0.1.0"
edition = "2018"
[dependencies]
orbclient = "0.3"
orbclient = "0.3.27"
redox_syscall = "0.1"
+5 -3
View File
@@ -10,8 +10,8 @@ use syscall::iopl;
use syscall::data::Packet;
use syscall::scheme::SchemeMut;
use bga::Bga;
use scheme::BgaScheme;
use crate::bga::Bga;
use crate::scheme::BgaScheme;
mod bga;
mod scheme;
@@ -45,7 +45,9 @@ fn main() {
loop {
let mut packet = Packet::default();
socket.read(&mut packet).expect("bgad: failed to read events from bga scheme");
if socket.read(&mut packet).expect("bgad: failed to read events from bga scheme") == 0 {
break;
}
scheme.handle(&mut packet);
socket.write(&packet).expect("bgad: failed to write responses to bga scheme");
}
+1 -1
View File
@@ -5,7 +5,7 @@ use std::str;
use syscall::{Error, Result, SchemeMut, EACCES, EINVAL, MODE_CHR};
use syscall::data::Stat;
use bga::Bga;
use crate::bga::Bga;
pub struct BgaScheme {
pub bga: Bga,
+2 -1
View File
@@ -1,9 +1,10 @@
[package]
name = "e1000d"
version = "0.1.0"
edition = "2018"
[dependencies]
bitflags = "0.7"
netutils = { git = "https://gitlab.redox-os.org/redox-os/netutils.git" }
netutils = { git = "https://gitlab.redox-os.org/redox-os/netutils.git", branch = "redox-unix" }
redox_event = { git = "https://gitlab.redox-os.org/redox-os/event.git" }
redox_syscall = "0.1"
+125 -93
View File
@@ -1,8 +1,8 @@
use std::{cmp, mem, ptr, slice, thread};
use std::collections::BTreeMap;
use std::{cmp, mem, ptr, slice, thread};
use netutils::setcfg;
use syscall::error::{Error, EACCES, EBADF, EINVAL, EWOULDBLOCK, Result};
use syscall::error::{Error, Result, EACCES, EBADF, EINVAL, EWOULDBLOCK};
use syscall::flag::O_NONBLOCK;
use syscall::io::Dma;
use syscall::scheme::SchemeBlockMut;
@@ -55,7 +55,7 @@ const RDT: u32 = 0x2818;
const RAL0: u32 = 0x5400;
const RAH0: u32 = 0x5404;
#[derive(Debug)]
#[derive(Debug, Copy, Clone)]
#[repr(packed)]
struct Rd {
buffer: u64,
@@ -78,7 +78,7 @@ const TDLEN: u32 = 0x3808;
const TDH: u32 = 0x3810;
const TDT: u32 = 0x3818;
#[derive(Debug)]
#[derive(Debug, Copy, Clone)]
#[repr(packed)]
struct Td {
buffer: u64,
@@ -98,12 +98,20 @@ pub struct Intel8254x {
base: usize,
receive_buffer: [Dma<[u8; 16384]>; 16],
receive_ring: Dma<[Rd; 16]>,
receive_index: usize,
transmit_buffer: [Dma<[u8; 16384]>; 16],
transmit_ring: Dma<[Td; 16]>,
transmit_ring_free: usize,
transmit_index: usize,
transmit_clean_index: usize,
next_id: usize,
pub handles: BTreeMap<usize, usize>,
}
fn wrap_ring(index: usize, ring_size: usize) -> usize {
(index + 1) & (ring_size - 1)
}
impl SchemeBlockMut for Intel8254x {
fn open(&mut self, _path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result<Option<usize>> {
if uid == 0 {
@@ -116,7 +124,7 @@ impl SchemeBlockMut for Intel8254x {
}
fn dup(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
if ! buf.is_empty() {
if !buf.is_empty() {
return Err(Error::new(EINVAL));
}
@@ -132,31 +140,20 @@ impl SchemeBlockMut for Intel8254x {
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
let flags = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let head = unsafe { self.read_reg(RDH) };
let mut tail = unsafe { self.read_reg(RDT) };
let desc = unsafe { &mut *(self.receive_ring.as_ptr().add(self.receive_index) as *mut Rd) };
tail += 1;
if tail >= self.receive_ring.len() as u32 {
tail = 0;
}
if desc.status & RD_DD == RD_DD {
desc.status = 0;
if tail != head {
let rd = unsafe { &mut * (self.receive_ring.as_ptr().offset(tail as isize) as *mut Rd) };
if rd.status & RD_DD == RD_DD {
rd.status = 0;
let data = &self.receive_buffer[self.receive_index][..desc.length as usize];
let data = &self.receive_buffer[tail as usize][.. rd.length as usize];
let i = cmp::min(buf.len(), data.len());
buf[..i].copy_from_slice(&data[..i]);
let mut i = 0;
while i < buf.len() && i < data.len() {
buf[i] = data[i];
i += 1;
}
unsafe { self.write_reg(RDT, self.receive_index as u32) };
self.receive_index = wrap_ring(self.receive_index, self.receive_ring.len());
unsafe { self.write_reg(RDT, tail) };
return Ok(Some(i));
}
return Ok(Some(i));
}
if flags & O_NONBLOCK == O_NONBLOCK {
@@ -169,44 +166,56 @@ impl SchemeBlockMut for Intel8254x {
fn write(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
let _flags = self.handles.get(&id).ok_or(Error::new(EBADF))?;
loop {
let head = unsafe { self.read_reg(TDH) };
let mut tail = unsafe { self.read_reg(TDT) };
let old_tail = tail;
if self.transmit_ring_free == 0 {
loop {
let desc = unsafe {
&*(self.transmit_ring.as_ptr().add(self.transmit_clean_index) as *const Td)
};
tail += 1;
if tail >= self.transmit_ring.len() as u32 {
tail = 0;
}
if tail != head {
let td = unsafe { &mut * (self.transmit_ring.as_ptr().offset(old_tail as isize) as *mut Td) };
td.cso = 0;
td.command = TD_CMD_EOP | TD_CMD_IFCS | TD_CMD_RS;
td.status = 0;
td.css = 0;
td.special = 0;
td.length = (cmp::min(buf.len(), 0x3FFF)) as u16;
let mut data = unsafe { slice::from_raw_parts_mut(self.transmit_buffer[old_tail as usize].as_ptr() as *mut u8, td.length as usize) };
let mut i = 0;
while i < buf.len() && i < data.len() {
data[i] = buf[i];
i += 1;
if desc.status != 0 {
self.transmit_clean_index =
wrap_ring(self.transmit_clean_index, self.transmit_ring.len());
self.transmit_ring_free += 1;
} else if self.transmit_ring_free > 0 {
break;
}
unsafe { self.write_reg(TDT, tail) };
while td.status == 0 {
thread::yield_now();
if self.transmit_ring_free >= self.transmit_ring.len() {
break;
}
return Ok(Some(i));
}
}
let desc =
unsafe { &mut *(self.transmit_ring.as_ptr().add(self.transmit_index) as *mut Td) };
let data = unsafe {
slice::from_raw_parts_mut(
self.transmit_buffer[self.transmit_index].as_ptr() as *mut u8,
cmp::min(buf.len(), self.transmit_buffer[self.transmit_index].len()) as usize,
)
};
let i = cmp::min(buf.len(), data.len());
data[..i].copy_from_slice(&buf[..i]);
desc.cso = 0;
desc.command = TD_CMD_EOP | TD_CMD_IFCS | TD_CMD_RS;
desc.status = 0;
desc.css = 0;
desc.special = 0;
desc.length = (cmp::min(
buf.len(),
self.transmit_buffer[self.transmit_index].len() - 1,
)) as u16;
self.transmit_index = wrap_ring(self.transmit_index, self.transmit_ring.len());
self.transmit_ring_free -= 1;
unsafe { self.write_reg(TDT, self.transmit_index as u32) };
Ok(Some(i))
}
fn fevent(&mut self, id: usize, _flags: usize) -> Result<Option<usize>> {
@@ -239,20 +248,29 @@ impl SchemeBlockMut for Intel8254x {
impl Intel8254x {
pub unsafe fn new(base: usize) -> Result<Self> {
#[rustfmt::skip]
let mut module = Intel8254x {
base: base,
receive_buffer: [Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?],
receive_buffer: [
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
],
receive_ring: Dma::zeroed()?,
transmit_buffer: [Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?],
transmit_buffer: [
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
],
receive_index: 0,
transmit_ring: Dma::zeroed()?,
transmit_ring_free: 16,
transmit_index: 0,
transmit_clean_index: 0,
next_id: 0,
handles: BTreeMap::new()
handles: BTreeMap::new(),
};
module.init();
@@ -266,19 +284,10 @@ impl Intel8254x {
}
pub fn next_read(&self) -> usize {
let head = unsafe { self.read_reg(RDH) };
let mut tail = unsafe { self.read_reg(RDT) };
let desc = unsafe { &*(self.receive_ring.as_ptr().add(self.receive_index) as *const Rd) };
tail += 1;
if tail >= self.receive_ring.len() as u32 {
tail = 0;
}
if tail != head {
let rd = unsafe { &* (self.receive_ring.as_ptr().offset(tail as isize) as *const Rd) };
if rd.status & RD_DD == RD_DD {
return rd.length as usize;
}
if desc.status & RD_DD == RD_DD {
return desc.length as usize;
}
0
@@ -324,14 +333,28 @@ impl Intel8254x {
let mac_low = self.read_reg(RAL0);
let mac_high = self.read_reg(RAH0);
let mac = [mac_low as u8,
(mac_low >> 8) as u8,
(mac_low >> 16) as u8,
(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]));
let _ = setcfg("mac", &format!("{:>02X}-{:>02X}-{:>02X}-{:>02X}-{:>02X}-{:>02X}\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]));
let mac = [
mac_low as u8,
(mac_low >> 8) as u8,
(mac_low >> 16) as u8,
(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]
)
);
let _ = setcfg(
"mac",
&format!(
"{:>02X}-{:>02X}-{:>02X}-{:>02X}-{:>02X}-{:>02X}\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
),
);
//
// MTA => 0;
@@ -344,7 +367,10 @@ impl Intel8254x {
self.write_reg(RDBAH, (self.receive_ring.physical() >> 32) as u32);
self.write_reg(RDBAL, self.receive_ring.physical() as u32);
self.write_reg(RDLEN, (self.receive_ring.len() * mem::size_of::<Rd>()) as u32);
self.write_reg(
RDLEN,
(self.receive_ring.len() * mem::size_of::<Rd>()) as u32,
);
self.write_reg(RDH, 0);
self.write_reg(RDT, self.receive_ring.len() as u32 - 1);
@@ -355,7 +381,10 @@ impl Intel8254x {
self.write_reg(TDBAH, (self.transmit_ring.physical() >> 32) as u32);
self.write_reg(TDBAL, self.transmit_ring.physical() as u32);
self.write_reg(TDLEN, (self.transmit_ring.len() * mem::size_of::<Td>()) as u32);
self.write_reg(
TDLEN,
(self.transmit_ring.len() * mem::size_of::<Td>()) as u32,
);
self.write_reg(TDH, 0);
self.write_reg(TDT, 0);
@@ -384,10 +413,13 @@ impl Intel8254x {
while self.read_reg(STATUS) & 2 != 2 {
print!(" - Waiting for link up: {:X}\n", self.read_reg(STATUS));
}
print!(" - Link is up with speed {}\n", match (self.read_reg(STATUS) >> 6) & 0b11 {
0b00 => "10 Mb/s",
0b01 => "100 Mb/s",
_ => "1000 Mb/s",
});
print!(
" - Link is up with speed {}\n",
match (self.read_reg(STATUS) >> 6) & 0b11 {
0b00 => "10 Mb/s",
0b01 => "100 Mb/s",
_ => "1000 Mb/s",
}
);
}
}
+105 -50
View File
@@ -7,17 +7,20 @@ extern crate syscall;
use std::cell::RefCell;
use std::env;
use std::fs::File;
use std::io::{Read, Write, Result};
use std::os::unix::io::{AsRawFd, FromRawFd};
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, SchemeBlockMut, PHYSMAP_NO_CACHE, PHYSMAP_WRITE};
use syscall::error::EWOULDBLOCK;
pub mod device;
fn handle_update(socket: &mut File, device: &mut device::Intel8254x, todo: &mut Vec<Packet>) -> Result<()> {
fn handle_update(
socket: &mut File,
device: &mut device::Intel8254x,
todo: &mut Vec<Packet>,
) -> Result<bool> {
// Handle any blocked packets
let mut i = 0;
while i < todo.len() {
@@ -33,8 +36,16 @@ fn handle_update(socket: &mut File, device: &mut device::Intel8254x, todo: &mut
// Check that the socket is empty
loop {
let mut packet = Packet::default();
if socket.read(&mut packet)? == 0 {
break;
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) {
@@ -45,7 +56,7 @@ fn handle_update(socket: &mut File, device: &mut device::Intel8254x, todo: &mut
}
}
Ok(())
Ok(false)
}
fn main() {
@@ -60,20 +71,36 @@ fn main() {
let irq_str = args.next().expect("e1000d: no irq provided");
let irq = irq_str.parse::<u8>().expect("e1000d: failed to parse irq");
print!("{}", format!(" + E1000 {} on: {:X} IRQ: {}\n", name, bar, irq));
print!(
"{}",
format!(" + E1000 {} on: {:X} IRQ: {}\n", 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("e1000d: failed to create network scheme");
let socket = Arc::new(RefCell::new(unsafe { File::from_raw_fd(socket_fd) }));
let socket_fd = syscall::open(
":network",
syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK,
)
.expect("e1000d: failed to create network scheme");
let socket = Arc::new(RefCell::new(unsafe {
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 mut irq_file =
File::open(format!("irq:{}", irq)).expect("e1000d: failed to open IRQ file");
let address = unsafe { syscall::physmap(bar, 128*1024, PHYSMAP_WRITE | PHYSMAP_NO_CACHE).expect("e1000d: failed to map address") };
let address = unsafe {
syscall::physmap(bar, 128 * 1024, PHYSMAP_WRITE | PHYSMAP_NO_CACHE)
.expect("e1000d: failed to map address")
};
{
let device = Arc::new(RefCell::new(unsafe { device::Intel8254x::new(address).expect("e1000d: failed to allocate device") }));
let device = Arc::new(RefCell::new(unsafe {
device::Intel8254x::new(address).expect("e1000d: failed to allocate device")
}));
let mut event_queue = EventQueue::<usize>::new().expect("e1000d: failed to create event queue");
let mut event_queue =
EventQueue::<usize>::new().expect("e1000d: failed to create event queue");
syscall::setrens(0, 0).expect("e1000d: failed to enter null namespace");
@@ -82,62 +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<Option<usize>> {
let mut irq = [0; 8];
irq_file.read(&mut irq)?;
if unsafe { device_irq.borrow().irq() } {
irq_file.write(&mut irq)?;
event_queue
.add(
irq_file.as_raw_fd(),
move |_event| -> Result<Option<usize>> {
let mut irq = [0; 8];
irq_file.read(&mut irq)?;
if unsafe { device_irq.borrow().irq() } {
irq_file.write(&mut irq)?;
handle_update(&mut socket_irq.borrow_mut(), &mut device_irq.borrow_mut(), &mut todo_irq.borrow_mut())?;
if handle_update(
&mut socket_irq.borrow_mut(),
&mut device_irq.borrow_mut(),
&mut todo_irq.borrow_mut(),
)? {
return Ok(Some(0));
}
let next_read = device_irq.borrow().next_read();
if next_read > 0 {
return Ok(Some(next_read));
}
}
Ok(None)
}).expect("e1000d: failed to catch events on IRQ file");
let next_read = device_irq.borrow().next_read();
if next_read > 0 {
return Ok(Some(next_read));
}
}
Ok(None)
},
)
.expect("e1000d: failed to catch events on IRQ file");
let device_packet = device.clone();
let socket_packet = socket.clone();
event_queue.add(socket_fd, move |_event| -> Result<Option<usize>> {
handle_update(&mut socket_packet.borrow_mut(), &mut device_packet.borrow_mut(), &mut todo.borrow_mut());
event_queue
.add(socket_fd as RawFd, move |_event| -> Result<Option<usize>> {
if handle_update(
&mut socket_packet.borrow_mut(),
&mut device_packet.borrow_mut(),
&mut todo.borrow_mut(),
)? {
return Ok(Some(0));
}
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("e1000d: failed to catch events on scheme file");
Ok(None)
})
.expect("e1000d: 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("e1000d: failed to write event");
}
};
for event_count in event_queue.trigger_all(event::Event {
fd: 0,
flags: 0,
}).expect("e1000d: failed to trigger events") {
for event_count in event_queue
.trigger_all(event::Event { fd: 0, flags: 0 })
.expect("e1000d: failed to trigger events")
{
send_events(event_count);
}
loop {
let event_count = event_queue.run().expect("e1000d: 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);
}
}
}
+1
View File
@@ -1,6 +1,7 @@
[package]
name = "ihdad"
version = "0.1.0"
edition = "2018"
[dependencies]
bitflags = "0.7"
+5 -5
View File
@@ -790,21 +790,21 @@ impl IntelHDA {
for i in 0..iss {
if ((sis >> i) & 1 ) == 1 {
let mut input = self.get_input_stream_descriptor(i).unwrap();
let input = self.get_input_stream_descriptor(i).unwrap();
input.clear_interrupts();
}
}
for i in 0..oss {
if ((sis >> (i + iss)) & 1 ) == 1 {
let mut output = self.get_output_stream_descriptor(i).unwrap();
let output = self.get_output_stream_descriptor(i).unwrap();
output.clear_interrupts();
}
}
for i in 0..bss {
if ((sis >> (i + iss + oss)) & 1 ) == 1 {
let mut bid = self.get_bidirectional_stream_descriptor(i).unwrap();
let bid = self.get_bidirectional_stream_descriptor(i).unwrap();
bid.clear_interrupts();
}
}
@@ -897,7 +897,7 @@ impl SchemeBlockMut for IntelHDA {
fn write(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
let index = {
let mut handles = self.handles.lock();
let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let _handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
0
};
@@ -926,7 +926,7 @@ impl SchemeBlockMut for IntelHDA {
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
let mut handles = self.handles.lock();
let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let _handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let mut i = 0;
let scheme_path = b"hda:";
+2 -2
View File
@@ -295,7 +295,7 @@ impl StreamBuffer {
syscall::physalloc(block_length * block_count)
} {
Ok(phys) => phys,
Err(err) => {
Err(_err) => {
return Err("Could not allocate physical memory for buffer.");
}
};
@@ -304,7 +304,7 @@ impl StreamBuffer {
syscall::physmap(phys, block_length * block_count, PHYSMAP_WRITE | PHYSMAP_NO_CACHE)
} {
Ok(addr) => addr,
Err(err) => {
Err(_err) => {
unsafe {
syscall::physfree(phys, block_length * block_count);
}
+15 -5
View File
@@ -8,8 +8,8 @@ extern crate event;
use std::{env, usize};
use std::fs::File;
use std::io::{Read, Write, Result};
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::io::{ErrorKind, Read, Write, Result};
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use syscall::{PHYSMAP_NO_CACHE, PHYSMAP_WRITE, Packet, SchemeBlockMut};
use std::cell::RefCell;
use std::sync::Arc;
@@ -55,7 +55,7 @@ fn main() {
let device = Arc::new(RefCell::new(unsafe { hda::IntelHDA::new(address, vend_prod).expect("ihdad: failed to allocate device") }));
let socket_fd = syscall::open(":hda", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK).expect("IHDA: failed to create hda scheme");
let socket = Arc::new(RefCell::new(unsafe { File::from_raw_fd(socket_fd) }));
let socket = Arc::new(RefCell::new(unsafe { File::from_raw_fd(socket_fd as RawFd) }));
let mut event_queue = EventQueue::<usize>::new().expect("IHDA: Could not create event queue.");
@@ -100,8 +100,14 @@ fn main() {
event_queue.add(socket_fd, move |_event| -> Result<Option<usize>> {
loop {
let mut packet = Packet::default();
if socket_packet.borrow_mut().read(&mut packet)? == 0 {
break;
match socket_packet.borrow_mut().read(&mut packet) {
Ok(0) => return Ok(Some(0)),
Ok(_) => (),
Err(err) => if err.kind() == ErrorKind::WouldBlock {
break;
} else {
return Err(err);
}
}
if let Some(a) = device.borrow_mut().handle(&mut packet) {
@@ -143,6 +149,10 @@ fn main() {
//device_loop.borrow_mut().handle_interrupts();
}
let event_count = event_queue.run().expect("IHDA: failed to handle events");
if event_count == 0 {
//TODO: Handle todo
break;
}
socket.borrow_mut().write(&Packet {
id: 0,
+1 -1
View File
@@ -22,7 +22,7 @@ vendor = 33006
device = 48879
command = ["bgad", "$NAME", "$BAR0"]
# nvmed
#nvmed
[[drivers]]
name = "NVME storage"
class = 1
+1 -1
Submodule ixgbed updated: 26c0142179...97a1efdd22
+1
View File
@@ -1,6 +1,7 @@
[package]
name = "nvmed"
version = "0.1.0"
edition = "2018"
[dependencies]
bitflags = "0.7"
+74 -46
View File
@@ -1,4 +1,3 @@
//#![deny(warnings)]
#![feature(asm)]
extern crate bitflags;
@@ -7,24 +6,16 @@ extern crate syscall;
use std::{env, usize};
use std::fs::File;
use std::io::{Read, Write};
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use syscall::{EVENT_READ, PHYSMAP_NO_CACHE, PHYSMAP_WRITE, Event, Packet, Result, Scheme};
use std::io::{ErrorKind, Read, Write};
use std::os::unix::io::{RawFd, FromRawFd};
use syscall::{EVENT_READ, PHYSMAP_NO_CACHE, PHYSMAP_WRITE, Event, Packet, Result, SchemeBlockMut};
use self::nvme::Nvme;
use self::scheme::DiskScheme;
mod nvme;
/*
fn create_scheme_fallback<'a>(name: &'a str, fallback: &'a str) -> Result<(&'a str, RawFd)> {
if let Ok(fd) = syscall::open(&format!(":{}", name), syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK) {
Ok((name, fd))
} else {
syscall::open(&format!(":{}", fallback), syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK)
.map(|fd| (fallback, fd))
}
}
*/
mod scheme;
fn main() {
let mut args = env::args().skip(1);
@@ -42,50 +33,87 @@ fn main() {
// Daemonize
if unsafe { syscall::clone(0).unwrap() } == 0 {
let address = unsafe { syscall::physmap(bar, 4096, PHYSMAP_WRITE | PHYSMAP_NO_CACHE).expect("nvmed: failed to map address") };
//TODO: Figure out correct size of mapping, not just 256 * 1024
let address = unsafe { syscall::physmap(bar, 256 * 1024, PHYSMAP_WRITE | PHYSMAP_NO_CACHE).expect("nvmed: failed to map address") };
{
let mut nvme = Nvme::new(address);
nvme.init();
/*
let (_scheme_name, socket_fd) = create_scheme_fallback("disk", &name).expect("nvmed: failed to create disk scheme");
let mut socket = unsafe { File::from_raw_fd(socket_fd) };
syscall::fevent(socket_fd, EVENT_READ).expect("nvmed: failed to fevent disk scheme");
let event_fd = syscall::open("event:", syscall::O_RDWR | syscall::O_CLOEXEC)
.expect("nvmed: failed to open event queue");
let mut event_file = unsafe { File::from_raw_fd(event_fd as RawFd) };
let mut irq_file = File::open(&format!("irq:{}", irq)).expect("nvmed: failed to open irq file");
let irq_fd = irq_file.as_raw_fd();
syscall::fevent(irq_fd, EVENT_READ).expect("nvmed: failed to fevent irq file");
let irq_fd = syscall::open(
&format!("irq:{}", irq),
syscall::O_RDWR | syscall::O_NONBLOCK | syscall::O_CLOEXEC
).expect("nvmed: failed to open irq file");
syscall::write(event_fd, &syscall::Event {
id: irq_fd,
flags: syscall::EVENT_READ,
data: 0,
}).expect("nvmed: failed to watch irq file events");
let mut irq_file = unsafe { File::from_raw_fd(irq_fd as RawFd) };
let mut event_file = File::open("event:").expect("nvmed: failed to open event file");
let scheme = DiskScheme::new(nvme::disks(address, &name));
let scheme_name = format!("disk/{}", name);
let socket_fd = syscall::open(
&format!(":{}", scheme_name),
syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK | syscall::O_CLOEXEC
).expect("nvmed: failed to create disk scheme");
syscall::write(event_fd, &syscall::Event {
id: socket_fd,
flags: syscall::EVENT_READ,
data: 1,
}).expect("nvmed: failed to watch disk scheme events");
let mut socket_file = unsafe { File::from_raw_fd(socket_fd as RawFd) };
syscall::setrens(0, 0).expect("nvmed: failed to enter null namespace");
loop {
let mut nvme = Nvme::new(address).expect("nvmed: failed to allocate driver data");
let namespaces = unsafe { nvme.init() };
let mut scheme = DiskScheme::new(scheme_name, nvme, namespaces);
let mut todo = Vec::new();
'events: loop {
let mut event = Event::default();
if event_file.read(&mut event).expect("nvmed: failed to read event file") == 0 {
if event_file.read(&mut event).expect("nvmed: failed to read event queue") == 0 {
break;
}
if event.id == socket_fd {
loop {
let mut packet = Packet::default();
if socket.read(&mut packet).expect("nvmed: failed to read disk scheme") == 0 {
break;
match event.data {
0 => {
let mut irq = [0; 8];
if irq_file.read(&mut irq).expect("nvmed: failed to read irq file") >= irq.len() {
if scheme.irq() {
irq_file.write(&irq).expect("nvmed: failed to write irq file");
}
}
scheme.handle(&mut packet);
socket.write(&mut packet).expect("nvmed: failed to write disk scheme");
},
1 => loop {
let mut packet = Packet::default();
match socket_file.read(&mut packet) {
Ok(0) => break 'events,
Ok(_) => (),
Err(err) => match err.kind() {
ErrorKind::WouldBlock => break,
_ => Err(err).expect("nvmed: failed to read disk scheme"),
}
}
todo.push(packet);
},
unknown => {
panic!("nvmed: unknown event data {}", unknown);
},
}
let mut i = 0;
while i < todo.len() {
if let Some(a) = scheme.handle(&todo[i]) {
let mut packet = todo.remove(i);
packet.a = a;
socket_file.write(&packet).expect("nvmed: failed to write disk scheme");
} else {
i += 1;
}
} else if event.id == irq_fd {
let mut irq = [0; 8];
if irq_file.read(&mut irq).expect("nvmed: failed to read irq file") >= irq.len() {
//TODO : Test for IRQ
//irq_file.write(&irq).expect("nvmed: failed to write irq file");
}
} else {
println!("Unknown event {}", event.id);
}
}
*/
//TODO: destroy NVMe stuff
}
unsafe { let _ = syscall::physunmap(address); }
}
+537 -27
View File
@@ -1,5 +1,9 @@
use syscall::io::{Io, Mmio};
use std::thread;
use std::collections::BTreeMap;
use syscall::io::{Dma, Io, Mmio};
use syscall::error::{Error, Result, EINVAL};
#[derive(Clone, Copy)]
#[repr(packed)]
pub struct NvmeCmd {
/// Opcode
@@ -31,41 +35,142 @@ pub struct NvmeCmd {
}
impl NvmeCmd {
pub fn read(cid: u16, lba: u64, count: u16, dst: u64) -> Self {
NvmeCmd {
opcode: 2,
flags: 1 << 6,
pub fn create_io_completion_queue(cid: u16, qid: u16, ptr: usize, size: u16) -> Self {
Self {
opcode: 5,
flags: 0,
cid: cid,
nsid: 0xFFFFFFFF,
nsid: 0,
_rsvd: 0,
mptr: 0,
dptr: [dst, (count as u64) << 9],
cdw10: lba as u32,
cdw11: (lba >> 32) as u32,
cdw12: count as u32,
dptr: [ptr as u64, 0],
cdw10: ((size as u32) << 16) | (qid as u32),
cdw11: 1 /* Physically Contiguous */, //TODO: IV, IEN
cdw12: 0,
cdw13: 0,
cdw14: 0,
cdw15: 0,
}
}
pub fn write(cid: u16, lba: u64, count: u16, src: u64) -> Self {
NvmeCmd {
pub fn create_io_submission_queue(cid: u16, qid: u16, ptr: usize, size: u16, cqid: u16) -> Self {
Self {
opcode: 1,
flags: 1 << 6,
flags: 0,
cid: cid,
nsid: 0xFFFFFFFF,
nsid: 0,
_rsvd: 0,
mptr: 0,
dptr: [src, (count as u64) << 9],
cdw10: lba as u32,
cdw11: (lba >> 32) as u32,
cdw12: count as u32,
dptr: [ptr as u64, 0],
cdw10: ((size as u32) << 16) | (qid as u32),
cdw11: ((cqid as u32) << 16) | 1 /* Physically Contiguous */, //TODO: QPRIO
cdw12: 0, //TODO: NVMSETID
cdw13: 0,
cdw14: 0,
cdw15: 0,
}
}
pub fn identify_namespace(cid: u16, ptr: usize, nsid: u32) -> Self {
Self {
opcode: 6,
flags: 0,
cid: cid,
nsid: nsid,
_rsvd: 0,
mptr: 0,
dptr: [ptr as u64, 0],
cdw10: 0,
cdw11: 0,
cdw12: 0,
cdw13: 0,
cdw14: 0,
cdw15: 0,
}
}
pub fn identify_controller(cid: u16, ptr: usize) -> Self {
Self {
opcode: 6,
flags: 0,
cid: cid,
nsid: 0,
_rsvd: 0,
mptr: 0,
dptr: [ptr as u64, 0],
cdw10: 1,
cdw11: 0,
cdw12: 0,
cdw13: 0,
cdw14: 0,
cdw15: 0,
}
}
pub fn identify_namespace_list(cid: u16, ptr: usize, base: u32) -> Self {
Self {
opcode: 6,
flags: 0,
cid: cid,
nsid: base,
_rsvd: 0,
mptr: 0,
dptr: [ptr as u64, 0],
cdw10: 2,
cdw11: 0,
cdw12: 0,
cdw13: 0,
cdw14: 0,
cdw15: 0,
}
}
pub fn io_read(cid: u16, nsid: u32, lba: u64, blocks_1: u16, ptr0: u64, ptr1: u64) -> Self {
Self {
opcode: 2,
flags: 1 << 6,
cid: cid,
nsid: nsid,
_rsvd: 0,
mptr: 0,
dptr: [ptr0, ptr1],
cdw10: lba as u32,
cdw11: (lba >> 32) as u32,
cdw12: blocks_1 as u32,
cdw13: 0,
cdw14: 0,
cdw15: 0,
}
}
pub fn io_write(cid: u16, nsid: u32, lba: u64, blocks_1: u16, ptr0: u64, ptr1: u64) -> Self {
Self {
opcode: 1,
flags: 1 << 6,
cid: cid,
nsid: nsid,
_rsvd: 0,
mptr: 0,
dptr: [ptr0, ptr1],
cdw10: lba as u32,
cdw11: (lba >> 32) as u32,
cdw12: blocks_1 as u32,
cdw13: 0,
cdw14: 0,
cdw15: 0,
}
}
}
#[derive(Clone, Copy, Debug)]
#[repr(packed)]
pub struct NvmeComp {
command_specific: u32,
_rsvd: u32,
sq_head: u16,
sq_id: u16,
cid: u16,
status: u16,
}
#[repr(packed)]
@@ -98,19 +203,424 @@ pub struct NvmeRegs {
cmbsz: Mmio<u32>,
}
pub struct Nvme {
regs: &'static mut NvmeRegs
pub struct NvmeCmdQueue {
data: Dma<[NvmeCmd; 64]>,
i: usize,
}
impl Nvme {
pub fn new(address: usize) -> Self {
Nvme {
regs: unsafe { &mut *(address as *mut NvmeRegs) }
impl NvmeCmdQueue {
fn new() -> Result<Self> {
Ok(Self {
data: Dma::zeroed()?,
i: 0,
})
}
fn submit(&mut self, entry: NvmeCmd) -> usize {
self.data[self.i] = entry;
self.i = (self.i + 1) % self.data.len();
self.i
}
}
pub struct NvmeCompQueue {
data: Dma<[NvmeComp; 256]>,
i: usize,
phase: bool,
}
impl NvmeCompQueue {
fn new() -> Result<Self> {
Ok(Self {
data: Dma::zeroed()?,
i: 0,
phase: true,
})
}
fn complete(&mut self) -> Option<(usize, NvmeComp)> {
let entry = self.data[self.i];
if ((entry.status & 1) == 1) == self.phase {
self.i = (self.i + 1) % self.data.len();
if self.i == 0 {
self.phase = ! self.phase;
}
Some((self.i, entry))
} else {
None
}
}
pub fn init(&mut self) {
println!(" - CAPS: {:X}", self.regs.cap.read());
println!(" - VS: {:X}", self.regs.vs.read());
fn complete_spin(&mut self) -> (usize, NvmeComp) {
loop {
if let Some(some) = self.complete() {
return some;
} else {
thread::yield_now();
}
}
}
}
pub struct NvmeNamespace {
pub id: u32,
pub blocks: u64,
pub block_size: u64,
}
pub struct Nvme {
regs: &'static mut NvmeRegs,
submission_queues: [NvmeCmdQueue; 2],
completion_queues: [NvmeCompQueue; 2],
buffer: Dma<[u8; 512 * 4096]>, // 2MB of buffer
buffer_prp: Dma<[u64; 512]>, // 4KB of PRP for the buffer
}
impl Nvme {
pub fn new(address: usize) -> Result<Self> {
Ok(Nvme {
regs: unsafe { &mut *(address as *mut NvmeRegs) },
submission_queues: [NvmeCmdQueue::new()?, NvmeCmdQueue::new()?],
completion_queues: [NvmeCompQueue::new()?, NvmeCompQueue::new()?],
buffer: Dma::zeroed()?,
buffer_prp: Dma::zeroed()?,
})
}
unsafe fn doorbell(&mut self, index: usize) -> &'static mut Mmio<u32> {
let dstrd = ((self.regs.cap.read() >> 32) & 0b1111) as usize;
let addr = (self.regs as *mut _ as usize)
+ 0x1000
+ index * (4 << dstrd);
&mut *(addr as *mut Mmio<u32>)
}
pub unsafe fn submission_queue_tail(&mut self, qid: u16, tail: u16) {
self.doorbell(2 * (qid as usize)).write(tail as u32);
}
pub unsafe fn completion_queue_head(&mut self, qid: u16, head: u16) {
self.doorbell(2 * (qid as usize) + 1).write(head as u32)
}
pub unsafe fn init(&mut self) -> BTreeMap<u32, NvmeNamespace> {
for i in 0..self.buffer_prp.len() {
self.buffer_prp[i] = (self.buffer.physical() + i * 4096) as u64;
}
println!(" - CAPS: {:X}", self.regs.cap.read());
println!(" - VS: {:X}", self.regs.vs.read());
println!(" - CC: {:X}", self.regs.cc.read());
println!(" - CSTS: {:X}", self.regs.csts.read());
println!(" - Disable");
self.regs.cc.writef(1, false);
println!(" - Mask all interrupts");
self.regs.intms.write(0xFFFFFFFF);
for (qid, queue) in self.completion_queues.iter().enumerate() {
let data = &queue.data;
println!(" - completion queue {}: {:X}, {}", qid, data.physical(), data.len());
}
for (qid, queue) in self.submission_queues.iter().enumerate() {
let data = &queue.data;
println!(" - submission queue {}: {:X}, {}", qid, data.physical(), data.len());
}
{
let asq = &self.submission_queues[0];
let acq = &self.completion_queues[0];
self.regs.aqa.write(((acq.data.len() as u32 - 1) << 16) | (asq.data.len() as u32 - 1));
self.regs.asq.write(asq.data.physical() as u64);
self.regs.acq.write(acq.data.physical() as u64);
// Set IOCQES, IOSQES, AMS, MPS, and CSS
let mut cc = self.regs.cc.read();
cc &= 0xFF00000F;
cc |= (4 << 20) | (6 << 16);
self.regs.cc.write(cc);
}
println!(" - Enable");
self.regs.cc.writef(1, true);
println!(" - Waiting for ready");
while ! self.regs.csts.readf(1) {
thread::yield_now();
}
{
//TODO: Use buffer
let data: Dma<[u8; 4096]> = Dma::zeroed().unwrap();
println!(" - Attempting to identify controller");
{
let qid = 0;
let queue = &mut self.submission_queues[qid];
let cid = queue.i as u16;
let entry = NvmeCmd::identify_controller(
cid, data.physical()
);
let tail = queue.submit(entry);
self.submission_queue_tail(qid as u16, tail as u16);
}
println!(" - Waiting to identify controller");
{
let qid = 0;
let queue = &mut self.completion_queues[qid];
let (head, entry) = queue.complete_spin();
self.completion_queue_head(qid as u16, head as u16);
}
println!(" - Dumping identify controller");
let mut serial = String::new();
for &b in &data[4..24] {
if b == 0 {
break;
}
serial.push(b as char);
}
println!(" - Serial: {}", serial);
let mut model = String::new();
for &b in &data[24..64] {
if b == 0 {
break;
}
model.push(b as char);
}
println!(" - Model: {}", model);
let mut firmware = String::new();
for &b in &data[64..72] {
if b == 0 {
break;
}
firmware.push(b as char);
}
println!(" - Firmware: {}", firmware);
}
let mut nsids = Vec::new();
{
//TODO: Use buffer
let data: Dma<[u32; 1024]> = Dma::zeroed().unwrap();
println!(" - Attempting to retrieve namespace ID list");
{
let qid = 0;
let queue = &mut self.submission_queues[qid];
let cid = queue.i as u16;
let entry = NvmeCmd::identify_namespace_list(
cid, data.physical(), 0
);
let tail = queue.submit(entry);
self.submission_queue_tail(qid as u16, tail as u16);
}
println!(" - Waiting to retrieve namespace ID list");
{
let qid = 0;
let queue = &mut self.completion_queues[qid];
let (head, entry) = queue.complete_spin();
self.completion_queue_head(qid as u16, head as u16);
}
println!(" - Dumping namespace ID list");
for &nsid in data.iter() {
if nsid != 0 {
println!(" - {}", nsid);
nsids.push(nsid);
}
}
}
let mut namespaces = BTreeMap::new();
for &nsid in nsids.iter() {
//TODO: Use buffer
let data: Dma<[u8; 4096]> = Dma::zeroed().unwrap();
println!(" - Attempting to identify namespace {}", nsid);
{
let qid = 0;
let queue = &mut self.submission_queues[qid];
let cid = queue.i as u16;
let entry = NvmeCmd::identify_namespace(
cid, data.physical(), nsid
);
let tail = queue.submit(entry);
self.submission_queue_tail(qid as u16, tail as u16);
}
println!(" - Waiting to identify namespace {}", nsid);
{
let qid = 0;
let queue = &mut self.completion_queues[qid];
let (head, entry) = queue.complete_spin();
self.completion_queue_head(qid as u16, head as u16);
}
println!(" - Dumping identify namespace");
let size = *(data.as_ptr().offset(0) as *const u64);
println!(" - Size: {}", size);
let capacity = *(data.as_ptr().offset(8) as *const u64);
println!(" - Capacity: {}", capacity);
//TODO: Read block size
namespaces.insert(nsid, NvmeNamespace {
id: nsid,
blocks: size,
block_size: 512, // TODO
});
}
for io_qid in 1..self.completion_queues.len() {
let (ptr, len) = {
let queue = &self.completion_queues[io_qid];
(queue.data.physical(), queue.data.len())
};
println!(" - Attempting to create I/O completion queue {}", io_qid);
{
let qid = 0;
let queue = &mut self.submission_queues[qid];
let cid = queue.i as u16;
let entry = NvmeCmd::create_io_completion_queue(
cid, io_qid as u16, ptr, (len - 1) as u16
);
let tail = queue.submit(entry);
self.submission_queue_tail(qid as u16, tail as u16);
}
println!(" - Waiting to create I/O completion queue {}", io_qid);
{
let qid = 0;
let queue = &mut self.completion_queues[qid];
let (head, entry) = queue.complete_spin();
self.completion_queue_head(qid as u16, head as u16);
}
}
for io_qid in 1..self.submission_queues.len() {
let (ptr, len) = {
let queue = &self.submission_queues[io_qid];
(queue.data.physical(), queue.data.len())
};
println!(" - Attempting to create I/O submission queue {}", io_qid);
{
let qid = 0;
let queue = &mut self.submission_queues[qid];
let cid = queue.i as u16;
//TODO: Get completion queue ID through smarter mechanism
let entry = NvmeCmd::create_io_submission_queue(
cid, io_qid as u16, ptr, (len - 1) as u16, io_qid as u16
);
let tail = queue.submit(entry);
self.submission_queue_tail(qid as u16, tail as u16);
}
println!(" - Waiting to create I/O submission queue {}", io_qid);
{
let qid = 0;
let queue = &mut self.completion_queues[qid];
let (head, entry) = queue.complete_spin();
self.completion_queue_head(qid as u16, head as u16);
}
}
namespaces
}
unsafe fn namespace_rw(&mut self, nsid: u32, lba: u64, blocks_1: u16, write: bool) -> Result<()> {
//TODO: Get real block size
let block_size = 512;
let bytes = ((blocks_1 as u64) + 1) * block_size;
let (ptr0, ptr1) = if bytes <= 4096 {
(self.buffer_prp[0], 0)
} else if bytes <= 8192 {
(self.buffer_prp[0], self.buffer_prp[1])
} else {
(self.buffer_prp[0], (self.buffer_prp.physical() + 8) as u64)
};
{
let qid = 1;
let queue = &mut self.submission_queues[qid];
let cid = queue.i as u16;
let entry = if write {
NvmeCmd::io_write(
cid, nsid, lba, blocks_1, ptr0, ptr1
)
} else {
NvmeCmd::io_read(
cid, nsid, lba, blocks_1, ptr0, ptr1
)
};
let tail = queue.submit(entry);
self.submission_queue_tail(qid as u16, tail as u16);
}
{
let qid = 1;
let queue = &mut self.completion_queues[qid];
let (head, entry) = queue.complete_spin();
//TODO: Handle errors
self.completion_queue_head(qid as u16, head as u16);
}
Ok(())
}
pub unsafe fn namespace_read(&mut self, nsid: u32, mut lba: u64, buf: &mut [u8]) -> Result<Option<usize>> {
//TODO: Use interrupts
//TODO: Get real block size
let block_size = 512;
for chunk in buf.chunks_mut(self.buffer.len()) {
let blocks = (chunk.len() + block_size - 1) / block_size;
assert!(blocks > 0);
assert!(blocks <= 0x1_0000);
self.namespace_rw(nsid, lba, (blocks - 1) as u16, false)?;
chunk.copy_from_slice(&self.buffer[..chunk.len()]);
lba += blocks as u64;
}
Ok(Some(buf.len()))
}
pub unsafe fn namespace_write(&mut self, nsid: u32, mut lba: u64, buf: &[u8]) -> Result<Option<usize>> {
//TODO: Use interrupts
//TODO: Get real block size
let block_size = 512;
for chunk in buf.chunks(self.buffer.len()) {
let blocks = (chunk.len() + block_size - 1) / block_size;
assert!(blocks > 0);
assert!(blocks <= 0x1_0000);
self.buffer[..chunk.len()].copy_from_slice(chunk);
self.namespace_rw(nsid, lba, (blocks - 1) as u16, true)?;
lba += blocks as u64;
}
Ok(Some(buf.len()))
}
}
+221
View File
@@ -0,0 +1,221 @@
use std::collections::BTreeMap;
use std::{cmp, str};
use std::fmt::Write;
use std::io::Read;
use syscall::{
Error, EACCES, EBADF, EINVAL, EISDIR, ENOENT, Result,
Io, SchemeBlockMut, Stat, MODE_DIR, MODE_FILE, O_DIRECTORY,
O_STAT, SEEK_CUR, SEEK_END, SEEK_SET};
use crate::nvme::{Nvme, NvmeNamespace};
#[derive(Clone)]
enum Handle {
List(Vec<u8>, usize),
Disk(u32, usize)
}
pub struct DiskScheme {
scheme_name: String,
nvme: Nvme,
disks: BTreeMap<u32, NvmeNamespace>,
handles: BTreeMap<usize, Handle>,
next_id: usize
}
impl DiskScheme {
pub fn new(scheme_name: String, nvme: Nvme, disks: BTreeMap<u32, NvmeNamespace>) -> DiskScheme {
DiskScheme {
scheme_name,
nvme,
disks,
handles: BTreeMap::new(),
next_id: 0
}
}
}
impl DiskScheme {
pub fn irq(&mut self) -> bool {
// TODO: implement
false
}
}
impl SchemeBlockMut for DiskScheme {
fn open(&mut self, path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result<Option<usize>> {
if uid == 0 {
let path_str = str::from_utf8(path).or(Err(Error::new(ENOENT)))?.trim_matches('/');
if path_str.is_empty() {
if flags & O_DIRECTORY == O_DIRECTORY || flags & O_STAT == O_STAT {
let mut list = String::new();
for (nsid, _disk) in self.disks.iter() {
write!(list, "{}\n", nsid).unwrap();
}
let id = self.next_id;
self.next_id += 1;
self.handles.insert(id, Handle::List(list.into_bytes(), 0));
Ok(Some(id))
} else {
Err(Error::new(EISDIR))
}
} else {
let nsid = path_str.parse::<u32>().or(Err(Error::new(ENOENT)))?;
if self.disks.contains_key(&nsid) {
let id = self.next_id;
self.next_id += 1;
self.handles.insert(id, Handle::Disk(nsid, 0));
Ok(Some(id))
} else {
Err(Error::new(ENOENT))
}
}
} else {
Err(Error::new(EACCES))
}
}
fn dup(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
if ! buf.is_empty() {
return Err(Error::new(EINVAL));
}
let new_handle = {
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
handle.clone()
};
let new_id = self.next_id;
self.next_id += 1;
self.handles.insert(new_id, new_handle);
Ok(Some(new_id))
}
fn fstat(&mut self, id: usize, stat: &mut Stat) -> Result<Option<usize>> {
match *self.handles.get(&id).ok_or(Error::new(EBADF))? {
Handle::List(ref data, _) => {
stat.st_mode = MODE_DIR;
stat.st_size = data.len() as u64;
Ok(Some(0))
},
Handle::Disk(number, _) => {
let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?;
stat.st_mode = MODE_FILE;
stat.st_size = disk.blocks * disk.block_size;
Ok(Some(0))
}
}
}
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let mut i = 0;
let scheme_name = self.scheme_name.as_bytes();
let mut j = 0;
while i < buf.len() && j < scheme_name.len() {
buf[i] = scheme_name[j];
i += 1;
j += 1;
}
if i < buf.len() {
buf[i] = b':';
i += 1;
}
match *handle {
Handle::List(_, _) => (),
Handle::Disk(number, _) => {
let number_str = format!("{}", number);
let number_bytes = number_str.as_bytes();
j = 0;
while i < buf.len() && j < number_bytes.len() {
buf[i] = number_bytes[j];
i += 1;
j += 1;
}
}
}
Ok(Some(i))
}
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
Handle::List(ref mut handle, ref mut size) => {
let count = (&handle[*size..]).read(buf).unwrap();
*size += count;
Ok(Some(count))
},
Handle::Disk(number, ref mut size) => {
let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?;
let block_size = disk.block_size;
if let Some(count) = unsafe {
self.nvme.namespace_read(disk.id, (*size as u64)/block_size, buf)?
} {
*size += count;
Ok(Some(count))
} else {
Ok(None)
}
}
}
}
fn write(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
Handle::List(_, _) => {
Err(Error::new(EBADF))
},
Handle::Disk(number, ref mut size) => {
let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?;
let block_size = disk.block_size;
if let Some(count) = unsafe {
self.nvme.namespace_write(disk.id, (*size as u64)/block_size, buf)?
} {
*size += count;
Ok(Some(count))
} else {
Ok(None)
}
}
}
}
fn seek(&mut self, id: usize, pos: usize, whence: usize) -> Result<Option<usize>> {
match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
Handle::List(ref mut handle, ref mut size) => {
let len = handle.len() as usize;
*size = match whence {
SEEK_SET => cmp::min(len, pos),
SEEK_CUR => cmp::max(0, cmp::min(len as isize, *size as isize + pos as isize)) as usize,
SEEK_END => cmp::max(0, cmp::min(len as isize, len as isize + pos as isize)) as usize,
_ => return Err(Error::new(EINVAL))
};
Ok(Some(*size))
},
Handle::Disk(number, ref mut size) => {
let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?;
let len = (disk.blocks * disk.block_size) as usize;
*size = match whence {
SEEK_SET => cmp::min(len, pos),
SEEK_CUR => cmp::max(0, cmp::min(len as isize, *size as isize + pos as isize)) as usize,
SEEK_END => cmp::max(0, cmp::min(len as isize, len as isize + pos as isize)) as usize,
_ => return Err(Error::new(EINVAL))
};
Ok(Some(*size))
}
}
}
fn close(&mut self, id: usize) -> Result<Option<usize>> {
self.handles.remove(&id).ok_or(Error::new(EBADF)).and(Ok(Some(0)))
}
}
+1
View File
@@ -1,6 +1,7 @@
[package]
name = "pcid"
version = "0.1.0"
edition = "2018"
[dependencies]
bitflags = "1.0"
+1
View File
@@ -1,3 +1,4 @@
use std::collections::BTreeMap;
use std::ops::Range;
#[derive(Debug, Default, Deserialize)]
+2 -3
View File
@@ -1,5 +1,4 @@
#![feature(asm)]
#![feature(iterator_step_by)]
#[macro_use] extern crate bitflags;
extern crate byteorder;
@@ -13,8 +12,8 @@ use std::io::Read;
use std::process::Command;
use syscall::iopl;
use config::Config;
use pci::{Pci, PciClass, PciHeader, PciHeaderError, PciHeaderType};
use crate::config::Config;
use crate::pci::{Pci, PciClass, PciHeader, PciHeaderError, PciHeaderType};
mod config;
mod pci;
+2 -1
View File
@@ -1,9 +1,10 @@
[package]
name = "ps2d"
version = "0.1.0"
edition = "2018"
[dependencies]
bitflags = "0.7"
orbclient = "0.3"
orbclient = "0.3.27"
redox_event = { git = "https://gitlab.redox-os.org/redox-os/event.git" }
redox_syscall = "0.1"
+1 -2
View File
@@ -1,4 +1,3 @@
#![deny(warnings)]
#![feature(asm)]
#[macro_use]
@@ -17,7 +16,7 @@ use std::sync::Arc;
use event::EventQueue;
use syscall::iopl;
use state::Ps2d;
use crate::state::Ps2d;
mod controller;
mod keymap;
+30 -35
View File
@@ -1,12 +1,12 @@
use orbclient::{KeyEvent, MouseEvent, ButtonEvent, ScrollEvent};
use std::cmp;
use orbclient::{KeyEvent, MouseEvent, MouseRelativeEvent, ButtonEvent, ScrollEvent};
use std::fs::File;
use std::io::Write;
use std::os::unix::io::AsRawFd;
use std::str;
use syscall;
use controller::Ps2;
use vm;
use crate::controller::Ps2;
use crate::vm;
bitflags! {
flags MousePacketFlags: u8 {
@@ -46,7 +46,7 @@ impl<F: Fn(u8,bool) -> char> Ps2d<F> {
let mut ps2 = Ps2::new();
let extra_packet = ps2.init();
let vmmouse = vm::enable();
let vmmouse = false; //vm::enable();
let mut ps2d = Ps2d {
ps2: ps2,
@@ -75,7 +75,7 @@ impl<F: Fn(u8,bool) -> char> Ps2d<F> {
pub fn resize(&mut self) {
let mut buf: [u8; 4096] = [0; 4096];
if let Ok(count) = syscall::fpath(self.input.as_raw_fd() as usize, &mut buf) {
let path = unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) };
let path = unsafe { str::from_utf8_unchecked(&buf[..count]) };
let res = path.split(":").nth(1).unwrap_or("");
self.width = res.split("/").nth(1).unwrap_or("").parse::<u32>().unwrap_or(0);
self.height = res.split("/").nth(2).unwrap_or("").parse::<u32>().unwrap_or(0);
@@ -89,9 +89,6 @@ impl<F: Fn(u8,bool) -> char> Ps2d<F> {
}
pub fn handle(&mut self, keyboard: bool, data: u8) {
// TODO: Improve efficiency
self.resize();
if keyboard {
let (scancode, pressed) = if data >= 0x80 {
(data - 0x80, false)
@@ -127,26 +124,28 @@ impl<F: Fn(u8,bool) -> char> Ps2d<F> {
let (status, dx, dy, dz, _, _) = unsafe { vm::cmd(vm::ABSPOINTER_DATA, 4) };
let (x, y) = if status & vm::RELATIVE_PACKET == vm::RELATIVE_PACKET {
(
cmp::max(0, cmp::min(self.width as i32, self.mouse_x + dx as i32)),
cmp::max(0, cmp::min(self.height as i32, self.mouse_y - dy as i32))
)
if status & vm::RELATIVE_PACKET == vm::RELATIVE_PACKET {
if dx != 0 || dy != 0 {
self.input.write(&MouseRelativeEvent {
dx: dx as i32,
dy: -(dy as i32),
}.to_event()).expect("ps2d: failed to write mouse event");
}
} else {
(
dx as i32 * self.width as i32 / 0xFFFF,
dy as i32 * self.height as i32 / 0xFFFF
)
};
// TODO: Improve efficiency
self.resize();
if x != self.mouse_x || y != self.mouse_y {
self.mouse_x = x;
self.mouse_y = y;
self.input.write(&MouseEvent {
x: x,
y: y,
}.to_event()).expect("ps2d: failed to write mouse event");
}
let x = dx as i32 * self.width as i32 / 0xFFFF;
let y = dy as i32 * self.height as i32 / 0xFFFF;
if x != self.mouse_x || y != self.mouse_y {
self.mouse_x = x;
self.mouse_y = y;
self.input.write(&MouseEvent {
x: x,
y: y,
}.to_event()).expect("ps2d: failed to write mouse event");
}
};
if dz != 0 {
self.input.write(&ScrollEvent {
@@ -200,14 +199,10 @@ impl<F: Fn(u8,bool) -> char> Ps2d<F> {
dz = -scroll as i32;
}
let x = cmp::max(0, cmp::min(self.width as i32, self.mouse_x + dx));
let y = cmp::max(0, cmp::min(self.height as i32, self.mouse_y + dy));
if x != self.mouse_x || y != self.mouse_y {
self.mouse_x = x;
self.mouse_y = y;
self.input.write(&MouseEvent {
x: x,
y: y,
if dx != 0 || dy != 0 {
self.input.write(&MouseRelativeEvent {
dx: dx,
dy: dy,
}.to_event()).expect("ps2d: failed to write mouse event");
}
+2 -1
View File
@@ -1,9 +1,10 @@
[package]
name = "rtl8168d"
version = "0.1.0"
edition = "2018"
[dependencies]
bitflags = "0.7"
netutils = { git = "https://gitlab.redox-os.org/redox-os/netutils.git" }
netutils = { git = "https://gitlab.redox-os.org/redox-os/netutils.git", branch = "redox-unix" }
redox_event = { git = "https://gitlab.redox-os.org/redox-os/event.git" }
redox_syscall = "0.1"
+15 -6
View File
@@ -7,8 +7,8 @@ extern crate syscall;
use std::cell::RefCell;
use std::env;
use std::fs::File;
use std::io::{Read, Write, Result};
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::io::{self, Read, Write, Result};
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::sync::Arc;
use event::EventQueue;
@@ -34,7 +34,7 @@ fn main() {
// 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) }));
let socket = Arc::new(RefCell::new(unsafe { File::from_raw_fd(socket_fd as RawFd) }));
let mut irq_file = File::open(format!("irq:{}", irq)).expect("rtl8168d: failed to open IRQ file");
@@ -83,11 +83,17 @@ fn main() {
let device_packet = device.clone();
let socket_packet = socket.clone();
event_queue.add(socket_fd, move |_event| -> Result<Option<usize>> {
event_queue.add(socket_fd as RawFd, move |_event| -> Result<Option<usize>> {
loop {
let mut packet = Packet::default();
if socket_packet.borrow_mut().read(&mut packet)? == 0 {
break;
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);
}
}
let a = packet.a;
@@ -132,6 +138,9 @@ fn main() {
loop {
let event_count = event_queue.run().expect("rtl8168d: failed to handle events");
if event_count == 0 {
break;
}
send_events(event_count);
}
}
+2 -1
View File
@@ -1,8 +1,9 @@
[package]
name = "vboxd"
version = "0.1.0"
edition = "2018"
[dependencies]
orbclient = "0.3"
orbclient = "0.3.27"
redox_event = { git = "https://gitlab.redox-os.org/redox-os/event.git" }
redox_syscall = "0.1"
+1 -1
View File
@@ -13,7 +13,7 @@ use syscall::flag::{PHYSMAP_NO_CACHE, PHYSMAP_WRITE};
use syscall::io::{Dma, Io, Mmio, Pio};
use syscall::iopl;
use bga::Bga;
use crate::bga::Bga;
mod bga;
+2 -1
View File
@@ -1,9 +1,10 @@
[package]
name = "vesad"
version = "0.1.0"
edition = "2018"
[dependencies]
orbclient = "0.3"
orbclient = "0.3.27"
ransid = "0.4"
rusttype = { version = "0.2", optional = true }
redox_syscall = "0.1"
+1 -1
View File
@@ -5,7 +5,7 @@ use std::alloc::{Alloc, Global, Layout};
use std::{cmp, slice};
use std::ptr::NonNull;
use primitive::{fast_set32, fast_set64, fast_copy};
use crate::primitive::{fast_set32, fast_set64, fast_copy};
#[cfg(feature="rusttype")]
use self::rusttype::{Font, FontCollection, Scale, point};
+7 -4
View File
@@ -10,9 +10,9 @@ use std::fs::File;
use std::io::{Read, Write};
use syscall::{physmap, physunmap, Packet, SchemeMut, EVENT_READ, PHYSMAP_WRITE, PHYSMAP_WRITE_COMBINE};
use mode_info::VBEModeInfo;
use primitive::fast_set64;
use scheme::{DisplayScheme, HandleKind};
use crate::mode_info::VBEModeInfo;
use crate::primitive::fast_set64;
use crate::scheme::{DisplayScheme, HandleKind};
pub mod display;
pub mod mode_info;
@@ -65,7 +65,10 @@ fn main() {
let mut blocked = Vec::new();
loop {
let mut packet = Packet::default();
socket.read(&mut packet).expect("vesad: failed to read display scheme");
if socket.read(&mut packet).expect("vesad: failed to read display scheme") == 0 {
//TODO: Handle blocked
break;
}
// If it is a read packet, and there is no data, block it. Otherwise, handle packet
if packet.a == syscall::number::SYS_READ && packet.d > 0 && scheme.can_read(packet.b).is_none() {
+5 -5
View File
@@ -4,8 +4,8 @@ use std::{mem, slice, str};
use orbclient::{Event, EventOption};
use syscall::{Result, Error, EACCES, EBADF, EINVAL, ENOENT, O_NONBLOCK, Map, SchemeMut};
use display::Display;
use screen::{Screen, GraphicScreen, TextScreen};
use crate::display::Display;
use crate::screen::{Screen, GraphicScreen, TextScreen};
#[derive(Clone)]
pub enum HandleKind {
@@ -25,14 +25,14 @@ pub struct DisplayScheme {
width: usize,
height: usize,
active: usize,
pub screens: BTreeMap<usize, Box<Screen>>,
pub screens: BTreeMap<usize, Box<dyn Screen>>,
next_id: usize,
pub handles: BTreeMap<usize, Handle>,
}
impl DisplayScheme {
pub fn new(width: usize, height: usize, onscreen: usize, spec: &[bool]) -> DisplayScheme {
let mut screens: BTreeMap<usize, Box<Screen>> = BTreeMap::new();
let mut screens: BTreeMap<usize, Box<dyn Screen>> = BTreeMap::new();
let mut screen_i = 1;
for &screen_type in spec.iter() {
@@ -227,7 +227,7 @@ impl SchemeMut for DisplayScheme {
let mut new_active_opt = None;
match event.to_option() {
EventOption::Key(key_event) => match key_event.scancode {
f @ 0x3B ... 0x44 => { // F1 through F10
f @ 0x3B ..= 0x44 => { // F1 through F10
new_active_opt = Some((f - 0x3A) as usize);
},
0x57 => { // F11
+3 -3
View File
@@ -5,9 +5,9 @@ use orbclient::{Event, ResizeEvent};
use syscall::error::*;
use syscall::flag::{SEEK_SET, SEEK_CUR, SEEK_END};
use display::Display;
use primitive::fast_copy;
use screen::Screen;
use crate::display::Display;
use crate::primitive::fast_copy;
use crate::screen::Screen;
pub struct GraphicScreen {
pub display: Display,
+4 -4
View File
@@ -6,8 +6,8 @@ use std::ptr;
use orbclient::{Event, EventOption};
use syscall::error::*;
use display::Display;
use screen::Screen;
use crate::display::Display;
use crate::screen::Screen;
pub struct TextScreen {
pub console: ransid::Console,
@@ -92,8 +92,8 @@ impl Screen for TextScreen {
},
_ => {
let c = match key_event.character {
c @ 'A' ... 'Z' if self.ctrl => ((c as u8 - b'A') + b'\x01') as char,
c @ 'a' ... 'z' if self.ctrl => ((c as u8 - b'a') + b'\x01') as char,
c @ 'A' ..= 'Z' if self.ctrl => ((c as u8 - b'A') + b'\x01') as char,
c @ 'a' ..= 'z' if self.ctrl => ((c as u8 - b'a') + b'\x01') as char,
c => c
};
+1
View File
@@ -1,6 +1,7 @@
[package]
name = "xhcid"
version = "0.1.0"
edition = "2018"
[dependencies]
bitflags = "0.7"
+3 -3
View File
@@ -9,14 +9,14 @@ use std::cell::RefCell;
use std::env;
use std::fs::File;
use std::io::{Result, Read, Write};
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::sync::Arc;
use syscall::data::Packet;
use syscall::flag::{PHYSMAP_NO_CACHE, PHYSMAP_WRITE};
use syscall::error::EWOULDBLOCK;
use syscall::scheme::SchemeMut;
use xhci::Xhci;
use crate::xhci::Xhci;
mod usb;
mod xhci;
@@ -38,7 +38,7 @@ fn main() {
// Daemonize
if unsafe { syscall::clone(0).unwrap() } == 0 {
let socket_fd = syscall::open(":usb", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK).expect("xhcid: failed to create usb scheme");
let socket = Arc::new(RefCell::new(unsafe { File::from_raw_fd(socket_fd) }));
let socket = Arc::new(RefCell::new(unsafe { File::from_raw_fd(socket_fd as RawFd) }));
let mut irq_file = File::open(format!("irq:{}", irq)).expect("xhcid: failed to open IRQ file");
+1 -1
View File
@@ -1,5 +1,5 @@
use syscall::error::Result;
use syscall::io::Dma;
use super::event::EventRing;
use super::ring::Ring;
+1 -1
View File
@@ -2,7 +2,7 @@ use plain::Plain;
use std::{mem, slice};
use syscall::error::Result;
use syscall::io::{Dma, Io};
use usb;
use crate::usb;
mod capability;
mod command;
+1 -1
View File
@@ -1,6 +1,6 @@
use std::{fmt, mem};
use syscall::io::{Io, Mmio};
use usb;
use crate::usb;
#[repr(u8)]
pub enum TrbType {