1use core::panic::PanicInfo;
8use mango_core::println;
9
10fn _panic_exit(system: &spin::Mutex<impl mango_hal::devices::System>) -> !
18{
19 #[cfg(not(feature = "test_build"))]
20 {
21 system.lock().wait_forever()
22 }
23
24 #[cfg(feature = "test_build")]
25 {
26 mango_core::qemu::exit_qemu(mango_core::qemu::QemuExitCode::Failed);
27 }
28}
29
30fn panic_prevent_reenter(system: &spin::Mutex<impl mango_hal::devices::System>)
43{
44 use core::sync::atomic::{AtomicBool, Ordering};
45
46 #[cfg(not(any(target_arch = "aarch64", target_arch = "x86_64")))]
47 compile_error!("Add the target_arch to above's check if the following code is safe to use");
48
49 static PANIC_IN_PROGRESS: AtomicBool = AtomicBool::new(false);
50
51 if !PANIC_IN_PROGRESS.load(Ordering::Relaxed)
52 {
53 PANIC_IN_PROGRESS.store(true, Ordering::Relaxed);
54
55 return;
56 }
57
58 _panic_exit(system)
59}
60
61pub fn panic_handler(info: &PanicInfo, system: &spin::Mutex<impl mango_hal::devices::System>) -> !
63{
64 system.lock().disable_interruptions();
65 panic_prevent_reenter(system);
67
68 let timestamp = mango_core::TIME.lock().get_uptime_or(0);
69 let (location, line, column) = match info.location()
70 {
71 Some(loc) => (loc.file(), loc.line(), loc.column()),
72 _ => ("???", 0, 0),
73 };
74
75 println!(
76 "[ {:>3}.{:06}] Kernel panic!\n\n\
77 Panic location:\n File '{}', line {}, column {}\n\n\
78 {}",
79 timestamp.as_secs(),
80 timestamp.subsec_micros(),
81 location,
82 line,
83 column,
84 info.message(),
85 );
86
87 _panic_exit(system)
88}