vmbase: Separate console form aarch64 UART implementation
Number and and initialization code of UART may be different between platforms, for example x86_64 may use I/O ports other platform may use MMIO. This commit separate console logic from platform dependent UART implementations.
Bug: 362733888
Test: m {libvmbase, pvmfw, vmbase_example_{bios, kernel}}_bin
test: atest rialto_test vmbase_example.integration_test
Change-Id: I82360003e4511aa760831135f826e9a4a28cc902
diff --git a/libs/libvmbase/src/console.rs b/libs/libvmbase/src/console.rs
index 533f2b6..6d9a4fe 100644
--- a/libs/libvmbase/src/console.rs
+++ b/libs/libvmbase/src/console.rs
@@ -14,67 +14,25 @@
//! Console driver for 8250 UART.
-use crate::arch::uart::Uart;
+use crate::arch::platform;
use core::fmt::{write, Arguments, Write};
-use spin::{mutex::SpinMutex, Once};
-
-// Arbitrary limit on the number of consoles that can be registered.
-//
-// Matches the UART count in crosvm.
-const MAX_CONSOLES: usize = 4;
-
-static CONSOLES: [Once<SpinMutex<Uart>>; MAX_CONSOLES] =
- [Once::new(), Once::new(), Once::new(), Once::new()];
-static ADDRESSES: [Once<usize>; MAX_CONSOLES] =
- [Once::new(), Once::new(), Once::new(), Once::new()];
-
-/// Index of the console used by default for logging.
-pub const DEFAULT_CONSOLE_INDEX: usize = 0;
-
-/// Index of the console used by default for emergency logging.
-pub const DEFAULT_EMERGENCY_CONSOLE_INDEX: usize = DEFAULT_CONSOLE_INDEX;
-
-/// Initialises the global instance(s) of the UART driver.
-///
-/// This must be called before using the `print!` and `println!` macros.
-///
-/// # Safety
-///
-/// This must be called once with the bases of UARTs, mapped as device memory and (if necessary)
-/// shared with the host as MMIO, to which no other references must be held.
-pub unsafe fn init(base_addresses: &[usize]) {
- for (i, &base_address) in base_addresses.iter().enumerate() {
- // Remember the valid address, for emergency console accesses.
- ADDRESSES[i].call_once(|| base_address);
-
- // Initialize the console driver, for normal console accesses.
- assert!(!CONSOLES[i].is_completed(), "console::init() called more than once");
- // SAFETY: The caller promised that base_address is the base of a mapped UART with no
- // aliases.
- CONSOLES[i].call_once(|| SpinMutex::new(unsafe { Uart::new(base_address) }));
- }
-}
/// 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 fn writeln(n: usize, format_args: Arguments) {
- let uart = &mut *CONSOLES[n].get().unwrap().lock();
-
+ let uart = &mut *platform::uart(n).lock();
write(uart, format_args).unwrap();
let _ = uart.write_str("\n");
}
-/// Reinitializes the n-th UART driver and writes a formatted string followed by a newline to it.
+/// Reinitializes the emergency UART driver and writes a formatted string followed by a newline 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 ewriteln(n: usize, format_args: Arguments) {
- let Some(addr) = ADDRESSES[n].get() else { return };
-
- // SAFETY: addr contains the base of a mapped UART, passed in init().
- let mut uart = unsafe { Uart::new(*addr) };
-
+pub fn ewriteln(format_args: Arguments) {
+ let mut uart = platform::emergency_uart();
let _ = write(&mut uart, format_args);
let _ = uart.write_str("\n");
}
@@ -98,7 +56,7 @@
/// use `eprintln!` instead.
macro_rules! println {
($($arg:tt)*) => ({
- $crate::console::console_writeln!($crate::console::DEFAULT_CONSOLE_INDEX, $($arg)*)
+ $crate::console::console_writeln!($crate::arch::platform::DEFAULT_CONSOLE_INDEX, $($arg)*)
})
}
@@ -111,6 +69,6 @@
#[macro_export]
macro_rules! eprintln {
($($arg:tt)*) => ({
- $crate::console::ewriteln($crate::console::DEFAULT_EMERGENCY_CONSOLE_INDEX, format_args!($($arg)*))
+ $crate::console::ewriteln(format_args!($($arg)*))
})
}