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

Cortex-M85 System Control Block driver implementation. More...

#include "ra8_scb.h"
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
Include dependency graph for ra8_scb.c:

Go to the source code of this file.

Enumerations

enum  ra8_scb_reg_addr_t : uintptr_t {
  k_ra8_scb_vtor = 0xE000ED08UL ,
  k_ra8_scb_cfsr = 0xE000ED28UL ,
  k_ra8_scb_hfsr = 0xE000ED2CUL ,
  k_ra8_scb_dfsr = 0xE000ED30UL ,
  k_ra8_scb_mmfar = 0xE000ED34UL ,
  k_ra8_scb_bfar = 0xE000ED38UL ,
  k_ra8_scb_afsr = 0xE000ED3CUL ,
  k_ra8_scb_sfsr = 0xE000EDE4UL ,
  k_ra8_scb_sfar = 0xE000EDE8UL ,
  k_ra8_scb_demcr = 0xE000EDFCUL
}
 Arm v8-M SCB register addresses (PPB window 0xE000EDxx). More...
enum  ra8_scb_bits_t : uint32_t { k_ra8_scb_demcr_trcena = 0x01000000UL }
 Named bit fields within the SCB registers this driver touches. More...

Functions

static volatile uint32_t * internal_scb_reg (ra8_scb_reg_addr_t addr)
 Typed pointer to a 32-bit SCB register.
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 driver implementation.

Implements ::ra8_scb.h against the Arm v8-M System Control Block (PPB window 0xE000ED00). The fault-status read loads the eight status / address registers with plain volatile reads; the VTOR helpers write and read the Vector Table Offset Register; the trace helpers read and set DEMCR.TRCENA.

These are Arm-architecture registers, so the inline comments reference the Arm v8-M Architecture Reference Manual ("Arm v8-M ARM") rather than the RA8D2 Hardware User's Manual – the HUM defers the Cortex-M85 core registers to the Arm v8-M ARM. Every access goes through internal_scb_reg (the pattern ra8_cache.c uses), so on a host build the fake MMIO map backs the window and the reads / writes are observable to unit tests.

Since
0.1.0

Definition in file ra8_scb.c.

Enumeration Type Documentation

◆ ra8_scb_bits_t

enum ra8_scb_bits_t : uint32_t

Named bit fields within the SCB registers this driver touches.

Arm v8-M ARM (Debug) DEMCR register description.

Enumerator
k_ra8_scb_demcr_trcena 

DEMCR.TRCENA – bit 24.

Definition at line 56 of file ra8_scb.c.

◆ ra8_scb_reg_addr_t

enum ra8_scb_reg_addr_t : uintptr_t

Arm v8-M SCB register addresses (PPB window 0xE000EDxx).

Arm v8-M ARM B3.2 "System Control Block" and the Debug / Security Extension register views. Backed by the fake core window (0xE0000000) on a host build, real PPB on silicon.

Enumerator
k_ra8_scb_vtor 

Vector Table Offset Register (VTOR).

k_ra8_scb_cfsr 

Configurable Fault Status (CFSR).

k_ra8_scb_hfsr 

HardFault Status Register (HFSR).

k_ra8_scb_dfsr 

Debug Fault Status Register (DFSR).

k_ra8_scb_mmfar 

MemManage Fault Address (MMFAR).

k_ra8_scb_bfar 

BusFault Address Register (BFAR).

k_ra8_scb_afsr 

Auxiliary Fault Status (AFSR).

k_ra8_scb_sfsr 

SecureFault Status (SFSR, S-banked).

k_ra8_scb_sfar 

SecureFault Address (SFAR, S-banked).

k_ra8_scb_demcr 

Debug Exception + Monitor Ctrl (DEMCR).

Definition at line 38 of file ra8_scb.c.

Function Documentation

◆ internal_scb_reg()

volatile uint32_t * internal_scb_reg ( ra8_scb_reg_addr_t addr)
inlinestatic

Typed pointer to a 32-bit SCB register.

Trivial address-cast helper so each access site reads *internal_scb_reg(k_...) instead of an inline cast. Always inlined.

Parameters
[in]addrOne of ra8_scb_reg_addr_t.
Returns
Volatile pointer for a single read or write.
Return values
(volatileuint32_t*)addr Alias of the live register.
Precondition
addr is a valid SCB register address.
The PPB / fake core window is accessible.
Postcondition
No state changed by forming the pointer.
The returned pointer aliases the live register.
Note
Arm v8-M ARM B3.2 "System Control Block". Trivially thread-safe.
Since
0.1.0

Definition at line 81 of file ra8_scb.c.

Referenced by ra8_scb_get_vtor(), ra8_scb_read_fault_status(), ra8_scb_set_vtor(), ra8_scb_trace_enable(), and ra8_scb_trace_enabled().

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