use core::fmt::Display;
#[cfg(feature = "std-compat")]
pub(crate) fn install_std_hook() {
std::panic::set_hook(std::boxed::Box::new(|info| panic_now(info)));
}
pub(crate) fn panic_now(info: &impl Display) -> ! {
let _oops_guard = begin_panic();
panic_primary(info)
}
fn begin_panic() -> axpanic::OopsGuard {
ax_cpu::interrupt::disable_irqs();
match axpanic::enter_panic(current_cpu_id()) {
axpanic::PanicDisposition::Primary => axpanic::enter_oops(),
axpanic::PanicDisposition::Recursive | axpanic::PanicDisposition::Concurrent => {
panic_shutdown()
}
}
}
fn panic_primary(info: &impl Display) -> ! {
let _ = crate::emergency_console::write_fmt(format_args!("ARCEOS_PANIC_EMERGENCY\n{info}\n"));
if axbacktrace::is_enabled() && axpanic::should_emit_panic_backtrace() {
let backtrace = axbacktrace::RawBacktrace::capture().kind("panic");
let _ = crate::emergency_console::write_fmt(format_args!("{backtrace}"));
}
panic_shutdown()
}
fn panic_shutdown() -> ! {
crate::hal::power::system_off()
}
fn current_cpu_id() -> usize {
#[cfg(feature = "smp")]
{
unsafe { crate::hal::percpu::with_cpu_pin(crate::hal::percpu::this_cpu_id_pinned) }
.unwrap_or_else(|_| panic_shutdown())
}
#[cfg(not(feature = "smp"))]
{
0
}
}
struct RuntimeFatalTrap;
ax_cpu::trap::fatal::fatal_trap::impl_trait! {
impl FatalTrap for RuntimeFatalTrap {
fn terminate(record: core::fmt::Arguments<'_>) -> ! {
let _oops_guard = begin_panic();
let _ = crate::emergency_console::write_fmt(format_args!(
"ARCEOS_PANIC_EMERGENCY\n{record}\n"
));
panic_shutdown()
}
}
}