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

SCS write watchers + DWT time base (see emu_exc.h). More...

#include <stdio.h>
#include "board_periph.h"
#include "emu_console.h"
#include "emu_engine.h"
#include "emu_exc.h"
#include "emu_seams.h"
Include dependency graph for emu_exc_scs.c:

Go to the source code of this file.

Enumerations

enum  dwt_model_t : uint64_t {
  k_dwt_ctrl_addr = 0xE0001000UL ,
  k_dwt_cyccnt_addr = 0xE0001004UL ,
  k_dwt_ctrl_cyccntena = 0x00000001UL ,
  k_dwt_cyccnt_per_chunk = 500000UL
}
 Data Watchpoint and Trace (DWT) cycle-counter register model. More...

Functions

static RA8_INTERNAL void internal_on_scb_ctrl_write (uc_engine *uc, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user)
 UC_HOOK_MEM_WRITE handler for the SCB control words AIRCR and CCR.
static RA8_INTERNAL void internal_on_nvic_en_write (uc_engine *uc, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user)
 UC_HOOK_MEM_WRITE handler for the NVIC ISER / ICER arrays.
void dwt_cyccnt_advance (uc_engine *uc)
 Advance the DWT cycle counter by one outer chunk's worth of cycles.
void emu_exc_install_scb_nvic (uc_engine *uc)
 Implementation of emu_exc_install_scb_nvic() – SCB ctrl + NVIC hooks.
bool emu_exc_reboot_requested (void)
 Implementation of emu_exc_reboot_requested() – plain flag read.
void emu_exc_clear_reboot_request (void)
 Implementation of emu_exc_clear_reboot_request() – plain clear.

Variables

static bool s_reboot_request
 AIRCR.SYSRESETREQ observed: the run loop performs a warm reboot.

Detailed Description

SCS write watchers + DWT time base (see emu_exc.h).

The system-control-space companions of the exception engine: the SCB control-word watcher (AIRCR.SYSRESETREQ warm-reboot requests and the CCR.DIV_0_TRP arming of the div-0 seam), the NVIC ISER/ICER W1S/W1C folding into board_periph's enable shadow, and the DWT cycle-counter model that keeps a masked-context ra8_delay_ms advancing. Moved verbatim out of the ra8_emulator main translation unit.

Since
0.1.0

Definition in file emu_exc_scs.c.

Enumeration Type Documentation

◆ dwt_model_t

enum dwt_model_t : uint64_t

Data Watchpoint and Trace (DWT) cycle-counter register model.

The Armv8-M DWT unit exposes a free-running 32-bit cycle counter (CYCCNT) that the firmware uses as a PRIMASK-immune busy-wait time base: ra8_delay_ms (libs/ra8_core/src/ra8_time.c) spins on CYCCNT whenever interrupts are masked, which is exactly the early bring-up window (SystemInit runs cpsid i and only ra8_isr_globals_enable clears PRIMASK later). The PPB is mapped as plain RAM here, so without a model CYCCNT reads a constant 0, the delta never reaches the target, and any masked-context ra8_delay_ms spins the whole run budget – which is what stalled pdm_mic_demo and camera_capture before their first banner. These constants let dwt_cyccnt_advance model the counter's advance.

Enumerator
k_dwt_ctrl_addr 

DWT_CTRL (bit 0 CYCCNTENA).

k_dwt_cyccnt_addr 

DWT_CYCCNT free-running cycle counter.

k_dwt_ctrl_cyccntena 

DWT_CTRL.CYCCNTENA: counter enable.

k_dwt_cyccnt_per_chunk 

Cycles charged per outer chunk (==.

k_run_chunk_insns: retired insns ~= elapsed cycles at ~1 IPC).

Definition at line 152 of file emu_exc_scs.c.

Function Documentation

◆ dwt_cyccnt_advance()

void dwt_cyccnt_advance ( uc_engine * uc)

Advance the DWT cycle counter by one outer chunk's worth of cycles.

Models DWT_CYCCNT as the free-running cycle counter the Armv8-M architecture (DDI0553 D1.2.1) specifies: it counts only while DEMCR.TRCENA and DWT_CTRL.CYCCNTENA are both set. ra8_time_init arms both bits, so once the firmware has initialised its time base the counter advances; an app that never enables the cycle counter sees CYCCNT stay at its firmware-written value (zero by default), so this model is inert for every such app and cannot regress it.

The per-chunk increment (k_dwt_cyccnt_per_chunk) equals the busy chunk's instruction budget, i.e. one chunk of execution is charged one chunk of cycles (~1 instruction per cycle on the M85). A read-modify-write is used so a firmware CYCCNT reset (a DWT->CYCCNT = 0 at init) is honoured and the count simply resumes from there. Called once per outer chunk, in lockstep with the SysTick period the run loop already advances, so time bases stay consistent.

Parameters
[in,out]ucActive Unicorn engine (CYCCNT and its enables live in PPB RAM, read/written through uc).
Returns
Nothing.
Precondition
uc has stopped at an instruction boundary (outer-chunk cadence).
The PPB (DEMCR / DWT_CTRL / DWT_CYCCNT) is mapped as RAM.
Postcondition
CYCCNT is advanced iff the trace subsystem and cycle counter are enabled.
No PPB word other than DWT_CYCCNT is modified.
Note
Not thread-safe; the run loop is single-threaded host-side.
Since
0.1.0

Definition at line 190 of file emu_exc_scs.c.

References k_dwt_ctrl_addr, k_dwt_ctrl_cyccntena, k_dwt_cyccnt_addr, k_dwt_cyccnt_per_chunk, k_scb_demcr_addr, k_scb_demcr_trcena, rd32(), and wr32().

Referenced by internal_run_loop_tick_inputs().

◆ emu_exc_clear_reboot_request()

void emu_exc_clear_reboot_request ( void )

Implementation of emu_exc_clear_reboot_request() – plain clear.

Clear the latched warm-reboot request (after performing it).

Definition at line 248 of file emu_exc_scs.c.

References s_reboot_request.

Referenced by internal_run_loop_run_chunk().

◆ emu_exc_install_scb_nvic()

void emu_exc_install_scb_nvic ( uc_engine * uc)

Implementation of emu_exc_install_scb_nvic() – SCB ctrl + NVIC hooks.

Arm the SCB control-word and NVIC ISER/ICER write watchers.

Definition at line 205 of file emu_exc_scs.c.

References internal_on_nvic_en_write(), internal_on_scb_ctrl_write(), k_nvic_en_span, k_nvic_icer_base, k_nvic_iser_base, k_scb_aircr, and k_scb_ccr.

Referenced by internal_main_install_core_seams().

◆ emu_exc_reboot_requested()

bool emu_exc_reboot_requested ( void )

Implementation of emu_exc_reboot_requested() – plain flag read.

Whether AIRCR.SYSRESETREQ requested a warm reboot.

Definition at line 242 of file emu_exc_scs.c.

References s_reboot_request.

Referenced by internal_run_inner_check_stops(), and internal_run_loop_run_chunk().

◆ internal_on_nvic_en_write()

RA8_INTERNAL void internal_on_nvic_en_write ( uc_engine * uc,
uc_mem_type type,
uint64_t addr,
int size,
int64_t value,
void * user )
static

UC_HOOK_MEM_WRITE handler for the NVIC ISER / ICER arrays.

The NVIC set-enable (ISER) and clear-enable (ICER) registers are not normal read/write words: a written 1 sets (ISER) or clears (ICER) that interrupt line and a written 0 has no effect, so independent stores accumulate. The PPB is mapped as plain RAM here, so the raw store would overwrite the whole word and drop every other enabled line – which breaks any firmware that enables more than one line (e.g. the SCI RXI + TXI + TEI of the interrupt-driven UART path, or several USB controller lines later). This hook decodes the written bits and folds them into board_periph's authoritative enable shadow, which the ICU model consults when deciding whether to pend a line. The raw RAM word is left as-is (nothing reads ISER/ICER back on the modelled paths).

Parameters
[in,out]ucUnicorn engine; unused (state lives in board_periph).
[in]typeMemory access type (write); unused.
[in]addrThe ISER/ICER word being written.
[in]sizeAccess width in bytes; unused.
[in]valueThe bit-mask the firmware is setting/clearing.
[in]userHook user pointer; unused.
Returns
Nothing.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for on NVIC en write.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the emu exc scs model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 115 of file emu_exc_scs.c.

References board_periph_nvic_set_enable(), k_nvic_en_span, k_nvic_icer_base, k_nvic_iser_base, and RA8_INTERNAL.

Referenced by emu_exc_install_scb_nvic().

◆ internal_on_scb_ctrl_write()

RA8_INTERNAL void internal_on_scb_ctrl_write ( uc_engine * uc,
uc_mem_type type,
uint64_t addr,
int size,
int64_t value,
void * user )
static

UC_HOOK_MEM_WRITE handler for the SCB control words AIRCR and CCR.

One write hook spans the SCB control block from AIRCR (0xE000ED0C) through CCR (0xE000ED14) and dispatches strictly by word address, so the two nearby control registers share a single hook rather than each adding its own – this Unicorn build consults every installed memory hook per access, so folding CCR in here keeps a hot read loop paying the baseline hook count. Intervening words (VTOR, SCR) fall through untouched.

  • AIRCR: writing SYSRESETREQ (with the mandatory 0x05FA key in the upper half-word) asks the chip to reset. The emulator honours it as a warm reboot: record the request and stop the chunk; the run loop's reboot wrapper re-runs the firmware from its reset vector (latching RSTSR1.SWRF). Without this, ra8_reset_software_reset would spin forever waiting for a reset that never came.
  • CCR: writing DIV_0_TRP arms the divide-by-zero UsageFault by overwriting the tracked divide sites with UDF (div0_patch_sites) the instant the firmware opts in, race-free even when the arming write and the divide share one chunk.
Parameters
[in,out]ucUnicorn engine (stopped to end the chunk on a reset).
[in]typeUnused memory-event type.
[in]addrObserved SCB address (dispatched by word).
[in]sizeAccess width (unused).
[in]valueValue written.
[in]userUnused hook context.
Returns
Nothing.
Since
0.1.0
Precondition
Arguments satisfy the ranges documented for on SCB ctrl write.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the emu exc scs model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.

Definition at line 61 of file emu_exc_scs.c.

References div0_patch_sites(), k_aircr_sysresetreq, k_ccr_div_0_trp, k_scb_aircr, k_scb_ccr, RA8_INTERNAL, and s_reboot_request.

Referenced by emu_exc_install_scb_nvic().

Variable Documentation

◆ s_reboot_request

bool s_reboot_request
static

AIRCR.SYSRESETREQ observed: the run loop performs a warm reboot.

Definition at line 27 of file emu_exc_scs.c.

Referenced by emu_exc_clear_reboot_request(), emu_exc_reboot_requested(), and internal_on_scb_ctrl_write().