| //! 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)+)) |
| }); |
| } |