/// Prints to the host through the serial interface.
#[macro_export]
macro_rules! serial_print {
    ($($arg:tt)*) => {
                    crate::arch::drivers::serial::SERIAL.lock().out(format_args!($($arg)*))
    };
}
/// Prints to the host through the serial interface, appending a newline.
#[macro_export]
macro_rules! serial_println {
    () => {
        crate::arch::drivers::serial::SERIAL
            .lock()
            .out(format_args!("\r\n"))
    };

    ($($arg:tt)*) => ($crate::print!("{}\r\n", format_args!($($arg)*)));
}

pub struct Serial123 {
    uart_data: u32,
}

impl Serial123 {
    pub fn out(&mut self, s: ::core::fmt::Arguments) {
        let uart_data = self.uart_data as *mut u8;
        for c in b"Hello, world!\n" {
            unsafe { uart_data.write_volatile(*c) };
        }
    }
}

lazy_static! {
    pub static ref SERIAL: Mutex<Serial123> = {
        let serial_port = Serial123 {
            /// UART port for the serial  bus
            uart_data: 0x10000000,
        };
        Mutex::new(serial_port)
    };
}

use {
    core::fmt::{Arguments, Error},
    lazy_static::lazy_static,
    spin::Mutex,
};
