//! Panic handler and diagnostic display. //! //! Prints panic information to the kernel log and displays the message on the //! framebuffer before halting the CPU. use core::arch::riscv64::wfi; use alloc::{format, string::ToString}; use log::error; use crate::{ HEAP_INITIALIZED, draw::{Color, Draw, FONT_HEIGHT}, uart::write_uart, vga::Vga, }; #[panic_handler] /// Kernel panic handler that displays the panic message on the framebuffer and halts. fn panic(panic_info: &core::panic::PanicInfo) -> ! { if !HEAP_INITIALIZED.load(core::sync::atomic::Ordering::Relaxed) { write_uart("EARLY PANIC !"); } else { error!("PANIC !"); let mut panic_message = panic_info.message().to_string(); if let Some(location) = panic_info.location() { panic_message = format!("{panic_message} at {}:{}", location.file(), location.line()); } error!("{panic_message}"); Vga.clear_screen(Color::WHITE); unsafe { Vga.draw_string(0, 0, "PANIC !", Color::BLACK, Color::WHITE) }; unsafe { Vga.draw_string( 0, FONT_HEIGHT as u16, panic_message, Color::BLACK, Color::WHITE, ) }; } loop { unsafe { wfi() } } }