pvmfw: Issue MMIO_GUARD_MAP for UART
Share the MMIO page containing the UART with the VMM.
When handling a synchronous exception, don't print to the UART if it
would cause re-entering the handler.
Bug: 237371962
Test: m pvmfw_img && flash pvmfw.img && access UART
Change-Id: Ia384f2e3a15b40b5e67cfafd50e571848fd5a126
diff --git a/pvmfw/src/main.rs b/pvmfw/src/main.rs
index 5f918fb..eb97961 100644
--- a/pvmfw/src/main.rs
+++ b/pvmfw/src/main.rs
@@ -18,25 +18,36 @@
#![no_std]
mod exceptions;
+mod helpers;
+mod smccc;
use core::fmt;
+use helpers::checked_page_of;
-use vmbase::{main, power::reboot, println};
+use vmbase::{console, main, power::reboot, println};
#[derive(Debug, Clone)]
-enum Error {}
+enum Error {
+ /// Failed to configure the UART; no logs available.
+ FailedUartSetup,
+}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- #[allow(clippy::match_single_binding)]
let msg = match self {
- _ => "",
+ Self::FailedUartSetup => "Failed to configure the UART",
};
write!(f, "{}", msg)
}
}
fn main(fdt_address: u64, payload_start: u64, payload_size: u64, arg3: u64) -> Result<(), Error> {
+ // We need to inform the hypervisor that the MMIO page containing the UART may be shared back.
+ let uart = console::BASE_ADDRESS as u64;
+ let mmio_granule = smccc::mmio_guard_info().map_err(|_| Error::FailedUartSetup)?;
+ let uart_page = checked_page_of(uart, mmio_granule).ok_or(Error::FailedUartSetup)?;
+ smccc::mmio_guard_map(uart_page).map_err(|_| Error::FailedUartSetup)?;
+
println!("pVM firmware");
println!(
"fdt_address={:#018x}, payload_start={:#018x}, payload_size={:#018x}, x3={:#018x}",