Add print macros, and use them for panic handling.

Bug: 223166344
Test: Ran unprotected VM under crosvm.
Change-Id: I2314d417f485a6bd9aad2d6816fef42747eab194
diff --git a/pvmfw/src/console.rs b/pvmfw/src/console.rs
index d44eb92..b52d924 100644
--- a/pvmfw/src/console.rs
+++ b/pvmfw/src/console.rs
@@ -46,7 +46,6 @@
 /// Writes a formatted string to the console.
 ///
 /// Panics if [`init`] was not called first.
-#[allow(unused)]
 pub fn write_args(format_args: Arguments) {
     write(CONSOLE.lock().as_mut().unwrap(), format_args).unwrap();
 }
@@ -59,3 +58,55 @@
     let mut uart = create();
     let _ = uart.write_str(s);
 }
+
+/// Reinitialises the UART driver and writes a formatted string to it.
+///
+/// This is intended for use in situations where the UART may be in an unknown state or the global
+/// instance may be locked, such as in an exception handler or panic handler.
+pub fn emergency_write_args(format_args: Arguments) {
+    let mut uart = create();
+    let _ = write(&mut uart, format_args);
+}
+
+/// Prints the given string to the console.
+///
+/// Panics if the console has not yet been initialised. May hang if used in an exception context;
+/// use `eprint!` instead.
+#[macro_export]
+macro_rules! print {
+    ($($arg:tt)*) => ($crate::console::write_args(format_args!($($arg)*)));
+}
+
+/// Prints the given formatted string to the console, followed by a newline.
+///
+/// Panics if the console has not yet been initialised. May hang if used in an exception context;
+/// use `eprintln!` instead.
+#[macro_export]
+macro_rules! println {
+    () => ($crate::console::write_str("\n"));
+    ($($arg:tt)*) => ({
+        $crate::console::write_args(format_args!($($arg)*))};
+        $crate::console::write_str("\n");
+    );
+}
+
+/// Prints the given string to the console in an emergency, such as an exception handler.
+///
+/// Never panics.
+#[macro_export]
+macro_rules! eprint {
+    ($($arg:tt)*) => ($crate::console::emergency_write_args(format_args!($($arg)*)));
+}
+
+/// Prints the given string followed by a newline to the console in an emergency, such as an
+/// exception handler.
+///
+/// Never panics.
+#[macro_export]
+macro_rules! eprintln {
+    () => ($crate::console::emergency_write_str("\n"));
+    ($($arg:tt)*) => ({
+        $crate::console::emergency_write_args(format_args!($($arg)*))};
+        $crate::console::emergency_write_str("\n");
+    );
+}
diff --git a/pvmfw/src/main.rs b/pvmfw/src/main.rs
index 7156213..4ab14b7 100644
--- a/pvmfw/src/main.rs
+++ b/pvmfw/src/main.rs
@@ -21,7 +21,6 @@
 mod psci;
 mod uart;
 
-use console::emergency_write_str;
 use core::panic::PanicInfo;
 use psci::{system_off, system_reset};
 
@@ -29,7 +28,7 @@
 #[no_mangle]
 pub extern "C" fn main() -> ! {
     console::init();
-    console::write_str("Hello world\n");
+    println!("Hello world");
 
     system_off();
     #[allow(clippy::empty_loop)]
@@ -37,8 +36,8 @@
 }
 
 #[panic_handler]
-fn panic(_info: &PanicInfo) -> ! {
-    emergency_write_str("panic\n");
+fn panic(info: &PanicInfo) -> ! {
+    eprintln!("{}", info);
     system_reset();
     loop {}
 }