feat(uno): add CPU fault/panic exception handlers#494
Open
radutta99 wants to merge 7 commits into
Open
Conversation
Introduce `azihsm_fw_uno_fault`, a no_std crate that installs the firmware's single `#[panic_handler]` plus overrides for the ARMv7-M `HardFault` and `DefaultHandler` exceptions. Previously the default cortex-m-rt HardFault handler was a silent infinite loop, so a bus fault (e.g. a stray write to a read-only peripheral STATUS register) escalated to HardFault and hung the core with no output. The new HardFault handler reads the SCB fault-status registers and dumps the decoded CFSR fault class, the faulting address (BFAR/MMFAR when valid), the stacked register frame, and MSP, with a dedicated stack-overflow path (HFSR.FORCED + CFSR.MSTKERR). Output goes through a generic fault sink (the SoC UART today, a blocking busy-poll MMIO path safe to call from fault context) that is compiled unconditionally, so diagnostics appear even in production builds shipped without a trace backend. The sink is named generically so it can later route to the HSP debug-log channel without touching call sites. - crates/fault: lib.rs (handlers), sink.rs (FaultWriter + print_fault!), decode.rs (CFSR bit decoding) - Features: `semihosting` (SYS_EXIT on fault for the emulator), `fault-stackdump` (dev-only raw stack hexdump; default dump is the mcr-hsm-style minimalist register report) - app: depend on the crate, force-link via `use ... as _;`, move the panic handler out of main.rs, route `semihosting` through the crate Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a dedicated no_std Uno firmware crate (azihsm_fw_uno_fault) that provides the firmware-wide panic handler plus HardFault and DefaultHandler overrides, emitting fault diagnostics through an always-compiled output sink. This replaces the previous app-local panic handler and wires feature flags through the app to support semihosting termination and an optional dev stack dump.
Changes:
- Introduce
azihsm_fw_uno_faultwith panic + exception handlers and CFSR decoding. - Add a minimal “fault-time” sink (currently UART) plus
print_fault!/println_fault!formatting macros. - Wire the new crate into the Uno firmware workspace and app (dependency + feature passthrough; remove app-local panic handler).
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| fw/plat/uno/fw/crates/fault/src/sink.rs | Adds a UART-backed, always-compiled fault output sink and formatting macros. |
| fw/plat/uno/fw/crates/fault/src/lib.rs | Implements panic, HardFault, and DefaultHandler reporting + optional stack dump. |
| fw/plat/uno/fw/crates/fault/src/decode.rs | Decodes SCB CFSR bits into readable per-fault lines. |
| fw/plat/uno/fw/crates/fault/Cargo.toml | Defines the new crate and its semihosting / fault-stackdump features. |
| fw/plat/uno/fw/Cargo.toml | Registers the new crate as a workspace member + dependency. |
| fw/plat/uno/fw/app/src/main.rs | Force-links the fault crate and removes the app-local panic handler. |
| fw/plat/uno/fw/app/Cargo.toml | Adds the fault crate dependency and routes semihosting / fault-stackdump features. |
- Treat a BusFault stacking error (CFSR.STKERR) as well as MSTKERR as an "exception frame unreliable" condition: if exception-entry stacking fails with a BusFault that escalates to HardFault, the pushed register frame is invalid and formatting it could fault again. - Align the stack_dump base address down to a 4-byte boundary before forming the *const u32, avoiding UB when sp is corrupted/misaligned. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- FaultWriter now writes through semihosting SYS_WRITE0 when the `semihosting` feature is enabled, instead of the SoC UART. The emulator does not model the UART, where write_byte would spin forever on STATUS.TX_READY (or fault on unmapped MMIO), stalling the report before SYS_EXIT. Silicon builds keep writing the UART directly. Mirrors the trace backend's backend-uart / backend-semihosting selection. - Pass u32::MAX (instead of `-1i32 as u32`) to sys_exit for clarity. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
cortex-m-rt requires these exception handlers to be unsafe fn; satisfy clippy::missing_safety_doc (-D warnings) with a # Safety section. Also note STKERR alongside MSTKERR in the HardFault doc. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Use the UART driver write(&str) (filters non-printable bytes to 0xFE) instead of write_bytes() so control chars/embedded NUL do not garble fault logs. Reference the public \::FaultWriter re-export from the exported print_fault!/println_fault! macros instead of the private sink module, so downstream callers do not hit a privacy error. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
azihsm_fw_uno_fault, ano_stdcrate that installs the Uno firmware's single#[panic_handler]plus overrides for the ARMv7-MHardFaultandDefaultHandlerexceptions.Motivation
The default
cortex-m-rtHardFault handler is a silent infinite loop. So when a bus fault occurs — for example a stray write to a read-only peripheralSTATUSregister (exactly the SHA/AES bug fixed in #488) — it escalates to HardFault and hangs the core with no output, making it painful to diagnose. These handlers make any future fault self-report on the serial console.What it does
HardFault reads the SCB fault-status registers and dumps:
CFSRfault class (MemManage / BusFault / UsageFault, per-bit),BFAR/MMFARwhen the matching*VALIDbit is set,ExceptionFrame(R0–R3, R12, LR, PC, xPSR) andMSP,HFSR.FORCED+CFSR.MSTKERR), where the frame is unreliable and onlyMSPis reported.panic emits the panic location and message.
DefaultHandler reports the offending exception/IRQ number so an unexpected interrupt is no longer silent.
Output goes through a small UART sink that is always compiled (so diagnostics appear even in trace-disabled production builds) and is named transport-agnostically so it can later route to the HSP debug-log channel without touching call sites.
Features
semihosting— issueSYS_EXIT(-1)on fault so the emulator host stops.fault-stackdump— dev-only raw stack hexdump appended to the HardFault report (default dump is the minimalist register/CFSR report, mirroring the mcr-hsm handlers).Wiring
The app depends on the crate and force-links it via
use azihsm_fw_uno_fault as _;(thepanic-haltpattern); the panic handler is moved out ofapp/src/main.rs, and thesemihostingfeature is routed through the crate.Scope
Deliberately a CPU-fault reporter. Cross-core crash notification, persistent crash dumps, and peripheral-error ISRs (present in the mcr-hsm
exception-handlerscrate) depend on infrastructure the Uno port does not yet have (Tcon mailbox, crashdump store) and are out of scope here.Testing
Builds in all three configs (default/no-trace,
trace-uart,trace-uart,fault-stackdump). Validated on the Manticore EVB by deliberately triggering faults withtrace-uartenabled and confirming the decoded dump on COM6:BusFault: IMPRECISERR … (BFAR unreliable),HFSRFORCED — i.e. the previously-silent hang now produces a full dump.udf):UsageFault: UNDEFINSTR, with a precisePCpointing exactly at the faulting instruction in the disassembly.