Panic: Guard against infinite panic loops

pull/151/head
Andre Richter 2 years ago
parent 0f2db4bf8e
commit 68b81aa6a0
No known key found for this signature in database
GPG Key ID: 2116C1AB102F615E

@ -6,6 +6,10 @@
use core::panic::PanicInfo;
//--------------------------------------------------------------------------------------------------
// Private Code
//--------------------------------------------------------------------------------------------------
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
unimplemented!()

@ -327,13 +327,16 @@ diff -uNr 01_wait_forever/src/main.rs 02_runtime_init/src/main.rs
diff -uNr 01_wait_forever/src/panic_wait.rs 02_runtime_init/src/panic_wait.rs
--- 01_wait_forever/src/panic_wait.rs
+++ 02_runtime_init/src/panic_wait.rs
@@ -4,9 +4,10 @@
@@ -4,6 +4,7 @@
//! A panic handler that infinitely waits.
+use crate::cpu;
use core::panic::PanicInfo;
//--------------------------------------------------------------------------------------------------
@@ -12,5 +13,5 @@
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
- unimplemented!()

@ -7,6 +7,10 @@
use crate::cpu;
use core::panic::PanicInfo;
//--------------------------------------------------------------------------------------------------
// Private Code
//--------------------------------------------------------------------------------------------------
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
cpu::wait_forever()

@ -238,7 +238,7 @@ diff -uNr 02_runtime_init/src/main.rs 03_hacky_hello_world/src/main.rs
diff -uNr 02_runtime_init/src/panic_wait.rs 03_hacky_hello_world/src/panic_wait.rs
--- 02_runtime_init/src/panic_wait.rs
+++ 03_hacky_hello_world/src/panic_wait.rs
@@ -4,10 +4,16 @@
@@ -4,14 +4,52 @@
//! A panic handler that infinitely waits.
@ -246,9 +246,45 @@ diff -uNr 02_runtime_init/src/panic_wait.rs 03_hacky_hello_world/src/panic_wait.
+use crate::{cpu, println};
use core::panic::PanicInfo;
//--------------------------------------------------------------------------------------------------
// Private Code
//--------------------------------------------------------------------------------------------------
+/// Stop immediately if called a second time.
+///
+/// # Note
+///
+/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
+///
+/// On `AArch64`, which is the only implemented architecture at the time of writing this,
+/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
+/// instructions. They are therefore safe to use even with MMU + caching deactivated.
+///
+/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
+/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
+fn panic_prevent_reenter() {
+ use core::sync::atomic::{AtomicBool, Ordering};
+
+ #[cfg(not(target_arch = "aarch64"))]
+ compile_error!("Add the target_arch to above's check if the following code is safe to use");
+
+ 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]
-fn panic(_info: &PanicInfo) -> ! {
+fn panic(info: &PanicInfo) -> ! {
+ // Protect against panic infinite loops if any of the following code panics itself.
+ panic_prevent_reenter();
+
+ if let Some(args) = info.message() {
+ println!("\nKernel panic: {}", args);
+ } else {

@ -7,8 +7,44 @@
use crate::{cpu, println};
use core::panic::PanicInfo;
//--------------------------------------------------------------------------------------------------
// Private Code
//--------------------------------------------------------------------------------------------------
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
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]
fn panic(info: &PanicInfo) -> ! {
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
if let Some(args) = info.message() {
println!("\nKernel panic: {}", args);
} else {

@ -7,8 +7,44 @@
use crate::{cpu, println};
use core::panic::PanicInfo;
//--------------------------------------------------------------------------------------------------
// Private Code
//--------------------------------------------------------------------------------------------------
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
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]
fn panic(info: &PanicInfo) -> ! {
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
if let Some(args) = info.message() {
println!("\nKernel panic: {}", args);
} else {

@ -1414,7 +1414,7 @@ diff -uNr 04_safe_globals/src/main.rs 05_drivers_gpio_uart/src/main.rs
diff -uNr 04_safe_globals/src/panic_wait.rs 05_drivers_gpio_uart/src/panic_wait.rs
--- 04_safe_globals/src/panic_wait.rs
+++ 05_drivers_gpio_uart/src/panic_wait.rs
@@ -4,15 +4,35 @@
@@ -4,13 +4,29 @@
//! A panic handler that infinitely waits.
@ -1422,11 +1422,11 @@ diff -uNr 04_safe_globals/src/panic_wait.rs 05_drivers_gpio_uart/src/panic_wait.
-use core::panic::PanicInfo;
+use crate::{bsp, cpu};
+use core::{fmt, panic::PanicInfo};
+
+//--------------------------------------------------------------------------------------------------
+// Private Code
+//--------------------------------------------------------------------------------------------------
+
//--------------------------------------------------------------------------------------------------
// Private Code
//--------------------------------------------------------------------------------------------------
+fn _panic_print(args: fmt::Arguments) {
+ use fmt::Write;
+
@ -1442,9 +1442,13 @@ diff -uNr 04_safe_globals/src/panic_wait.rs 05_drivers_gpio_uart/src/panic_wait.
+ _panic_print(format_args_nl!($($arg)*));
+ })
+}
+
/// Stop immediately if called a second time.
///
/// # Note
@@ -46,9 +62,9 @@
panic_prevent_reenter();
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
if let Some(args) = info.message() {
- println!("\nKernel panic: {}", args);
+ panic_println!("\nKernel panic: {}", args);

@ -27,8 +27,40 @@ macro_rules! panic_println {
})
}
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
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]
fn panic(info: &PanicInfo) -> ! {
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
if let Some(args) = info.message() {
panic_println!("\nKernel panic: {}", args);
} else {

@ -27,8 +27,40 @@ macro_rules! panic_println {
})
}
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
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]
fn panic(info: &PanicInfo) -> ! {
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
if let Some(args) = info.message() {
panic_println!("\nKernel panic: {}", args);
} else {

@ -635,12 +635,15 @@ diff -uNr 06_uart_chainloader/src/main.rs 07_timestamps/src/main.rs
diff -uNr 06_uart_chainloader/src/panic_wait.rs 07_timestamps/src/panic_wait.rs
--- 06_uart_chainloader/src/panic_wait.rs
+++ 07_timestamps/src/panic_wait.rs
@@ -29,10 +29,23 @@
@@ -58,13 +58,26 @@
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
+ use crate::time::interface::TimeManager;
+
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
+ let timestamp = crate::time::time_manager().uptime();
+
if let Some(args) = info.message() {

@ -27,10 +27,42 @@ macro_rules! panic_println {
})
}
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
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]
fn panic(info: &PanicInfo) -> ! {
use crate::time::interface::TimeManager;
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
let timestamp = crate::time::time_manager().uptime();
if let Some(args) = info.message() {

@ -27,10 +27,42 @@ macro_rules! panic_println {
})
}
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
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]
fn panic(info: &PanicInfo) -> ! {
use crate::time::interface::TimeManager;
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
let timestamp = crate::time::time_manager().uptime();
if let Some(args) = info.message() {

@ -27,10 +27,42 @@ macro_rules! panic_println {
})
}
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
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]
fn panic(info: &PanicInfo) -> ! {
use crate::time::interface::TimeManager;
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
let timestamp = crate::time::time_manager().uptime();
if let Some(args) = info.message() {

@ -27,10 +27,42 @@ macro_rules! panic_println {
})
}
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
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]
fn panic(info: &PanicInfo) -> ! {
use crate::time::interface::TimeManager;
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
let timestamp = crate::time::time_manager().uptime();
if let Some(args) = info.message() {

@ -27,10 +27,42 @@ macro_rules! panic_println {
})
}
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
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]
fn panic(info: &PanicInfo) -> ! {
use crate::time::interface::TimeManager;
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
let timestamp = crate::time::time_manager().uptime();
if let Some(args) = info.message() {

@ -1744,7 +1744,16 @@ diff -uNr 11_exceptions_part1_groundwork/src/panic_wait.rs 12_integrated_testing
/// Prints with a newline - only use from the panic handler.
///
/// Carbon copy from <https://doc.rust-lang.org/src/std/macros.rs.html>
@@ -48,5 +65,5 @@
@@ -53,7 +70,7 @@
return;
}
- cpu::wait_forever()
+ _panic_exit()
}
#[panic_handler]
@@ -80,5 +97,5 @@
);
}

@ -44,10 +44,42 @@ macro_rules! panic_println {
})
}
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
static PANIC_IN_PROGRESS: AtomicBool = AtomicBool::new(false);
if !PANIC_IN_PROGRESS.load(Ordering::Relaxed) {
PANIC_IN_PROGRESS.store(true, Ordering::Relaxed);
return;
}
_panic_exit()
}
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
use crate::time::interface::TimeManager;
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
let timestamp = crate::time::time_manager().uptime();
if let Some(args) = info.message() {

@ -2511,15 +2511,15 @@ diff -uNr 12_integrated_testing/src/panic_wait.rs 13_exceptions_part2_peripheral
use core::{fmt, panic::PanicInfo};
//--------------------------------------------------------------------------------------------------
@@ -48,6 +48,8 @@
@@ -77,6 +77,8 @@
fn panic(info: &PanicInfo) -> ! {
use crate::time::interface::TimeManager;
+ unsafe { exception::asynchronous::local_irq_mask() };
+
let timestamp = crate::time::time_manager().uptime();
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
if let Some(args) = info.message() {
diff -uNr 12_integrated_testing/src/state.rs 13_exceptions_part2_peripheral_IRQs/src/state.rs
--- 12_integrated_testing/src/state.rs

@ -44,12 +44,44 @@ macro_rules! panic_println {
})
}
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
static PANIC_IN_PROGRESS: AtomicBool = AtomicBool::new(false);
if !PANIC_IN_PROGRESS.load(Ordering::Relaxed) {
PANIC_IN_PROGRESS.store(true, Ordering::Relaxed);
return;
}
_panic_exit()
}
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
use crate::time::interface::TimeManager;
unsafe { exception::asynchronous::local_irq_mask() };
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
let timestamp = crate::time::time_manager().uptime();
if let Some(args) = info.message() {

@ -44,12 +44,44 @@ macro_rules! panic_println {
})
}
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
static PANIC_IN_PROGRESS: AtomicBool = AtomicBool::new(false);
if !PANIC_IN_PROGRESS.load(Ordering::Relaxed) {
PANIC_IN_PROGRESS.store(true, Ordering::Relaxed);
return;
}
_panic_exit()
}
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
use crate::time::interface::TimeManager;
unsafe { exception::asynchronous::local_irq_mask() };
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
let timestamp = crate::time::time_manager().uptime();
if let Some(args) = info.message() {

@ -44,12 +44,44 @@ macro_rules! panic_println {
})
}
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
static PANIC_IN_PROGRESS: AtomicBool = AtomicBool::new(false);
if !PANIC_IN_PROGRESS.load(Ordering::Relaxed) {
PANIC_IN_PROGRESS.store(true, Ordering::Relaxed);
return;
}
_panic_exit()
}
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
use crate::time::interface::TimeManager;
unsafe { exception::asynchronous::local_irq_mask() };
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
let timestamp = crate::time::time_manager().uptime();
if let Some(args) = info.message() {

@ -44,12 +44,44 @@ macro_rules! panic_println {
})
}
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
static PANIC_IN_PROGRESS: AtomicBool = AtomicBool::new(false);
if !PANIC_IN_PROGRESS.load(Ordering::Relaxed) {
PANIC_IN_PROGRESS.store(true, Ordering::Relaxed);
return;
}
_panic_exit()
}
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
use crate::time::interface::TimeManager;
unsafe { exception::asynchronous::local_irq_mask() };
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
let timestamp = crate::time::time_manager().uptime();
if let Some(args) = info.message() {

Binary file not shown.

Binary file not shown.

@ -27,10 +27,42 @@ macro_rules! panic_println {
})
}
/// Stop immediately if called a second time.
///
/// # Note
///
/// Using atomics here relieves us from needing to use `unsafe` for the static variable.
///
/// On `AArch64`, which is the only implemented architecture at the time of writing this,
/// [`AtomicBool::load`] and [`AtomicBool::store`] are lowered to ordinary load and store
/// instructions. They are therefore safe to use even with MMU + caching deactivated.
///
/// [`AtomicBool::load`]: core::sync::atomic::AtomicBool::load
/// [`AtomicBool::store`]: core::sync::atomic::AtomicBool::store
fn panic_prevent_reenter() {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_arch = "aarch64"))]
compile_error!("Add the target_arch to above's check if the following code is safe to use");
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]
fn panic(info: &PanicInfo) -> ! {
use crate::time::interface::TimeManager;
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();
let timestamp = crate::time::time_manager().uptime();
if let Some(args) = info.message() {

Loading…
Cancel
Save