diff options
author | Christian Cunningham <cc@localhost> | 2022-08-26 17:25:34 -0700 |
---|---|---|
committer | Christian Cunningham <cc@localhost> | 2022-08-26 17:25:34 -0700 |
commit | a04cf2dbb8d2e890405fbf0a1022aaad3015b1e8 (patch) | |
tree | 381892074d13c059d50cb88caa41f8a8722c07ce /src/util/panic_wait.rs | |
parent | 7f3d7d9ce9818078b6a4616b4c31a28e2868397b (diff) |
Modularize
Diffstat (limited to 'src/util/panic_wait.rs')
-rw-r--r-- | src/util/panic_wait.rs | 45 |
1 files changed, 45 insertions, 0 deletions
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() +} |