1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//! Utilities that enable formatted printing for early runtime init.

use std::fmt;

use twizzler_abi::syscall::{sys_kernel_console_write, KernelConsoleWriteFlags};

#[repr(C)]
struct PreinitLogger;

impl fmt::Write for PreinitLogger {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        sys_kernel_console_write(s.as_bytes(), KernelConsoleWriteFlags::empty());
        Ok(())
    }
}

static mut PREINIT_OUTPUT: PreinitLogger = PreinitLogger;

#[doc(hidden)]
pub fn _print_normal(args: core::fmt::Arguments) {
    use fmt::Write;
    let _ = unsafe { &mut PREINIT_OUTPUT }.write_fmt(args);
}

#[macro_export]
macro_rules! preinit_print {
    ($($arg:tt)*) => {
        $crate::preinit::_print_normal(format_args!($($arg)*))
    };
}

#[macro_export]
macro_rules! preinit_println {
    () => {
        $crate::preinit_print!("\n")
    };
    ($fmt:expr) => {
        $crate::preinit_print!(concat!($fmt, "\n"))
    };
    ($fmt:expr, $($arg:tt)*) => {
        $crate::preinit_print!(concat!($fmt, "\n"), $($arg)*)
    };
}

#[track_caller]
pub fn preinit_abort() -> ! {
    core::intrinsics::abort()
}

#[track_caller]
pub fn preinit_unwrap<T>(op: Option<T>) -> T {
    match op {
        Some(item) => item,
        None => {
            preinit_println!(
                "failed to unwrap option: {}",
                core::panic::Location::caller()
            );
            preinit_abort();
        }
    }
}

#[track_caller]
#[allow(dead_code)]
pub fn preinit_unwrap_result<T, E: core::fmt::Display>(op: Result<T, E>) -> T {
    match op {
        Ok(item) => item,
        Err(e) => {
            preinit_println!(
                "failed to unwrap result: {} at {}",
                e,
                core::panic::Location::caller()
            );
            preinit_abort();
        }
    }
}