diff --git a/arch/x86_64/src/interrupt/irq.rs b/arch/x86_64/src/interrupt/irq.rs index ee5f72d..a36d019 100644 --- a/arch/x86_64/src/interrupt/irq.rs +++ b/arch/x86_64/src/interrupt/irq.rs @@ -1,8 +1,11 @@ +use spin::Mutex; use x86::io; use device::ps2::{PS2_KEYBOARD, PS2_MOUSE}; use device::serial::{COM1, COM2}; +pub static COUNTS: Mutex<[usize; 16]> = Mutex::new([0; 16]); + #[inline(always)] unsafe fn master_ack() { io::outb(0x20, 0x20); @@ -15,10 +18,12 @@ unsafe fn slave_ack() { } interrupt!(pit, { + COUNTS.lock()[0] += 1; master_ack(); }); interrupt!(keyboard, { + COUNTS.lock()[1] += 1; if let Some(ref mut keyboard) = *PS2_KEYBOARD.lock(){ keyboard.on_irq(); } @@ -26,56 +31,59 @@ interrupt!(keyboard, { }); interrupt!(cascade, { - print!("CASCADE\n"); + COUNTS.lock()[2] += 1; master_ack(); }); interrupt!(com2, { + COUNTS.lock()[3] += 1; COM2.lock().on_receive(); master_ack(); }); interrupt!(com1, { + COUNTS.lock()[4] += 1; COM1.lock().on_receive(); master_ack(); }); interrupt!(lpt2, { - print!("LPT2\n"); + COUNTS.lock()[5] += 1; master_ack(); }); interrupt!(floppy, { - print!("FLOPPY\n"); + COUNTS.lock()[6] += 1; master_ack(); }); interrupt!(lpt1, { - print!("LPT1\n"); + COUNTS.lock()[7] += 1; master_ack(); }); interrupt!(rtc, { - print!("RTC\n"); + COUNTS.lock()[8] += 1; slave_ack(); }); interrupt!(pci1, { - print!("PCI1\n"); + COUNTS.lock()[9] += 1; slave_ack(); }); interrupt!(pci2, { - print!("PCI2\n"); + COUNTS.lock()[10] += 1; slave_ack(); }); interrupt!(pci3, { - print!("PCI3\n"); + COUNTS.lock()[11] += 1; slave_ack(); }); interrupt!(mouse, { + COUNTS.lock()[12] += 1; if let Some(ref mut mouse) = *PS2_MOUSE.lock() { mouse.on_irq(); } @@ -83,16 +91,16 @@ interrupt!(mouse, { }); interrupt!(fpu, { - print!("FPU\n"); + COUNTS.lock()[13] += 1; slave_ack(); }); interrupt!(ata1, { - print!("ATA1\n"); + COUNTS.lock()[14] += 1; slave_ack(); }); interrupt!(ata2, { - print!("ATA2\n"); + COUNTS.lock()[15] += 1; slave_ack(); }); diff --git a/ion b/ion index cbb3c30..4d87d44 160000 --- a/ion +++ b/ion @@ -1 +1 @@ -Subproject commit cbb3c3003f654d09cd3b3cf1a179469bb1b558b3 +Subproject commit 4d87d44273ce1a408e833c7bc44312ad30c779ee diff --git a/kernel/scheme/debug.rs b/kernel/scheme/debug.rs index 8f63bf6..0dc6726 100644 --- a/kernel/scheme/debug.rs +++ b/kernel/scheme/debug.rs @@ -1,6 +1,6 @@ use collections::VecDeque; use core::str; -use spin::{Mutex, MutexGuard, Once}; +use spin::{Mutex, Once}; use context; use syscall::Result; diff --git a/kernel/scheme/irq.rs b/kernel/scheme/irq.rs new file mode 100644 index 0000000..9d7d42d --- /dev/null +++ b/kernel/scheme/irq.rs @@ -0,0 +1,57 @@ +use core::{mem, str}; + +use arch::interrupt::irq::COUNTS; +use context; +use syscall::{Error, Result}; +use super::Scheme; + +pub struct IrqScheme; + +impl Scheme for IrqScheme { + fn open(&mut self, path: &[u8], _flags: usize) -> Result { + let path_str = str::from_utf8(path).or(Err(Error::NoEntry))?; + let id = path_str.parse::().or(Err(Error::NoEntry))?; + if id < COUNTS.lock().len() { + Ok(id) + } else { + Err(Error::NoEntry) + } + } + + fn dup(&mut self, file: usize) -> Result { + Ok(file) + } + + fn read(&mut self, file: usize, buffer: &mut [u8]) -> Result { + // Ensures that the length of the buffer is larger than the size of a usize + if buffer.len() >= mem::size_of::() { + let current = 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::()); + unsafe { *(buffer.as_mut_ptr() as *mut usize) = next }; + return Ok(mem::size_of::()); + } else { + // Safe if all locks have been dropped + unsafe { context::switch(); } + } + } + } else { + Err(Error::InvalidValue) + } + } + + fn write(&mut self, _file: usize, _buffer: &[u8]) -> Result { + Err(Error::NotPermitted) + } + + fn fsync(&mut self, file: usize) -> Result<()> { + Ok(()) + } + + fn close(&mut self, file: usize) -> Result<()> { + Ok(()) + } +} diff --git a/kernel/scheme/mod.rs b/kernel/scheme/mod.rs index af9f0a9..6ca5c13 100644 --- a/kernel/scheme/mod.rs +++ b/kernel/scheme/mod.rs @@ -18,6 +18,7 @@ use syscall::{Error, Result}; use self::debug::DebugScheme; use self::env::EnvScheme; use self::initfs::InitFsScheme; +use self::irq::IrqScheme; /// Debug scheme pub mod debug; @@ -28,6 +29,9 @@ pub mod env; /// InitFS scheme pub mod initfs; +/// IRQ handling +pub mod irq; + /// Limit on number of schemes pub const SCHEME_MAX_SCHEMES: usize = 65536; @@ -98,6 +102,7 @@ fn init_schemes() -> RwLock { list.insert(Box::new(*b"debug"), Arc::new(Mutex::new(Box::new(DebugScheme)))).expect("failed to insert debug: scheme"); list.insert(Box::new(*b"env"), Arc::new(Mutex::new(Box::new(EnvScheme::new())))).expect("failed to insert env: scheme"); list.insert(Box::new(*b"initfs"), Arc::new(Mutex::new(Box::new(InitFsScheme::new())))).expect("failed to insert initfs: scheme"); + list.insert(Box::new(*b"irq"), Arc::new(Mutex::new(Box::new(IrqScheme)))).expect("failed to insert irq: scheme"); RwLock::new(list) }