48typedef enum : uint64_t {
56typedef enum : uint32_t {
64typedef enum : uint64_t {
71typedef enum : uint32_t {
77typedef enum : uint32_t {
115 if (block ==
nullptr) {
121 (void)
priv_emu_io_errf(
"board_periph: block registry FULL (k_block_max=%u) -- "
122 "DROPPING '%s'; raise k_block_max\n",
124 (block->
name !=
nullptr) ? block->
name :
"?");
175 return (addr >= base) && (addr < (base + span));
288typedef enum : uint32_t {
332 const uint32_t word = irq / 32U;
351 const uint64_t word = (uint64_t)
k_nvic_ispr_base + ((uint64_t)(irq / 32U) * 4U);
353 ispr |= (1U << (irq % 32U));
359 const uint32_t word = irq / 32U;
363 const uint32_t bit = 1U << (irq % 32U);
406 (void)
priv_emu_io_errf(
" [trace] ICU event 0x%03X -> NVIC IRQ %u pended\n", event, slot);
440 if ((addr < lo) || (addr >= hi)) {
443 return (uint32_t)((addr - lo) / 4U);
492 const uint32_t ir_keep = ((value & (uint32_t)
k_ielsr_ir_mask) != 0U) ? ir_now : 0U;
541 if (b->reset !=
nullptr) {
576 if ((block !=
nullptr) && !block->
observe) {
585 return block->
read(uc, addr, size);
591 bool usb_hit =
false;
592 const uint64_t usb_val =
board_usb_read(uc, addr, size, &usb_hit);
598 bool usbh_hit =
false;
615 if (block !=
nullptr) {
623 block->
write(uc, addr, size, value);
631 bool usb_hit =
false;
638 bool usbh_hit =
false;
655 if (b->tick !=
nullptr) {
681 (void)
priv_emu_io_errf(
" [trace] NVIC IRQ %u taken (real exception via VTOR)\n", irq);
715 (void)
priv_emu_io_errf(
" NVIC IRQs : 0 taken (no event-linked, enabled line fired)\n");
732 bool irq_done =
false;
740 if (b->report !=
nullptr) {
nvic_addr_t
Cortex-M NVIC register bases (PPB, read straight from memory).
@ k_nvic_word_bits
Lines per ISER/ISPR word.
void board_periph_tick(uc_engine *uc)
Advance every modelled timer by one emulation chunk and raise events.
void board_periph_icu_raise_event(uc_engine *uc, uint16_t event)
Raise a peripheral ELC event through the core's ICU -> NVIC path.
static const board_periph_block_t * s_blocks[k_block_max]
Registered blocks.
void board_periph_init(bool trace)
One-time reset of all peripheral-model state.
static uint32_t s_nvic_iser_shadow[k_nvic_enable_words]
static bool internal_nvic_enabled(uc_engine *uc, uint32_t irq)
True iff NVIC line irq is enabled in the set-enable shadow.
void board_periph_register_block(const board_periph_block_t *block)
Register a peripheral block's descriptor with the core registry.
static void internal_board_periph_build_order(void)
Build s_block_order: registry indices sorted by descriptor order.
static void internal_usb_irq_raiser(uc_engine *uc, uint16_t event)
ICU event-raise hook handed to the USB model (see board_usb.h).
board_device_t board_periph_device(void)
Report which RA8 device the peripheral model is emulating.
static uint64_t internal_icu_read(uint64_t addr)
Dispatch an ICU IELSR read from the model's own event-link state.
core_tune_t
Registry capacity + the core's own report slot ordering.
@ k_block_max
Max registered peripheral blocks.
@ k_core_irq_report_order
Where the IRQ report sits among blocks.
void board_periph_nvic_set_enable(uint32_t irq, bool enable)
Set or clear a NVIC line's enable in the model's set-enable shadow.
static board_device_t s_device
static uint32_t s_irq_ring[k_irq_queue_len]
static uint32_t s_ielsr[k_icu_ielsr_cnt]
static uint32_t s_irq_taken[k_irq_track_max]
Times each IRQ was taken.
static void internal_report_irqs(void)
Print the per-IRQ taken totals (or a "none fired" note).
static uint32_t s_irq_tail
void board_periph_note_irq_taken(uint32_t irq)
Record that NVIC IRQ irq was actually taken (for the summary).
static uint32_t internal_periph_rd32(uc_engine *uc, uint64_t addr)
Read a 32-bit little-endian word from emulated memory.
uint32_t board_periph_icu_dtc_slot(uint16_t event)
Find the IELSR slot that activates the DTC for an ELC event.
static void internal_irq_ring_push(uint32_t irq)
Push an IRQ onto the pending ring (drop silently if full).
static bool internal_in_range(uint64_t addr, uint64_t base, uint64_t span)
True iff addr is inside [base, base + span).
static const board_periph_block_t * internal_block_for_addr(uint64_t addr)
Find the registered block owning addr on the active device, or NULL.
irq_tune_t
Pending-IRQ ring + per-IRQ tracking sizing.
@ k_irq_track_max
Distinct IRQ numbers tracked.
@ k_irq_queue_len
Pending-IRQ ring capacity.
void board_periph_set_usbhs_loop(bool on)
Enable the chip-internal USBHS-host self-loop model (–usbhs-loop).
ielsr_field_t
ICU IELSR layout – ra8_ielsr_bit_t / ra8_ielsr_mask_t.
@ k_ielsr_dtce_mask
DTCE: DTC activation enable [24].
@ k_ielsr_iels_mask
IELS event-select field [9:0].
@ k_ielsr_ir_bit
IR interrupt status flag (W0C).
@ k_ielsr_ir_mask
IR bit mask.
void board_periph_write(uc_engine *uc, uint64_t addr, unsigned size, uint64_t value, bool *handled)
Dispatch an MMIO write to the owning block, if any.
static const board_periph_block_t * s_last_block
Last block returned by internal_block_for_addr (one-entry dispatch cache).
bool board_periph_usbhs_loop(void)
Report whether the USBHS-host self-loop model is enabled.
static void internal_nvic_set_pending(uc_engine *uc, uint32_t irq)
Mirror the pended line into NVIC ISPR so firmware can observe it.
static uint8_t s_block_order[k_block_max]
Tick/report order.
static uint32_t s_irq_total
Total IRQs delivered.
uint32_t board_periph_irq_total(void)
Total NVIC interrupts the ICU has delivered in this run.
uint64_t board_periph_read(uc_engine *uc, uint64_t addr, unsigned size, bool *handled)
Dispatch an MMIO read to the owning block, if any.
static uint32_t s_block_count
Live entries.
bool board_periph_trace(void)
Whether –trace is active (blocks log transitions when true).
icu_map_t
ICU block geometry (ra8_icu_regs.h).
@ k_icu_off_ielsr
IELSR[0..95], 32-bit each.
@ k_icu_ielsr_cnt
IELSR slot count on RA8D2.
void board_periph_report(uc_engine *uc)
Print the peripheral-model section of the end-of-run summary.
static uint32_t internal_icu_ielsr_slot(uint64_t addr)
Index of the IELSR slot owning addr, or k_icu_ielsr_cnt if none.
static bool internal_block_on_active_device(const board_periph_block_t *b)
Whether block b is exposed on the active emulation device + run.
static uint32_t s_irq_head
void board_periph_set_device(board_device_t device)
Select which RA8 device the peripheral model emulates.
static void internal_icu_write(uint64_t addr, uint32_t value)
Dispatch an ICU IELSR write; IR is W0C, the IELS/DTCE bits are RW.
bool board_periph_next_irq(uint32_t *out_irq)
Pop the next pending, enabled NVIC IRQ number the ICU has queued.
@ k_nvic_enable_words
256 NVIC lines tracked (8 * 32).
uint32_t board_periph_irq_count(uint32_t irq)
Number of times a given NVIC line was taken in this run.
static bool s_order_built
s_block_order valid.
Register-accurate peripheral-model framework for the board emulator.
board_device_t
The RA8 device the emulator models for this run.
@ k_board_device_ra8p1
Renesas RA8P1: adds the Ethos-U55 NPU.
@ k_board_device_ra8d2
Renesas RA8D2 (default): no NPU.
Decentralized peripheral-block registry for the board emulator core.
@ k_board_block_dev_ra8p1
RA8P1-only (Ethos-U55 NPU).
Module-private module-stop (MSTP) gate state shared with the core.
void priv_board_mstp_note_gated_access(uint64_t addr, bool is_write)
Record that an MMIO access to a module-stopped peripheral was dropped.
bool priv_board_mstp_addr_stopped(uint64_t addr)
Report whether the peripheral instance owning addr is module-stopped.
USBFS controller model + a virtual USB host for the board emulator.
void board_usb_write(uc_engine *uc, uint64_t addr, unsigned size, uint64_t value, bool *handled)
Dispatch an MMIO write inside the USBFS register window.
void board_usb_report(void)
Print the USB section of the end-of-run summary.
void board_usb_tick(uc_engine *uc)
Advance the virtual USB host one emulation chunk.
void board_usb_init(bool trace)
Reset the USBFS controller model and the virtual host state machine.
void board_usb_set_irq_raiser(board_usb_irq_raiser_t raise)
Install the ICU event-raise hook used to pend the USBFS interrupt.
uint64_t board_usb_read(uc_engine *uc, uint64_t addr, unsigned size, bool *handled)
Dispatch an MMIO read inside the USBFS register window.
USBHS HOST-mode controller model (self-loop peer of the USBFS device).
void board_usb_host_report(void)
Print the USBHS host-model section of the end-of-run summary.
void board_usb_host_write(uc_engine *uc, uint64_t addr, unsigned size, uint64_t value, bool *handled)
Dispatch an MMIO write inside the USBHS register window.
uint64_t board_usb_host_read(uc_engine *uc, uint64_t addr, unsigned size, bool *handled)
Dispatch an MMIO read inside the USBHS register window.
void board_usb_host_init(bool trace)
Reset the USBHS host-mode model to its power-on state.
Bounded raw-descriptor I/O seam for the RA8 emulator.
emu_io_result_t priv_emu_io_errf(const char *format,...)
Format bounded text and write it to the injected error descriptor.
uc_err emu_mem_read(uc_engine *uc, uint64_t address, void *bytes, size_t count)
Read guest memory through the central access seam.
uc_err emu_mem_write(uc_engine *uc, uint64_t address, const void *bytes, size_t count)
Write guest memory through the central access seam.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
A modelled peripheral block's self-description for the core registry.
bool observe
Observe-only: snoop, do not own the MMIO.
const char * name
Short label (diagnostics only).
board_periph_write_fn write
MMIO write handler (required).
board_periph_read_fn read
MMIO read handler (required).
@ k_nvic_ispr_base
NVIC Interrupt Set-Pending Register array.
@ k_nvic_iser_base
NVIC Interrupt Set-Enable Register array.
static volatile uint32_t s_trace[k_dcd_trace_entries]
JLink-readable ring of packed transfer/SETUP events.