1use core::panic::PanicInfo;
8use core::sync::atomic::{AtomicBool, Ordering};
9use crate::types::panic_codes::PanicCode;
10use crate::arch::instructions;
11use crate::SIMPLE_STATE;
12use crate::types::fmt_buffer::FmtBuffer;
13
14static KERNEL_PANIC_TRIGERRED: AtomicBool = AtomicBool::new(false);
16
17static RUST_PANIC_TRIGERRED: AtomicBool = AtomicBool::new(false);
19
20pub fn kernel_panic(panic_code: PanicCode, panic_message: &str) -> ! {
22 instructions::disable_interrupts();
23
24 unsafe { crate::logging::kprint::force_unlock_kprint_state(); }
27
28 if KERNEL_PANIC_TRIGERRED.load(Ordering::Acquire) {
29 loop {
30 instructions::halt_cpu();
31 }
32 }
33 KERNEL_PANIC_TRIGERRED.store(true, Ordering::Release);
34
35 if SIMPLE_STATE.serial.is_completed() {
36 use crate::logging::_serial::_Serial;
37 let serial = SIMPLE_STATE.serial.get().unwrap();
38
39 serial.write("Kernel Panic! :(\n");
40 serial.write(panic_code.as_str());
41 serial.write("\n");
42 serial.write(panic_message);
43 }
44
45 if SIMPLE_STATE.basic_fb.is_completed() && SIMPLE_STATE.basic_fb_psf2_font.is_completed() {
46 let fb = SIMPLE_STATE.basic_fb.get().unwrap();
47 let font = SIMPLE_STATE.basic_fb_psf2_font.get().unwrap();
48 let mut x: usize = 0;
49 let mut y: usize = 0;
50
51 fb.clear();
52 font.draw_string(fb, "Kernel Panic! :(\n", &mut x, &mut y, Some(0x00FF0000));
53 font.draw_string(fb, panic_code.as_str(), &mut x, &mut y, None);
54 font.draw_string(fb, "\n", &mut x, &mut y, None);
55 font.draw_string(fb, panic_message, &mut x, &mut y, None);
56 }
57
58 loop {
59 instructions::halt_cpu();
60 }
61}
62
63#[panic_handler]
65fn panic(panic_info: &PanicInfo) -> ! {
66 use core::fmt::Write;
67
68 instructions::disable_interrupts();
69
70 unsafe { crate::logging::kprint::force_unlock_kprint_state(); }
73
74 if RUST_PANIC_TRIGERRED.load(Ordering::Acquire) {
75 loop {
76 instructions::halt_cpu();
77 }
78 }
79 RUST_PANIC_TRIGERRED.store(true, Ordering::Release);
80
81 let mut message_buf: FmtBuffer<128> = FmtBuffer::new();
82 if panic_info.message().as_str().is_none() {
83 let _ = write!(message_buf, "(No panic message given)\n\n");
84 } else {
85 let _ = write!(message_buf, "Panic Message: {}\n\n", panic_info.message());
86 }
87
88 let mut location_buf: FmtBuffer<256> = FmtBuffer::new();
89 if panic_info.location().is_none() {
90 let _ = write!(location_buf, "(No panic location given)");
91 } else {
92 let location = panic_info.location().unwrap();
93 let _ = write!(location_buf, "{}\n on line {}", location.file(), location.line());
94 }
95
96 if SIMPLE_STATE.serial.is_completed() {
97 use crate::logging::_serial::_Serial;
98 let serial = SIMPLE_STATE.serial.get().unwrap();
99
100 serial.write("\nKernel Panic! :(\n");
101 serial.write("[!] This panic was triggered by Rust (language-triggered or via a panic!() call)\n\n");
102 serial.write(message_buf.as_str());
103 serial.write(location_buf.as_str());
104 }
105
106 if SIMPLE_STATE.basic_fb.is_completed() && SIMPLE_STATE.basic_fb_psf2_font.is_completed() {
107 let fb = SIMPLE_STATE.basic_fb.get().unwrap();
108 let font = SIMPLE_STATE.basic_fb_psf2_font.get().unwrap();
109 let mut x: usize = 0;
110 let mut y: usize = 0;
111
112 fb.clear();
113 font.draw_string(fb, "Kernel Panic! :(\n", &mut x, &mut y, Some(0x00FF0000));
114 font.draw_string(fb, "[!] This panic was triggered by Rust (runtime error or panic!() called)\n\n", &mut x, &mut y, None);
115 font.draw_string(fb, message_buf.as_str(), &mut x, &mut y, None);
116 font.draw_string(fb, location_buf.as_str(), &mut x, &mut y, None);
117 }
118
119 loop {
120 instructions::halt_cpu();
121 }
122}