blob: 848a76fbeba036108538bd4a7ee7421ef323ec4f [file] [log] [blame]
//! Unsafe synchronous dump-string-to-uart impl and macro for debugging.
use core2::io::{Cursor, Write};
use core::fmt;
// TODO(jtgans|aappleby): b/239714445. Use the actual UART registers defined in
// opentitan/uart.rs instead of hardcoding them here. Or better: get rid of this
// gross hack and replace with something less gross. :P
pub const TX_BUSY: *const u32 = 0x4000_0014 as *const u32;
pub const TX_PORT: *mut u32 = 0x4000_001c as *mut u32;
pub fn send_sync(buf: &[u8], len: usize) {
unsafe {
for i in 0..len {
// TODO(jtgans|aappleby): b/239714445. This is a gross hack to
// ensure we don't buffer dprintf output for diagnosing early boot
// of the system.
//
// NOTE: if the UART registers change, we're going to have to fix
// this here as well!
while (TX_BUSY.read_volatile() & 1) != 0 {}
TX_PORT.write_volatile(buf[i] as u32);
}
}
}
pub fn vdprintf(args: fmt::Arguments) {
let mut uart_buf = [0u8; 256];
let mut cur = Cursor::new(&mut uart_buf[..]);
if cur.write_fmt(args).is_ok() {
let pos = cur.position();
send_sync(&uart_buf, pos as usize);
}
}
#[macro_export]
macro_rules! dprintf {
($msg:expr) => ({
$crate::dprintf_hal::vdprintf(format_args!($msg))
});
($fmt:expr, $($arg:tt)+) => ({
$crate::dprintf_hal::vdprintf(format_args!($fmt, $($arg)+))
});
}