|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
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"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. | |
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.
Definition in file emu_exc_scs.c.
| 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.
Definition at line 152 of file emu_exc_scs.c.
| 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.
| [in,out] | uc | Active Unicorn engine (CYCCNT and its enables live in PPB RAM, read/written through uc). |
uc has stopped at an instruction boundary (outer-chunk cadence). 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().
| 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().
| 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().
| 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().
|
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).
| [in,out] | uc | Unicorn engine; unused (state lives in board_periph). |
| [in] | type | Memory access type (write); unused. |
| [in] | addr | The ISER/ICER word being written. |
| [in] | size | Access width in bytes; unused. |
| [in] | value | The bit-mask the firmware is setting/clearing. |
| [in] | user | Hook user pointer; unused. |
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().
|
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.
| [in,out] | uc | Unicorn engine (stopped to end the chunk on a reset). |
| [in] | type | Unused memory-event type. |
| [in] | addr | Observed SCB address (dispatched by word). |
| [in] | size | Access width (unused). |
| [in] | value | Value written. |
| [in] | user | Unused hook context. |
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().
|
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().