From 4403e3e7acc41b5a9b088e20589d427a11dc0ae0 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Sun, 18 Sep 2016 20:17:08 -0600 Subject: [PATCH] Allow userspace to handle IRQs (WIP). Create basic keyboard handler --- context/memory.rs | 2 +- scheme/initfs.rs | 3 ++- scheme/irq.rs | 46 +++++++++++++++++++++++++++++++--------------- syscall/process.rs | 4 ++-- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/context/memory.rs b/context/memory.rs index 34e69a30..8f1fecbb 100644 --- a/context/memory.rs +++ b/context/memory.rs @@ -13,7 +13,7 @@ pub struct Memory { flags: EntryFlags } -#[derive(Debug)] +#[derive(Clone, Debug)] pub enum SharedMemory { Owned(Arc<Mutex<Memory>>), Borrowed(Weak<Mutex<Memory>>) diff --git a/scheme/initfs.rs b/scheme/initfs.rs index 0b15bd23..aa5e7ff5 100644 --- a/scheme/initfs.rs +++ b/scheme/initfs.rs @@ -21,7 +21,8 @@ impl InitFsScheme { files.insert(b"bin/init", include_bytes!("../../build/userspace/init")); files.insert(b"bin/ion", include_bytes!("../../build/userspace/ion")); files.insert(b"bin/pcid", include_bytes!("../../build/userspace/pcid")); - files.insert(b"etc/init.rc", b"echo testing\ninitfs:bin/pcid\ninitfs:bin/ion"); + files.insert(b"bin/ps2d", include_bytes!("../../build/userspace/ps2d")); + files.insert(b"etc/init.rc", b"echo testing\n#initfs:bin/pcid\ninitfs:bin/ps2d\n#initfs:bin/ion"); InitFsScheme { next_id: 0, diff --git a/scheme/irq.rs b/scheme/irq.rs index 9d7d42da..8eee59db 100644 --- a/scheme/irq.rs +++ b/scheme/irq.rs @@ -1,6 +1,6 @@ use core::{mem, str}; -use arch::interrupt::irq::COUNTS; +use arch::interrupt::irq::{COUNTS, acknowledge}; use context; use syscall::{Error, Result}; use super::Scheme; @@ -10,7 +10,9 @@ pub struct IrqScheme; impl Scheme for IrqScheme { fn open(&mut self, path: &[u8], _flags: usize) -> Result<usize> { let path_str = str::from_utf8(path).or(Err(Error::NoEntry))?; + let id = path_str.parse::<usize>().or(Err(Error::NoEntry))?; + if id < COUNTS.lock().len() { Ok(id) } else { @@ -19,35 +21,49 @@ impl Scheme for IrqScheme { } fn dup(&mut self, file: usize) -> Result<usize> { - Ok(file) + Err(Error::NotPermitted) } fn read(&mut self, file: usize, buffer: &mut [u8]) -> Result<usize> { // Ensures that the length of the buffer is larger than the size of a usize if buffer.len() >= mem::size_of::<usize>() { - let current = COUNTS.lock()[file]; + let prev = { COUNTS.lock()[file] }; loop { - let next = COUNTS.lock()[file]; - if next != current { - // Safe if the length of the buffer is larger than the size of a usize - assert!(buffer.len() >= mem::size_of::<usize>()); - unsafe { *(buffer.as_mut_ptr() as *mut usize) = next }; - return Ok(mem::size_of::<usize>()); - } else { - // Safe if all locks have been dropped - unsafe { context::switch(); } + { + let current = COUNTS.lock()[file]; + if prev != current { + // Safe if the length of the buffer is larger than the size of a usize + assert!(buffer.len() >= mem::size_of::<usize>()); + unsafe { *(buffer.as_mut_ptr() as *mut usize) = current; } + return Ok(mem::size_of::<usize>()); + } } + + // Safe if all locks have been dropped + unsafe { context::switch(); } } } else { Err(Error::InvalidValue) } } - fn write(&mut self, _file: usize, _buffer: &[u8]) -> Result<usize> { - Err(Error::NotPermitted) + fn write(&mut self, file: usize, buffer: &[u8]) -> Result<usize> { + if buffer.len() >= mem::size_of::<usize>() { + assert!(buffer.len() >= mem::size_of::<usize>()); + let prev = unsafe { *(buffer.as_ptr() as *const usize) }; + let current = COUNTS.lock()[file]; + if prev == current { + unsafe { acknowledge(file); } + return Ok(mem::size_of::<usize>()); + } else { + return Ok(0); + } + } else { + Err(Error::InvalidValue) + } } - fn fsync(&mut self, file: usize) -> Result<()> { + fn fsync(&mut self, _file: usize) -> Result<()> { Ok(()) } diff --git a/syscall/process.rs b/syscall/process.rs index 383141cb..f05271a9 100644 --- a/syscall/process.rs +++ b/syscall/process.rs @@ -96,11 +96,11 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { if flags & CLONE_VM == CLONE_VM { for memory_shared in context.image.iter() { - image.push(memory_shared.borrow()); + image.push(memory_shared.clone()); } if let Some(ref heap_shared) = context.heap { - heap_option = Some(heap_shared.borrow()); + heap_option = Some(heap_shared.clone()); } } else { for memory_shared in context.image.iter() { -- GitLab