use crate::sync::interface::Mutex; use crate::sync::NullLock; use uart_16550::SerialPort; pub struct Serial { buffer: Option, } impl Serial { pub const fn new() -> Self { Serial { buffer: None } } } impl crate::sync::interface::Initializable for Serial { fn init(&mut self) { let mut serial_port = unsafe { SerialPort::new(0x3F8) }; serial_port.init(); self.buffer = Some(serial_port); } } #[doc(hidden)] pub fn _print(args: ::core::fmt::Arguments) { use core::fmt::Write; SERIAL1.lock(|serial| { if let Some(buffer) = &mut serial.buffer { buffer.write_fmt(args).expect("printing to serial failed!"); } }) } /// Prints to the host through the serial interface. #[macro_export] macro_rules! serial_print { ($($arg:tt)*) => { $crate::serial::_print(format_args!($($arg)*)); }; } /// Prints to the host through the serial interface, appending a newline. #[macro_export] macro_rules! serial_println { () => ($crate::serial_print!("\n")); ($fmt:expr) => ($crate::serial_print!(concat!($fmt, "\n"))); ($fmt:expr, $($arg:tt)*) => ($crate::serial_print!( concat!($fmt, "\n"), $($arg)*)); } pub static SERIAL1: NullLock = NullLock::new(Serial::new());