From a04cf2dbb8d2e890405fbf0a1022aaad3015b1e8 Mon Sep 17 00:00:00 2001 From: Christian Cunningham Date: Fri, 26 Aug 2022 17:25:34 -0700 Subject: Modularize --- src/util/panic_wait.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/util/panic_wait.rs (limited to 'src/util/panic_wait.rs') diff --git a/src/util/panic_wait.rs b/src/util/panic_wait.rs new file mode 100644 index 0000000..a8d0962 --- /dev/null +++ b/src/util/panic_wait.rs @@ -0,0 +1,45 @@ +//! # Panic module +//! +//! A panic handler that infinitely waits + +use crate::{cpu, serial_println}; +use core::panic::PanicInfo; + +/// # Prevent Double Faulting +/// +/// An atomic operation is used to mark that +/// a fault has occurred. If it detects that +/// there was already a fault, it spins to +/// prevent a recursive faulting cycle. +fn panic_prevent_reenter() { + use core::sync::atomic::{AtomicBool, Ordering}; + + static PANIC_IN_PROGRESS: AtomicBool = AtomicBool::new(false); + + if !PANIC_IN_PROGRESS.load(Ordering::Relaxed) { + PANIC_IN_PROGRESS.store(true, Ordering::Relaxed); + return; + } + + cpu::wait_forever() +} + +/// # Panic handler +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + panic_prevent_reenter(); + + let (location, line, column) = match info.location() { + Some(loc) => (loc.file(), loc.line(), loc.column()), + _ => ("???", 0, 0), + }; + + serial_println!( + "Kernel panic!\n\nPanic Location:\n\tFile: '{}', line {}, column {}\n\n{}", + location, + line, + column, + info.message().unwrap_or(&format_args!("")), + ); + cpu::wait_forever() +} -- cgit v1.2.1