40static const char*
s_tag =
"IPC";
43typedef enum : uintptr_t {
51typedef enum : uint32_t {
143#ifdef RA8_BUILD_FOR_CPU1
207 if (irq_bits == 0U) {
212 const uint32_t bit = (uint32_t)1U << (uint32_t)i;
213 if ((irq_bits & bit) == 0U) {
287 if (reg ==
nullptr) {
372 reg->
ISET = (uint32_t)1U << (uint32_t)event_id;
389 reg->
CLR = (uint32_t)1U << (uint32_t)event_id;
434 for (uint16_t i = 0U; i <= max_retries; ++i) {
466 uint32_t written = 0U;
470 for (uint32_t i = 0U; i < count; ++i) {
479 *out_written = written;
516 for (uint16_t i = 0U; i <= max_retries; ++i) {
539 if (capacity == 0U) {
545 uint32_t read_count = 0U;
548 for (uint32_t i = 0U; i < capacity; ++i) {
554 out_data[i] = reg->
RXD;
557 *out_read = read_count;
599 if (reg ==
nullptr) {
612 if (reg ==
nullptr) {
624 if (reg ==
nullptr) {
651 out_attr->
secure = ((sar & bit) != 0U);
667 out_attr->
secure = ((sar & bit) != 0U);
682 const uint32_t bit = (uint32_t)1U << (uint32_t)group;
683 out_attr->
secure = ((sar & bit) != 0U);
698 const bool secure_match = live.
secure == required->
secure;
700 *out_can_access = (bool)(secure_match && privileged_match);
739 if (reg ==
nullptr) {
745 const uint32_t sta = reg->
STA;
749 uint32_t message = 0U;
761 if ((fn !=
nullptr) && (fired != 0U)) {
762 fn(ctx, channel, fired, message);
793 const uint8_t unit = (uint8_t)(uintptr_t)ctx;
799 const uint8_t base = (uint8_t)((uint8_t)unit * 2U);
static const char * s_tag
Logging / check tag.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Event Link Controller (ELC) register layout for the Renesas RA8D2.
ra8_elc_event_t
Partial list of ELC events (populate as drivers need them).
Error Code Definitions for ra8-firmware.
@ k_ra8_err_busy
Resource busy – blocking operation cannot proceed.
@ k_ra8_err_no_data
No application data available (e.g.
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_err_exists
Item already exists – cannot create again.
@ k_ra8_err_hw_timeout
Hardware timed out waiting for a flag or handshake.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_not_found
Requested item not found (lookup / search missed).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
static volatile r_ipc_channel_regs_t * internal_ra8_ipc_get_regs(uint8_t channel)
Validate channel id and return the channel reg pointer.
ra8_err_t ra8_ipc_recv_message(uint8_t channel, uint32_t *out_msg)
Pop one 32-bit word from the channel RX FIFO.
ra8_err_t ra8_ipc_send_message_retry(uint8_t channel, uint32_t message, uint16_t max_retries)
Bounded-retry variant of ra8_ipc_send_message.
ra8_err_t ra8_ipc_install_isr(uint8_t unit, uint8_t priority)
Wire the IPC IRQ event into the ISR table.
ra8_err_t ra8_ipc_attach_handler(ra8_ipc_event_fn_t fn, void *ctx)
Attach a single event callback shared across all channels.
ra8_err_t ra8_ipc_clear_errors(uint8_t channel)
Clear RERR + FERR on the channel.
ra8_err_t ra8_ipc_send_message(uint8_t channel, uint32_t message)
Push one 32-bit word into the channel TX FIFO.
ra8_err_t ra8_ipc_channel_for_recv(ra8_ipc_core_id_t core, uint8_t pair, uint8_t *out_channel)
Pick the channel id this core reads from.
static ra8_ipc_isr_state_t s_ipc_isr_state[k_ra8_ipc_nmi_unit_count]
ra8_err_t ra8_ipc_get_attribution(uint8_t channel, ra8_ipc_attr_t *out_attr)
Read the security / privilege attribution for one channel.
ra8_err_t ra8_ipc_has_data(uint8_t channel, bool *out_has_data)
Predicate: would ra8_ipc_recv_message succeed right now?
ra8_err_t ra8_ipc_init(const ra8_ipc_config_t *cfg)
Initialise one IPC channel.
static void internal_ra8_ipc_dispatch_irq_lines(uint8_t channel, uint32_t mask)
Walk every IRQn bit in mask and call the per-line callback registered for that channel/line,...
ra8_err_t ra8_ipc_clear_event(uint8_t channel, ra8_ipc_irq_event_id_t event_id)
Clear one received IRQ event line on the local core.
ra8_err_t ra8_ipc_set_event_mask(uint8_t channel, uint32_t mask)
Update the event-mask filter for an already-initialized channel.
ra8_ipc_internal_const_t
Magic constants used inside the driver only.
@ k_ra8_ipc_internal_event_full_mask
RA8 ipc internal event full mask.
ra8_err_t ra8_ipc_get_status(uint8_t channel, uint32_t *out_sta)
Read the raw channel status register.
ipc_alias_t
Secure->Non-secure address alias offset.
@ k_ipc_ns_alias_offset
Ipc ns alias offset.
static uint16_t internal_ra8_ipc_unit_to_event(uint8_t unit)
Read the ELC event id matching one IPC unit.
ra8_err_t ra8_ipc_can_access(uint8_t channel, ra8_ipc_attr_t const *required, bool *out_can_access)
Predicate: does this core's attribution allow writing the channel?
ra8_err_t ra8_ipc_channel_for_send(ra8_ipc_core_id_t core, uint8_t pair, uint8_t *out_channel)
Pick the channel id this core writes to.
ra8_err_t ra8_ipc_clear_status(uint8_t channel, uint32_t mask)
Clear selected status bits on a channel.
ra8_err_t ra8_ipc_get_nmi_attribution(uint8_t unit, ra8_ipc_attr_t *out_attr)
Read the attribution for one NMI unit.
ra8_err_t ra8_ipc_send_burst(uint8_t channel, const uint32_t *data, uint32_t count, uint32_t *out_written)
Push up to count words into the channel TX FIFO.
static ra8_ipc_channel_state_t s_ipc_channels[k_ra8_ipc_channel_count]
ra8_err_t ra8_ipc_reset_fifo(uint8_t channel)
Issue a CLR.RST on one channel without altering callbacks.
ra8_err_t ra8_ipc_get_sem_attribution(ra8_ipc_sem_attr_group_t group, ra8_ipc_attr_t *out_attr)
Read the attribution for an IPCSEM group.
static ra8_ipc_event_fn_t s_ipc_callback
ra8_err_t ra8_ipc_uninstall_isr(uint8_t unit)
Tear down a previously installed IPC ISR.
ra8_err_t ra8_ipc_send_event(uint8_t channel, ra8_ipc_irq_event_id_t event_id)
Generate a maskable IRQ event on the peer core.
void ra8_ipc_dispatch(uint8_t channel)
Drive the event callback for one channel.
ra8_err_t ra8_ipc_can_send(uint8_t channel, bool *out_can_send)
Predicate: would ra8_ipc_send_message succeed right now?
static void internal_ra8_ipc_isr(void *ctx)
ISR trampoline – dispatches both channels in one IPC unit.
ra8_err_t ra8_ipc_recv_message_retry(uint8_t channel, uint32_t *out_msg, uint16_t max_retries)
Bounded-retry variant of ra8_ipc_recv_message.
static void * s_ipc_context
ra8_err_t ra8_ipc_recv_burst(uint8_t channel, uint32_t *out_data, uint32_t capacity, uint32_t *out_read)
Drain up to capacity words from the channel RX FIFO.
static uint32_t internal_ra8_ipc_event_to_clr(uint32_t event_mask)
Translate a public ra8_ipc_event_t mask into the matching IPCnCLRm bit pattern.
ra8_err_t ra8_ipc_attach_event_handler(uint8_t channel, ra8_ipc_irq_event_id_t event_id, ra8_ipc_irq_fn_t fn, void *ctx)
Attach a callback for a single IRQ event line on a channel.
ra8_err_t ra8_ipc_deinit(uint8_t channel)
Tear down one IPC channel.
Inter-Processor Communication (IPC) HAL driver – public API.
Inter-Processor Communication (IPC) register layout for the RA8D2.
static volatile r_ipc_channel_regs_t * ra8_ipc_channel(uint8_t channel)
Get a pointer to one IPC FIFO channel register window.
static volatile uint32_t * ra8_ipc_ipcpar(void)
Get a pointer to the IPCPAR Privileged Attribution register.
@ k_ra8_ipc_elc_event_irq0
Receiving-side IRQ for IPC0_*.
@ k_ra8_ipc_elc_event_irq1
Receiving-side IRQ for IPC1_*.
static volatile uint32_t * ra8_ipc_ipcsar(void)
Get a pointer to the IPCSAR Security Attribution register.
ra8_ipc_core_id_t
Logical CPU core identifiers used by attribution helpers.
@ k_ra8_ipc_core_cpu0
Cortex-M85 (primary core).
@ k_ra8_ipc_core_cpu1
Cortex-M33 (secondary core).
@ k_ra8_ipc_attr_shift_nmi_base
SAIPCNMI0 / PAIPCNMI0 position.
@ k_ra8_ipc_attr_shift_ir_base
SAIPCIR0 / PAIPCIR0 bit position.
@ k_ra8_ipc_sta_mask_full
FULL: FIFO full.
@ k_ra8_ipc_sta_mask_rdy
RDY: FIFO non-empty.
@ k_ra8_ipc_clr_mask_fclr
FCLR: clear FERR.
@ k_ra8_ipc_clr_mask_rst
RST: reset message FIFO.
@ k_ra8_ipc_clr_mask_rclr
RCLR: clear RERR.
@ k_ra8_ipc_clr_mask_irq_all
CLR7..CLR0 -> clear IRQn.
@ k_ra8_ipc_irq_event_count
8 IRQ event lines per channel.
@ k_ra8_ipc_nmi_unit_count
IPC0 + IPC1 NMI units.
@ k_ra8_ipc_channel_count
Total FIFO channels: 2 per unit x 2.
ra8_ipc_sem_attr_group_t
IPCSEMn attribution-group selector (HUM Ch 3.3.1 p 227-228).
@ k_ra8_ipc_sem_group_high
IPCSEM8..IPCSEM15 attribution group.
@ k_ra8_ipc_unit_ipc0
CPU1 -> CPU0 (M33 sends, M85 receives).
static void ra8_ipc_barrier(void)
Cross-core data-memory barrier for IPC publish + lock ordering.
@ k_ra8_ipc_retry_max
Hard cap accepted by the API.
void(* ra8_ipc_event_fn_t)(void *ctx, uint8_t channel, uint32_t event_mask, uint32_t message)
IPC event callback signature.
ra8_ipc_irq_event_id_t
Index of an IRQ event line within a channel (0..7).
@ k_ra8_ipc_event_irq3
Maskable IRQ event line 3.
@ k_ra8_ipc_event_irq4
Maskable IRQ event line 4.
@ k_ra8_ipc_event_irq0
Maskable IRQ event line 0.
@ k_ra8_ipc_event_msg_ready
RDY: receive FIFO non-empty.
@ k_ra8_ipc_event_irq5
Maskable IRQ event line 5.
@ k_ra8_ipc_event_fifo_full
FULL: send FIFO is full.
@ k_ra8_ipc_event_irq2
Maskable IRQ event line 2.
@ k_ra8_ipc_event_irq6
Maskable IRQ event line 6.
@ k_ra8_ipc_event_err_full
FERR: write-while-full.
@ k_ra8_ipc_event_irq1
Maskable IRQ event line 1.
@ k_ra8_ipc_event_err_empty
RERR: read-while-empty.
@ k_ra8_ipc_event_irq_all
IRQ7..IRQ0 union mask.
@ k_ra8_ipc_event_irq7
Maskable IRQ event line 7.
void(* ra8_ipc_irq_fn_t)(void *ctx, uint8_t channel, ra8_ipc_irq_event_id_t event_id)
Per-IRQ-event-line callback signature.
NVIC + ICU IELSR allocator.
ra8_err_t ra8_isr_register(ra8_elc_event_t event, ra8_isr_handler_t handler, void *ctx, uint8_t priority, uint16_t *out_slot)
Allocate an IELSR slot for an ELC event + handler.
ra8_err_t ra8_isr_unregister(ra8_elc_event_t event)
Release a previously-allocated IELSR slot.
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info_val(tag, message, value)
RA8 log info val.
Per-FIFO-channel register window (5 x 32-bit at +0x20 stride).
volatile uint32_t ISET
+0x04 IRQ request set (W).
volatile uint32_t CLR
+0x10 Status / error / FIFO clear (W).
volatile uint32_t RXD
+0x0C FIFO receive data (R).
volatile uint32_t TXD
+0x08 FIFO transmit data (W).
volatile uint32_t STA
+0x00 Status (RDY/FULL/RERR/FERR/IRQn).
Snapshot of the security / privilege attribution for one IPC channel, decoded from IPCSAR / IPCPAR.
bool privileged
true -> unprivileged, false -> privileged (IPCPAR.PAIPCIRn).
bool secure
true -> non-secure, false -> secure (IPCSAR.SAIPCIRn).
Per-channel runtime state held by the driver.
ra8_ipc_irq_slot_t per_event[k_ra8_ipc_irq_event_count]
Per-IRQ-line callback table.
bool active
true after init.
uint32_t event_mask
Filter mask.
Per-channel configuration descriptor passed to ra8_ipc_init.
bool reset_fifo
true -> issue CLR.RST during init.
uint8_t channel
Channel id 0..3.
uint32_t event_mask
Bitmask of events the user cares about.
bool clear_status
true -> clear all IRQ + error bits.
Per-IRQ-event-line callback slot.
void * ctx
Opaque context handed back to fn.
ra8_ipc_irq_fn_t fn
User callback (NULL = unused).
Per-IPC-unit ISR registration state.
bool installed
true while ra8_ipc_install_isr owns the slot.