ostd/
console.rs

1// SPDX-License-Identifier: MPL-2.0
2
3//! Console output.
4
5use core::fmt::{self, Arguments, Write};
6
7use crate::sync::{LocalIrqDisabled, SpinLock};
8
9struct Stdout;
10
11impl Write for Stdout {
12    fn write_str(&mut self, s: &str) -> fmt::Result {
13        for &c in s.as_bytes() {
14            crate::arch::serial::send(c);
15        }
16        Ok(())
17    }
18}
19
20static STDOUT: SpinLock<Stdout, LocalIrqDisabled> = SpinLock::new(Stdout);
21
22/// Prints formatted arguments to the console.
23pub fn early_print(args: Arguments) {
24    #[cfg(target_arch = "x86_64")]
25    crate::arch::if_tdx_enabled!({
26        // Hold the lock to prevent the logs from interleaving.
27        let _guard = STDOUT.lock();
28        tdx_guest::print(args);
29    } else {
30        STDOUT.lock().write_fmt(args).unwrap();
31    });
32    #[cfg(not(target_arch = "x86_64"))]
33    STDOUT.lock().write_fmt(args).unwrap();
34}
35
36/// Prints to the console.
37#[macro_export]
38macro_rules! early_print {
39    ($fmt: literal $(, $($arg: tt)+)?) => {
40        $crate::console::early_print(format_args!($fmt $(, $($arg)+)?))
41    }
42}
43
44/// Prints to the console with a newline.
45#[macro_export]
46macro_rules! early_println {
47    () => { $crate::early_print!("\n") };
48    ($fmt: literal $(, $($arg: tt)+)?) => {
49        $crate::console::early_print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?))
50    }
51}