|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Hand-modelled Cortex-M exception engine (see emu_exc.h). More...
#include "emu_exc.h"#include <stdio.h>#include "board_periph.h"#include "emu_console.h"#include "emu_engine.h"#include "emu_host_io_internal.h"#include "emu_memmap.h"#include "emu_seams.h"Go to the source code of this file.
Enumerations | |
| enum | emu_exc_decode_t : uint32_t { k_op_branch_self = 0xE7FEU , k_op_wfi = 0xBF30U , k_op_cpsie_i = 0xB662U , k_op_bn_mask = 0xF800U , k_op_bn_base = 0xE000U , k_op_bn_imm = 0x07FFU , k_bn_imm_sext_shl = 21U , k_bn_imm_sext_shr = 20U , k_idle_scan_fwd = 8U , k_idle_loop_max = 32U , k_thumb_op5_shift = 11U , k_thumb_op5_mask = 0x1FU , k_thumb32_op5_min = 0x1DU } |
| Thumb decode + idle-spin scan constants for this exception engine. More... | |
Functions | |
| static RA8_INTERNAL uint32_t | internal_exc_active_prio (void) |
| Priority value (lower = higher) of the active handler, or sentinel. | |
| static RA8_INTERNAL uint32_t | internal_exc_priority (uc_engine *uc, uint32_t exc_num) |
| Read a system-handler priority byte from an SHPR register. | |
| static RA8_INTERNAL void | internal_exc_stack_frame (uc_engine *uc, uint32_t sp, bool fp_active, uint32_t frame_xpsr) |
Stack the basic {R0-R3,R12,LR,PC,xPSR} frame + optional FP frame at sp. | |
| static RA8_INTERNAL uint32_t | internal_exc_return_value (bool in_thread, bool use_psp, bool fp_active) |
| Select the EXC_RETURN magic for the outgoing mode/stack/FP state. | |
| void | exc_enter (uc_engine *uc, uint32_t exc_num, uint32_t handler) |
| Enter a Cortex-M exception: stack the basic frame and vector in. | |
| static RA8_INTERNAL void | internal_exc_restore_fp_frame (uc_engine *uc, uint32_t sp) |
Restore the Armv8-M FP extended frame (S0-S15 + FPSCR) from sp. | |
| static RA8_INTERNAL void | internal_exc_restore_mode (uc_engine *uc, uint32_t xpsr, bool to_thread, bool to_psp) |
| Restore CONTROL.SPSEL + xPSR/IPSR for the returned-to context. | |
| void | exc_return (uc_engine *uc, uint32_t exc_ret) |
| Perform a Cortex-M exception return for an observed EXC_RETURN branch. | |
| static RA8_INTERNAL bool | internal_is_exc_return (uint64_t pc) |
True if pc is an EXC_RETURN magic value. | |
| uint32_t | exc_vector (uc_engine *uc, uint32_t vtor_base, uint32_t exc_num) |
| Read the handler address for an exception from the vector table. | |
| static RA8_INTERNAL bool | internal_exc_take_periph_irq (uc_engine *uc, uint32_t vtor_base, uint32_t active) |
| Take one pending peripheral NVIC IRQ the ICU has queued, if allowed. | |
| bool | exc_take_pending (uc_engine *uc, uint32_t vtor_base, bool allow_systick) |
| Take the highest-priority pending exception, if one may activate now. | |
| static RA8_INTERNAL const char * | internal_unmapped_access_kind (uc_mem_type type) |
| Name the access kind that hit an unmapped address. | |
| static RA8_INTERNAL bool | internal_on_unmapped (uc_engine *uc, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user) |
| Hook fired on access to unmapped memory (peripheral surface gap). | |
| static RA8_INTERNAL bool | internal_on_intr_sec_insn (uc_engine *uc, uint32_t pc, uint32_t insn) |
| Model the Armv8-M Security-Extension opcodes Unicorn's M33 lacks. | |
| static RA8_INTERNAL bool | internal_on_intr_bkpt (uc_engine *uc, uint32_t pc, uint32_t insn) |
| Model a firmware BKPT as a halt (record the site and stop). | |
| static RA8_INTERNAL void | internal_on_intr (uc_engine *uc, uint32_t int_no, void *user_data) |
| UC_HOOK_INTR handler: take the SVCall exception on an svc opcode. | |
| static RA8_INTERNAL void | internal_on_icsr_write (uc_engine *uc, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user) |
| UC_HOOK_MEM_WRITE handler for SCB ICSR – take PendSV promptly. | |
| void | emu_exc_install_core (uc_engine *uc) |
| Implementation of emu_exc_install_core() – unmapped/INTR/ICSR hooks. | |
| void | emu_exc_arm_systick (void) |
| Implementation of emu_exc_arm_systick() – pend the periodic tick. | |
| bool | emu_exc_take_exc_return (uint64_t *out_pc) |
| Implementation of emu_exc_take_exc_return() – read + clear latch. | |
| void | emu_exc_clear_pendsv_stop (void) |
| Implementation of emu_exc_clear_pendsv_stop() – per-launch clear. | |
| bool | emu_exc_pendsv_stop (void) |
| Implementation of emu_exc_pendsv_stop() – plain flag read. | |
| bool | emu_exc_bkpt_hit (void) |
| Implementation of emu_exc_bkpt_hit() – plain flag read. | |
| uint32_t | emu_exc_bkpt_pc (void) |
| Implementation of emu_exc_bkpt_pc() – plain state read. | |
| uint32_t | emu_exc_systick_fires (void) |
| Implementation of emu_exc_systick_fires() – plain counter read. | |
| uint32_t | emu_exc_pendsv_takes (void) |
| Implementation of emu_exc_pendsv_takes() – plain counter read. | |
| uint32_t | emu_exc_svc_takes (void) |
| Implementation of emu_exc_svc_takes() – plain counter read. | |
| void | emu_exc_reset (void) |
| Implementation of emu_exc_reset() – warm-reboot exception state. | |
Variables | |
| static uint32_t | s_systick_fires |
| static uint32_t | s_exc_stack [k_exc_nest_max] |
| Active-handler priorities. | |
| static uint32_t | s_exc_depth |
| Number of active handlers. | |
| static uint32_t | s_pendsv_takes |
| PendSV exceptions taken. | |
| static uint32_t | s_svc_takes |
| SVCall exceptions taken. | |
| static uint64_t | s_exc_return_pc |
| Pending EXC_RETURN to unstack. | |
| static bool | s_exc_return_hit |
| An EXC_RETURN branch was seen. | |
| static bool | s_systick_pending |
| SysTick exception is pended. | |
| static bool | s_pendsv_stop |
| Chunk ended on a PENDSVSET. | |
| static bool | s_bkpt_hit |
| Firmware executed a BKPT. | |
| static uint32_t | s_bkpt_pc |
| PC of the BKPT that halted. | |
Hand-modelled Cortex-M exception engine (see emu_exc.h).
Unicorn's Cortex-M33 core carries no NVIC / exception unit, so ra8_emulator takes exceptions by hand: the active-priority stack, the basic + FP frame stacking/unstacking of exception entry/return, SysTick/PendSV/SVCall and peripheral-IRQ activation with hardware priority rules, the EXC_RETURN recognition, the SVC/BKPT/security-instruction INTR dispatch, the ICSR PendSV promptness hook, the SCB control-word watcher (SYSRESETREQ warm reboot + CCR.DIV_0_TRP arming), the NVIC ISER/ICER W1S/W1C folding, the idle-spin detector and the DWT cycle-counter model. Moved verbatim out of the ra8_emulator main translation unit.
Definition in file emu_exc.c.
| enum emu_exc_decode_t : uint32_t |
Thumb decode + idle-spin scan constants for this exception engine.
| void emu_exc_arm_systick | ( | void | ) |
Implementation of emu_exc_arm_systick() – pend the periodic tick.
Pend the periodic SysTick for this outer chunk.
Definition at line 926 of file emu_exc.c.
References s_systick_pending.
Referenced by internal_run_loop_tick_inputs().
| bool emu_exc_bkpt_hit | ( | void | ) |
Implementation of emu_exc_bkpt_hit() – plain flag read.
Whether the firmware executed a BKPT (deliberate trap / give-up).
Definition at line 955 of file emu_exc.c.
References s_bkpt_hit.
Referenced by internal_run_inner_check_stops(), internal_run_print_stop_summary(), internal_run_print_verdict(), and priv_run_cleanup().
| uint32_t emu_exc_bkpt_pc | ( | void | ) |
Implementation of emu_exc_bkpt_pc() – plain state read.
PC of the BKPT that halted the run.
Definition at line 961 of file emu_exc.c.
References s_bkpt_pc.
Referenced by internal_run_print_stop_summary().
| void emu_exc_clear_pendsv_stop | ( | void | ) |
Implementation of emu_exc_clear_pendsv_stop() – per-launch clear.
Clear the PendSV context-switch stop marker (per relaunch).
Definition at line 943 of file emu_exc.c.
References s_pendsv_stop.
Referenced by priv_run_inner().
| void emu_exc_install_core | ( | uc_engine * | uc | ) |
Implementation of emu_exc_install_core() – unmapped/INTR/ICSR hooks.
Arm the core exception hooks (unmapped / INTR / ICSR watch).
Definition at line 898 of file emu_exc.c.
References internal_on_icsr_write(), internal_on_intr(), internal_on_unmapped(), and k_scb_icsr.
Referenced by internal_main_install_core_seams().
| bool emu_exc_pendsv_stop | ( | void | ) |
Implementation of emu_exc_pendsv_stop() – plain flag read.
Whether the last engine stop was a PENDSVSET context-switch stop.
Definition at line 949 of file emu_exc.c.
References s_pendsv_stop.
Referenced by internal_run_inner_take_exception().
| uint32_t emu_exc_pendsv_takes | ( | void | ) |
Implementation of emu_exc_pendsv_takes() – plain counter read.
PendSV exceptions taken this run (report + idle signature).
Definition at line 973 of file emu_exc.c.
References s_pendsv_takes.
Referenced by internal_run_print_stop_summary(), and internal_run_stop_idle().
| void emu_exc_reset | ( | void | ) |
Implementation of emu_exc_reset() – warm-reboot exception state.
Reset the exception bookkeeping for a warm reboot.
Definition at line 985 of file emu_exc.c.
References s_bkpt_hit, s_exc_depth, s_exc_return_hit, s_pendsv_stop, s_pendsv_takes, s_svc_takes, s_systick_fires, and s_systick_pending.
Referenced by warm_reboot().
| uint32_t emu_exc_svc_takes | ( | void | ) |
Implementation of emu_exc_svc_takes() – plain counter read.
SVCall exceptions taken this run (report + idle signature).
Definition at line 979 of file emu_exc.c.
References s_svc_takes.
Referenced by internal_run_print_stop_summary(), and internal_run_stop_idle().
| uint32_t emu_exc_systick_fires | ( | void | ) |
Implementation of emu_exc_systick_fires() – plain counter read.
SysTick exceptions taken this run (report telemetry).
Definition at line 967 of file emu_exc.c.
References s_systick_fires.
Referenced by internal_run_print_stop_summary().
| bool emu_exc_take_exc_return | ( | uint64_t * | out_pc | ) |
Implementation of emu_exc_take_exc_return() – read + clear latch.
Consume a latched EXC_RETURN branch (read + clear).
Definition at line 932 of file emu_exc.c.
References s_exc_return_hit, and s_exc_return_pc.
Referenced by internal_run_inner_take_exception().
| void exc_enter | ( | uc_engine * | uc, |
| uint32_t | exc_num, | ||
| uint32_t | handler ) |
Enter a Cortex-M exception: stack the basic frame and vector in.
Reproduces Armv7E-M / Armv8-M exception entry that Unicorn's core does not model. The active stack is chosen exactly as hardware would: PSP when in Thread mode with CONTROL.SPSEL set, else MSP. The 8-word basic frame {R0,R1,R2,R3,R12,LR,PC,xPSR} is pushed with 8-byte alignment (the realign pad is recorded in the stacked xPSR bit 9 so exit can undo it), the banked SP is updated, the core is switched to Handler mode on MSP, LR is loaded with the matching EXC_RETURN, IPSR is set to exc_num, and PC is vectored to the handler fetched from the VTOR-relative table. The handler's priority is pushed on the active-exception stack so nesting respects priority.
| [in,out] | uc | Unicorn engine. |
| [in] | exc_num | Exception number to take (11, 14, or 15). |
| [in] | handler | Handler entry address (Thumb bit ignored). |
uc has MSP/PSP/CONTROL/xPSR readable and the target stack mapped. exc_num is permitted now (priority/PRIMASK already checked). exc_num) running on MSP. Definition at line 210 of file emu_exc.c.
References internal_exc_priority(), internal_exc_return_value(), internal_exc_stack_frame(), k_control_fpca, k_control_spsel, k_exc_frame_bytes, k_exc_nest_max, k_fp_frame_extra, k_xpsr_align9, k_xpsr_ipsr_mask, k_xpsr_t_bit, reg_get(), reg_set(), s_exc_depth, and s_exc_stack.
Referenced by div0_synth_usagefault(), exc_take_pending(), internal_exc_take_periph_irq(), internal_on_intr(), and mpu_synth_memmanage().
| void exc_return | ( | uc_engine * | uc, |
| uint32_t | exc_ret ) |
Perform a Cortex-M exception return for an observed EXC_RETURN branch.
The inverse of exc_enter. exc_ret (the magic value the core branched to) selects the stack to unstack from (bit2: PSP vs MSP) and the mode to return to (bit3: Thread vs Handler). The 8-word basic frame is popped (plus the S0-S15 + FPSCR words when FType, bit4, is clear), the recorded 8-byte realignment (stacked xPSR bit 9) is undone, the banked SP and CONTROL.SPSEL are restored, xPSR (hence IPSR) is reloaded, the active-exception stack is popped, and PC resumes the interrupted instruction stream.
| [in,out] | uc | Unicorn engine. |
| [in] | exc_ret | The EXC_RETURN value (prefix bits[31:7] set) returned to. |
uc is in Handler mode with a valid basic frame on the indicated stack. exc_ret has the EXC_RETURN prefix (bits[31:7] all set). Definition at line 335 of file emu_exc.c.
References internal_exc_restore_fp_frame(), internal_exc_restore_mode(), k_exc_frame_bytes, k_exc_ret_ftype, k_exc_ret_mode, k_exc_ret_spsel, k_fp_frame_extra, k_frame_off_lr, k_frame_off_pc, k_frame_off_r3, k_frame_off_xpsr, k_xpsr_align9, rd32(), reg_get(), reg_set(), and s_exc_depth.
Referenced by internal_run_inner_take_exception().
| bool exc_take_pending | ( | uc_engine * | uc, |
| uint32_t | vtor_base, | ||
| bool | allow_systick ) |
Take the highest-priority pending exception, if one may activate now.
The software replacement for the NVIC's "take the highest-priority pending, enabled exception whose priority is greater than the current execution priority" rule – called at every instruction boundary AND immediately after each exception return (so a lower-priority pend tail-chains exactly as hardware would instead of returning to the interrupted code first). Two sources are modelled:
SysTick (priority 0x40) outranks PendSV (0xFF), so when both are pending SysTick activates first and may even pre-empt a PendSV that is spinning in its idle wait – exactly the nesting ThreadX relies on to make a sleeping thread runnable. PRIMASK and the active-priority stack are both honoured.
| [in,out] | uc | Unicorn engine. |
| [in] | vtor_base | Fallback vector base if VTOR reads as 0. |
| [in] | allow_systick | When false, the armed SysTick is left pending (not taken) so modelled time does NOT advance. The run loop passes false on a context-switch stop (a PENDSVSET write consumes no time), so a thread that just suspended on a tick-based wait is not woken before lower-priority ready threads run. Passes true on a full-budget boundary, where genuine execution (or an idle spin) has elapsed a tick's worth of time. |
uc has stopped at an instruction boundary or just returned. Definition at line 530 of file emu_exc.c.
References exc_enter(), exc_vector(), internal_exc_active_prio(), internal_exc_priority(), internal_exc_take_periph_irq(), k_exc_pendsv, k_exc_systick, k_icsr_pendsvset, k_scb_icsr, k_syst_csr, k_syst_csr_run, rd32(), reg_get(), s_pendsv_takes, s_systick_fires, s_systick_pending, and wr32().
Referenced by internal_run_inner_take_exception().
| uint32_t exc_vector | ( | uc_engine * | uc, |
| uint32_t | vtor_base, | ||
| uint32_t | exc_num ) |
Read the handler address for an exception from the vector table.
| [in,out] | uc | Unicorn engine. |
| [in] | vtor_base | Fallback vector base used when VTOR reads as 0. |
| [in] | exc_num | Exception/vector index to look up. |
| 0 | when no usable handler is installed at that vector slot. |
uc has the vector table mapped at VTOR (or vtor_base). exc_num is a valid vector index (< table length). Definition at line 417 of file emu_exc.c.
References k_scb_vtor, k_vector_erased, and rd32().
Referenced by div0_synth_usagefault(), exc_take_pending(), internal_exc_take_periph_irq(), internal_on_intr(), and mpu_synth_memmanage().
|
static |
Priority value (lower = higher) of the active handler, or sentinel.
Priority value (lower = higher) of the active handler, or sentinel; this step is contained within the emu exc model and uses bounded caller or module-owned storage.
| value | The operation-specific exc active prio value. |
Definition at line 76 of file emu_exc.c.
References k_exc_prio_none, RA8_INTERNAL, s_exc_depth, and s_exc_stack.
Referenced by exc_take_pending(), and internal_on_icsr_write().
|
static |
Read a system-handler priority byte from an SHPR register.
Cortex-M packs four 8-bit handler priorities per SHPRn word. SVCall (#11) is byte 3 of SHPR2; PendSV (#14) is byte 2 and SysTick (#15) byte 3 of SHPR3. ThreadX's tx_initialize_low_level programs these (SysTick 0x40, PendSV/SVC 0xFF), and the value drives whether one exception may pre-empt another. The PPB is plain RAM here, so the firmware's stores are simply read back.
| [in,out] | uc | Unicorn engine. |
| [in] | exc_num | Exception/vector number (11, 14, or 15). |
| 0xFF | when exc_num is not one of the modelled system handlers. |
uc is an initialised engine with the PPB mapped as RAM. Definition at line 104 of file emu_exc.c.
References k_byte_bits, k_byte_mask, k_exc_pendsv, k_exc_prio_max, k_exc_svcall, k_exc_systick, k_scb_shpr2, k_scb_shpr3, RA8_INTERNAL, and rd32().
Referenced by exc_enter(), exc_take_pending(), and internal_on_icsr_write().
|
static |
Restore the Armv8-M FP extended frame (S0-S15 + FPSCR) from sp.
Restore the armv8-m fp extended frame (s0-s15 + fpscr) from sp; this step is contained within the emu exc model and uses bounded caller or module-owned storage.
| [in,out] | uc | Unicorn engine whose emulated state is read or updated. |
| [in] | sp | Sp input used by the operation. |
Definition at line 267 of file emu_exc.c.
References k_fp_s_words, k_frame_off_fpscr, k_frame_off_s0, k_word_bytes, RA8_INTERNAL, rd32(), and reg_set().
Referenced by exc_return().
|
static |
Restore CONTROL.SPSEL + xPSR/IPSR for the returned-to context.
Restore control.spsel + xpsr/ipsr for the returned-to context; this step is contained within the emu exc model and uses bounded caller or module-owned storage.
| [in,out] | uc | Unicorn engine whose emulated state is read or updated. |
| [in] | xpsr | Xpsr input used by the operation. |
| [in] | to_thread | To thread input used by the operation. |
| [in] | to_psp | To psp input used by the operation. |
Definition at line 292 of file emu_exc.c.
References k_control_spsel, k_xpsr_ipsr_mask, k_xpsr_t_bit, reg_get(), and reg_set().
Referenced by exc_return().
|
static |
Select the EXC_RETURN magic for the outgoing mode/stack/FP state.
Select the exc_return magic for the outgoing mode/stack/fp state; this step is contained within the emu exc model and uses bounded caller or module-owned storage.
| [in] | in_thread | In thread input used by the operation. |
| [in] | use_psp | Use psp input used by the operation. |
| [in] | fp_active | Fp active input used by the operation. |
| value | The operation-specific exc return value value. |
Definition at line 165 of file emu_exc.c.
References k_exc_ret_ftype, k_exc_ret_handler, k_exc_ret_msp, k_exc_ret_psp, and RA8_INTERNAL.
Referenced by exc_enter().
|
static |
Stack the basic {R0-R3,R12,LR,PC,xPSR} frame + optional FP frame at sp.
Stack the basic {r0-r3,r12,lr,pc,xpsr} frame + optional fp frame at sp; this step is contained within the emu exc model and uses bounded caller or module-owned storage.
| [in,out] | uc | Unicorn engine whose emulated state is read or updated. |
| [in] | sp | Sp input used by the operation. |
| [in] | fp_active | Fp active input used by the operation. |
| [in] | frame_xpsr | Frame xpsr input used by the operation. |
Definition at line 132 of file emu_exc.c.
References k_fp_s_words, k_frame_off_fpscr, k_frame_off_lr, k_frame_off_pc, k_frame_off_r3, k_frame_off_s0, k_frame_off_xpsr, k_word_bytes, reg_get(), and wr32().
Referenced by exc_enter().
|
static |
Take one pending peripheral NVIC IRQ the ICU has queued, if allowed.
The peripheral counterpart to the SysTick / PendSV logic in exc_take_pending. board_periph's ICU model queues an IRQ whenever a peripheral event is event-linked through IELSR and its NVIC line is enabled; this pops one and – if its NVIC priority (IPR byte, top nibble used) outranks the active execution priority – vectors it in as a real Cortex-M exception (vector 16 + IRQn read from VTOR), exactly the path a hardware IRQ takes. The ISR therefore runs in genuine handler context and returns via the same EXC_RETURN unstack as every other exception. The matching ISPR pending bit is cleared on activation, as hardware does.
| [in,out] | uc | Unicorn engine. |
| [in] | vtor_base | Fallback vector base when VTOR reads as 0. |
| [in] | active | Current active-handler priority (sentinel if none). |
uc has stopped at an instruction boundary; PRIMASK already checked. | true | The exc take periph interrupt condition holds or completed successfully; false otherwise. |
Definition at line 457 of file emu_exc.c.
References board_periph_next_irq(), board_periph_note_irq_taken(), exc_enter(), exc_vector(), k_exc_irq_vec0, k_lo4_mask, k_nvic_ipr_base, k_nvic_ispr_base, k_nvic_prio_shift, rd32(), and wr32().
Referenced by exc_take_pending().
|
static |
True if pc is an EXC_RETURN magic value.
Matches the Armv8-M EXC_RETURN prefix – bits[31:7] all set (0xFFFFFF80..0xFFFFFFFF). This covers both the Armv7-M values ra8_emulator itself generates (0xFFFFFFF1/F9/FD) and the Armv8-M Non-Secure thread returns ThreadX uses (0xFFFFFFBC basic, 0xFFFFFFAC with an FP frame), where bit6 (S) is clear. Nothing in this firmware's map executes at 0xFFFFFFxx, so a fetch into that range is always an exception return, never a real branch.
| [in] | pc | Guest program-counter value associated with the operation. |
| true | The is exc return condition holds or completed successfully; false otherwise. |
Definition at line 398 of file emu_exc.c.
References k_exc_ret_v8_mask, and RA8_INTERNAL.
Referenced by internal_on_intr(), and internal_on_unmapped().
|
static |
UC_HOOK_MEM_WRITE handler for SCB ICSR – take PendSV promptly.
On hardware, writing ICSR.PENDSVSET pends PendSV, and – because ThreadX follows the store with DSB+ISB and PendSV is enabled at a priority above thread level with interrupts unmasked – the exception activates at the very next instruction. ra8_emulator runs the CPU in long chunks, so without help it would only notice PENDSVSET at the end of a 500k-instruction chunk; by then the requesting thread (e.g. a thread suspending inside tx_queue_receive) has run far past the point where it expected to be switched out and observes inconsistent scheduler state. Stopping the chunk the instant PENDSVSET is written hands control straight back to the run loop, which takes PendSV at that boundary – restoring next-instruction activation semantics. The store itself has already landed in PPB RAM, so exc_take_pending sees the bit set.
| [in,out] | uc | Unicorn engine. |
| [in] | type | Memory access type (write); unused. |
| [in] | addr | Faulting/observed address (the ICSR word). |
| [in] | size | Access width in bytes; unused. |
| [in] | value | The value being written to ICSR. |
| [in] | user | Hook user pointer; unused. |
uc is mid-chunk executing the store to ICSR. Definition at line 843 of file emu_exc.c.
References emu_mem_read(), internal_exc_active_prio(), internal_exc_priority(), k_exc_pendsv, k_icsr_pendsvset, k_thumb32_op5_min, k_thumb_op5_mask, k_thumb_op5_shift, RA8_INTERNAL, and s_pendsv_stop.
Referenced by emu_exc_install_core().
|
static |
UC_HOOK_INTR handler: take the SVCall exception on an svc opcode.
Unicorn raises UC_HOOK_INTR when the firmware executes the Thumb svc instruction but, lacking an exception unit, does not vector it. This models SVCall (#11): the basic frame is stacked and the core vectors to SVC_Handler via exc_enter, then emulation is stopped so the chunked run loop relaunches cleanly from the handler entry (editing PC mid-block and continuing corrupts Unicorn's block/Thumb state – the same stop-then-relaunch contract the touch and conditional-select stubs use). ThreadX in single-mode never issues an SVC, but bare-metal / future RTOS paths that start the first thread via svc are handled correctly here. PRIMASK does not mask SVCall (it is synchronous), matching hardware.
| [in,out] | uc | Unicorn engine. |
| [in] | int_no | Interrupt/exception number reported by Unicorn. |
| [in] | user_data | Hook user pointer (unused; signature fixed by Unicorn). |
uc has just executed an svc instruction or branched to EXC_RETURN. Definition at line 752 of file emu_exc.c.
References emu_mem_read(), emu_memmap_mram_base(), emu_mve_nocp_emulate(), exc_enter(), exc_vector(), internal_is_exc_return(), internal_on_intr_bkpt(), internal_on_intr_sec_insn(), k_exc_svcall, RA8_INTERNAL, s_exc_return_hit, s_exc_return_pc, and s_svc_takes.
Referenced by emu_exc_install_core().
|
static |
Model a firmware BKPT as a halt (record the site and stop).
A BKPT (0xBExx) is a deliberate firmware trap – Default_Handler's bkpt #0, a failed assert, or a fault give-up. It is NOT an svc: taking SVCall here would stack a frame, vector to the (often Default_Handler) SVC slot, return to the same bkpt, and re-trap forever – the stack grows until it underflows (the historical tz_nsc_cgc_usb storm). Model it as a halt: record the site and stop so the run loop ends and the report shows where the firmware trapped.
| [in,out] | uc | Unicorn engine. |
| [in] | pc | PC of the trapping instruction. |
| [in] | insn | The 32-bit opcode word read at pc. |
insn was a BKPT and the core was halted. | true | The on intr bkpt condition holds or completed successfully; false otherwise. |
Definition at line 711 of file emu_exc.c.
References k_bkpt_hw_base, k_bkpt_hw_mask, k_lo16_mask, RA8_INTERNAL, s_bkpt_hit, and s_bkpt_pc.
Referenced by internal_on_intr().
|
static |
Model the Armv8-M Security-Extension opcodes Unicorn's M33 lacks.
ra8_emulator is a single flat (no Secure/Non-Secure split) address space, so these reduce to their plain effects here:
| [in,out] | uc | Unicorn engine. |
| [in] | pc | PC of the trapping instruction. |
| [in] | insn | The 32-bit opcode word read at pc. |
insn was an SG / FPCXTNS opcode and was handled. | true | The on intr sec insn condition holds or completed successfully; false otherwise. |
Definition at line 664 of file emu_exc.c.
References emu_mem_write(), k_armv8m_sg_opcode, k_fpcxtns_pop, k_fpcxtns_push, k_thumb2_insn_bytes, k_word_bytes, and RA8_INTERNAL.
Referenced by internal_on_intr().
|
static |
Hook fired on access to unmapped memory (peripheral surface gap).
Hook fired on access to unmapped memory (peripheral surface gap); this step is contained within the emu exc model and uses bounded caller or module-owned storage.
| [in,out] | uc | Unicorn engine whose emulated state is read or updated. |
| [in] | type | Type input used by the operation. |
| [in] | addr | Guest address involved in the operation. |
| [in] | size | Size of the requested region or access in bytes. |
| [in] | value | Register or payload value involved in the operation. |
| [in,out] | user | Hook context supplied when the callback was registered. |
| true | The on unmapped condition holds or completed successfully; false otherwise. |
Definition at line 613 of file emu_exc.c.
References internal_is_exc_return(), internal_unmapped_access_kind(), priv_emu_io_errf(), RA8_INTERNAL, s_exc_return_hit, and s_exc_return_pc.
Referenced by emu_exc_install_core().
|
static |
Name the access kind that hit an unmapped address.
| [in] | type | Unicorn memory-access type reported by the hook. |
type is one of the UC_MEM_*_UNMAPPED values. Definition at line 589 of file emu_exc.c.
References RA8_INTERNAL.
Referenced by internal_on_unmapped().
|
static |
Firmware executed a BKPT.
Definition at line 66 of file emu_exc.c.
Referenced by emu_exc_bkpt_hit(), emu_exc_reset(), and internal_on_intr_bkpt().
|
static |
PC of the BKPT that halted.
Definition at line 67 of file emu_exc.c.
Referenced by emu_exc_bkpt_pc(), and internal_on_intr_bkpt().
|
static |
Number of active handlers.
Definition at line 59 of file emu_exc.c.
Referenced by emu_exc_reset(), exc_enter(), exc_return(), and internal_exc_active_prio().
|
static |
An EXC_RETURN branch was seen.
Definition at line 63 of file emu_exc.c.
Referenced by emu_exc_reset(), emu_exc_take_exc_return(), internal_on_intr(), and internal_on_unmapped().
|
static |
Pending EXC_RETURN to unstack.
Definition at line 62 of file emu_exc.c.
Referenced by emu_exc_take_exc_return(), internal_on_intr(), and internal_on_unmapped().
|
static |
Active-handler priorities.
Definition at line 58 of file emu_exc.c.
Referenced by exc_enter(), and internal_exc_active_prio().
|
static |
Chunk ended on a PENDSVSET.
Definition at line 65 of file emu_exc.c.
Referenced by emu_exc_clear_pendsv_stop(), emu_exc_pendsv_stop(), emu_exc_reset(), and internal_on_icsr_write().
|
static |
PendSV exceptions taken.
Definition at line 60 of file emu_exc.c.
Referenced by emu_exc_pendsv_takes(), emu_exc_reset(), and exc_take_pending().
|
static |
SVCall exceptions taken.
Definition at line 61 of file emu_exc.c.
Referenced by emu_exc_reset(), emu_exc_svc_takes(), and internal_on_intr().
|
static |
Definition at line 49 of file emu_exc.c.
Referenced by emu_exc_reset(), emu_exc_systick_fires(), and exc_take_pending().
|
static |
SysTick exception is pended.
Definition at line 64 of file emu_exc.c.
Referenced by emu_exc_arm_systick(), emu_exc_reset(), and exc_take_pending().