Merge "pvmfw: Print RebootReason on secondary UART" into main
diff --git a/pvmfw/src/entry.rs b/pvmfw/src/entry.rs
index 36ead46..0ff7270 100644
--- a/pvmfw/src/entry.rs
+++ b/pvmfw/src/entry.rs
@@ -30,7 +30,7 @@
 use log::LevelFilter;
 use vmbase::util::RangeExt as _;
 use vmbase::{
-    configure_heap,
+    configure_heap, console_writeln,
     hyp::{get_mem_sharer, get_mmio_guard},
     layout::{self, crosvm, UART_PAGE_ADDR},
     main,
@@ -59,6 +59,21 @@
     SecretDerivationError,
 }
 
+impl RebootReason {
+    pub fn as_avf_reboot_string(&self) -> &'static str {
+        match self {
+            Self::InvalidBcc => "PVM_FIRMWARE_INVALID_BCC",
+            Self::InvalidConfig => "PVM_FIRMWARE_INVALID_CONFIG_DATA",
+            Self::InternalError => "PVM_FIRMWARE_INTERNAL_ERROR",
+            Self::InvalidFdt => "PVM_FIRMWARE_INVALID_FDT",
+            Self::InvalidPayload => "PVM_FIRMWARE_INVALID_PAYLOAD",
+            Self::InvalidRamdisk => "PVM_FIRMWARE_INVALID_RAMDISK",
+            Self::PayloadVerificationError => "PVM_FIRMWARE_PAYLOAD_VERIFICATION_FAILED",
+            Self::SecretDerivationError => "PVM_FIRMWARE_SECRET_DERIVATION_FAILED",
+        }
+    }
+}
+
 main!(start);
 configure_heap!(SIZE_128KB);
 
@@ -70,7 +85,11 @@
 
     match main_wrapper(fdt_address as usize, payload_start as usize, payload_size as usize) {
         Ok((entry, bcc)) => jump_to_payload(fdt_address, entry.try_into().unwrap(), bcc),
-        Err(_) => reboot(), // TODO(b/220071963) propagate the reason back to the host.
+        Err(e) => {
+            const REBOOT_REASON_CONSOLE: usize = 1;
+            console_writeln!(REBOOT_REASON_CONSOLE, "{}", e.as_avf_reboot_string());
+            reboot()
+        }
     }
 
     // if we reach this point and return, vmbase::entry::rust_entry() will call power::shutdown().
diff --git a/vmbase/src/console.rs b/vmbase/src/console.rs
index f829eb5..bbbcb07 100644
--- a/vmbase/src/console.rs
+++ b/vmbase/src/console.rs
@@ -65,7 +65,7 @@
 /// Writes a formatted string followed by a newline to the n-th console.
 ///
 /// Panics if the n-th console was not initialized by calling [`init`] first.
-pub(crate) fn writeln(n: usize, format_args: Arguments) {
+pub fn writeln(n: usize, format_args: Arguments) {
     let mut guard = CONSOLES[n].lock();
     let uart = guard.as_mut().unwrap();
 
@@ -88,13 +88,26 @@
     let _ = uart.write_str("\n");
 }
 
+/// Prints the given formatted string to the n-th console, followed by a newline.
+///
+/// Panics if the console has not yet been initialized. May hang if used in an exception context;
+/// use `eprintln!` instead.
+#[macro_export]
+macro_rules! console_writeln {
+    ($n:expr, $($arg:tt)*) => ({
+        $crate::console::writeln($n, format_args!($($arg)*))
+    })
+}
+
+pub(crate) use console_writeln;
+
 /// Prints the given formatted string to the console, followed by a newline.
 ///
 /// Panics if the console has not yet been initialized. May hang if used in an exception context;
 /// use `eprintln!` instead.
 macro_rules! println {
     ($($arg:tt)*) => ({
-        $crate::console::writeln($crate::console::DEFAULT_CONSOLE_INDEX, format_args!($($arg)*))
+        $crate::console::console_writeln!($crate::console::DEFAULT_CONSOLE_INDEX, $($arg)*)
     })
 }