Add wnohang, make PS/2 driver write input to display scheme, which then passes it to the shell

This commit is contained in:
Jeremy Soller 2016-09-22 10:10:27 -06:00
parent 046236c10f
commit 76b0c7eeea
9 changed files with 151 additions and 96 deletions

View file

@ -24,12 +24,12 @@ all: $(KBUILD)/harddrive.bin
clean: clean:
cargo clean cargo clean
cargo clean --manifest-path libstd/Cargo.toml cargo clean --manifest-path libstd/Cargo.toml
cargo clean --manifest-path init/Cargo.toml
cargo clean --manifest-path ion/Cargo.toml
cargo clean --manifest-path login/Cargo.toml
cargo clean --manifest-path drivers/ps2d/Cargo.toml cargo clean --manifest-path drivers/ps2d/Cargo.toml
cargo clean --manifest-path drivers/pcid/Cargo.toml cargo clean --manifest-path drivers/pcid/Cargo.toml
cargo clean --manifest-path drivers/vesad/Cargo.toml cargo clean --manifest-path drivers/vesad/Cargo.toml
cargo clean --manifest-path programs/init/Cargo.toml
cargo clean --manifest-path programs/ion/Cargo.toml
cargo clean --manifest-path programs/login/Cargo.toml
cargo clean --manifest-path schemes/example/Cargo.toml cargo clean --manifest-path schemes/example/Cargo.toml
rm -rf initfs/bin rm -rf initfs/bin
rm -rf build rm -rf build

View file

@ -42,7 +42,7 @@ impl Mapper {
/// Map a page to the next free frame /// Map a page to the next free frame
pub fn map(&mut self, page: Page, flags: EntryFlags) { pub fn map(&mut self, page: Page, flags: EntryFlags) {
let frame = allocate_frame().expect("out of memory"); let frame = allocate_frame().expect("out of frames");
self.map_to(page, frame, flags) self.map_to(page, frame, flags)
} }

View file

@ -5,9 +5,12 @@ use std::thread;
use keymap; use keymap;
pub fn keyboard() { pub fn keyboard() {
let mut file = File::open("irq:1").expect("ps2d: failed to open irq:1"); 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 { loop {
let mut irqs = [0; 8]; let mut irqs = [0; 8];
if file.read(&mut irqs).expect("ps2d: failed to read irq:1") >= mem::size_of::<usize>() { if file.read(&mut irqs).expect("ps2d: failed to read irq:1") >= mem::size_of::<usize>() {
@ -16,17 +19,25 @@ pub fn keyboard() {
asm!("in al, dx" : "={al}"(data) : "{dx}"(0x60) : : "intel", "volatile"); 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 { let (scancode, pressed) = if data >= 0x80 {
(data - 0x80, false) (data - 0x80, false)
} else { } else {
(data, true) (data, true)
}; };
if pressed { if scancode == 0x2A {
print!("{}", keymap::get_char(scancode)); lshift = pressed;
} else if scancode == 0x36 {
rshift = pressed;
} else if pressed {
let c = keymap::get_char(scancode, lshift || rshift);
if c != '\0' {
print!("{}", c);
input.write(&[c as u8]).expect("ps2d: failed to write input");
}
} }
file.write(&irqs).expect("ps2d: failed to write irq:1");
} else { } else {
thread::yield_now(); thread::yield_now();
} }

View file

@ -1,67 +1,71 @@
static ENGLISH: [[char; 3]; 58] = [ static ENGLISH: [[char; 2]; 58] = [
['\0', '\0', '\0'], ['\0', '\0'],
['\x1B', '\x1B', '\x1B'], ['\x1B', '\x1B'],
['1', '!', '1'], ['1', '!'],
['2', '@', '2'], ['2', '@'],
['3', '#', '3'], ['3', '#'],
['4', '$', '4'], ['4', '$'],
['5', '%', '5'], ['5', '%'],
['6', '^', '6'], ['6', '^'],
['7', '&', '7'], ['7', '&'],
['8', '*', '8'], ['8', '*'],
['9', '(', '9'], ['9', '('],
['0', ')', '0'], ['0', ')'],
['-', '_', '-'], ['-', '_'],
['=', '+', '='], ['=', '+'],
['\0', '\0', '\0'], ['\x7F', '\x7F'],
['\t', '\t', '\t'], ['\t', '\t'],
['q', 'Q', 'q'], ['q', 'Q'],
['w', 'W', 'w'], ['w', 'W'],
['e', 'E', 'e'], ['e', 'E'],
['r', 'R', 'r'], ['r', 'R'],
['t', 'T', 't'], ['t', 'T'],
['y', 'Y', 'y'], ['y', 'Y'],
['u', 'U', 'u'], ['u', 'U'],
['i', 'I', 'i'], ['i', 'I'],
['o', 'O', 'o'], ['o', 'O'],
['p', 'P', 'p'], ['p', 'P'],
['[', '{', '['], ['[', '{'],
[']', '}', ']'], [']', '}'],
['\n', '\n', '\n'], ['\n', '\n'],
['\0', '\0', '\0'], ['\0', '\0'],
['a', 'A', 'a'], ['a', 'A'],
['s', 'S', 's'], ['s', 'S'],
['d', 'D', 'd'], ['d', 'D'],
['f', 'F', 'f'], ['f', 'F'],
['g', 'G', 'g'], ['g', 'G'],
['h', 'H', 'h'], ['h', 'H'],
['j', 'J', 'j'], ['j', 'J'],
['k', 'K', 'k'], ['k', 'K'],
['l', 'L', 'l'], ['l', 'L'],
[';', ':', ';'], [';', ':'],
['\'', '"', '\''], ['\'', '"'],
['`', '~', '`'], ['`', '~'],
['\0', '\0', '\0'], ['\0', '\0'],
['\\', '|', '\\'], ['\\', '|'],
['z', 'Z', 'z'], ['z', 'Z'],
['x', 'X', 'x'], ['x', 'X'],
['c', 'C', 'c'], ['c', 'C'],
['v', 'V', 'v'], ['v', 'V'],
['b', 'B', 'b'], ['b', 'B'],
['n', 'N', 'n'], ['n', 'N'],
['m', 'M', 'm'], ['m', 'M'],
[',', '<', ','], [',', '<'],
['.', '>', '.'], ['.', '>'],
['/', '?', '/'], ['/', '?'],
['\0', '\0', '\0'], ['\0', '\0'],
['\0', '\0', '\0'], ['\0', '\0'],
['\0', '\0', '\0'], ['\0', '\0'],
[' ', ' ', ' '] [' ', ' ']
]; ];
pub fn get_char(scancode: u8) -> char { pub fn get_char(scancode: u8, shift: bool) -> char {
if let Some(c) = ENGLISH.get(scancode as usize) { if let Some(c) = ENGLISH.get(scancode as usize) {
c[0] if shift {
c[1]
} else {
c[0]
}
} else { } else {
'\0' '\0'
} }

View file

@ -8,6 +8,7 @@ extern crate ransid;
extern crate syscall; extern crate syscall;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::VecDeque;
use std::fs::File; use std::fs::File;
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::{slice, thread}; use std::{slice, thread};
@ -24,32 +25,55 @@ pub mod primitive;
struct DisplayScheme { struct DisplayScheme {
console: RefCell<Console>, console: RefCell<Console>,
display: RefCell<Display> display: RefCell<Display>,
input: RefCell<VecDeque<u8>>
} }
impl Scheme for DisplayScheme { impl Scheme for DisplayScheme {
fn open(&self, _path: &[u8], _flags: usize) -> Result<usize> { fn open(&self, path: &[u8], _flags: usize) -> Result<usize> {
Ok(0) if path == b"input" {
Ok(1)
} else {
Ok(0)
}
} }
fn dup(&self, _id: usize) -> Result<usize> { fn dup(&self, id: usize) -> Result<usize> {
Ok(0) Ok(id)
} }
fn fsync(&self, _id: usize) -> Result<usize> { fn fsync(&self, _id: usize) -> Result<usize> {
Ok(0) Ok(0)
} }
fn write(&self, _id: usize, buf: &[u8]) -> Result<usize> { fn read(&self, _id: usize, buf: &mut [u8]) -> Result<usize> {
let mut display = self.display.borrow_mut(); let mut i = 0;
self.console.borrow_mut().write(buf, |event| { let mut input = self.input.borrow_mut();
match event { while i < buf.len() && ! input.is_empty() {
Event::Char { x, y, c, color, .. } => display.char(x * 8, y * 16, c, color.data), buf[i] = input.pop_front().unwrap();
Event::Rect { x, y, w, h, color } => display.rect(x * 8, y * 16, w * 8, h * 16, color.data), i += 1;
Event::Scroll { rows, color } => display.scroll(rows * 16, color.data) }
Ok(i)
}
fn write(&self, id: usize, buf: &[u8]) -> Result<usize> {
if id == 1 {
let mut input = self.input.borrow_mut();
for &b in buf.iter() {
input.push_back(b);
} }
}); Ok(buf.len())
Ok(buf.len()) } else {
let mut display = self.display.borrow_mut();
self.console.borrow_mut().write(buf, |event| {
match event {
Event::Char { x, y, c, color, .. } => display.char(x * 8, y * 16, c, color.data),
Event::Rect { x, y, w, h, color } => display.rect(x * 8, y * 16, w * 8, h * 16, color.data),
Event::Scroll { rows, color } => display.scroll(rows * 16, color.data)
}
});
Ok(buf.len())
}
} }
fn close(&self, _id: usize) -> Result<usize> { fn close(&self, _id: usize) -> Result<usize> {
@ -89,15 +113,27 @@ fn main() {
display: RefCell::new(Display::new(width, height, display: RefCell::new(Display::new(width, height,
unsafe { slice::from_raw_parts_mut(onscreen as *mut u32, size) }, unsafe { slice::from_raw_parts_mut(onscreen as *mut u32, size) },
unsafe { slice::from_raw_parts_mut(offscreen as *mut u32, size) } unsafe { slice::from_raw_parts_mut(offscreen as *mut u32, size) }
)) )),
input: RefCell::new(VecDeque::new())
}; };
let mut blocked = VecDeque::new();
loop { loop {
let mut packet = Packet::default(); let mut packet = Packet::default();
socket.read(&mut packet).expect("vesad: failed to read display scheme"); socket.read(&mut packet).expect("vesad: failed to read display scheme");
//println!("vesad: {:?}", packet); //println!("vesad: {:?}", packet);
scheme.handle(&mut packet); if packet.a == syscall::number::SYS_READ && packet.d > 0 && scheme.input.borrow().is_empty() {
socket.write(&packet).expect("vesad: failed to write display scheme"); blocked.push_back(packet);
} else {
scheme.handle(&mut packet);
socket.write(&packet).expect("vesad: failed to write display scheme");
}
while ! scheme.input.borrow().is_empty() {
if let Some(mut packet) = blocked.pop_front() {
scheme.handle(&mut packet);
socket.write(&packet).expect("vesad: failed to write display scheme");
}
}
} }
}); });
} }

View file

@ -18,7 +18,7 @@ use elf::{self, program_header};
use scheme; use scheme;
use syscall; use syscall;
use syscall::error::*; use syscall::error::*;
use syscall::flag::{CLONE_VM, CLONE_FS, CLONE_FILES, MAP_WRITE, MAP_WRITE_COMBINE}; use syscall::flag::{CLONE_VM, CLONE_FS, CLONE_FILES, MAP_WRITE, MAP_WRITE_COMBINE, WNOHANG};
use syscall::validate::{validate_slice, validate_slice_mut}; use syscall::validate::{validate_slice, validate_slice_mut};
pub fn brk(address: usize) -> Result<usize> { pub fn brk(address: usize) -> Result<usize> {
@ -594,7 +594,7 @@ pub fn sched_yield() -> Result<usize> {
Ok(0) Ok(0)
} }
pub fn waitpid(pid: usize, status_ptr: usize, _options: usize) -> Result<usize> { pub fn waitpid(pid: usize, status_ptr: usize, flags: usize) -> Result<usize> {
//TODO: Implement status_ptr and options //TODO: Implement status_ptr and options
loop { loop {
{ {
@ -616,6 +616,8 @@ pub fn waitpid(pid: usize, status_ptr: usize, _options: usize) -> Result<usize>
if exited { if exited {
let mut contexts = context::contexts_mut(); let mut contexts = context::contexts_mut();
return contexts.remove(pid).ok_or(Error::new(ESRCH)).and(Ok(pid)); return contexts.remove(pid).ok_or(Error::new(ESRCH)).and(Ok(pid));
} else if flags & WNOHANG == WNOHANG {
return Ok(0);
} }
} }

2
libstd

@ -1 +1 @@
Subproject commit ae80aff4d39b2d3a83f7d32bc95739e4e1169184 Subproject commit a5a6e9fe349d80918d6fc233d23530c4bf3b4f96

View file

@ -11,13 +11,13 @@ pub fn main() {
let sh = args.next().expect("login: no sh provided"); let sh = args.next().expect("login: no sh provided");
let sh_args: Vec<String> = args.collect(); let sh_args: Vec<String> = args.collect();
syscall::close(2); let _ = syscall::close(2);
syscall::close(1); let _ = syscall::close(1);
syscall::close(0); let _ = syscall::close(0);
syscall::open(&tty, syscall::flag::O_RDWR); let _ = syscall::open(&tty, syscall::flag::O_RDWR);
syscall::open(&tty, syscall::flag::O_RDWR); let _ = syscall::open(&tty, syscall::flag::O_RDWR);
syscall::open(&tty, syscall::flag::O_RDWR); let _ = syscall::open(&tty, syscall::flag::O_RDWR);
thread::spawn(move || { thread::spawn(move || {
loop { loop {

View file

@ -41,3 +41,5 @@ pub const O_FSYNC: usize = 0x80;
pub const O_CREAT: usize = 0x200; pub const O_CREAT: usize = 0x200;
pub const O_TRUNC: usize = 0x400; pub const O_TRUNC: usize = 0x400;
pub const O_EXCL: usize = 0x800; pub const O_EXCL: usize = 0x800;
pub const WNOHANG: usize = 1;