ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_scb.h File Reference

Cortex-M85 System Control Block: VTOR relocation + fault-status decode. More...

#include <stdint.h>
#include "ra8_err.h"
Include dependency graph for ra8_scb.h:
This graph shows which files directly or indirectly include this file:

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.

Detailed Description

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:

  • fault-status decodera8_scb_read_fault_status fills one struct from CFSR / HFSR / DFSR / MMFAR / BFAR / AFSR plus the ARMv8-M Security Extension SFSR / SFAR pair, exactly the set the exception decoder needs;
  • vector-table relocationra8_scb_set_vtor / ra8_scb_get_vtor write and read VTOR, the primitive the DFU copy-to-run launcher uses to point the core at a freshly-staged image;
  • trace unlockra8_scb_trace_enabled / ra8_scb_trace_enable read and set DEMCR.TRCENA, the bit the ITM log transport pre-checks before it touches any trace register (a clear TRCENA powers the ITM block down, so reading its registers first would bus-fault).

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.

Note
On a host build (RA8_OFF_TARGET) the SCB window is backed by the fake MMIO map (tests/mocks/src/ra8_fake_mmap.c), so every read and write is observable to unit tests while having no real core effect; the decode and relocation logic are exercised exactly as on silicon.

Definition in file ra8_scb.h.

Function Documentation

◆ ra8_scb_get_vtor()

uintptr_t ra8_scb_get_vtor ( void )
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.

Returns
Current vector-table base address held in VTOR.
Return values
0..UINTPTR_MAXWhatever VTOR currently holds.
Precondition
The SCB PPB window is accessible (always on Cortex-M85).
No precondition on prior relocation – VTOR always reads its live value.
Postcondition
No architectural state is modified (pure read).
The returned value equals the last value written to VTOR by hardware reset or software.
Note
Thread-safe; reads a single architectural register.
Since
0.1.0

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_scb_read_fault_status()

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.

Parameters
[out]outDestination snapshot. Must not be nullptr; every field is overwritten on success.
Returns
Error code.
Return values
k_ra8_okSnapshot populated from the live SCB.
k_ra8_err_null_ptrout was nullptr; nothing was read.
Precondition
out points to writable storage for one ra8_scb_fault_status_t.
The SCB PPB window (0xE000ED00) is accessible (always on Cortex-M85; the fake MMIO map backs it on a host build).
Postcondition
On k_ra8_ok every field of *out reflects the SCB at call time.
No SCB register is modified (pure read).
Note
Not reentrant against a concurrent SCB write, but the reads themselves are side-effect-free and fault-context safe.
Since
0.1.0

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().

◆ ra8_scb_set_vtor()

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).

Parameters
[in]baseAbsolute base address of the new vector table.
Precondition
base is aligned as the Arm v8-M ARM requires for VTOR.
Caller has masked interrupts if a table swap must be atomic w.r.t. entry.
Postcondition
SCB->VTOR holds base (low reserved bits per hardware).
No other SCB register is modified.
Note
Not thread-safe; intended for single-threaded boot / launch context.
Since
0.1.0

Definition at line 111 of file ra8_scb.c.

References internal_scb_reg(), and k_ra8_scb_vtor.

Referenced by ra8_dfu_launch().

◆ ra8_scb_trace_enable()

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.

Precondition
The SCB PPB window is accessible (always on Cortex-M85).
Caller intends to use ITM / DWT after this returns.
Postcondition
DEMCR.TRCENA is set; all other DEMCR bits are preserved.
ra8_scb_trace_enabled returns true afterwards.
Note
Not thread-safe against a concurrent DEMCR writer; intended for boot.
Since
0.1.0

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().

◆ ra8_scb_trace_enabled()

bool ra8_scb_trace_enabled ( void )
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.

Returns
Whether the trace subsystem is enabled.
Return values
trueDEMCR.TRCENA is set; ITM / DWT registers are safe to touch.
falseDEMCR.TRCENA is clear; the trace block is powered down.
Precondition
The SCB PPB window is accessible (always on Cortex-M85).
No precondition on debugger attach – DEMCR reads regardless.
Postcondition
No architectural state is modified (pure read).
The result reflects DEMCR at the moment of the call.
Note
Thread-safe; reads a single architectural register.
Since
0.1.0

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().