From 1afb23196b9882f85c8fbcfbfbd5f92a58960e14 Mon Sep 17 00:00:00 2001 From: Nathan Ringo Date: Mon, 2 Sep 2024 01:02:29 -0500 Subject: Re-adds a bad logger. --- crates/kernel/src/logger.rs | 71 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 crates/kernel/src/logger.rs (limited to 'crates/kernel/src/logger.rs') diff --git a/crates/kernel/src/logger.rs b/crates/kernel/src/logger.rs new file mode 100644 index 0000000..696c9a6 --- /dev/null +++ b/crates/kernel/src/logger.rs @@ -0,0 +1,71 @@ +//! The logger used to store logs from the kernel. This accepts logs from the `log` crate, and +//! delivers them to console devices. + +use core::fmt::{self, Write}; + +/// Initializes the logger. This should be called exactly once, early in boot. +pub fn init() { + log::set_logger(&Logger).expect("failed to set logger"); + log::set_max_level(log::LevelFilter::Trace); + log::warn!("Using a bad unportable logger that only works on qemu-virt"); +} + +struct BadRiscvWrite; + +impl Write for BadRiscvWrite { + fn write_str(&mut self, s: &str) -> fmt::Result { + let ptr = 0x10000000 as *mut u8; + for b in s.bytes() { + unsafe { ptr.write_volatile(b) }; + } + Ok(()) + } +} + +pub struct Logger; + +impl log::Log for Logger { + fn enabled(&self, _metadata: &log::Metadata) -> bool { + true + } + + fn log(&self, record: &log::Record) { + if !self.enabled(record.metadata()) { + return; + } + + let body = |line| { + let level = match record.level() { + log::Level::Error => "\x1b[1;31mERR\x1b[0m", + log::Level::Warn => "\x1b[1;33mWRN\x1b[0m", + log::Level::Info => "\x1b[1;36mINF\x1b[0m", + log::Level::Debug => "\x1b[1;35mDBG\x1b[0m", + log::Level::Trace => "TRC", + }; + let file = record.file().unwrap_or("???"); + let args = record.args(); + + let result = if args.as_str() == Some("") { + // A silly convenience, but don't write the extra space if we're + // not going to write anything anyways. + writeln!(BadRiscvWrite, "[{level}][{file}:{line}]") + } else { + writeln!(BadRiscvWrite, "[{level}][{file}:{line}] {args}") + }; + + // UNWRAP: Since the fmt::Write impl for ConsoleInner has a + // contract promising that it won't ever return an error, this + // should be unreachable. + result.unwrap(); + }; + + // Some contortions to avoid running afoul of the lifetime requirements + // of format_args... + match record.line() { + Some(line) => body(format_args!("{line}")), + None => body(format_args!("???")), + } + } + + fn flush(&self) {} +} -- cgit v1.2.3