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

Inner per-chunk exception-resolve loop (see emu_run_internal.h). More...

#include "emu_engine.h"
#include "emu_exc.h"
#include "emu_mpu.h"
#include "emu_prof.h"
#include "emu_run_internal.h"
#include "emu_seams.h"
#include "emu_view.h"
Include dependency graph for emu_run_inner.c:

Go to the source code of this file.

Enumerations

enum  inner_action_t : uint8_t {
  k_inner_continue = 0 ,
  k_inner_break = 1
}
 Loop-control verdict a priv_run_inner boundary helper hands back. More...

Functions

static RA8_INTERNAL size_t internal_run_inner_budget (uc_engine *uc, uint32_t run_pc)
 Compute one inner chunk's instruction budget for run_pc.
static RA8_INTERNAL bool internal_run_inner_check_stops (uc_engine *uc, bool *faulted, inner_action_t *act)
 Resolve the zero-time relaunch and run-ending stop conditions.
static RA8_INTERNAL inner_action_t internal_run_inner_take_exception (uc_engine *uc, uint32_t vtor_base, uint32_t *run_pc, uc_err err, bool *faulted)
 Take the pending exception (or end) at the chunk boundary.
bool priv_run_inner (uc_engine *uc, uint32_t vtor_base, uint32_t *run_pc_io, uc_err *err_out)
 Run one outer chunk's inner exception-resolve loop.

Detailed Description

Inner per-chunk exception-resolve loop (see emu_run_internal.h).

The inner exception-resolve loop that services one outer chunk: the idle / low-power budget, the zero-time relaunch + run-ending stop checks, and the exception boundary (EXC_RETURN unstack + tail-chain, MPU / div-0 fault synthesis, tick / PendSV take). Split out of emu_run.c so each TU stays under the file-size bar. The contract for priv_run_inner() lives on its declaration in emu_run_internal.h.

Since
0.1.0

Definition in file emu_run_inner.c.

Enumeration Type Documentation

◆ inner_action_t

enum inner_action_t : uint8_t

Loop-control verdict a priv_run_inner boundary helper hands back.

The inner exception-resolve loop either re-enters (a zero-time relaunch, tail-chain or fault-synthesis) or ends (fault / BKPT / stop / quiescent budget). The helpers return this so priv_run_inner stays a thin driver.

Invariant
Exactly one value is returned per helper call.
See also
internal_run_inner_check_stops() First consumer.
internal_run_inner_take_exception() Second consumer.
Since
0.1.0
Enumerator
k_inner_continue 

Re-enter the inner loop (relaunch / tail-chain).

k_inner_break 

End the inner loop (fault / BKPT / quiescent).

Definition at line 39 of file emu_run_inner.c.

Function Documentation

◆ internal_run_inner_budget()

RA8_INTERNAL size_t internal_run_inner_budget ( uc_engine * uc,
uint32_t run_pc )
static

Compute one inner chunk's instruction budget for run_pc.

Idle fast-forward: when the core is parked on a wait-for-interrupt spin (ThreadX's __tx_wait_here b ., a wfi halt, or a cpsie i poll), running a full k_run_chunk_insns just burns wall time to reach the SAME SysTick already armed once per outer chunk, so the budget collapses to k_idle_spin_insns – the tick still fires once per chunk, so the ThreadX tick COUNT (and every tick-measured deadline) is identical to a full idle chunk. Low-power (Model A) shrinks the busy budget by k_low_power_div (the 4:1 M85:M33 clock ratio); idle spins still collapse regardless.

Parameters
[in,out]ucUnicorn engine (read to classify the PC's opcode).
[in]run_pcThe resume PC to classify.
Returns
The instruction budget for the next uc_emu_start.
Return values
k_idle_spin_insnsThe PC sits on a wait-for-interrupt spin.
Precondition
The engine is set up and run_pc is a valid resume PC.
The seams / exception hooks are installed.
Postcondition
No engine state changes (the classification is a read-only probe).
The returned budget is one of the three modelled bounds.
Note
Not thread-safe; part of the single-threaded run core.
Since
0.1.0

Definition at line 67 of file emu_run_inner.c.

References emu_low_power(), idle_spin_at(), k_idle_spin_insns, k_low_power_div, k_run_chunk_insns, and RA8_INTERNAL.

Referenced by priv_run_inner().

◆ internal_run_inner_check_stops()

RA8_INTERNAL bool internal_run_inner_check_stops ( uc_engine * uc,
bool * faulted,
inner_action_t * act )
static

Resolve the zero-time relaunch and run-ending stop conditions.

Checked right after a chunk returns, before any exception is taken: a –fast-sd seam relaunch re-enters directly (no time charged); a profiler STOP_PC hit, an AIRCR.SYSRESETREQ reboot request, or a firmware BKPT each end the run (only the BKPT is a fault). When none apply the caller proceeds to the exception boundary.

Parameters
[in,out]ucUnicorn engine.
[out]faultedSet true iff a BKPT ended the run.
[out]actThe loop action when this helper handled the boundary.
Returns
true when act is authoritative, false to fall through.
Return values
trueOne of the relaunch / stop conditions applied.
falseNo condition applied; take the exception boundary next.
Precondition
faulted and act are non-NULL.
The chunk has returned and its final PC has been read back.
Postcondition
faulted is written only when true is returned via a BKPT.
On true, act is k_inner_continue or k_inner_break.
Note
Not thread-safe; part of the single-threaded run core.
Since
0.1.0

Definition at line 99 of file emu_run_inner.c.

References emu_exc_bkpt_hit(), emu_exc_reboot_requested(), emu_prof_stop_hit(), emu_seam_take_relaunch(), k_inner_break, and k_inner_continue.

Referenced by priv_run_inner().

◆ internal_run_inner_take_exception()

RA8_INTERNAL inner_action_t internal_run_inner_take_exception ( uc_engine * uc,
uint32_t vtor_base,
uint32_t * run_pc,
uc_err err,
bool * faulted )
static

Take the pending exception (or end) at the chunk boundary.

Runs only when internal_run_inner_check_stops fell through. An EXC_RETURN branch is unstacked and the NVIC re-checked so a still-pending lower-priority exception tail-chains (PendSV right after SysTick) as hardware would; an emulation error ends the run as a fault; MPU / div-0 faults are synthesised at the boundary; a PENDSVSET yield takes PendSV; otherwise the full budget elapsed and the highest-priority pend (SysTick and/or PendSV) is taken. None of the zero-time paths advance the SysTick; only a full budget does.

Parameters
[in,out]ucUnicorn engine.
[in]vtor_baseVTOR fallback for exception vectoring.
[in,out]run_pcResume PC in, post-boundary PC out.
[in]errThe chunk's final uc_emu_start status.
[out]faultedSet true iff err ended the run as a fault.
Returns
The loop action for priv_run_inner.
Return values
k_inner_continueA boundary was resolved; re-enter the loop.
k_inner_breakAn emulation fault or quiescence ended the run.
Precondition
run_pc and faulted are non-NULL.
The chunk returned and internal_run_inner_check_stops returned false.
Postcondition
run_pc reflects the post-boundary PC.
faulted is true only on a returned k_inner_break via err.
Note
Not thread-safe; part of the single-threaded run core.
Since
0.1.0

Definition at line 151 of file emu_run_inner.c.

References div0_synth_usagefault(), emu_div0_clear_fault(), emu_div0_fault_pending(), emu_exc_pendsv_stop(), emu_exc_take_exc_return(), emu_mpu_clear_fault(), emu_mpu_fault_pending(), emu_mve_nocp_take(), exc_return(), exc_take_pending(), k_inner_break, k_inner_continue, mpu_synth_memmanage(), and RA8_INTERNAL.

Referenced by priv_run_inner().

◆ priv_run_inner()

bool priv_run_inner ( uc_engine * uc,
uint32_t vtor_base,
uint32_t * run_pc_io,
uc_err * err_out )

Run one outer chunk's inner exception-resolve loop.

Runs a chunk, then services exceptions to a steady state before the next chunk (zero-time relaunches, EXC_RETURN unstack + tail-chain, MPU / div-0 fault synthesis, tick / PendSV take). Returns once the full budget elapsed with nothing pending, or on a fault / BKPT / stop request. Defined in emu_run_inner.c; called by the run loop in emu_run.c.

Parameters
[in,out]ucUnicorn engine.
[in]vtor_baseVTOR fallback for exception vectoring.
[in,out]run_pc_ioResume PC in, final PC out.
[out]err_outFinal uc_emu_start status for the report.
Returns
true when the run must end (fault or BKPT), false to continue.
Return values
trueThe outer loop breaks and reports the stop cause.
falseThe chunk resolved cleanly; the outer loop continues.
Precondition
The engine is set up and run_pc_io holds a valid resume PC.
The seams / exception hooks are installed.
Postcondition
run_pc_io and err_out reflect the loop's final state.
Note
Not thread-safe; this is the single-threaded run core.
Since
0.1.0
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 217 of file emu_run_inner.c.

References emu_exc_clear_pendsv_stop(), internal_run_inner_budget(), internal_run_inner_check_stops(), internal_run_inner_take_exception(), k_inner_break, k_inner_continue, and k_run_inner_max.

Referenced by internal_run_loop_run_chunk().