|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Inter-Processor Communication (IPC) peripheral-block model for ra8_emulator. More...
#include <stdint.h>#include <stdio.h>#include "board_periph_block.h"#include "emu_host_io_internal.h"Go to the source code of this file.
Data Structures | |
| struct | ipc_fifo_t |
| One channel's 4-stage message FIFO plus its sticky error latches. More... | |
| struct | ipc_state_t |
| Modelled IPC state: per-channel IRQ bits + FIFOs plus run counters. More... | |
Enumerations | |
| enum | ipc_order_t : uint32_t { k_ipc_block_order = 62U } |
| Per-tick order slot for the IPC block. More... | |
| enum | ipc_geom_t : uint64_t { k_ipc_base = 0x40020000UL , k_ipc_span = 0x140UL } |
| IPC register window geometry (ra8_ipc_regs.h). More... | |
| enum | ipc_reg_off_t : uint64_t { k_ipc_ch0_off = 0xC0UL , k_ipc_ch_stride = 0x20UL , k_ipc_reg_sta = 0x00UL , k_ipc_reg_iset = 0x04UL , k_ipc_reg_txd = 0x08UL , k_ipc_reg_rxd = 0x0CUL , k_ipc_reg_clr = 0x10UL } |
| Channel-window layout within the IPC register block. More... | |
| enum | ipc_chan_t : uint32_t { k_ipc_ch_count = 4U , k_ipc_unit_split = 2U , k_ipc_fifo_depth = 4U } |
| Channel-count, unit-split and FIFO-depth constants. More... | |
| enum | ipc_status_t : uint32_t { k_ipc_sta_irq_mask = 0x000000FFU , k_ipc_sta_rdy = 0x00010000U , k_ipc_sta_full = 0x00020000U , k_ipc_sta_rerr = 0x01000000U , k_ipc_sta_ferr = 0x02000000U , k_ipc_clr_rst = 0x00010000U , k_ipc_clr_rclr = 0x01000000U , k_ipc_clr_fclr = 0x02000000U , k_ipc0_irq_event = 0x05BU , k_ipc1_irq_event = 0x05CU } |
| Status-register masks and the receiving-core ELC event ids. More... | |
Functions | |
| static RA8_INTERNAL bool | internal_ipc_decode (uint64_t off, uint32_t *ch, uint32_t *reg) |
| Decode a window offset to its channel index and register offset. | |
| static RA8_INTERNAL uint32_t | internal_ipc_sta_value (uint32_t ch) |
| Compose one channel's live STA value from its shadows. | |
| static RA8_INTERNAL uint32_t | internal_ipc_fifo_pop (uint32_t ch) |
| Pop the oldest word off a channel's message FIFO (RXD read). | |
| static RA8_INTERNAL uint64_t | internal_ipc_read (uc_engine *uc, uint64_t addr, unsigned size) |
| Read an IPC register: STA composes live status, RXD pops the FIFO. | |
| static RA8_INTERNAL void | internal_ipc_fifo_push (uint32_t ch, uint32_t value) |
| Push one word onto a channel's message FIFO (TXD write). | |
| static RA8_INTERNAL void | internal_ipc_clr_write (uint32_t ch, uint32_t value) |
| Apply a CLR write: W1C IRQ lines, FIFO reset, error-latch clears. | |
| static RA8_INTERNAL void | internal_ipc_write (uc_engine *uc, uint64_t addr, unsigned size, uint64_t value) |
| Write an IPC register: ISET latches + raises, TXD pushes, CLR clears. | |
| static RA8_INTERNAL void | internal_ipc_reset (void) |
| Clear the IPC channel shadows and the run counters. | |
| static RA8_INTERNAL void | internal_ipc_report (void) |
| Print the IPC send / wake / FIFO totals when the path was exercised. | |
| static RA8_INTERNAL void | internal_board_periph_ipc_register (void) |
| Self-register the IPC window before main runs (decentralised). | |
Variables | |
| static ipc_state_t | s_ipc |
| Single shared IPC model instance (both engines dispatch into it). | |
| static const board_periph_block_t | s_k_ipc_block |
| IPC register window + reset / report (no tick: event-driven only). | |
Inter-Processor Communication (IPC) peripheral-block model for ra8_emulator.
Models the maskable-IRQ event path of the RA8D2 IPC unit (ra8_ipc_regs.h, ra8_ipc.c) so the dual-core compile_on_m33 example can replace its busy done-flag poll with a real interrupt-driven wake: the secondary Cortex-M33, having finished the EPUB->RABOOK1 compile, pokes IPC0ISET0 (HUM Ch 3.2.11 "IPC0ISET0" p 215) and the primary Cortex-M85 – idling in WFI – takes the IPC0 receive interrupt and re-checks the mailbox.
Two surfaces are modelled per channel; the semaphores / NMI windows are not exercised by any consumer, so reads there return 0 and writes are benign no-ops. Per channel the model keeps the STA pending-IRQ shadow plus a 4-stage message FIFO (HUM Ch 3.1 "Overview" p 204 fixes the depth):
ISET (set-IRQ, +0x04) latches the written IRQ-line bits into STA and raises the receiving core's ELC event through the core's ICU -> NVIC path, exactly the cross-core poke real silicon performs. IPC0 channels (CPU1 -> CPU0) raise ELC_EVENT_IPC_IRQ0 (0x05B); IPC1 channels (CPU0 -> CPU1) raise ELC_EVENT_IPC_IRQ1 (0x05C).STA (+0x00) returns the latched pending bits the receiver's ra8_ipc_dispatch decodes, plus the live FIFO status: RDY (bit 16, FIFO non-empty), FULL (bit 17), and the RERR / FERR sticky error latches (bits 24 / 25). HUM Ch 3.2.10 "IPC0STA0" p 214.TXD (+0x08) pushes one 32-bit word onto the channel FIFO (FERR latches on a write-while-full); a read of RXD (+0x0C) pops one word (RERR latches on a read-while-empty). This is the data path the dual-core ping-pong (cpu1_pingpong_ipc) exchanges its magic words over: the sender pushes on one engine, the receiver polls STA.RDY and pops on the other, against ONE shared model instance. HUM Ch 3.2.12 "IPC0TXD0" p 215 / Ch 3.2.13 "IPC0RXD0" p 216.CLR (W1C, +0x10) clears the acknowledged IRQ-line bits; RST (bit 16) empties the FIFO (dropping RDY / FULL), and RCLR / FCLR (bits 24 / 25) drop the sticky error latches. HUM Ch 3.2.14 "IPC0CLR0" p 216-217.The M33 reaches this window through the bit[28] non-secure peripheral alias (0x50020000); the cpu1 engine maps that alias to the same models via the same MMIO hooks, so an alias access dispatches here identically to a Secure one.
The IPC has no time-based behaviour, so the block carries no tick.
Definition in file board_periph_ipc.c.
| enum ipc_chan_t : uint32_t |
Channel-count, unit-split and FIFO-depth constants.
| Enumerator | |
|---|---|
| k_ipc_ch_count | IPC0_0, IPC0_1, IPC1_0, IPC1_1. |
| k_ipc_unit_split | Channels < split are IPC0, the rest IPC1. |
| k_ipc_fifo_depth | 4-stage message FIFO (HUM Ch 3.1 p 204). |
Definition at line 86 of file board_periph_ipc.c.
| enum ipc_geom_t : uint64_t |
IPC register window geometry (ra8_ipc_regs.h).
| Enumerator | |
|---|---|
| k_ipc_base | IPC unit base (Secure alias). |
| k_ipc_span | Semaphores + NMI + four channel windows. |
Definition at line 69 of file board_periph_ipc.c.
| enum ipc_order_t : uint32_t |
Per-tick order slot for the IPC block.
The IPC carries no tick, so its order is never consulted for advance; the value only has to be unique among the registered blocks. Placed above the RTC slot (60) following the same decentralised-ordering convention.
| Enumerator | |
|---|---|
| k_ipc_block_order | IPC reset / report order slot. |
Definition at line 64 of file board_periph_ipc.c.
| enum ipc_reg_off_t : uint64_t |
Channel-window layout within the IPC register block.
Definition at line 75 of file board_periph_ipc.c.
| enum ipc_status_t : uint32_t |
Status-register masks and the receiving-core ELC event ids.
Definition at line 93 of file board_periph_ipc.c.
|
static |
Self-register the IPC window before main runs (decentralised).
Definition at line 460 of file board_periph_ipc.c.
References board_periph_register_block(), RA8_INTERNAL, and s_k_ipc_block.
|
static |
Apply a CLR write: W1C IRQ lines, FIFO reset, error-latch clears.
| [in] | ch | Channel index (0..k_ipc_ch_count - 1). |
| [in] | value | The written CLR word. |
ch is a decoded channel index (< k_ipc_ch_count). Apply a clr write: w1c irq lines, fifo reset, error-latch clears; this step is contained within the board periph ipc model and uses bounded caller or module-owned storage.
Definition at line 339 of file board_periph_ipc.c.
References ipc_fifo_t::count, ipc_fifo_t::ferr, k_ipc_clr_fclr, k_ipc_clr_rclr, k_ipc_clr_rst, k_ipc_sta_irq_mask, RA8_INTERNAL, ipc_fifo_t::rd, ipc_fifo_t::rerr, and s_ipc.
Referenced by internal_ipc_write().
|
static |
Decode a window offset to its channel index and register offset.
| [in] | off | Byte offset from k_ipc_base. |
| [out] | ch | Receives the channel index 0..3 on success. |
| [out] | reg | Receives the in-channel register offset on success. |
off lands inside a channel window. | true | off is in [0xC0, 0x140); ch / reg are set. |
| false | off is in the semaphore / NMI region (no channel). |
ch and reg are non-NULL. off is within the block span. ch < k_ipc_ch_count. ch and reg are untouched.Decode a window offset to its channel index and register offset; this step is contained within the board periph ipc model and uses bounded caller or module-owned storage.
Definition at line 172 of file board_periph_ipc.c.
References k_ipc_ch0_off, k_ipc_ch_count, k_ipc_ch_stride, and RA8_INTERNAL.
Referenced by internal_ipc_read(), and internal_ipc_write().
|
static |
Pop the oldest word off a channel's message FIFO (RXD read).
| [in] | ch | Channel index (0..k_ipc_ch_count - 1). |
| 0 | FIFO was empty (RERR sticky latched) or the queued word was 0. |
ch is a decoded channel index (< k_ipc_ch_count). pops advances. Pop the oldest word off a channel's message fifo (rxd read); this step is contained within the board periph ipc model and uses bounded caller or module-owned storage.
Definition at line 246 of file board_periph_ipc.c.
References ipc_fifo_t::count, k_ipc_fifo_depth, RA8_INTERNAL, ipc_fifo_t::rd, ipc_fifo_t::rerr, s_ipc, and ipc_fifo_t::word.
Referenced by internal_ipc_read().
|
static |
Push one word onto a channel's message FIFO (TXD write).
| [in] | ch | Channel index (0..k_ipc_ch_count - 1). |
| [in] | value | The 32-bit message word to queue. |
ch is a decoded channel index (< k_ipc_ch_count). pushes advances; the receiver's next STA read shows RDY. Push one word onto a channel's message fifo (txd write); this step is contained within the board periph ipc model and uses bounded caller or module-owned storage.
Definition at line 310 of file board_periph_ipc.c.
References ipc_fifo_t::count, ipc_fifo_t::ferr, k_ipc_fifo_depth, RA8_INTERNAL, ipc_fifo_t::rd, s_ipc, and ipc_fifo_t::word.
Referenced by internal_ipc_write().
|
static |
Read an IPC register: STA composes live status, RXD pops the FIFO.
Read an ipc register: sta composes live status, rxd pops the fifo; this step is contained within the board periph ipc model and uses bounded caller or module-owned storage.
| [in,out] | uc | Unicorn engine whose emulated state is read or updated. |
| [in] | addr | Guest address involved in the operation. |
| [in] | size | Size of the requested region or access in bytes. |
| value | The operation-specific ipc read value. |
Definition at line 273 of file board_periph_ipc.c.
References internal_ipc_decode(), internal_ipc_fifo_pop(), internal_ipc_sta_value(), k_ipc_base, k_ipc_reg_rxd, k_ipc_reg_sta, and RA8_INTERNAL.
|
static |
Print the IPC send / wake / FIFO totals when the path was exercised.
Print the ipc send / wake / fifo totals when the path was exercised; this step is contained within the board periph ipc model and uses bounded caller or module-owned storage.
Definition at line 434 of file board_periph_ipc.c.
References priv_emu_io_errf(), RA8_INTERNAL, and s_ipc.
|
static |
Clear the IPC channel shadows and the run counters.
Clear the ipc channel shadows and the run counters; this step is contained within the board periph ipc model and uses bounded caller or module-owned storage.
Definition at line 421 of file board_periph_ipc.c.
References RA8_INTERNAL, and s_ipc.
|
static |
Compose one channel's live STA value from its shadows.
| [in] | ch | Channel index (0..k_ipc_ch_count - 1). |
| 0 | Channel idle: no pending IRQ, empty FIFO, no latched error. |
ch is a decoded channel index (< k_ipc_ch_count). count > 0 and FULL reflects count == depth.Compose one channel's live sta value from its shadows; this step is contained within the board periph ipc model and uses bounded caller or module-owned storage.
Definition at line 210 of file board_periph_ipc.c.
References ipc_fifo_t::count, ipc_fifo_t::ferr, k_ipc_fifo_depth, k_ipc_sta_ferr, k_ipc_sta_full, k_ipc_sta_rdy, k_ipc_sta_rerr, RA8_INTERNAL, ipc_fifo_t::rerr, and s_ipc.
Referenced by internal_ipc_read().
|
static |
Write an IPC register: ISET latches + raises, TXD pushes, CLR clears.
Write an ipc register: iset latches + raises, txd pushes, clr clears; this step is contained within the board periph ipc model and uses bounded caller or module-owned storage.
| [in,out] | uc | Unicorn engine whose emulated state is read or updated. |
| [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. |
Definition at line 368 of file board_periph_ipc.c.
References board_periph_icu_raise_event(), board_periph_trace(), internal_ipc_clr_write(), internal_ipc_decode(), internal_ipc_fifo_push(), k_ipc0_irq_event, k_ipc1_irq_event, k_ipc_base, k_ipc_reg_clr, k_ipc_reg_iset, k_ipc_reg_txd, k_ipc_sta_irq_mask, k_ipc_unit_split, priv_emu_io_errf(), and s_ipc.
|
static |
Single shared IPC model instance (both engines dispatch into it).
Definition at line 145 of file board_periph_ipc.c.
Referenced by internal_ipc_clr_write(), internal_ipc_fifo_pop(), internal_ipc_fifo_push(), internal_ipc_report(), internal_ipc_reset(), internal_ipc_sta_value(), and internal_ipc_write().
|
static |
IPC register window + reset / report (no tick: event-driven only).
Definition at line 447 of file board_periph_ipc.c.
Referenced by internal_board_periph_ipc_register().