...
 
Commits (6)
This diff is collapsed.
......@@ -7,6 +7,7 @@ members = [
"ihdad",
"nvmed",
"pcid",
"pcspkrd",
"ps2d",
"rtl8168d",
"vboxd",
......
......@@ -67,59 +67,80 @@ impl DiskATA {
BufferKind::Write(ref buffer) => (true, buffer.as_ptr() as usize, buffer.len()/512),
};
let mut request = match self.request_opt.take() {
Some(request) => if address == request.address && total_sectors == request.total_sectors {
// Keep servicing current request
request
} else {
// Have to wait for another request to finish
self.request_opt = Some(request);
return Ok(None);
},
None => {
// Create new request
Request {
address,
total_sectors,
sector: 0,
running_opt: None,
//TODO: Go back to interrupt magic
let use_interrupts = false;
loop {
let mut request = match self.request_opt.take() {
Some(request) => if address == request.address && total_sectors == request.total_sectors {
// Keep servicing current request
request
} else {
// Have to wait for another request to finish
self.request_opt = Some(request);
return Ok(None);
},
None => {
// Create new request
Request {
address,
total_sectors,
sector: 0,
running_opt: None,
}
}
}
};
// Finish a previously running request
if let Some(running) = request.running_opt.take() {
self.port.ata_stop(running.0)?;
};
if let BufferKind::Read(ref mut buffer) = buffer_kind {
unsafe { ptr::copy(self.buf.as_ptr(), buffer.as_mut_ptr().add(request.sector * 512), running.1 * 512); }
}
// Finish a previously running request
if let Some(running) = request.running_opt.take() {
if self.port.ata_running(running.0) {
// Continue waiting for request
request.running_opt = Some(running);
self.request_opt = Some(request);
if use_interrupts {
return Ok(None);
} else {
::std::thread::yield_now();
continue;
}
}
request.sector += running.1;
}
self.port.ata_stop(running.0)?;
if request.sector < request.total_sectors {
// Start a new request
let sectors = if request.total_sectors - request.sector >= 255 {
255
} else {
request.total_sectors - request.sector
};
if let BufferKind::Read(ref mut buffer) = buffer_kind {
unsafe { ptr::copy(self.buf.as_ptr(), buffer.as_mut_ptr().add(request.sector * 512), running.1 * 512); }
}
if let BufferKind::Write(ref buffer) = buffer_kind {
unsafe { ptr::copy(buffer.as_ptr().add(request.sector * 512), self.buf.as_mut_ptr(), sectors * 512); }
request.sector += running.1;
}
if let Some(slot) = self.port.ata_dma(block + request.sector as u64, sectors, write, &mut self.clb, &mut self.ctbas, &mut self.buf) {
request.running_opt = Some((slot, sectors));
}
if request.sector < request.total_sectors {
// Start a new request
let sectors = if request.total_sectors - request.sector >= 255 {
255
} else {
request.total_sectors - request.sector
};
if let BufferKind::Write(ref buffer) = buffer_kind {
unsafe { ptr::copy(buffer.as_ptr().add(request.sector * 512), self.buf.as_mut_ptr(), sectors * 512); }
}
if let Some(slot) = self.port.ata_dma(block + request.sector as u64, sectors, write, &mut self.clb, &mut self.ctbas, &mut self.buf) {
request.running_opt = Some((slot, sectors));
}
self.request_opt = Some(request);
self.request_opt = Some(request);
Ok(None)
} else {
// Done
Ok(Some(request.sector * 512))
if use_interrupts {
return Ok(None);
} else {
::std::thread::yield_now();
continue;
}
} else {
// Done
return Ok(Some(request.sector * 512));
}
}
}
}
......
......@@ -116,7 +116,7 @@ impl HbaPort {
self.fb[1].write((fb.physical() >> 32) as u32);
let is = self.is.read();
self.is.write(is);
self.ie.write(0b10111);
self.ie.write(0 /*TODO: Enable interrupts: 0b10111*/);
let serr = self.serr.read();
self.serr.write(serr);
......@@ -319,8 +319,12 @@ impl HbaPort {
}
}
pub fn ata_running(&self, slot: u32) -> bool {
(self.ci.readf(1 << slot) || self.tfd.readf(0x80)) && self.is.read() & HBA_PORT_IS_ERR == 0
}
pub fn ata_stop(&mut self, slot: u32) -> Result<()> {
while (self.ci.readf(1 << slot) || self.tfd.readf(0x80)) && self.is.read() & HBA_PORT_IS_ERR == 0 {
while self.ata_running(slot) {
thread::yield_now();
}
......
......@@ -84,23 +84,13 @@ fn main() {
todo.push(packet);
}
}
// 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.write(&mut packet).expect("ahcid: 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("ahcid: failed to read irq file") >= irq.len() {
if scheme.irq() {
irq_file.write(&irq).expect("ahcid: failed to write irq file");
// Handle todos in order to finish previous packets if possible
let mut i = 0;
while i < todo.len() {
if let Some(a) = scheme.handle(&todo[i]) {
......@@ -116,6 +106,18 @@ fn main() {
} else {
println!("Unknown event {}", event.id);
}
// Handle todos to start new packets if possible
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.write(&mut packet).expect("ahcid: failed to write disk scheme");
} else {
i += 1;
}
}
}
}
unsafe { let _ = syscall::physunmap(address); }
......
......@@ -5,7 +5,7 @@ use netutils::setcfg;
use syscall::error::{Error, EACCES, EBADF, EINVAL, EWOULDBLOCK, Result};
use syscall::flag::O_NONBLOCK;
use syscall::io::Dma;
use syscall::scheme::SchemeMut;
use syscall::scheme::SchemeBlockMut;
const CTRL: u32 = 0x00;
const CTRL_LRST: u32 = 1 << 3;
......@@ -104,18 +104,18 @@ pub struct Intel8254x {
pub handles: BTreeMap<usize, usize>,
}
impl SchemeMut for Intel8254x {
fn open(&mut self, _path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result<usize> {
impl SchemeBlockMut for Intel8254x {
fn open(&mut self, _path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result<Option<usize>> {
if uid == 0 {
self.next_id += 1;
self.handles.insert(self.next_id, flags);
Ok(self.next_id)
Ok(Some(self.next_id))
} else {
Err(Error::new(EACCES))
}
}
fn dup(&mut self, id: usize, buf: &[u8]) -> Result<usize> {
fn dup(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
if ! buf.is_empty() {
return Err(Error::new(EINVAL));
}
......@@ -126,10 +126,10 @@ impl SchemeMut for Intel8254x {
};
self.next_id += 1;
self.handles.insert(self.next_id, flags);
Ok(self.next_id)
Ok(Some(self.next_id))
}
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
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) };
......@@ -155,18 +155,18 @@ impl SchemeMut for Intel8254x {
unsafe { self.write_reg(RDT, tail) };
return Ok(i);
return Ok(Some(i));
}
}
if flags & O_NONBLOCK == O_NONBLOCK {
Ok(0)
} else {
Err(Error::new(EWOULDBLOCK))
} else {
Ok(None)
}
}
fn write(&mut self, id: usize, buf: &[u8]) -> Result<usize> {
fn write(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
let _flags = self.handles.get(&id).ok_or(Error::new(EBADF))?;
loop {
......@@ -204,17 +204,17 @@ impl SchemeMut for Intel8254x {
thread::yield_now();
}
return Ok(i);
return Ok(Some(i));
}
}
}
fn fevent(&mut self, id: usize, _flags: usize) -> Result<usize> {
fn fevent(&mut self, id: usize, _flags: usize) -> Result<Option<usize>> {
let _flags = self.handles.get(&id).ok_or(Error::new(EBADF))?;
Ok(id)
Ok(Some(id))
}
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
let _flags = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let mut i = 0;
......@@ -223,17 +223,17 @@ impl SchemeMut for Intel8254x {
buf[i] = scheme_path[i];
i += 1;
}
Ok(i)
Ok(Some(i))
}
fn fsync(&mut self, id: usize) -> Result<usize> {
fn fsync(&mut self, id: usize) -> Result<Option<usize>> {
let _flags = self.handles.get(&id).ok_or(Error::new(EBADF))?;
Ok(0)
Ok(Some(0))
}
fn close(&mut self, id: usize) -> Result<usize> {
fn close(&mut self, id: usize) -> Result<Option<usize>> {
self.handles.remove(&id).ok_or(Error::new(EBADF))?;
Ok(0)
Ok(Some(0))
}
}
......
......@@ -12,7 +12,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd};
use std::sync::Arc;
use event::EventQueue;
use syscall::{Packet, SchemeMut, PHYSMAP_WRITE};
use syscall::{Packet, SchemeBlockMut, PHYSMAP_WRITE};
use syscall::error::EWOULDBLOCK;
pub mod device;
......@@ -21,14 +21,12 @@ fn handle_update(socket: &mut File, device: &mut device::Intel8254x, todo: &mut
// Handle any blocked packets
let mut i = 0;
while i < todo.len() {
let a = todo[i].a;
device.handle(&mut todo[i]);
if todo[i].a == (-EWOULDBLOCK) as usize {
todo[i].a = a;
i += 1;
if let Some(a) = device.handle(&todo[i]) {
let mut packet = todo.remove(i);
packet.a = a;
socket.write(&packet)?;
} else {
socket.write(&mut todo[i])?;
todo.remove(i);
i += 1;
}
}
......@@ -39,13 +37,11 @@ fn handle_update(socket: &mut File, device: &mut device::Intel8254x, todo: &mut
break;
}
let a = packet.a;
device.handle(&mut packet);
if packet.a == (-EWOULDBLOCK) as usize {
if let Some(a) = device.handle(&packet) {
packet.a = a;
todo.push(packet);
socket.write(&packet)?;
} else {
socket.write(&mut packet)?;
todo.push(packet);
}
}
......
......@@ -93,7 +93,7 @@ fn main() {
}
*/
}
Ok(Some(0))
Ok(None)
}).expect("IHDA: failed to catch events on IRQ file");
let socket_fd = socket.borrow().as_raw_fd();
let socket_packet = socket.clone();
......
[package]
name = "pcspkrd"
version = "0.1.0"
authors = ["Tibor Nagy <xnagytibor@gmail.com>"]
edition = "2018"
[dependencies]
redox_syscall = "0.1"
mod pcspkr;
mod scheme;
use std::fs::File;
use std::io::{Read, Write};
use syscall::data::Packet;
use syscall::iopl;
use syscall::scheme::SchemeMut;
use self::pcspkr::Pcspkr;
use self::scheme::PcspkrScheme;
fn main() {
// Daemonize
if unsafe { syscall::clone(0).unwrap() } == 0 {
unsafe { iopl(3).unwrap() };
let mut socket = File::create(":pcspkr").expect("pcspkrd: failed to create pcspkr scheme");
let pcspkr = Pcspkr::new();
println!(" + pcspkr");
let mut scheme = PcspkrScheme {
pcspkr: pcspkr,
handle: None,
next_id: 0,
};
syscall::setrens(0, 0).expect("pcspkrd: failed to enter null namespace");
loop {
let mut packet = Packet::default();
socket
.read(&mut packet)
.expect("pcspkrd: failed to read events from pcspkr scheme");
scheme.handle(&mut packet);
socket
.write(&packet)
.expect("pcspkrd: failed to write responses to pcspkr scheme");
}
}
}
use syscall::io::{Io, Pio};
pub struct Pcspkr {
command: Pio<u8>,
channel: Pio<u8>,
gate: Pio<u8>,
}
const PIT_FREQUENCY: usize = 0x1234DC;
impl Pcspkr {
pub fn new() -> Pcspkr {
Pcspkr {
command: Pio::new(0x43),
channel: Pio::new(0x42),
gate: Pio::new(0x61),
}
}
pub fn set_frequency(&mut self, frequency: usize) {
let div = PIT_FREQUENCY.checked_div(frequency).unwrap_or(0);
self.command.write(0xB6);
self.channel.write((div & 0xFF) as u8);
self.channel.write(((div >> 8) & 0xFF) as u8);
}
pub fn set_gate(&mut self, state: bool) {
let gate_value = self.gate.read();
if state {
self.gate.write(gate_value | 0x03);
} else {
self.gate.write(gate_value & 0xFC);
}
}
}
use syscall::data::Stat;
use syscall::{
Error, Result, SchemeMut, EBUSY, EINVAL, EPERM, MODE_CHR, O_ACCMODE, O_STAT, O_WRONLY,
};
use crate::pcspkr::Pcspkr;
pub struct PcspkrScheme {
pub pcspkr: Pcspkr,
pub handle: Option<usize>,
pub next_id: usize,
}
impl SchemeMut for PcspkrScheme {
fn open(&mut self, _path: &[u8], flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
if (flags & O_ACCMODE == 0) && (flags & O_STAT == O_STAT) {
Ok(0)
} else if flags & O_ACCMODE == O_WRONLY {
if self.handle.is_none() {
self.next_id += 1;
self.handle = Some(self.next_id);
Ok(self.next_id)
} else {
Err(Error::new(EBUSY))
}
} else {
Err(Error::new(EINVAL))
}
}
fn dup(&mut self, _id: usize, _buf: &[u8]) -> Result<usize> {
Err(Error::new(EPERM))
}
fn read(&mut self, _id: usize, _buf: &mut [u8]) -> Result<usize> {
Err(Error::new(EPERM))
}
fn write(&mut self, id: usize, buf: &[u8]) -> Result<usize> {
if self.handle != Some(id) {
return Err(Error::new(EINVAL));
}
if buf.len() != 2 {
return Err(Error::new(EINVAL));
}
let frequency = buf[0] as usize + ((buf[1] as usize) << 8);
if frequency == 0 {
self.pcspkr.set_gate(false);
} else {
self.pcspkr.set_frequency(frequency);
self.pcspkr.set_gate(true);
}
Ok(buf.len())
}
fn fpath(&mut self, _id: usize, buf: &mut [u8]) -> Result<usize> {
let mut i = 0;
let scheme_path = b"pcspkr";
while i < buf.len() && i < scheme_path.len() {
buf[i] = scheme_path[i];
i += 1;
}
Ok(i)
}
fn fstat(&mut self, _id: usize, stat: &mut Stat) -> Result<usize> {
*stat = Stat {
st_mode: MODE_CHR | 0o222,
..Default::default()
};
Ok(0)
}
fn fcntl(&mut self, _id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
Ok(0)
}
fn close(&mut self, id: usize) -> Result<usize> {
if self.handle == Some(id) {
self.pcspkr.set_gate(false);
self.handle = None;
}
Ok(0)
}
}