feat: better debugging levels

This commit is contained in:
2021-10-18 13:04:36 +03:00
parent 573bc92523
commit 0d827c2820
12 changed files with 106 additions and 64 deletions
+5 -6
View File
@@ -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();
-2
View File
@@ -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);
+11 -20
View File
@@ -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");
}
+62 -7
View File
@@ -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<T: 'static + SerialDevice> {
inner: &'static T,
}
@@ -24,22 +37,64 @@ impl<T: SerialDevice> fmt::Write for SerialOutput<T> {
}
}
/// 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;
+22 -21
View File
@@ -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<DeviceTree, Errno> {
+1 -1
View File
@@ -50,7 +50,7 @@ impl GenericPcieHost {
}
fn map_function(&self, addr: PciAddress, cfg: EcamCfgSpace) -> Result<(), Errno> {
debugln!(
infoln!(
"{:?}: {:04x}:{:04x}",
addr,
cfg.vendor_id(),
+1 -1
View File
@@ -33,7 +33,7 @@ pub mod util;
#[panic_handler]
fn panic_handler(pi: &core::panic::PanicInfo) -> ! {
debugln!("Panic: {:?}", pi);
errorln!("Panic: {:?}", pi);
// TODO
loop {}
}
+1 -1
View File
@@ -52,7 +52,7 @@ static HEAP: InitOnce<IrqSafeNullLock<Heap>> = 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));
}
+2 -2
View File
@@ -91,7 +91,7 @@ pub unsafe fn init_from_iter<T: Iterator<Item = MemoryRegion> + 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<T: Iterator<Item = MemoryRegion> + 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);
}
+1 -1
View File
@@ -35,7 +35,7 @@ static mut RESERVED_REGIONS_HEAD: *mut ReservedRegion = null_mut();
static mut RESERVED_REGION_KERNEL: MaybeUninit<ReservedRegion> = MaybeUninit::uninit();
static mut RESERVED_REGION_PAGES: MaybeUninit<ReservedRegion> = MaybeUninit::uninit();
pub unsafe fn reserve(usage: &str, region: *mut ReservedRegion) {
debugln!(
infoln!(
"Reserving {:?} region: {:#x}..{:#x}",
usage,
(*region).start,
-1
View File
@@ -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());
-1
View File
@@ -136,7 +136,6 @@ impl Scheduler {
inner.queue.pop_front().unwrap()
};
debugln!("{} -> {}", current, next);
inner.current = Some(next);
(
inner.processes.get(&current).unwrap().clone(),