From 0d827c282056f080022bf8a084b7d3743d65bd9b Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Mon, 18 Oct 2021 13:04:36 +0300 Subject: [PATCH] feat: better debugging levels --- kernel/src/arch/aarch64/boot/mod.rs | 11 ++--- kernel/src/arch/aarch64/context.rs | 2 - kernel/src/arch/aarch64/exception.rs | 31 +++++-------- kernel/src/debug.rs | 69 +++++++++++++++++++++++++--- kernel/src/dev/fdt.rs | 43 ++++++++--------- kernel/src/dev/pci/pcie/gpex.rs | 2 +- kernel/src/main.rs | 2 +- kernel/src/mem/heap.rs | 2 +- kernel/src/mem/phys/mod.rs | 4 +- kernel/src/mem/phys/reserved.rs | 2 +- kernel/src/mem/virt/table.rs | 1 - kernel/src/proc/mod.rs | 1 - 12 files changed, 106 insertions(+), 64 deletions(-) diff --git a/kernel/src/arch/aarch64/boot/mod.rs b/kernel/src/arch/aarch64/boot/mod.rs index 6f28939..dec33bd 100644 --- a/kernel/src/arch/aarch64/boot/mod.rs +++ b/kernel/src/arch/aarch64/boot/mod.rs @@ -52,18 +52,17 @@ extern "C" fn __aa64_bsp_main(fdt_base: usize) -> ! { machine::init_board().unwrap(); if fdt_base != 0 { - debugln!("fdt_base = {:#x}", fdt_base); let fdt = DeviceTree::from_phys(fdt_base + 0xFFFFFF8000000000); - if let Ok(fdt) = fdt { - fdt.dump(); + if let Ok(_fdt) = fdt { + // fdt.dump(Level::Debug); } else { - debugln!("Failed to init FDT"); + errorln!("Failed to init FDT"); } } else { - debugln!("No FDT present"); + warnln!("No FDT present"); } - debugln!("Machine init finished"); + infoln!("Machine init finished"); unsafe { machine::local_timer().enable().unwrap(); diff --git a/kernel/src/arch/aarch64/context.rs b/kernel/src/arch/aarch64/context.rs index 09a5e36..43986dc 100644 --- a/kernel/src/arch/aarch64/context.rs +++ b/kernel/src/arch/aarch64/context.rs @@ -24,8 +24,6 @@ impl Context { pub fn kernel(entry: usize, arg: usize, ttbr0: usize, ustack: usize) -> Self { let mut stack = Stack::new(8); - debugln!("STACK {:#x}, {:#x}", stack.bp, stack.bp + 8 * 4096); - stack.push(entry); stack.push(arg); stack.push(ttbr0); diff --git a/kernel/src/arch/aarch64/exception.rs b/kernel/src/arch/aarch64/exception.rs index 08f1159..60bc656 100644 --- a/kernel/src/arch/aarch64/exception.rs +++ b/kernel/src/arch/aarch64/exception.rs @@ -4,6 +4,7 @@ use crate::arch::machine; use crate::dev::irq::{IntController, IrqContext}; use cortex_a::registers::{ESR_EL1, FAR_EL1}; use tock_registers::interfaces::Readable; +use crate::debug::Level; /// Trapped SIMD/FP functionality pub const EC_FP_TRAP: u64 = 0b000111; @@ -50,20 +51,20 @@ extern "C" fn __aa64_exc_irq_handler(_exc: &mut ExceptionFrame) { } } -fn dump_data_abort(esr: u64, far: u64) { +fn dump_data_abort(level: Level, esr: u64, far: u64) { let iss = esr & 0x1FFFFFF; - debugln!("Data Abort:"); + println!(level, "Data Abort:"); - debug!(" Illegal {}", data_abort_access_type(iss),); + print!(level, " Illegal {}", data_abort_access_type(iss),); if iss & (1 << 24) != 0 { - debug!(" of a {}", data_abort_access_size(iss)); + print!(level, " of a {}", data_abort_access_size(iss)); } if iss & (1 << 10) == 0 { - debug!(" at {:#018x}", far); + print!(level, " at {:#018x}", far); } else { - debug!(" at UNKNOWN"); + print!(level, " at UNKNOWN"); } - debugln!(""); + print!(level, ""); } #[no_mangle] @@ -75,32 +76,22 @@ extern "C" fn __aa64_exc_sync_handler(exc: &mut ExceptionFrame) { match err_code { EC_DATA_ABORT_ELX => { let far = FAR_EL1.get(); - dump_data_abort(esr, far); + dump_data_abort(Level::Error, esr, far); } EC_SVC_AA64 => { - debugln!("{:#x} {:#x}", exc.x[0], exc.x[1]); + infoln!("{:#x} {:#x}", exc.x[0], exc.x[1]); return; } _ => {} } - debugln!( + errorln!( "Unhandled exception at ELR={:#018x}, ESR={:#010x}, exc ctx @ {:p}", exc.elr_el1, esr, exc ); - if exc.sp_el0 == 0xFFFFFF50 { - for i in 0..10 { - debugln!("[{:#x}] {:#x}", exc.sp_el0 + i * 8, unsafe { - core::ptr::read((exc.sp_el0 + i * 8) as *const u64) - }); - } - } - - debugln!("{:#x?}", exc); - panic!("Unhandled exception"); } diff --git a/kernel/src/debug.rs b/kernel/src/debug.rs index 4650e41..0dc1e5e 100644 --- a/kernel/src/debug.rs +++ b/kernel/src/debug.rs @@ -7,6 +7,19 @@ use crate::dev::serial::SerialDevice; use core::fmt; +/// Kernel logging levels +#[derive(Clone, Copy, PartialEq)] +pub enum Level { + /// Debugging information + Debug, + /// General informational messages + Info, + /// Non-critical warnings + Warn, + /// Critical errors + Error, +} + struct SerialOutput { inner: &'static T, } @@ -24,22 +37,64 @@ impl fmt::Write for SerialOutput { } } -/// Writes a debug message to debug output +/// Writes a formatted message to output stream #[macro_export] -macro_rules! debug { - ($($it:tt)+) => ($crate::debug::_debug(format_args!($($it)+))) +macro_rules! print { + ($level:expr, $($it:tt)+) => ($crate::debug::_debug($level, format_args!($($it)+))) } -/// Writes a debug message, followed by a newline, to debug output +/// Writes a formatted message, followed by a newline, to output stream +#[macro_export] +macro_rules! println { + ($level:expr, $($it:tt)+) => (print!($level, "{}\n", format_args!($($it)+))) +} + +/// Writes a message, annotated with current file and line, with a newline, to +/// debug level output. /// -/// See [debug!] +/// See [println!]. #[macro_export] macro_rules! debugln { - ($($it:tt)+) => (debug!("{}\n", format_args!($($it)+))) + ($($it:tt)+) => ( + print!($crate::debug::Level::Debug, "[{}:{}] {}\n", file!(), line!(), format_args!($($it)+)) + ) +} + +/// Writes a message, annotated with current file and line, with a newline, to +/// info level output. +/// +/// See [println!]. +#[macro_export] +macro_rules! infoln { + ($($it:tt)+) => ( + print!($crate::debug::Level::Info, "\x1B[1m[{}:{}] {}\x1B[0m\n", file!(), line!(), format_args!($($it)+)) + ) +} + +/// Writes a message, annotated with current file and line, with a newline, to +/// warning level output. +/// +/// See [println!]. +#[macro_export] +macro_rules! warnln { + ($($it:tt)+) => ( + print!($crate::debug::Level::Warn, "\x1B[33;1m[{}:{}] {}\x1B[0m\n", file!(), line!(), format_args!($($it)+)) + ) +} + +/// Writes a message, annotated with current file and line, with a newline, to +/// error level output. +/// +/// See [println!]. +#[macro_export] +macro_rules! errorln { + ($($it:tt)+) => ( + print!($crate::debug::Level::Error, "\x1B[41;1m[{}:{}] {}\x1B[0m\n", file!(), line!(), format_args!($($it)+)) + ) } #[doc(hidden)] -pub fn _debug(args: fmt::Arguments) { +pub fn _debug(_level: Level, args: fmt::Arguments) { use crate::arch::machine; use fmt::Write; diff --git a/kernel/src/dev/fdt.rs b/kernel/src/dev/fdt.rs index b84854b..b67e654 100644 --- a/kernel/src/dev/fdt.rs +++ b/kernel/src/dev/fdt.rs @@ -1,5 +1,6 @@ use error::Errno; use fdt_rs::prelude::*; +use crate::debug::Level; use fdt_rs::{ base::DevTree, index::{DevTreeIndex, DevTreeIndexNode}, @@ -20,59 +21,59 @@ pub struct DeviceTree { index: DevTreeIndex<'static, 'static>, } -fn tab(depth: usize) { +fn tab(level: Level, depth: usize) { for _ in 0..depth { - debug!("\t"); + print!(level, "\t"); } } -fn dump_node(node: &INode, depth: usize) { +fn dump_node(level: Level, node: &INode, depth: usize) { if node.name().unwrap().starts_with("virtio_mmio@") { return; } - tab(depth); - debugln!("{:?} {{", node.name().unwrap()); + tab(level, depth); + println!(level, "{:?} {{", node.name().unwrap()); for prop in node.props() { - tab(depth + 1); + tab(level, depth + 1); let name = prop.name().unwrap(); - debug!("{:?} = ", name); + print!(level, "{:?} = ", name); match name { - "compatible" => debug!("{:?}", prop.str().unwrap()), - "#address-cells" | "#size-cells" => debug!("{}", prop.u32(0).unwrap()), + "compatible" => print!(level, "{:?}", prop.str().unwrap()), + "#address-cells" | "#size-cells" => print!(level, "{}", prop.u32(0).unwrap()), "reg" => { - debug!("<"); + print!(level, "<"); let len = prop.length() / 4; for i in 0..len { - debug!("{:#010x}", prop.u32(i).unwrap()); + print!(level, "{:#010x}", prop.u32(i).unwrap()); if i < len - 1 { - debug!(", "); + print!(level, ", "); } } - debug!(">"); + print!(level, ">"); } - _ => debug!("..."), + _ => print!(level, "..."), } - debugln!(";"); + println!(level, ";"); } if node.children().next().is_some() { - debugln!(""); + println!(level, ""); } for child in node.children() { - dump_node(&child, depth + 1); + dump_node(level, &child, depth + 1); } - tab(depth); - debugln!("}}"); + tab(level, depth); + println!(level, "}}"); } impl DeviceTree { - pub fn dump(&self) { - dump_node(&self.index.root(), 0); + pub fn dump(&self, level: Level) { + dump_node(level, &self.index.root(), 0); } pub fn from_phys(base: usize) -> Result { diff --git a/kernel/src/dev/pci/pcie/gpex.rs b/kernel/src/dev/pci/pcie/gpex.rs index 2d721d4..ee215d2 100644 --- a/kernel/src/dev/pci/pcie/gpex.rs +++ b/kernel/src/dev/pci/pcie/gpex.rs @@ -50,7 +50,7 @@ impl GenericPcieHost { } fn map_function(&self, addr: PciAddress, cfg: EcamCfgSpace) -> Result<(), Errno> { - debugln!( + infoln!( "{:?}: {:04x}:{:04x}", addr, cfg.vendor_id(), diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 00cd64d..d9ff92a 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -33,7 +33,7 @@ pub mod util; #[panic_handler] fn panic_handler(pi: &core::panic::PanicInfo) -> ! { - debugln!("Panic: {:?}", pi); + errorln!("Panic: {:?}", pi); // TODO loop {} } diff --git a/kernel/src/mem/heap.rs b/kernel/src/mem/heap.rs index 3165f98..31a6aa8 100644 --- a/kernel/src/mem/heap.rs +++ b/kernel/src/mem/heap.rs @@ -52,7 +52,7 @@ static HEAP: InitOnce> = InitOnce::new(); pub unsafe fn init(base: usize, size: usize) { let heap = Heap { base, size, ptr: 0 }; - debugln!("Kernel heap: {:#x}..{:#x}", base, base + size); + infoln!("Kernel heap: {:#x}..{:#x}", base, base + size); HEAP.init(IrqSafeNullLock::new(heap)); } diff --git a/kernel/src/mem/phys/mod.rs b/kernel/src/mem/phys/mod.rs index 47f8660..bd4391d 100644 --- a/kernel/src/mem/phys/mod.rs +++ b/kernel/src/mem/phys/mod.rs @@ -91,7 +91,7 @@ pub unsafe fn init_from_iter + Clone>(iter: T) mem_base = reg.start; } } - debugln!("Memory base is {:#x}", mem_base); + infoln!("Memory base is {:#x}", mem_base); // Step 1. Count available memory let mut total_pages = 0usize; for reg in iter.clone() { @@ -118,7 +118,7 @@ pub unsafe fn init_from_iter + Clone>(iter: T) } } } - debug!("{}K of usable physical memory\n", usable_pages * 4); + infoln!("{}K of usable physical memory", usable_pages * 4); *MANAGER.lock() = Some(manager); } diff --git a/kernel/src/mem/phys/reserved.rs b/kernel/src/mem/phys/reserved.rs index 02851a3..b5f1e73 100644 --- a/kernel/src/mem/phys/reserved.rs +++ b/kernel/src/mem/phys/reserved.rs @@ -35,7 +35,7 @@ static mut RESERVED_REGIONS_HEAD: *mut ReservedRegion = null_mut(); static mut RESERVED_REGION_KERNEL: MaybeUninit = MaybeUninit::uninit(); static mut RESERVED_REGION_PAGES: MaybeUninit = MaybeUninit::uninit(); pub unsafe fn reserve(usage: &str, region: *mut ReservedRegion) { - debugln!( + infoln!( "Reserving {:?} region: {:#x}..{:#x}", usage, (*region).start, diff --git a/kernel/src/mem/virt/table.rs b/kernel/src/mem/virt/table.rs index ec88f3d..8457fdc 100644 --- a/kernel/src/mem/virt/table.rs +++ b/kernel/src/mem/virt/table.rs @@ -41,7 +41,6 @@ impl Table { Ok(unsafe { &mut *(mem::virtualize(entry.address_unchecked()) as *mut _) }) } else { let phys = phys::alloc_page(PageUsage::Paging)?; - debugln!("Allocated new page table at {:#x}", phys); let res = unsafe { &mut *(mem::virtualize(phys) as *mut Self) }; self[index] = Entry::table(phys, MapAttributes::empty()); res.entries.fill(Entry::invalid()); diff --git a/kernel/src/proc/mod.rs b/kernel/src/proc/mod.rs index 4cc61fa..4f249ee 100644 --- a/kernel/src/proc/mod.rs +++ b/kernel/src/proc/mod.rs @@ -136,7 +136,6 @@ impl Scheduler { inner.queue.pop_front().unwrap() }; - debugln!("{} -> {}", current, next); inner.current = Some(next); ( inner.processes.get(¤t).unwrap().clone(),