|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Cortex-M85 CPU exception diagnostic implementation. More...
#include "ra8_exception.h"#include <stdint.h>#include "ra8_attributes.h"#include "ra8_error_handler.h"#include "ra8_log.h"#include "ra8_scb.h"Go to the source code of this file.
Macros | |
| #define | RA8_EXCEPTION_HALT(tag, msg, exc) |
| RA8 EXCEPTION HALT. | |
Enumerations | |
| enum | ra8_exc_num_t : uint32_t { k_ra8_exc_num_nmi = 2U } |
| Architectural exception numbers this module special-cases. More... | |
Functions | |
| void | ra8_exception_capture_diagnostics (ra8_exception_diagnostics_t *out) |
| Implementation of ra8_exception_capture_diagnostics() – routes the SCB fault-status read through the shared ra8_scb primitive. | |
| void | ra8_exception_set_persist_hook (ra8_exception_persist_fn hook) |
| Implementation of ra8_exception_set_persist_hook() – store the sink pointer. | |
| static void | internal_exception_halt_loop (void) |
| Spin halt with a known PC at a named symbol. | |
| static void | internal_log_fault_dump (const ra8_exception_frame_t *frame, uint32_t exc_number, const ra8_exception_diagnostics_t *diag, uint32_t nmisr) |
| Best-effort log dump of a captured fault record. | |
| void | ra8_exception_report (const ra8_exception_frame_t *frame, uint32_t exc_number) |
| Implementation of ra8_exception_report() – fault dump + halt. | |
| void | ra8_exception_report_nmi (const ra8_exception_frame_t *frame, uint32_t nmisr) |
| Implementation of ra8_exception_report_nmi() – stage the ICU cause, then chain. | |
Variables | |
| volatile ra8_exception_last_t | g_ra8_exception_last |
| Definition of g_ra8_exception_last – contract documented in ra8_exception.h. | |
| static volatile uint32_t | s_ra8_exception_nmi_stage |
| NMISR cause staged by ra8_exception_report_nmi() for the record. | |
| static ra8_exception_persist_fn | s_ra8_exception_persist |
| Registered post-decode persistence sink, or nullptr when disarmed. | |
Cortex-M85 CPU exception diagnostic implementation.
Reads the SCB fault status registers and logs the stacked exception frame before halting via ra8_fatal_error().
The weak HardFault_Handler in src/boot/vector_table.c is replaced by a non-weak naked trampoline:
The trampoline picks the stack pointer the fault was taken on (MSP if EXC_RETURN[2]=0, PSP otherwise) and tail-calls ra8_exception_report() with a pointer to the stacked frame.
Definition in file ra8_exception.c.
| #define RA8_EXCEPTION_HALT | ( | tag, | |
| msg, | |||
| exc ) |
RA8 EXCEPTION HALT.
Definition at line 52 of file ra8_exception.c.
Referenced by ra8_exception_report().
| enum ra8_exc_num_t : uint32_t |
Architectural exception numbers this module special-cases.
| Enumerator | |
|---|---|
| k_ra8_exc_num_nmi | NMI vector slot – carries an ICU NMISR cause. |
Definition at line 65 of file ra8_exception.c.
|
static |
Spin halt with a known PC at a named symbol.
The fault handler MUST terminate at a symbol the debugger can name rather than escalate to LOCKUP at PC=0xEFFFFFFE. This function is a wfi loop in its own translation-unit-local symbol so a backtrace unambiguously points at "we got here from the fault handler" rather than at a random unmapped address.
Definition at line 180 of file ra8_exception.c.
References RA8_INTERNAL.
|
static |
Best-effort log dump of a captured fault record.
Emits the exception number, the stacked frame (when present), the SCB diagnostics, and – for the NMI class only – the ICU NMISR cause, all via ra8_log_error_val. Runs strictly AFTER the fixed-SRAM snapshot is complete, so a secondary fault inside the log backend can no longer lose the record.
| [in] | frame | Stacked exception frame; may be nullptr. |
| [in] | exc_number | Architectural exception number. |
| [in] | diag | Captured SCB diagnostics (never nullptr; sole caller passes a stack local). |
| [in] | nmisr | Recorded ICU NMI cause (logged only for exc 2). |
Definition at line 215 of file ra8_exception.c.
References ra8_exception_diagnostics_t::bfar, ra8_exception_diagnostics_t::cfsr, ra8_exception_diagnostics_t::hfsr, k_ra8_exc_num_nmi, ra8_exception_frame_t::lr, ra8_exception_diagnostics_t::mmfar, ra8_exception_frame_t::pc, ra8_exception_frame_t::r0, ra8_exception_frame_t::r1, ra8_exception_frame_t::r12, ra8_exception_frame_t::r2, ra8_exception_frame_t::r3, RA8_INTERNAL, ra8_log_error_val, ra8_exception_diagnostics_t::sfar, ra8_exception_diagnostics_t::sfsr, and ra8_exception_frame_t::xpsr.
Referenced by ra8_exception_report().
| void ra8_exception_capture_diagnostics | ( | ra8_exception_diagnostics_t * | out | ) |
Implementation of ra8_exception_capture_diagnostics() – routes the SCB fault-status read through the shared ra8_scb primitive.
Read the current SCB fault-status registers.
Delegates the CFSR / HFSR / DFSR / MMFAR / BFAR / AFSR + Secure SFSR / SFAR reads to ra8_scb_read_fault_status, then copies the snapshot into the exception-record layout. NULL argument is tolerated and returns silently (the fault path must never log from here), so the shared primitive is only ever handed a stack local and its null-guard return cannot trip. Behaviourally identical to the previous inline reads: the same eight registers in the same order, no register written.
| [out] | out | Destination buffer. May be nullptr. |
Definition at line 94 of file ra8_exception.c.
References ra8_exception_diagnostics_t::afsr, ra8_scb_fault_status_t::afsr, ra8_exception_diagnostics_t::bfar, ra8_scb_fault_status_t::bfar, ra8_exception_diagnostics_t::cfsr, ra8_scb_fault_status_t::cfsr, ra8_exception_diagnostics_t::dfsr, ra8_scb_fault_status_t::dfsr, ra8_exception_diagnostics_t::hfsr, ra8_scb_fault_status_t::hfsr, k_ra8_ok, ra8_exception_diagnostics_t::mmfar, ra8_scb_fault_status_t::mmfar, ra8_scb_read_fault_status(), ra8_exception_diagnostics_t::sfar, ra8_scb_fault_status_t::sfar, ra8_exception_diagnostics_t::sfsr, and ra8_scb_fault_status_t::sfsr.
Referenced by ra8_exception_report().
| void ra8_exception_report | ( | const ra8_exception_frame_t * | frame, |
| uint32_t | exc_number ) |
Implementation of ra8_exception_report() – fault dump + halt.
Emit a full fault dump over the log backend.
Captures the stacked frame and SCB diagnostics into the fixed-SRAM snapshot g_ra8_exception_last BEFORE any function call that might itself fault. Then best-effort logs them via internal_log_fault_dump (ra8_log silently drops every byte from a fault context on the default ITM backend; a registered byte sink still emits, see libs/ra8_core/src/ra8_log.c). Finally parks the CPU at the named internal_exception_halt_loop symbol on target so the debugger can give the halt a clean backtrace instead of escalating to LOCKUP at PC=0xEFFFFFFE.
| [in] | frame | Stacked exception frame; may be nullptr. |
| [in] | exc_number | Architectural exception number. |
Definition at line 270 of file ra8_exception.c.
References g_ra8_exception_last, internal_log_fault_dump(), k_ra8_exc_magic_valid, ra8_exception_frame_t::lr, ra8_exception_frame_t::pc, ra8_exception_frame_t::r0, ra8_exception_frame_t::r1, ra8_exception_frame_t::r12, ra8_exception_frame_t::r2, ra8_exception_frame_t::r3, ra8_exception_capture_diagnostics(), RA8_EXCEPTION_HALT, s_ra8_exception_nmi_stage, s_ra8_exception_persist, and ra8_exception_frame_t::xpsr.
Referenced by blc_fault_dispatch(), and ra8_exception_report_nmi().
| void ra8_exception_report_nmi | ( | const ra8_exception_frame_t * | frame, |
| uint32_t | nmisr ) |
Implementation of ra8_exception_report_nmi() – stage the ICU cause, then chain.
Report an NMI with its ICU cause register, then halt.
Definition at line 322 of file ra8_exception.c.
References k_ra8_exc_num_nmi, ra8_exception_report(), and s_ra8_exception_nmi_stage.
Referenced by internal_nmi_report(), and internal_ra8_board_nmi_report().
| void ra8_exception_set_persist_hook | ( | ra8_exception_persist_fn | hook | ) |
Implementation of ra8_exception_set_persist_hook() – store the sink pointer.
Register (or clear) the post-decode fault-persistence hook.
Definition at line 155 of file ra8_exception.c.
References s_ra8_exception_persist.
Referenced by ra8_crashlog_install().
| volatile ra8_exception_last_t g_ra8_exception_last |
Definition of g_ra8_exception_last – contract documented in ra8_exception.h.
The one fixed-SRAM ra8_exception_last_t snapshot instance.
Definition at line 114 of file ra8_exception.c.
Referenced by ra8_exception_report().
|
static |
NMISR cause staged by ra8_exception_report_nmi() for the record.
ra8_exception_report() owns the fixed-SRAM snapshot write order (everything first, magic last). The NMI entry point cannot write the record directly without racing that ordering, so it stages the ICU cause here (a plain SRAM store that cannot fault) and the common path copies it into g_ra8_exception_last.nmisr – then clears the stage so a later non-NMI record never inherits a stale cause.
Definition at line 133 of file ra8_exception.c.
Referenced by ra8_exception_report(), and ra8_exception_report_nmi().
|
static |
Registered post-decode persistence sink, or nullptr when disarmed.
Set by ra8_exception_set_persist_hook() and invoked by ra8_exception_report() once the fixed-SRAM snapshot is complete. Lives in .bss (zeroed by every reset), so a consumer must re-arm it early on each boot. Left nullptr unless an app opts into fault persistence, so the default fault path pulls in no crash-log code.
Definition at line 151 of file ra8_exception.c.
Referenced by ra8_exception_report(), and ra8_exception_set_persist_hook().