1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 //! Console driver for 8250 UART.
16
17 use crate::arch::platform::{self, emergency_uart, DEFAULT_EMERGENCY_CONSOLE_INDEX};
18 use crate::power::reboot;
19 use core::fmt::{self, write, Arguments, Write};
20 use core::panic::PanicInfo;
21
22 /// Writes a formatted string followed by a newline to the n-th console.
23 ///
24 /// Returns an error if the n-th console was not initialized by calling [`init`] first.
writeln(n: usize, format_args: Arguments) -> fmt::Result25 pub fn writeln(n: usize, format_args: Arguments) -> fmt::Result {
26 let uart = &mut *platform::uart(n).ok_or(fmt::Error)?.lock();
27
28 write(uart, format_args)?;
29 uart.write_str("\n")?;
30 Ok(())
31 }
32
33 /// Prints the given formatted string to the n-th console, followed by a newline.
34 ///
35 /// Returns an error if the console has not yet been initialized. May deadlock if used in a
36 /// synchronous exception handler.
37 #[macro_export]
38 macro_rules! console_writeln {
39 ($n:expr, $($arg:tt)*) => ({
40 $crate::console::writeln($n, format_args!($($arg)*))
41 })
42 }
43
44 /// Prints the given formatted string to the console, followed by a newline.
45 ///
46 /// Panics if the console has not yet been initialized. May hang if used in an exception context.
47 macro_rules! println {
48 ($($arg:tt)*) => ({
49 $crate::console_writeln!($crate::arch::platform::DEFAULT_CONSOLE_INDEX, $($arg)*).unwrap()
50 })
51 }
52
53 pub(crate) use println; // Make it available in this crate.
54
55 #[panic_handler]
panic(info: &PanicInfo) -> !56 fn panic(info: &PanicInfo) -> ! {
57 // SAFETY: We always reboot at the end of this method so there is no way for the
58 // original UART driver to be used after this.
59 if let Some(mut console) = unsafe { emergency_uart(DEFAULT_EMERGENCY_CONSOLE_INDEX) } {
60 // Ignore errors, to avoid a panic loop.
61 let _ = writeln!(console, "{}", info);
62 }
63 reboot()
64 }
65