Merge branch 'redox-unix'
This commit is contained in:
Generated
+283
-230
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
[package]
|
||||
name = "ahcid"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "0.7"
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,6 +1,7 @@
|
||||
[package]
|
||||
name = "ihdad"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "0.7"
|
||||
|
||||
@@ -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:";
|
||||
|
||||
@@ -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
@@ -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
@@ -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,6 +1,7 @@
|
||||
[package]
|
||||
name = "nvmed"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "0.7"
|
||||
|
||||
+74
-46
@@ -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
@@ -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()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,6 +1,7 @@
|
||||
[package]
|
||||
name = "pcid"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::ops::Range;
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
|
||||
+2
-3
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,6 +1,7 @@
|
||||
[package]
|
||||
name = "xhcid"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "0.7"
|
||||
|
||||
+3
-3
@@ -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,5 +1,5 @@
|
||||
use syscall::error::Result;
|
||||
use syscall::io::Dma;
|
||||
|
||||
|
||||
use super::event::EventRing;
|
||||
use super::ring::Ring;
|
||||
|
||||
@@ -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,6 +1,6 @@
|
||||
use std::{fmt, mem};
|
||||
use syscall::io::{Io, Mmio};
|
||||
use usb;
|
||||
use crate::usb;
|
||||
|
||||
#[repr(u8)]
|
||||
pub enum TrbType {
|
||||
|
||||
Reference in New Issue
Block a user