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-15 02:19:34 -05:00
|
|
|
pub 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-15 02:19:34 -05:00
|
|
|
// TERMINAL_LOGGER.lock().write_fmt(args)?;
|
|
|
|
let mut sc = SERIAL_CONSOLE.lock();
|
|
|
|
sc.write_fmt(args)?;
|
|
|
|
Ok(())
|
2023-03-30 16:43:04 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
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(())
|
|
|
|
}
|
|
|
|
}
|