Skip to main content

strat9_kernel/
debug.rs

1use core::fmt;
2use x86_64::instructions::port::Port;
3
4pub struct QemuDebug;
5
6impl fmt::Write for QemuDebug {
7    fn write_str(&mut self, s: &str) -> fmt::Result {
8        let mut port = Port::new(0xe9);
9        for &byte in s.as_bytes() {
10            unsafe {
11                port.write(byte);
12            }
13        }
14        Ok(())
15    }
16}
17
18#[macro_export]
19macro_rules! e9_print {
20    ($($arg:tt)*) => {
21        {
22            use core::fmt::Write;
23            let _ = write!($crate::debug::QemuDebug, $($arg)*);
24        }
25    };
26}
27
28#[macro_export]
29macro_rules! e9_println {
30    () => ($crate::e9_print!("\n"));
31    ($($arg:tt)*) => ($crate::e9_print!("{}\n", format_args!($($arg)*)));
32}
33
34/// Log a boot milestone with elapsed time since kernel entry.
35///
36/// Output format: `[boot +     12ms] Paging initialized`
37#[macro_export]
38macro_rules! boot_milestone {
39    ($($arg:tt)*) => {
40        $crate::serial_println!(
41            "[boot +{:>6}ms] {}",
42            $crate::arch::x86_64::boot_timestamp::elapsed_ms(),
43            format_args!($($arg)*)
44        );
45        if $crate::arch::x86_64::vga::is_available() {
46            let mut vbuf = [0u8; $crate::arch::x86_64::vgabuf::VGABUF_LINE_LEN];
47            let mut vpos = 0usize;
48            use core::fmt::Write;
49            struct VgaBufWriter<'a> {
50                buf: &'a mut [u8],
51                pos: &'a mut usize,
52            }
53            impl Write for VgaBufWriter<'_> {
54                fn write_str(&mut self, s: &str) -> core::fmt::Result {
55                    let bytes = s.as_bytes();
56                    let remaining = self.buf.len().saturating_sub(*self.pos);
57                    let n = bytes.len().min(remaining);
58                    self.buf[*self.pos..*self.pos + n].copy_from_slice(&bytes[..n]);
59                    *self.pos += n;
60                    Ok(())
61                }
62            }
63            let _ = write!(
64                VgaBufWriter { buf: &mut vbuf, pos: &mut vpos },
65                "[boot +{:>6}ms] {}\n",
66                $crate::arch::x86_64::boot_timestamp::elapsed_ms(),
67                format_args!($($arg)*)
68            );
69            if vpos > 0 {
70                $crate::arch::x86_64::vgabuf::vgabuf_write(&vbuf[..vpos]);
71            }
72        }
73    };
74}