feat: better debugging levels
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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> {
|
||||
|
||||
@@ -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
@@ -33,7 +33,7 @@ pub mod util;
|
||||
|
||||
#[panic_handler]
|
||||
fn panic_handler(pi: &core::panic::PanicInfo) -> ! {
|
||||
debugln!("Panic: {:?}", pi);
|
||||
errorln!("Panic: {:?}", pi);
|
||||
// TODO
|
||||
loop {}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -136,7 +136,6 @@ impl Scheduler {
|
||||
inner.queue.pop_front().unwrap()
|
||||
};
|
||||
|
||||
debugln!("{} -> {}", current, next);
|
||||
inner.current = Some(next);
|
||||
(
|
||||
inner.processes.get(¤t).unwrap().clone(),
|
||||
|
||||
Reference in New Issue
Block a user