|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Decentralized peripheral-block registry for the board emulator core. More...
Go to the source code of this file.
Data Structures | |
| struct | board_periph_block_t |
| A modelled peripheral block's self-description for the core registry. More... | |
Typedefs | |
| typedef uint64_t(* | board_periph_read_fn) (uc_engine *uc, uint64_t addr, unsigned size) |
| Read handler for a modelled peripheral block. | |
| typedef void(* | board_periph_write_fn) (uc_engine *uc, uint64_t addr, unsigned size, uint64_t value) |
| Write handler for a modelled peripheral block. | |
| typedef void(* | board_periph_tick_fn) (uc_engine *uc) |
| Per-emulation-chunk advance for a block, or NULL if it has none. | |
| typedef void(* | board_periph_reset_fn) (void) |
| Reset a block to its power-on state, or NULL if it keeps none. | |
| typedef void(* | board_periph_report_fn) (void) |
| Print a block's end-of-run summary section, or NULL if it has none. | |
Enumerations | |
| enum | board_block_device_t : uint8_t { k_board_block_dev_any = 0U , k_board_block_dev_ra8p1 = 1U } |
| Which modelled device(s) expose a given peripheral block. More... | |
| enum | board_periph_block_order_t : uint32_t { k_block_order_gpio = 10U , k_block_order_timer = 20U , k_block_order_sci = 30U , k_block_order_i2c = 40U } |
Recommended order values so parallel blocks tick in a stable cadence. More... | |
Functions | |
| void | board_periph_register_block (const board_periph_block_t *block) |
| Register a peripheral block's descriptor with the core registry. | |
| void | board_periph_icu_raise_event (uc_engine *uc, uint16_t event) |
| Raise a peripheral ELC event through the core's ICU -> NVIC path. | |
| uint32_t | board_periph_icu_dtc_slot (uint16_t event) |
| Find the IELSR slot that activates the DTC for an ELC event. | |
| bool | board_periph_trace (void) |
| Whether –trace is active (blocks log transitions when true). | |
Decentralized peripheral-block registry for the board emulator core.
The internal contract between the board_periph core (the block registry + MMIO dispatch + the ICU/NVIC routing) and each per-block model file (board_periph_gpio.c, board_periph_timer.c, board_periph_sci.c, board_periph_i2c.c, and any future block). It is NOT part of the public board_periph.h surface main.c uses; it exists so a new peripheral block can join the model with no edit to a hand-maintained central list.
A block describes itself with a board_periph_block_t – its absolute register address range plus read / write / tick / reset function pointers – and registers that descriptor with the core. Registration is decentralized: [[gnu::constructor]] * each block file self-registers from a file-scope that runs before main (ra8_emulator is a host program, so constructors are a sound startup mechanism), so ADDING A BLOCK is exactly "(a) a new
board_periph_<blk>.c and (b) a CMakeLists source line" – no other file changes. Registration order does not matter: MMIO dispatch is by disjoint address range, and the per-tick advance is ordered by the descriptor's board_periph_block_t::order field, so two blocks added in parallel never conflict.
The core also publishes the shared framework services a block needs back from it: board_periph_icu_raise_event (so a timer / UART block can pend an interrupt through the one ICU IELSR -> NVIC path the core owns) and board_periph_trace (the –trace flag).
Definition in file board_periph_block.h.
| typedef uint64_t(* board_periph_read_fn) (uc_engine *uc, uint64_t addr, unsigned size) |
Read handler for a modelled peripheral block.
| [in,out] | uc | Unicorn engine (a handler may read emulated memory). |
| [in] | addr | Absolute peripheral address being read (inside the block's registered range). |
| [in] | size | Access width in bytes (1 / 2 / 4). |
addr. Definition at line 57 of file board_periph_block.h.
| typedef void(* board_periph_report_fn) (void) |
Print a block's end-of-run summary section, or NULL if it has none.
Called by the core's board_periph_report in ascending board_periph_block_t::order, so the summary keeps its historical section order (LEDs, timers, UART, ... touch) without a central list.
Definition at line 100 of file board_periph_block.h.
| typedef void(* board_periph_reset_fn) (void) |
Reset a block to its power-on state, or NULL if it keeps none.
Definition at line 88 of file board_periph_block.h.
| typedef void(* board_periph_tick_fn) (uc_engine *uc) |
Per-emulation-chunk advance for a block, or NULL if it has none.
| [in,out] | uc | Unicorn engine (the block may raise an ICU event, which reads IELSR / NVIC from PPB). |
Definition at line 80 of file board_periph_block.h.
| typedef void(* board_periph_write_fn) (uc_engine *uc, uint64_t addr, unsigned size, uint64_t value) |
Write handler for a modelled peripheral block.
| [in,out] | uc | Unicorn engine (a handler may read emulated memory). |
| [in] | addr | Absolute peripheral address being written (inside the block's registered range). |
| [in] | size | Access width in bytes (1 / 2 / 4). |
| [in] | value | Value being written. |
Definition at line 70 of file board_periph_block.h.
| enum board_block_device_t : uint8_t |
Which modelled device(s) expose a given peripheral block.
Nearly every RA8 peripheral register base is byte-identical across the family, so a block is device-agnostic (k_board_block_dev_any) and answers on every modelled device. A block that models hardware present on ONE device only – the RA8P1's Arm Ethos-U55 NPU, which does not exist on the RA8D2 – tags itself so the core dispatches it ONLY when that device is the active emulation target (see board_periph_set_device). On any other device the tagged block is skipped and its address window falls through to the sparse fallback, exactly as an unmodelled reserved region does, which keeps the RA8D2 dispatch byte-for-behaviour unchanged.
| Enumerator | |
|---|---|
| k_board_block_dev_any | Present on every modelled device (default). |
| k_board_block_dev_ra8p1 | RA8P1-only (Ethos-U55 NPU). |
Definition at line 121 of file board_periph_block.h.
| enum board_periph_block_order_t : uint32_t |
Recommended order values so parallel blocks tick in a stable cadence.
A block picks one of these for board_periph_block_t::order. Spacing leaves room for new blocks between the existing ones without renumbering. Only the relative order matters; ties are broken by registration order. The historical cadence the core preserved was timers (AGT then GPT) before SCI, so the timer block sits below the SCI block here.
| Enumerator | |
|---|---|
| k_block_order_gpio | GPIO/PORT (no tick today). |
| k_block_order_timer | GPT + AGT timers. |
| k_block_order_sci | SCI_B UART. |
| k_block_order_i2c | I3C/I2C + GT911 (no tick today). |
Definition at line 180 of file board_periph_block.h.
| uint32_t board_periph_icu_dtc_slot | ( | uint16_t | event | ) |
Find the IELSR slot that activates the DTC for an ELC event.
The DTC block model needs to know which IELSR slot a software / peripheral event is routed to with DTC activation enabled, so it can index the DTC vector table (DTCVBR + slot*4) at the matching Transfer Information block. The core owns the IELSR event-link table (the same state board_periph_icu_raise_event scans), so it answers the query: the first slot whose IELS event-select field equals event and whose DTCE bit is set.
| [in] | event | ELC event number to resolve (e.g. ELC_SWEVT0 = 0x0CC). |
event, or a value >= 96 when none does. | value | The operation-specific board periph icu DTC slot value. |
Definition at line 413 of file board_periph.c.
References k_icu_ielsr_cnt, k_ielsr_dtce_mask, k_ielsr_iels_mask, and s_ielsr.
Referenced by internal_dtc_activate_swevt0().
| void board_periph_icu_raise_event | ( | uc_engine * | uc, |
| uint16_t | event ) |
Raise a peripheral ELC event through the core's ICU -> NVIC path.
The single entry point a block uses to assert an interrupt: the core owns the ICU IELSR event-link table, the NVIC enable shadow and the pending-IRQ ring, so a timer / UART block calls this rather than touching that state. The core latches IELSR.IR for the slot linked to event and, if that NVIC line is enabled, pends it for the engine to take.
| [in,out] | uc | Unicorn engine (the ICU reads IELSR / NVIC from PPB). |
| [in] | event | ELC event number the block is asserting. |
Definition at line 395 of file board_periph.c.
References internal_irq_ring_push(), internal_nvic_enabled(), internal_nvic_set_pending(), k_icu_ielsr_cnt, k_ielsr_iels_mask, k_ielsr_ir_mask, priv_emu_io_errf(), s_ielsr, and s_trace.
Referenced by internal_adc_write(), internal_agt_tick_channel(), internal_canfd_loopback_deliver(), internal_dmac_run_transfer(), internal_gpt_tick_channel(), internal_ipc_write(), internal_npu_execute(), internal_rtc_raise_events(), internal_sci_tick_channel(), internal_ulpt_tick_channel(), and internal_usb_irq_raiser().
| void board_periph_register_block | ( | const board_periph_block_t * | block | ) |
Register a peripheral block's descriptor with the core registry.
Called by each block file from a file-scope __attribute__((constructor)), so every block is registered before main runs. The core keeps the supplied pointer (the descriptor must be static) and dispatches MMIO / tick / reset through it. Registering more blocks than the fixed registry capacity drops the extra (a build-time assert in the core guards the common case); registration order is irrelevant to behaviour.
| [in] | block | Static block descriptor to add (ignored if NULL). |
block. Definition at line 113 of file board_periph.c.
References k_block_max, board_periph_block_t::name, priv_emu_io_errf(), s_block_count, s_blocks, and s_order_built.
Referenced by internal_bkup_block_register(), internal_board_periph_adc_register(), internal_board_periph_canfd_register(), internal_board_periph_ceu_register(), internal_board_periph_dac_register(), internal_board_periph_dmac_register(), internal_board_periph_gpio_register(), internal_board_periph_i2c_register(), internal_board_periph_ipc_register(), internal_board_periph_pdm_register(), internal_board_periph_riic_register(), internal_board_periph_rtc_register(), internal_board_periph_sci_register(), internal_board_periph_spi_register(), internal_board_periph_timer_register(), internal_board_periph_ulpt_register(), internal_cac_block_register(), internal_crc_block_register(), internal_doc_block_register(), internal_drw_block_register(), internal_dtc_block_register(), internal_eth_block_register(), internal_glcdc_block_register(), internal_gptp_block_register(), internal_lvd_block_register(), internal_mram_block_register(), internal_mstp_block_register(), internal_npu_block_register(), internal_pdctr_block_register(), internal_poeg_block_register(), internal_prcr_block_register(), internal_reset_block_register(), internal_rtt_block_register(), internal_sdhi_block_register(), internal_sram_block_register(), internal_ssie_block_register(), internal_usbhs_block_register(), internal_wdt_block_register(), and internal_xspi_block_register().
| bool board_periph_trace | ( | void | ) |
Whether –trace is active (blocks log transitions when true).
Whether –trace is active (blocks log transitions when true); this step is contained within the board periph block model and uses bounded caller or module-owned storage.
| true | The board periph trace condition holds or completed successfully; false otherwise. |
Definition at line 521 of file board_periph.c.
References s_trace.
Referenced by board_periph_sci_feed_rx(), internal_adc_write(), internal_canfd_loopback_deliver(), internal_ceu_do_capture(), internal_dac_write(), internal_dmac_run_transfer(), internal_ipc_write(), internal_port_trace_leds(), internal_rtc_raise_events(), and internal_ulpt_tick_channel().