| // Copyright 2022, The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| //! Console driver for 8250 UART. |
| |
| use crate::arch::platform::{self, emergency_uart, DEFAULT_EMERGENCY_CONSOLE_INDEX}; |
| use crate::power::reboot; |
| use core::fmt::{self, write, Arguments, Write}; |
| use core::panic::PanicInfo; |
| |
| /// Writes a formatted string followed by a newline to the n-th console. |
| /// |
| /// Returns an error if the n-th console was not initialized by calling [`init`] first. |
| pub fn writeln(n: usize, format_args: Arguments) -> fmt::Result { |
| let uart = &mut *platform::uart(n).ok_or(fmt::Error)?.lock(); |
| |
| write(uart, format_args)?; |
| uart.write_str("\n")?; |
| Ok(()) |
| } |
| |
| /// Prints the given formatted string to the n-th console, followed by a newline. |
| /// |
| /// Returns an error if the console has not yet been initialized. May deadlock if used in a |
| /// synchronous exception handler. |
| #[macro_export] |
| macro_rules! console_writeln { |
| ($n:expr, $($arg:tt)*) => ({ |
| $crate::console::writeln($n, format_args!($($arg)*)) |
| }) |
| } |
| |
| /// 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. |
| macro_rules! println { |
| ($($arg:tt)*) => ({ |
| $crate::console_writeln!($crate::arch::platform::DEFAULT_CONSOLE_INDEX, $($arg)*).unwrap() |
| }) |
| } |
| |
| pub(crate) use println; // Make it available in this crate. |
| |
| #[panic_handler] |
| fn panic(info: &PanicInfo) -> ! { |
| // SAFETY: We always reboot at the end of this method so there is no way for the |
| // original UART driver to be used after this. |
| if let Some(mut console) = unsafe { emergency_uart(DEFAULT_EMERGENCY_CONSOLE_INDEX) } { |
| // Ignore errors, to avoid a panic loop. |
| let _ = writeln!(console, "{}", info); |
| } |
| reboot() |
| } |