80 lines
2.1 KiB
Rust
80 lines
2.1 KiB
Rust
//! Kernel I/O helpers and logging frontend.
|
|
//!
|
|
//! Provides a lightweight logger implementation routing to UART and helper
|
|
//! macros for printing from kernel code.
|
|
|
|
use crate::print;
|
|
use crate::tty::{TTY_INITIALIZED, TTY0};
|
|
|
|
use alloc::format;
|
|
use io::Write;
|
|
use log::{Level, Metadata, Record};
|
|
use log::{LevelFilter, SetLoggerError};
|
|
|
|
use crate::uart::write_uart;
|
|
|
|
/// Print a string to the kernel console (via UART).
|
|
///
|
|
/// Accepts any type that implements `AsRef<str>` to avoid unnecessary
|
|
/// allocations at call sites.
|
|
pub(crate) fn print<T: AsRef<str>>(content: T) {
|
|
if TTY_INITIALIZED.load(core::sync::atomic::Ordering::Relaxed) {
|
|
unsafe { TTY0.new_node().write(content.as_ref().as_bytes()).unwrap() };
|
|
} else {
|
|
write_uart(&content);
|
|
}
|
|
}
|
|
|
|
/// Logger implementation that routes kernel log records to the UART-based console.
|
|
pub struct Logger;
|
|
|
|
impl log::Log for Logger {
|
|
fn enabled(&self, metadata: &Metadata) -> bool {
|
|
metadata.level() <= Level::Info
|
|
}
|
|
|
|
fn log(&self, record: &Record) {
|
|
if self.enabled(record.metadata()) {
|
|
let to_print = if let Some((file, line)) = record.file().zip(record.line()) {
|
|
format!(
|
|
"[{}] at {}:{} - {}\n",
|
|
record.level(),
|
|
file,
|
|
line,
|
|
record.args()
|
|
)
|
|
} else {
|
|
format!("[{}] - {}\n", record.level(), record.args())
|
|
};
|
|
print!("{to_print}");
|
|
}
|
|
}
|
|
|
|
fn flush(&self) {}
|
|
}
|
|
|
|
pub static LOGGER: Logger = Logger;
|
|
|
|
/// Initialize the kernel logger and set the default level.
|
|
///
|
|
/// Returns an error if a global logger has already been set.
|
|
pub fn init_log() -> Result<(), SetLoggerError> {
|
|
log::set_logger(&LOGGER).map(|()| log::set_max_level(LevelFilter::Info))
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! print {
|
|
($($args:expr),*) => {
|
|
$crate::io::print(alloc::format!($($args),*))
|
|
};
|
|
}
|
|
#[macro_export]
|
|
macro_rules! println {
|
|
() => {
|
|
$crate::print!("\n")
|
|
};
|
|
($($args:expr),*) => {{
|
|
$crate::print!("{}\n", alloc::format!($($args),*));
|
|
}};
|
|
}
|