From 05a5c52f6801465b52cdf4e821b253657ffdf4bc Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 14 Oct 2016 12:54:37 -0600 Subject: [PATCH] Use a single thread for ps/2 driver --- crates/event/src/lib.rs | 2 - drivers/ps2d/Cargo.toml | 1 + drivers/ps2d/src/keyboard.rs | 44 ----------- drivers/ps2d/src/main.rs | 148 ++++++++++++++++++++++++++++++----- drivers/ps2d/src/mouse.rs | 79 ------------------- 5 files changed, 131 insertions(+), 143 deletions(-) delete mode 100644 drivers/ps2d/src/keyboard.rs delete mode 100644 drivers/ps2d/src/mouse.rs diff --git a/crates/event/src/lib.rs b/crates/event/src/lib.rs index 54c0f34..965f2e9 100644 --- a/crates/event/src/lib.rs +++ b/crates/event/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(question_mark)] - extern crate syscall; use std::collections::BTreeMap; diff --git a/drivers/ps2d/Cargo.toml b/drivers/ps2d/Cargo.toml index 31bb252..0c10180 100644 --- a/drivers/ps2d/Cargo.toml +++ b/drivers/ps2d/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" [dependencies] bitflags = "*" +event = { path = "../../crates/event/" } io = { path = "../../crates/io/" } orbclient = "0.1" syscall = { path = "../../syscall/" } diff --git a/drivers/ps2d/src/keyboard.rs b/drivers/ps2d/src/keyboard.rs deleted file mode 100644 index 5384d69..0000000 --- a/drivers/ps2d/src/keyboard.rs +++ /dev/null @@ -1,44 +0,0 @@ -use std::fs::File; -use std::io::{Read, Write}; -use std::mem; - -use orbclient::KeyEvent; - -use keymap; - -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 lshift = false; - let mut rshift = false; - loop { - let mut irqs = [0; 8]; - if file.read(&mut irqs).expect("ps2d: failed to read irq:1") >= mem::size_of::() { - let data: u8; - unsafe { - asm!("in al, dx" : "={al}"(data) : "{dx}"(0x60) : : "intel", "volatile"); - } - - file.write(&irqs).expect("ps2d: failed to write irq:1"); - - let (scancode, pressed) = if data >= 0x80 { - (data - 0x80, false) - } else { - (data, true) - }; - - if scancode == 0x2A { - lshift = pressed; - } else if scancode == 0x36 { - rshift = pressed; - } - - input.write(&KeyEvent { - character: keymap::get_char(scancode, lshift || rshift), - scancode: scancode, - pressed: pressed - }.to_event()).expect("ps2d: failed to write key event"); - } - } -} diff --git a/drivers/ps2d/src/main.rs b/drivers/ps2d/src/main.rs index 60d1bfc..d1f1bff 100644 --- a/drivers/ps2d/src/main.rs +++ b/drivers/ps2d/src/main.rs @@ -2,42 +2,154 @@ #[macro_use] extern crate bitflags; +extern crate event; extern crate io; extern crate orbclient; extern crate syscall; -use std::thread; +use std::fs::File; +use std::io::{Read, Write, Result}; +use std::os::unix::io::AsRawFd; +use std::{mem, thread}; +use event::EventQueue; +use orbclient::{KeyEvent, MouseEvent}; use syscall::iopl; mod controller; -mod keyboard; mod keymap; -mod mouse; + +bitflags! { + flags MousePacketFlags: u8 { + const LEFT_BUTTON = 1, + const RIGHT_BUTTON = 1 << 1, + const MIDDLE_BUTTON = 1 << 2, + const ALWAYS_ON = 1 << 3, + const X_SIGN = 1 << 4, + const Y_SIGN = 1 << 5, + const X_OVERFLOW = 1 << 6, + const Y_OVERFLOW = 1 << 7 + } +} fn main() { - unsafe { - iopl(3).expect("ps2d: failed to get I/O permission"); - asm!("cli" :::: "intel", "volatile"); - } - - let extra_packet = controller::Ps2::new().init(); - thread::spawn(|| { unsafe { iopl(3).expect("ps2d: failed to get I/O permission"); asm!("cli" :::: "intel", "volatile"); } - keyboard::keyboard(); - }); + let extra_packet = controller::Ps2::new().init(); - thread::spawn(move || { - unsafe { - iopl(3).expect("ps2d: failed to get I/O permission"); - asm!("cli" :::: "intel", "volatile"); + let mut input = File::open("display:input").expect("ps2d: failed to open display:input"); + + let mut event_queue = EventQueue::<(bool, u8)>::new().expect("ps2d: failed to create event queue"); + + let mut key_irq = File::open("irq:1").expect("ps2d: failed to open irq:1"); + + event_queue.add(key_irq.as_raw_fd(), move |_count: usize| -> Result> { + let mut irq = [0; 8]; + if key_irq.read(&mut irq)? >= mem::size_of::() { + let data: u8; + unsafe { + asm!("in al, dx" : "={al}"(data) : "{dx}"(0x60) : : "intel", "volatile"); + } + + key_irq.write(&irq)?; + + Ok(Some((true, data))) + } else { + Ok(None) + } + }).expect("ps2d: failed to poll irq:1"); + + let mut mouse_irq = File::open("irq:12").expect("ps2d: failed to open irq:12"); + + event_queue.add(mouse_irq.as_raw_fd(), move |_count: usize| -> Result> { + let mut irq = [0; 8]; + if mouse_irq.read(&mut irq)? >= mem::size_of::() { + let data: u8; + unsafe { + asm!("in al, dx" : "={al}"(data) : "{dx}"(0x60) : : "intel", "volatile"); + } + + mouse_irq.write(&irq)?; + + Ok(Some((false, data))) + } else { + Ok(None) + } + }).expect("ps2d: failed to poll irq:12"); + + let mut lshift = false; + let mut rshift = false; + let mut packets = [0; 4]; + let mut packet_i = 0; + + loop { + let (keyboard, data) = event_queue.run().expect("ps2d: failed to handle events"); + + if keyboard { + let (scancode, pressed) = if data >= 0x80 { + (data - 0x80, false) + } else { + (data, true) + }; + + if scancode == 0x2A { + lshift = pressed; + } else if scancode == 0x36 { + rshift = pressed; + } + + input.write(&KeyEvent { + character: keymap::get_char(scancode, lshift || rshift), + scancode: scancode, + pressed: pressed + }.to_event()).expect("ps2d: failed to write key event"); + } else { + packets[packet_i] = data; + packet_i += 1; + + let flags = MousePacketFlags::from_bits_truncate(packets[0]); + if ! flags.contains(ALWAYS_ON) { + println!("MOUSE MISALIGN {:X}", packets[0]); + + packets = [0; 4]; + 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 i32; + if flags.contains(X_SIGN) { + dx -= 0x100; + } + + let mut dy = -(packets[2] as i32); + if flags.contains(Y_SIGN) { + dy += 0x100; + } + + let _extra = if extra_packet { + packets[3] + } else { + 0 + }; + + 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]); + } + + packets = [0; 4]; + packet_i = 0; + } + } } - - mouse::mouse(extra_packet); }); } diff --git a/drivers/ps2d/src/mouse.rs b/drivers/ps2d/src/mouse.rs deleted file mode 100644 index 0b96bf6..0000000 --- a/drivers/ps2d/src/mouse.rs +++ /dev/null @@ -1,79 +0,0 @@ -use std::fs::File; -use std::io::{Read, Write}; -use std::mem; - -use orbclient::MouseEvent; - -bitflags! { - flags MousePacketFlags: u8 { - const LEFT_BUTTON = 1, - const RIGHT_BUTTON = 1 << 1, - const MIDDLE_BUTTON = 1 << 2, - const ALWAYS_ON = 1 << 3, - const X_SIGN = 1 << 4, - const Y_SIGN = 1 << 5, - const X_OVERFLOW = 1 << 6, - const Y_OVERFLOW = 1 << 7 - } -} - -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; - loop { - let mut irqs = [0; 8]; - if file.read(&mut irqs).expect("ps2d: failed to read irq:12") >= mem::size_of::() { - let data: u8; - unsafe { - asm!("in al, dx" : "={al}"(data) : "{dx}"(0x60) : : "intel", "volatile"); - } - - file.write(&irqs).expect("ps2d: failed to write irq:12"); - - packets[packet_i] = data; - packet_i += 1; - - let flags = MousePacketFlags::from_bits_truncate(packets[0]); - if ! flags.contains(ALWAYS_ON) { - println!("MOUSE MISALIGN {:X}", packets[0]); - - packets = [0; 4]; - 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 i32; - if flags.contains(X_SIGN) { - dx -= 0x100; - } - - let mut dy = -(packets[2] as i32); - if flags.contains(Y_SIGN) { - dy += 0x100; - } - - let _extra = if extra_packet { - packets[3] - } else { - 0 - }; - - 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]); - } - - packets = [0; 4]; - packet_i = 0; - } - } - } -}