aboutsummaryrefslogtreecommitdiff
path: root/src/util/panic_wait.rs
diff options
context:
space:
mode:
authorChristian Cunningham <cc@localhost>2022-08-26 17:25:34 -0700
committerChristian Cunningham <cc@localhost>2022-08-26 17:25:34 -0700
commita04cf2dbb8d2e890405fbf0a1022aaad3015b1e8 (patch)
tree381892074d13c059d50cb88caa41f8a8722c07ce /src/util/panic_wait.rs
parent7f3d7d9ce9818078b6a4616b4c31a28e2868397b (diff)
Modularize
Diffstat (limited to 'src/util/panic_wait.rs')
-rw-r--r--src/util/panic_wait.rs45
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()
+}