use conquer_once::spin::OnceCell;
use heapless::String;
use spin::Mutex;
use uart_16550::SerialPort;
use crate::MAX_STRING_LENGTH;
pub static SERIAL1: OnceCell<Mutex<SerialPort>> = OnceCell::uninit();
fn init_serial() -> Mutex<SerialPort> {
let mut serial_port = unsafe { SerialPort::new(0x3F8) };
serial_port.init();
Mutex::new(serial_port)
}
#[doc(hidden)]
pub fn _serial_print(args: core::fmt::Arguments) {
use core::fmt::Write;
use x86_64::instructions::interrupts;
interrupts::without_interrupts(|| {
let serial = SERIAL1.get_or_init(|| init_serial());
serial.lock()
.write_fmt(args)
.expect("Printing to serial failed");
});
}
#[macro_export]
macro_rules! serial_print {
($($arg:tt)*) => {
$crate::log::_serial_print(format_args!($($arg)*));
};
}
#[macro_export]
macro_rules! serial_println {
($($arg:tt)*) => {
$crate::log::_serial_print(format_args!($($arg)*));
$crate::log::_serial_print(format_args!("\n"));
};
}
#[doc(hidden)]
pub fn _debugcon_print(args: core::fmt::Arguments) {
use core::fmt::Write;
let mut s = String::<MAX_STRING_LENGTH>::new();
s.write_fmt(args).expect("Failed to write to string");
unsafe {
for byte in s.bytes() {
core::arch::asm!("out 0xe9, al", in("al") byte);
}
}
}
#[macro_export]
macro_rules! debugcon_print {
($($arg:tt)*) => {
$crate::log::_debugcon_print(format_args!($($arg)*));
};
}
#[macro_export]
macro_rules! debugcon_println {
($($arg:tt)*) => {
$crate::log::_debugcon_print(format_args!($($arg)*));
$crate::log::_debugcon_print(format_args!("\n"));
};
}