From b80f38b03950a65821edc2560dc2f32222522bfd Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jeremy@system76.com> Date: Mon, 11 Mar 2019 19:50:50 -0600 Subject: [PATCH] More debugging output options --- Cargo.toml | 4 +- src/arch/x86_64/debug.rs | 59 +++++++++++++++++------- src/arch/x86_64/graphical_debug/debug.rs | 12 ++--- src/arch/x86_64/interrupt/irq.rs | 9 +++- src/devices/uart_16550.rs | 49 ++++++++------------ src/scheme/debug.rs | 12 ++--- 6 files changed, 80 insertions(+), 65 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 35cf50f4..5ee7cdb1 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 2398d92d..5519fd9a 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 21dcf94d..c0cbc3c5 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 17adbd09..c782f420 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 9e2566fa..b5e0b2fb 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 4f1cec5b..35de9cc6 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> { -- GitLab