diff --git a/Cargo.toml b/Cargo.toml index 35cf50f4a60bfc6112aa0e7f353598862bf2a894..5ee7cdb15f144fc8b826cdfda12bf21776c256ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,11 +31,13 @@ version = "0.9.0" default-features = false [features] -default = [] +default = ["qemu_debug"] acpi = [] doc = [] graphical_debug = [] live = [] multi_core = [] pti = [] +qemu_debug = [] +serial_debug = [] slab = ["slab_allocator"] diff --git a/src/arch/x86_64/debug.rs b/src/arch/x86_64/debug.rs index 2398d92dd9254aeaaf7733ce8b4c194a5be5ab67..5519fd9a4bdc39b0ddba8fc105ffc86f3da144f4 100644 --- a/src/arch/x86_64/debug.rs +++ b/src/arch/x86_64/debug.rs @@ -1,41 +1,66 @@ use core::fmt; -use spin::MutexGuard; +use spin::{Mutex, MutexGuard}; -use devices::uart_16550::SerialPort; +#[cfg(feature = "qemu_debug")] +use syscall::io::Io; use syscall::io::Pio; +#[cfg(feature = "serial_debug")] +use devices::uart_16550::SerialPort; -use super::device::serial::COM1; #[cfg(feature = "graphical_debug")] use super::graphical_debug::{DEBUG_DISPLAY, DebugDisplay}; +#[cfg(feature = "serial_debug")] +use super::device::serial::COM1; + +#[cfg(feature = "qemu_debug")] +pub static QEMU: Mutex<Pio<u8>> = Mutex::new(Pio::<u8>::new(0x402)); pub struct Writer<'a> { - serial: MutexGuard<'a, SerialPort<Pio<u8>>>, #[cfg(feature = "graphical_debug")] - display: MutexGuard<'a, Option<DebugDisplay>> + display: MutexGuard<'a, Option<DebugDisplay>>, + #[cfg(feature = "qemu_debug")] + qemu: MutexGuard<'a, Pio<u8>>, + #[cfg(feature = "serial_debug")] + serial: MutexGuard<'a, SerialPort<Pio<u8>>>, } impl<'a> Writer<'a> { pub fn new() -> Writer<'a> { Writer { - serial: COM1.lock(), #[cfg(feature = "graphical_debug")] display: DEBUG_DISPLAY.lock(), + #[cfg(feature = "qemu_debug")] + qemu: QEMU.lock(), + #[cfg(feature = "serial_debug")] + serial: COM1.lock(), } } -} -impl<'a> fmt::Write for Writer<'a> { - #[cfg(not(feature = "graphical_debug"))] - fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { - self.serial.write_str(s) - } + pub fn write(&mut self, buf: &[u8]) { + #[cfg(feature = "graphical_debug")] + { + if let Some(ref mut display) = *self.display { + let _ = display.write(buf); + } + } - #[cfg(feature = "graphical_debug")] - fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { - if let Some(ref mut display) = *self.display { - let _ = display.write_str(s); + #[cfg(feature = "qemu_debug")] + { + for &b in buf { + self.qemu.write(b); + } } - self.serial.write_str(s) + #[cfg(feature = "serial_debug")] + { + self.serial.write(buf); + } + } +} + +impl<'a> fmt::Write for Writer<'a> { + fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { + self.write(s.as_bytes()); + Ok(()) } } diff --git a/src/arch/x86_64/graphical_debug/debug.rs b/src/arch/x86_64/graphical_debug/debug.rs index 21dcf94dc358ad0aa0303525546979151e80a512..c0cbc3c557edd0ac8bc41269267932c541a8efae 100644 --- a/src/arch/x86_64/graphical_debug/debug.rs +++ b/src/arch/x86_64/graphical_debug/debug.rs @@ -27,7 +27,7 @@ impl DebugDisplay { self.display } - pub fn write(&mut self, c: char) { + pub fn write_char(&mut self, c: char) { if self.x >= self.w || c == '\n' { self.x = 0; self.y += 1; @@ -74,14 +74,10 @@ impl DebugDisplay { self.x += 1; } } -} -impl fmt::Write for DebugDisplay { - fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { - for c in s.chars() { - self.write(c); + pub fn write(&mut self, buf: &[u8]) { + for &b in buf { + self.write_char(b as char); } - - Ok(()) } } diff --git a/src/arch/x86_64/interrupt/irq.rs b/src/arch/x86_64/interrupt/irq.rs index 17adbd0973d82918d7a829f987ed899f27e8c6de..c782f42037b594caaf1fc6d138d2a1e51ae0661b 100644 --- a/src/arch/x86_64/interrupt/irq.rs +++ b/src/arch/x86_64/interrupt/irq.rs @@ -5,6 +5,7 @@ use context::timeout; use device::pic; use device::serial::{COM1, COM2}; use ipi::{ipi, IpiKind, IpiTarget}; +use scheme::debug::debug_input; use time; //resets to 0 in context::switch() @@ -74,12 +75,16 @@ interrupt!(cascade, { }); interrupt!(com2, { - COM2.lock().receive(); + while let Some(c) = COM2.lock().receive() { + debug_input(c); + } pic::MASTER.ack(); }); interrupt!(com1, { - COM1.lock().receive(); + while let Some(c) = COM1.lock().receive() { + debug_input(c); + } pic::MASTER.ack(); }); diff --git a/src/devices/uart_16550.rs b/src/devices/uart_16550.rs index 9e2566fa8bf6a92fd26d48b8b9f9418fb52cc70b..b5e0b2fb5eab5bc8d3008e7f178272a2cf1284cf 100644 --- a/src/devices/uart_16550.rs +++ b/src/devices/uart_16550.rs @@ -1,6 +1,3 @@ -use core::fmt::{self, Write}; - -use scheme::debug::debug_input; use syscall::io::{Io, Pio, Mmio, ReadOnly}; bitflags! { @@ -75,7 +72,7 @@ impl<T: Io<Value = u8>> SerialPort<T> { //TODO: Cleanup self.int_en.write(0x00); self.line_ctrl.write(0x80); - self.data.write(0x03); + self.data.write(0x01); self.int_en.write(0x00); self.line_ctrl.write(0x03); self.fifo_ctrl.write(0xC7); @@ -87,37 +84,31 @@ impl<T: Io<Value = u8>> SerialPort<T> { LineStsFlags::from_bits_truncate(self.line_sts.read()) } - pub fn receive(&mut self) { - while self.line_sts().contains(LineStsFlags::INPUT_FULL) { - let b = self.data.read(); - debug_input(b); + pub fn receive(&mut self) -> Option<u8> { + if self.line_sts().contains(LineStsFlags::INPUT_FULL) { + Some(self.data.read()) + } else { + None } } pub fn send(&mut self, data: u8) { - match data { - 8 | 0x7F => { - while ! self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {} - self.data.write(8); - while ! self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {} - self.data.write(b' '); - while ! self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {} - self.data.write(8); - }, - _ => { - while ! self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {} - self.data.write(data); - } - } + while ! self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {} + self.data.write(data); } -} -impl<T: Io<Value = u8>> Write for SerialPort<T> { - fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { - for byte in s.bytes() { - self.send(byte); + pub fn write(&mut self, buf: &[u8]) { + for &b in buf { + match b { + 8 | 0x7F => { + self.send(8); + self.send(b' '); + self.send(8); + }, + _ => { + self.send(b); + } + } } - - Ok(()) } } diff --git a/src/scheme/debug.rs b/src/scheme/debug.rs index 4f1cec5be3453c4fc8a21f2ceae1e6feae52eb55..35de9cc678d51a503a9468dc83e9c7b927c0b317 100644 --- a/src/scheme/debug.rs +++ b/src/scheme/debug.rs @@ -1,7 +1,7 @@ use core::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard}; -use device::serial::COM1; +use arch::debug::Writer; use event; use scheme::*; use sync::WaitQueue; @@ -76,18 +76,14 @@ impl Scheme for DebugScheme { /// Write the `buffer` to the `file` /// /// Returns the number of bytes written - fn write(&self, id: usize, buffer: &[u8]) -> Result<usize> { + fn write(&self, id: usize, buf: &[u8]) -> Result<usize> { let _flags = { let handles = handles(); *handles.get(&id).ok_or(Error::new(EBADF))? }; - let mut com = COM1.lock(); - for &byte in buffer.iter() { - com.send(byte); - } - - Ok(buffer.len()) + Writer::new().write(buf); + Ok(buf.len()) } fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> {