vmbase: Support secondary UARTs 0x2f8,0x3e8,0x2e8
Parameterize the code to allow printing to the "n-th" console and
setting up an arbitrary (up to MAX_CONSOLES) number of UARTs to be used
by client code.
Extend the layout to describe the 4 UARTs crosvm unconditionally
generates and configure console::init() to allow printing to any one of
them.
Bug: 300636104
Test: m pvmfw librialto libvmbase_example
Change-Id: I899f70dfb5eeb41e4ba399aee59d731db1264ff9
diff --git a/vmbase/src/layout.rs b/vmbase/src/layout.rs
index e65abda..5ac435f 100644
--- a/vmbase/src/layout.rs
+++ b/vmbase/src/layout.rs
@@ -26,14 +26,17 @@
/// First address that can't be translated by a level 1 TTBR0_EL1.
pub const MAX_VIRT_ADDR: usize = 1 << 40;
-/// Base memory-mapped address of the primary UART device.
+/// Base memory-mapped addresses of the UART devices.
///
/// See SERIAL_ADDR in https://crosvm.dev/book/appendix/memory_layout.html#common-layout.
-pub const UART_ADDR: usize = 0x3f8;
+pub const UART_ADDRESSES: [usize; 4] = [0x3f8, 0x2f8, 0x3e8, 0x2e8];
/// Address of the single page containing all the UART devices.
pub const UART_PAGE_ADDR: usize = 0;
-const_assert_eq!(UART_PAGE_ADDR, page_4kb_of(UART_ADDR));
+const_assert_eq!(UART_PAGE_ADDR, page_4kb_of(UART_ADDRESSES[0]));
+const_assert_eq!(UART_PAGE_ADDR, page_4kb_of(UART_ADDRESSES[1]));
+const_assert_eq!(UART_PAGE_ADDR, page_4kb_of(UART_ADDRESSES[2]));
+const_assert_eq!(UART_PAGE_ADDR, page_4kb_of(UART_ADDRESSES[3]));
/// Get an address from a linker-defined symbol.
#[macro_export]