* Port previous ethernet scheme

* Add ipd

* Fix initfs rebuilds, use QEMU user networking addresses in ipd

* Add tcp/udp, netutils, dns, and network config

* Add fsync to network driver

* Add dns, router, subnet by default

* Fix e1000 driver. Make ethernet and IP non-blocking to avoid deadlocks

* Add orbital server, WIP

* Add futex

* Add orbutils and orbital

* Update libstd, orbutils, and orbital
Move ANSI key encoding to vesad

* Add orbital assets

* Update orbital

* Update to add login manager

* Add blocking primitives, block for most things except waitpid, update orbital

* Wait in waitpid and IRQ, improvements for other waits

* Fevent in root scheme

* WIP: Switch to using fevent

* Reorganize

* Event based e1000d driver

* Superuser-only access to some network schemes, display, and disk

* Superuser root and irq schemes

* Fix orbital
This commit is contained in:
Jeremy Soller 2016-10-13 17:21:42 -06:00 • committed by GitHub
commit 224c43f761
24 changed files with 3418 additions and 476 deletions

View file

@ -4,7 +4,7 @@ version = "0.1.0"
[dependencies]
bitflags = "*"
dma = { path = "../dma/" }
io = { path = "../io/" }
dma = { path = "../../crates/dma/" }
io = { path = "../../crates/io/" }
spin = "*"
syscall = { path = "../../syscall/" }

View file

@ -25,6 +25,10 @@ const HBA_SIG_ATAPI: u32 = 0xEB140101;
const HBA_SIG_PM: u32 = 0x96690101;
const HBA_SIG_SEMB: u32 = 0xC33C0101;
fn pause() {
unsafe { asm!("pause" : : : "memory" : "intel", "volatile"); }
}
#[derive(Debug)]
pub enum HbaPortType {
None,
@ -119,7 +123,9 @@ impl HbaPort {
cmdfis.counth.write(0);
}
while self.tfd.readf((ATA_DEV_BUSY | ATA_DEV_DRQ) as u32) {}
while self.tfd.readf((ATA_DEV_BUSY | ATA_DEV_DRQ) as u32) {
pause();
}
self.ci.writef(1 << slot, true);
@ -127,6 +133,7 @@ impl HbaPort {
if self.is.readf(HBA_PORT_IS_TFES) {
return None;
}
pause();
}
if self.is.readf(HBA_PORT_IS_TFES) {
@ -194,7 +201,9 @@ impl HbaPort {
}
pub fn start(&mut self) {
while self.cmd.readf(HBA_PORT_CMD_CR) {}
while self.cmd.readf(HBA_PORT_CMD_CR) {
pause();
}
self.cmd.writef(HBA_PORT_CMD_FRE, true);
self.cmd.writef(HBA_PORT_CMD_ST, true);
@ -203,7 +212,9 @@ impl HbaPort {
pub fn stop(&mut self) {
self.cmd.writef(HBA_PORT_CMD_ST, false);
while self.cmd.readf(HBA_PORT_CMD_FR | HBA_PORT_CMD_CR) {}
while self.cmd.readf(HBA_PORT_CMD_FR | HBA_PORT_CMD_CR) {
pause();
}
self.cmd.writef(HBA_PORT_CMD_FRE, false);
}
@ -267,7 +278,9 @@ impl HbaPort {
cmdfis.counth.write((sectors >> 8) as u8);
}
while self.tfd.readf((ATA_DEV_BUSY | ATA_DEV_DRQ) as u32) {}
while self.tfd.readf((ATA_DEV_BUSY | ATA_DEV_DRQ) as u32) {
pause();
}
self.ci.writef(1 << slot, true);
@ -276,6 +289,7 @@ impl HbaPort {
println!("IS_TFES set in CI loop TFS {:X} SERR {:X}", self.tfd.read(), self.serr.read());
return Err(Error::new(EIO));
}
pause();
}
if self.is.readf(HBA_PORT_IS_TFES) {
@ -312,7 +326,9 @@ pub struct HbaMem {
impl HbaMem {
pub fn reset(&mut self) {
self.ghc.writef(1, true);
while self.ghc.readf(1) {}
while self.ghc.readf(1) {
pause();
}
}
}

View file

@ -8,10 +8,11 @@ extern crate io;
extern crate spin;
extern crate syscall;
use std::{env, thread, usize};
use std::fs::File;
use std::io::{Read, Write};
use std::{env, thread, usize};
use syscall::{iopl, physmap, physunmap, MAP_WRITE, Packet, Scheme};
use std::os::unix::io::AsRawFd;
use syscall::{EVENT_READ, MAP_WRITE, Event, Packet, Scheme};
use scheme::DiskScheme;
@ -29,21 +30,42 @@ fn main() {
thread::spawn(move || {
unsafe {
iopl(3).expect("ahcid: failed to get I/O permission");
syscall::iopl(3).expect("ahcid: failed to get I/O permission");
asm!("cli" :::: "intel", "volatile");
}
let address = unsafe { physmap(bar, 4096, MAP_WRITE).expect("ahcid: failed to map address") };
let address = unsafe { syscall::physmap(bar, 4096, MAP_WRITE).expect("ahcid: failed to map address") };
{
let mut socket = File::create(":disk").expect("ahcid: failed to create disk scheme");
let socket_fd = socket.as_raw_fd();
syscall::fevent(socket_fd, EVENT_READ).expect("ahcid: failed to fevent disk scheme");
let mut irq_file = File::open(&format!("irq:{}", irq)).expect("ahcid: failed to open irq file");
let irq_fd = irq_file.as_raw_fd();
syscall::fevent(irq_fd, EVENT_READ).expect("ahcid: failed to fevent irq file");
let mut event_file = File::open("event:").expect("ahcid: failed to open event file");
let scheme = DiskScheme::new(ahci::disks(address, irq));
loop {
let mut packet = Packet::default();
socket.read(&mut packet).expect("ahcid: failed to read disk scheme");
scheme.handle(&mut packet);
socket.write(&mut packet).expect("ahcid: failed to read disk scheme");
let mut event = Event::default();
event_file.read(&mut event).expect("ahcid: failed to read event file");
if event.id == socket_fd {
let mut packet = Packet::default();
socket.read(&mut packet).expect("ahcid: failed to read disk scheme");
scheme.handle(&mut packet);
socket.write(&mut packet).expect("ahcid: failed to write disk scheme");
} 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() {
println!("IRQ");
irq_file.write(&irq).expect("ahcid: failed to write irq file");
}
} else {
println!("Unknown event {}", event.id);
}
}
}
unsafe { let _ = physunmap(address); }
unsafe { let _ = syscall::physunmap(address); }
});
}

View file

@ -3,7 +3,7 @@ use std::{cmp, str};
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use spin::Mutex;
use syscall::{Error, EBADF, EINVAL, ENOENT, Result, Scheme, Stat, MODE_FILE, SEEK_CUR, SEEK_END, SEEK_SET};
use syscall::{Error, EACCES, EBADF, EINVAL, ENOENT, Result, Scheme, Stat, MODE_FILE, SEEK_CUR, SEEK_END, SEEK_SET};
use ahci::disk::Disk;
@ -29,17 +29,21 @@ impl DiskScheme {
}
impl Scheme for DiskScheme {
fn open(&self, path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
let path_str = str::from_utf8(path).or(Err(Error::new(ENOENT)))?;
fn open(&self, path: &[u8], _flags: usize, uid: u32, _gid: u32) -> Result<usize> {
if uid == 0 {
let path_str = str::from_utf8(path).or(Err(Error::new(ENOENT)))?;
let i = path_str.parse::<usize>().or(Err(Error::new(ENOENT)))?;
let i = path_str.parse::<usize>().or(Err(Error::new(ENOENT)))?;
if let Some(disk) = self.disks.get(i) {
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
self.handles.lock().insert(id, (disk.clone(), 0));
Ok(id)
if let Some(disk) = self.disks.get(i) {
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
self.handles.lock().insert(id, (disk.clone(), 0));
Ok(id)
} else {
Err(Error::new(ENOENT))
}
} else {
Err(Error::new(ENOENT))
Err(Error::new(EACCES))
}
}

View file

@ -1,6 +0,0 @@
[package]
name = "dma"
version = "0.1.0"
[dependencies]
syscall = { path = "../../syscall/" }

View file

@ -1,80 +0,0 @@
#![feature(question_mark)]
extern crate syscall;
use std::{mem, ptr};
use std::ops::{Deref, DerefMut};
use syscall::Result;
struct PhysBox {
address: usize,
size: usize
}
impl PhysBox {
fn new(size: usize) -> Result<PhysBox> {
let address = unsafe { syscall::physalloc(size)? };
Ok(PhysBox {
address: address,
size: size
})
}
}
impl Drop for PhysBox {
fn drop(&mut self) {
let _ = unsafe { syscall::physfree(self.address, self.size) };
}
}
pub struct Dma<T> {
phys: PhysBox,
virt: *mut T
}
impl<T> Dma<T> {
pub fn new(value: T) -> Result<Dma<T>> {
let phys = PhysBox::new(mem::size_of::<T>())?;
let virt = unsafe { syscall::physmap(phys.address, phys.size, syscall::MAP_WRITE)? } as *mut T;
unsafe { ptr::write(virt, value); }
Ok(Dma {
phys: phys,
virt: virt
})
}
pub fn zeroed() -> Result<Dma<T>> {
let phys = PhysBox::new(mem::size_of::<T>())?;
let virt = unsafe { syscall::physmap(phys.address, phys.size, syscall::MAP_WRITE)? } as *mut T;
unsafe { ptr::write_bytes(virt as *mut u8, 0, phys.size); }
Ok(Dma {
phys: phys,
virt: virt
})
}
pub fn physical(&self) -> usize {
self.phys.address
}
}
impl<T> Deref for Dma<T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.virt }
}
}
impl<T> DerefMut for Dma<T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.virt }
}
}
impl<T> Drop for Dma<T> {
fn drop(&mut self) {
unsafe { drop(ptr::read(self.virt)); }
let _ = unsafe { syscall::physunmap(self.virt as usize) };
}
}

View file

@ -4,7 +4,8 @@ version = "0.1.0"
[dependencies]
bitflags = "*"
dma = { path = "../dma/" }
io = { path = "../io/" }
dma = { path = "../../crates/dma/" }
event = { path = "../../crates/event/" }
io = { path = "../../crates/io/" }
spin = "*"
syscall = { path = "../../syscall/" }

View file

@ -1,7 +1,7 @@
use std::{cmp, mem, ptr, slice};
use dma::Dma;
use syscall::error::Result;
use syscall::error::{Error, EACCES, EWOULDBLOCK, Result};
use syscall::scheme::Scheme;
const CTRL: u32 = 0x00;
@ -96,12 +96,16 @@ pub struct Intel8254x {
receive_buffer: [Dma<[u8; 16384]>; 16],
receive_ring: Dma<[Rd; 16]>,
transmit_buffer: [Dma<[u8; 16384]>; 16],
transmit_ring: Dma<[Td; 16]>,
transmit_ring: Dma<[Td; 16]>
}
impl Scheme for Intel8254x {
fn open(&self, _path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
Ok(0)
fn open(&self, _path: &[u8], _flags: usize, uid: u32, _gid: u32) -> Result<usize> {
if uid == 0 {
Ok(0)
} else {
Err(Error::new(EACCES))
}
}
fn dup(&self, id: usize) -> Result<usize> {
@ -109,7 +113,15 @@ impl Scheme for Intel8254x {
}
fn read(&self, _id: usize, buf: &mut [u8]) -> Result<usize> {
for tail in 0..self.receive_ring.len() {
let head = unsafe { self.read(RDH) };
let mut tail = unsafe { self.read(RDT) };
tail += 1;
if tail >= self.receive_ring.len() as u32 {
tail = 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;
@ -121,11 +133,14 @@ impl Scheme for Intel8254x {
buf[i] = data[i];
i += 1;
}
unsafe { self.write(RDT, tail) };
return Ok(i);
}
}
Ok(0)
Err(Error::new(EWOULDBLOCK))
}
fn write(&self, _id: usize, buf: &[u8]) -> Result<usize> {
@ -166,8 +181,12 @@ impl Scheme for Intel8254x {
return Ok(i);
}
}
unsafe { asm!("pause" : : : "memory" : "intel", "volatile"); }
}
}
fn fsync(&self, _id: usize) -> Result<usize> {
Ok(0)
}
@ -198,6 +217,11 @@ impl Intel8254x {
Ok(module)
}
pub unsafe fn irq(&self) -> bool {
let icr = self.read(ICR);
icr != 0
}
pub unsafe fn read(&self, register: u32) -> u32 {
ptr::read_volatile((self.base + register as usize) as *mut u32)
}
@ -271,8 +295,7 @@ impl Intel8254x {
self.write(TDH, 0);
self.write(TDT, 0);
//self.write(IMS, IMS_RXT | IMS_RX | IMS_RXDMT | IMS_RXSEQ | IMS_LSC | IMS_TXQE | IMS_TXDW);
self.write(IMS, 0);
self.write(IMS, IMS_RXT | IMS_RX | IMS_RXDMT | IMS_RXSEQ); // | IMS_LSC | IMS_TXQE | IMS_TXDW
self.flag(RCTL, RCTL_EN, true);
self.flag(RCTL, RCTL_UPE, true);

View file

@ -2,13 +2,19 @@
#![feature(question_mark)]
extern crate dma;
extern crate event;
extern crate syscall;
use std::cell::RefCell;
use std::{env, thread};
use std::fs::File;
use std::io::{Read, Write};
use std::io::{Read, Write, Result};
use std::os::unix::io::AsRawFd;
use std::sync::Arc;
use syscall::{iopl, physmap, physunmap, Packet, Scheme, MAP_WRITE};
use event::EventQueue;
use syscall::{Packet, Scheme, MAP_WRITE};
use syscall::error::EWOULDBLOCK;
pub mod device;
@ -23,21 +29,66 @@ fn main() {
thread::spawn(move || {
unsafe {
iopl(3).expect("e1000d: failed to get I/O permission");
syscall::iopl(3).expect("e1000d: failed to get I/O permission");
asm!("cli" :::: "intel", "volatile");
}
let address = unsafe { physmap(bar, 128*1024, MAP_WRITE).expect("e1000d: failed to map address") };
let socket = Arc::new(RefCell::new(File::create(":network").expect("e1000d: failed to create network scheme")));
let address = unsafe { syscall::physmap(bar, 128*1024, MAP_WRITE).expect("e1000d: failed to map address") };
{
let mut device = unsafe { device::Intel8254x::new(address, irq).expect("e1000d: failed to allocate device") };
let mut socket = File::create(":network").expect("e1000d: failed to create network scheme");
loop {
let device = Arc::new(unsafe { device::Intel8254x::new(address, irq).expect("e1000d: failed to allocate device") });
let mut event_queue = EventQueue::<()>::new().expect("e1000d: failed to create event queue");
let todo = Arc::new(RefCell::new(Vec::<Packet>::new()));
let device_irq = device.clone();
let socket_irq = socket.clone();
let todo_irq = todo.clone();
let mut irq_file = File::open(format!("irq:{}", irq)).expect("e1000d: failed to open IRQ file");
event_queue.add(irq_file.as_raw_fd(), move |_count: usize| -> Result<Option<()>> {
let mut irq = [0; 8];
irq_file.read(&mut irq)?;
if unsafe { device_irq.irq() } {
irq_file.write(&mut irq)?;
let mut todo = todo_irq.borrow_mut();
let mut i = 0;
while i < todo.len() {
let a = todo[i].a;
device_irq.handle(&mut todo[i]);
if todo[i].a == (-EWOULDBLOCK) as usize {
todo[i].a = a;
i += 1;
} else {
socket_irq.borrow_mut().write(&mut todo[i])?;
todo.remove(i);
}
}
}
Ok(None)
}).expect("e1000d: failed to catch events on IRQ file");
let socket_fd = socket.borrow().as_raw_fd();
event_queue.add(socket_fd, move |_count: usize| -> Result<Option<()>> {
let mut packet = Packet::default();
socket.read(&mut packet).expect("e1000d: failed to read network scheme");
socket.borrow_mut().read(&mut packet)?;
let a = packet.a;
device.handle(&mut packet);
socket.write(&mut packet).expect("e1000d: failed to read network scheme");
}
if packet.a == (-EWOULDBLOCK) as usize {
packet.a = a;
todo.borrow_mut().push(packet);
} else {
socket.borrow_mut().write(&mut packet)?;
}
Ok(None)
}).expect("e1000d: failed to catch events on IRQ file");
event_queue.run().expect("e1000d: failed to handle events");
}
unsafe { let _ = physunmap(address); }
unsafe { let _ = syscall::physunmap(address); }
});
}

View file

@ -1,3 +0,0 @@
[package]
name = "io"
version = "0.1.0"

View file

@ -1,67 +0,0 @@
use core::cmp::PartialEq;
use core::ops::{BitAnd, BitOr, Not};
pub trait Io {
type Value: Copy + PartialEq + BitAnd<Output = Self::Value> + BitOr<Output = Self::Value> + Not<Output = Self::Value>;
fn read(&self) -> Self::Value;
fn write(&mut self, value: Self::Value);
#[inline(always)]
fn readf(&self, flags: Self::Value) -> bool {
(self.read() & flags) as Self::Value == flags
}
#[inline(always)]
fn writef(&mut self, flags: Self::Value, value: bool) {
let tmp: Self::Value = match value {
true => self.read() | flags,
false => self.read() & !flags,
};
self.write(tmp);
}
}
pub struct ReadOnly<I: Io> {
inner: I
}
impl<I: Io> ReadOnly<I> {
pub const fn new(inner: I) -> ReadOnly<I> {
ReadOnly {
inner: inner
}
}
#[inline(always)]
pub fn read(&self) -> I::Value {
self.inner.read()
}
#[inline(always)]
pub fn readf(&self, flags: I::Value) -> bool {
self.inner.readf(flags)
}
}
pub struct WriteOnly<I: Io> {
inner: I
}
impl<I: Io> WriteOnly<I> {
pub const fn new(inner: I) -> WriteOnly<I> {
WriteOnly {
inner: inner
}
}
#[inline(always)]
pub fn write(&mut self, value: I::Value) {
self.inner.write(value)
}
#[inline(always)]
pub fn writef(&mut self, flags: I::Value, value: bool) {
self.inner.writef(flags, value)
}
}

View file

@ -1,14 +0,0 @@
//! I/O functions
#![feature(asm)]
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![no_std]
pub use self::io::*;
pub use self::mmio::*;
pub use self::pio::*;
mod io;
mod mmio;
mod pio;

View file

@ -1,31 +0,0 @@
use core::intrinsics::{volatile_load, volatile_store};
use core::mem::uninitialized;
use core::ops::{BitAnd, BitOr, Not};
use super::io::Io;
#[repr(packed)]
pub struct Mmio<T> {
value: T,
}
impl<T> Mmio<T> {
/// Create a new Mmio without initializing
pub fn new() -> Self {
Mmio {
value: unsafe { uninitialized() }
}
}
}
impl<T> Io for Mmio<T> where T: Copy + PartialEq + BitAnd<Output = T> + BitOr<Output = T> + Not<Output = T> {
type Value = T;
fn read(&self) -> T {
unsafe { volatile_load(&self.value) }
}
fn write(&mut self, value: T) {
unsafe { volatile_store(&mut self.value, value) };
}
}

View file

@ -1,89 +0,0 @@
use core::marker::PhantomData;
use super::io::Io;
/// Generic PIO
#[derive(Copy, Clone)]
pub struct Pio<T> {
port: u16,
value: PhantomData<T>,
}
impl<T> Pio<T> {
/// Create a PIO from a given port
pub const fn new(port: u16) -> Self {
Pio::<T> {
port: port,
value: PhantomData,
}
}
}
/// Read/Write for byte PIO
impl Io for Pio<u8> {
type Value = u8;
/// Read
#[inline(always)]
fn read(&self) -> u8 {
let value: u8;
unsafe {
asm!("in $0, $1" : "={al}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
}
value
}
/// Write
#[inline(always)]
fn write(&mut self, value: u8) {
unsafe {
asm!("out $1, $0" : : "{al}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
}
}
}
/// Read/Write for word PIO
impl Io for Pio<u16> {
type Value = u16;
/// Read
#[inline(always)]
fn read(&self) -> u16 {
let value: u16;
unsafe {
asm!("in $0, $1" : "={ax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
}
value
}
/// Write
#[inline(always)]
fn write(&mut self, value: u16) {
unsafe {
asm!("out $1, $0" : : "{ax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
}
}
}
/// Read/Write for doubleword PIO
impl Io for Pio<u32> {
type Value = u32;
/// Read
#[inline(always)]
fn read(&self) -> u32 {
let value: u32;
unsafe {
asm!("in $0, $1" : "={eax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
}
value
}
/// Write
#[inline(always)]
fn write(&mut self, value: u32) {
unsafe {
asm!("out $1, $0" : : "{eax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
}
}
}

View file

@ -4,6 +4,6 @@ version = "0.1.0"
[dependencies]
bitflags = "*"
io = { path = "../io/" }
spin = "*"
io = { path = "../../crates/io/" }
orbclient = "0.1"
syscall = { path = "../../syscall/" }

View file

@ -1,7 +1,8 @@
use std::fs::File;
use std::io::{Read, Write};
use std::mem;
use std::thread;
use orbclient::KeyEvent;
use keymap;
@ -9,7 +10,6 @@ pub fn keyboard() {
let mut file = File::open("irq:1").expect("ps2d: failed to open irq:1");
let mut input = File::open("display:input").expect("ps2d: failed to open display:input");
let mut ctrl = false;
let mut lshift = false;
let mut rshift = false;
loop {
@ -28,71 +28,17 @@ pub fn keyboard() {
(data, true)
};
if scancode == 0x1D {
ctrl = pressed;
} else if scancode == 0x2A {
if scancode == 0x2A {
lshift = pressed;
} else if scancode == 0x36 {
rshift = pressed;
} else if pressed {
match scancode {
f @ 0x3B ... 0x44 => { // F1 through F10
input.write(&[(f - 0x3B) + 0xF4]).unwrap();
},
0x57 => { // F11
input.write(&[0xFE]).unwrap();
},
0x58 => { // F12
input.write(&[0xFF]).unwrap();
},
0x47 => { // Home
input.write(b"\x1B[H").unwrap();
},
0x48 => { // Up
input.write(b"\x1B[A").unwrap();
},
0x49 => { // Page up
input.write(b"\x1B[5~").unwrap();
},
0x4B => { // Left
input.write(b"\x1B[D").unwrap();
},
0x4D => { // Right
input.write(b"\x1B[C").unwrap();
},
0x4F => { // End
input.write(b"\x1B[F").unwrap();
},
0x50 => { // Down
input.write(b"\x1B[B").unwrap();
},
0x51 => { // Page down
input.write(b"\x1B[6~").unwrap();
},
0x52 => { // Insert
input.write(b"\x1B[2~").unwrap();
},
0x53 => { // Delete
input.write(b"\x1B[3~").unwrap();
},
_ => {
let c = if ctrl {
match keymap::get_char(scancode, false) {
c @ 'a' ... 'z' => ((c as u8 - b'a') + b'\x01') as char,
c => c
}
} else {
keymap::get_char(scancode, lshift || rshift)
};
if c != '\0' {
input.write(&[c as u8]).unwrap();
}
}
}
}
} else {
thread::yield_now();
input.write(&KeyEvent {
character: keymap::get_char(scancode, lshift || rshift),
scancode: scancode,
pressed: pressed
}.to_event()).expect("ps2d: failed to write key event");
}
}
}

View file

@ -3,6 +3,7 @@
#[macro_use]
extern crate bitflags;
extern crate io;
extern crate orbclient;
extern crate syscall;
use std::thread;

View file

@ -1,7 +1,8 @@
use std::fs::File;
use std::io::{Read, Write};
use std::mem;
use std::thread;
use orbclient::MouseEvent;
bitflags! {
flags MousePacketFlags: u8 {
@ -18,6 +19,7 @@ bitflags! {
pub fn mouse(extra_packet: bool) {
let mut file = File::open("irq:12").expect("ps2d: failed to open irq:12");
let mut input = File::open("display:input").expect("ps2d: failed to open display:input");
let mut packets = [0; 4];
let mut packet_i = 0;
@ -40,23 +42,29 @@ pub fn mouse(extra_packet: bool) {
packet_i = 0;
} else if packet_i >= packets.len() || (!extra_packet && packet_i >= 3) {
if ! flags.contains(X_OVERFLOW) && ! flags.contains(Y_OVERFLOW) {
let mut dx = packets[1] as isize;
let mut dx = packets[1] as i32;
if flags.contains(X_SIGN) {
dx -= 0x100;
}
let mut dy = packets[2] as isize;
let mut dy = -(packets[2] as i32);
if flags.contains(Y_SIGN) {
dy -= 0x100;
dy += 0x100;
}
let extra = if extra_packet {
let _extra = if extra_packet {
packets[3]
} else {
0
};
print!("ps2d: IRQ {:?}, {}, {}, {}\n", flags, dx, dy, extra);
input.write(&MouseEvent {
x: dx,
y: dy,
left_button: flags.contains(LEFT_BUTTON),
middle_button: flags.contains(MIDDLE_BUTTON),
right_button: flags.contains(RIGHT_BUTTON)
}.to_event()).expect("ps2d: failed to write mouse event");
} else {
println!("ps2d: overflow {:X} {:X} {:X} {:X}", packets[0], packets[1], packets[2], packets[3]);
}
@ -66,8 +74,6 @@ pub fn mouse(extra_packet: bool) {
}
file.write(&irqs).expect("ps2d: failed to write irq:12");
} else {
thread::yield_now();
}
}
}

View file

@ -3,6 +3,7 @@ name = "vesad"
version = "0.1.0"
[dependencies]
orbclient = "0.1"
ransid = { git = "https://github.com/redox-os/ransid.git", branch = "new_api" }
rusttype = { git = "https://github.com/dylanede/rusttype.git", optional = true }
syscall = { path = "../../syscall/" }

View file

@ -4,6 +4,7 @@
#![feature(question_mark)]
extern crate alloc;
extern crate orbclient;
extern crate syscall;
use std::fs::File;

Some files were not shown because too many files have changed in this diff Show more