ableos/kernel/src/arch/x86_64/logging.rs

49 lines
1.3 KiB
Rust
Raw Normal View History

2023-03-30 16:43:04 -05:00
//! Logging (as in terms of console / serial output)
2023-05-06 06:50:24 -05:00
use {
core::fmt::Write,
limine::{TerminalRequest, TerminalResponse},
spin::{Lazy, Mutex},
uart_16550::SerialPort,
};
2023-03-30 16:43:04 -05:00
2023-05-06 06:50:24 -05:00
static SERIAL_CONSOLE: Mutex<SerialPort> = Mutex::new(unsafe { SerialPort::new(0x3F8) });
2023-05-06 07:05:45 -05:00
static TERMINAL_LOGGER: Lazy<Mutex<TermLogger>> = Lazy::new(|| Mutex::new(TermLogger::new()));
2023-03-30 16:43:04 -05:00
pub fn init() {
SERIAL_CONSOLE.lock().init();
2023-05-06 07:05:45 -05:00
Lazy::force(&TERMINAL_LOGGER);
2023-03-30 16:43:04 -05:00
}
pub fn log(args: core::fmt::Arguments<'_>) -> core::fmt::Result {
x86_64::instructions::interrupts::without_interrupts(|| {
2023-05-06 07:05:45 -05:00
TERMINAL_LOGGER.lock().write_fmt(args)?;
2023-03-30 16:43:04 -05:00
SERIAL_CONSOLE.lock().write_fmt(args)
})
}
2023-05-06 07:05:45 -05:00
struct TermLogger(&'static TerminalResponse);
unsafe impl Send for TermLogger {}
impl TermLogger {
pub fn new() -> Self {
static TERM_REQ: TerminalRequest = TerminalRequest::new(0);
Self(
TERM_REQ
.get_response()
.get()
.expect("failed to get terminal response"),
)
}
}
2023-03-30 16:43:04 -05:00
2023-05-06 07:05:45 -05:00
impl Write for TermLogger {
fn write_str(&mut self, s: &str) -> core::fmt::Result {
if let (Some(w), ts) = (self.0.write(), self.0.terminals()) {
for term in ts {
w(term, s);
}
}
Ok(())
}
}