|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Cortex-M85 System Control Block: VTOR relocation + fault-status decode. More...
Go to the source code of this file.
Data Structures | |
| struct | ra8_scb_fault_status_t |
| One snapshot of the Cortex-M85 SCB fault-status registers. More... | |
Functions | |
| ra8_err_t | ra8_scb_read_fault_status (ra8_scb_fault_status_t *out) |
| Read the Cortex-M85 SCB fault-status registers into one struct. | |
| void | ra8_scb_set_vtor (uintptr_t base) |
| Relocate the vector table by writing SCB->VTOR. | |
| uintptr_t | ra8_scb_get_vtor (void) |
| Read the current vector-table base from SCB->VTOR. | |
| bool | ra8_scb_trace_enabled (void) |
| Report whether DEMCR.TRCENA (trace subsystem enable) is set. | |
| void | ra8_scb_trace_enable (void) |
| Set DEMCR.TRCENA to power up the trace subsystem. | |
Cortex-M85 System Control Block: VTOR relocation + fault-status decode.
One abstraction over the Arm v8-M System Control Block (PPB window 0xE000ED00), the block three first-party translation units otherwise reach raw – the exception decoder, the DFU copy-to-run launcher, and the ITM log transport:
This module lives in ra8_core – the foundation layer – rather than ra8_hal because two of its three consumers (the exception decoder and the log transport) are themselves ra8_core translation units, and ra8_core may depend on nothing above itself (scripts/checks/check_core_layering.py). The SCB is a Cortex-M85 core block, not an RA8D2 peripheral, so it is at home at the foundation next to the exception and log code that already read it.
These are Arm-architecture registers in the Cortex-M85 core, NOT RA8D2 peripherals, so the implementation references the Arm v8-M Architecture Reference Manual ("Arm v8-M ARM") rather than the Renesas Hardware User's Manual – the HUM itself defers the SCB to the Arm v8-M ARM. SFSR / SFAR are banked to the Secure state: read from Secure (every boot here) they carry the real SecureFault cause and address, read from Non-secure they are architecturally RAZ, so an unconditional capture is safe either way.
Definition in file ra8_scb.h.
|
nodiscard |
Read the current vector-table base from SCB->VTOR.
Returns the raw VTOR value as an address. Reset value is 0 (table at the start of code memory) until a boot stage or launcher relocates it.
| 0..UINTPTR_MAX | Whatever VTOR currently holds. |
Definition at line 118 of file ra8_scb.c.
References internal_scb_reg(), and k_ra8_scb_vtor.
Referenced by scb_demo_probe_and_report().
| ra8_err_t ra8_scb_read_fault_status | ( | ra8_scb_fault_status_t * | out | ) |
Read the Cortex-M85 SCB fault-status registers into one struct.
Loads CFSR, HFSR, DFSR, MMFAR, BFAR, AFSR, and the Secure-banked SFSR / SFAR pair with plain volatile reads and no side effects – no register is cleared or written. The read order matches the field order of ra8_scb_fault_status_t. Safe to call from a fault context: the SCB window is always mapped and the reads cannot themselves fault.
| [out] | out | Destination snapshot. Must not be nullptr; every field is overwritten on success. |
| k_ra8_ok | Snapshot populated from the live SCB. |
| k_ra8_err_null_ptr | out was nullptr; nothing was read. |
out points to writable storage for one ra8_scb_fault_status_t. Module log tag – block scope: this is the only function that logs.
Definition at line 86 of file ra8_scb.c.
References ra8_scb_fault_status_t::afsr, ra8_scb_fault_status_t::bfar, ra8_scb_fault_status_t::cfsr, ra8_scb_fault_status_t::dfsr, ra8_scb_fault_status_t::hfsr, internal_scb_reg(), k_ra8_ok, k_ra8_scb_afsr, k_ra8_scb_bfar, k_ra8_scb_cfsr, k_ra8_scb_dfsr, k_ra8_scb_hfsr, k_ra8_scb_mmfar, k_ra8_scb_sfar, k_ra8_scb_sfsr, ra8_scb_fault_status_t::mmfar, RA8_CHECK_NULL_PTR, ra8_scb_fault_status_t::sfar, and ra8_scb_fault_status_t::sfsr.
Referenced by ra8_exception_capture_diagnostics(), and scb_demo_probe_and_report().
| void ra8_scb_set_vtor | ( | uintptr_t | base | ) |
Relocate the vector table by writing SCB->VTOR.
Writes base to the Vector Table Offset Register so subsequent exception and interrupt entries fetch their vectors from a table based at base. The hardware ignores the low table-alignment bits of VTOR; the caller is responsible for basing the table at a suitably aligned address (Arm v8-M requires alignment to the table size, at least 128 bytes). The write is issued as-is with no alignment rejection so it substitutes exactly for a raw VTOR poke; ordering against a following table fetch is the caller's concern (bracket with DSB/ISB before branching to the relocated image).
| [in] | base | Absolute base address of the new vector table. |
base is aligned as the Arm v8-M ARM requires for VTOR. base (low reserved bits per hardware). Definition at line 111 of file ra8_scb.c.
References internal_scb_reg(), and k_ra8_scb_vtor.
Referenced by ra8_dfu_launch().
| void ra8_scb_trace_enable | ( | void | ) |
Set DEMCR.TRCENA to power up the trace subsystem.
Sets bit 24 (TRCENA) of DEMCR, leaving every other bit unchanged, so the ITM / DWT trace block is powered and its registers become accessible. This is the unlock a firmware-driven trace transport performs when it cannot rely on a debugger having set TRCENA. Idempotent: setting an already-set bit is a no-op in effect.
Definition at line 131 of file ra8_scb.c.
References internal_scb_reg(), k_ra8_scb_demcr, and k_ra8_scb_demcr_trcena.
Referenced by scb_demo_probe_and_report().
|
nodiscard |
Report whether DEMCR.TRCENA (trace subsystem enable) is set.
Reads bit 24 (TRCENA) of the Debug Exception and Monitor Control Register. While TRCENA is clear the ITM / DWT trace block is powered down and reading any of its registers bus-faults, so a trace transport must pre-check this before touching ITM. DEMCR itself is always accessible.
| true | DEMCR.TRCENA is set; ITM / DWT registers are safe to touch. |
| false | DEMCR.TRCENA is clear; the trace block is powered down. |
Definition at line 124 of file ra8_scb.c.
References internal_scb_reg(), k_ra8_scb_demcr, and k_ra8_scb_demcr_trcena.
Referenced by internal_itm_ready(), and scb_demo_probe_and_report().