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/exceptions.rs b/pvmfw/src/exceptions.rs
index 596ecc7..0fb2911 100644
--- a/pvmfw/src/exceptions.rs
+++ b/pvmfw/src/exceptions.rs
@@ -14,14 +14,23 @@
//! Exception handlers.
+use crate::helpers::page_4kb_of;
use core::arch::asm;
+use vmbase::console;
use vmbase::{console::emergency_write_str, eprintln, power::reboot};
+const ESR_32BIT_EXT_DABT: u64 = 0x96000010;
+const UART_PAGE: u64 = page_4kb_of(console::BASE_ADDRESS as u64);
+
#[no_mangle]
extern "C" fn sync_exception_current(_elr: u64, _spsr: u64) {
let esr = read_esr();
- emergency_write_str("sync_exception_current\n");
- print_esr(esr);
+ let far = read_far();
+ // Don't print to the UART if we're handling the exception it could raise.
+ if esr != ESR_32BIT_EXT_DABT || page_4kb_of(far) != UART_PAGE {
+ emergency_write_str("sync_exception_current\n");
+ print_esr(esr);
+ }
reboot();
}
@@ -86,3 +95,12 @@
fn print_esr(esr: u64) {
eprintln!("esr={:#08x}", esr);
}
+
+#[inline]
+fn read_far() -> u64 {
+ let mut far: u64;
+ unsafe {
+ asm!("mrs {far}, far_el1", far = out(reg) far);
+ }
+ far
+}