|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
CPU0 (Cortex-M85 primary core) driver: stage an EPUB, offload its compile to the M33. More...
#include <stddef.h>#include <stdint.h>#include <string.h>#include "book.h"#include "compile_on_m33.h"#include "parity_fixture.h"#include "ra8_attributes.h"#include "ra8_boot_entry.h"#include "ra8_dual_core.h"#include "ra8_err.h"#include "ra8_ipc.h"#include "ra8_isr.h"#include "ra8_log.h"Go to the source code of this file.
Enumerations | |
| enum | m85_poll_t : uint32_t { k_m85_sig_poll_budget = 10000000UL , k_m85_done_poll_budget = 50000000UL } |
| Bounded iteration limits for the M85 polling loops. More... | |
| enum | m85_ipc_t : uint8_t { k_ipc_wake_channel = 0U } |
| IPC channel the M85 watches for the M33's compile-done wake. More... | |
Functions | |
| static void | ipc_wake_handler (void *ctx, uint8_t channel, ra8_ipc_irq_event_id_t event_id) |
| IPC0 receive event callback: record that the M33's wake poke arrived. | |
| static void | ipc0_receive_isr (void *ctx) |
| IPC0 receive ISR trampoline: decode the channel's pending events. | |
| static bool | arm_ipc_wake (void) |
| Arm the IPC0 receive interrupt so the M85 can WFI-idle for the M33. | |
| static void | prep_mailbox (volatile com33_mailbox_t *mb) |
| Publish the mailbox, stage the source .epub, and post the compile job. | |
| static bool | wait_for_m33_sig (const volatile com33_mailbox_t *mb) |
| Poll the mailbox until the M33 stamps its boot signature. | |
| static bool | wait_for_done (const volatile com33_mailbox_t *mb) |
| Idle in WFI until the M33's IPC poke signals the done flag. | |
| static bool | verify_blob (volatile com33_mailbox_t *mb) |
| Validate the M33-emitted blob and cross-check the mailbox report. | |
| static void | park_forever (void) |
| Park the M85 forever after the verdict (or an unrecoverable failure). | |
| void | main (void) |
| CPU0 (Cortex-M85) application entry. | |
Variables | |
| uint32_t | g_ra8_ls_cpu1_mram_start |
| Base of the embedded M33 image / its vector table (MRAM_CPU1). | |
| uint32_t | g_ra8_ls_cpu1_stack_top |
| Initial stack pointer handed to the M33 at release. | |
| static volatile bool | s_m33_woke |
| Set by the IPC0 receive callback when the M33 signals compile-done. | |
CPU0 (Cortex-M85 primary core) driver: stage an EPUB, offload its compile to the M33.
This is the firmware that runs on the RA8D2's primary core, the Cortex-M85, out of reset. It demonstrates the #149 compiler offload: the M85 stages a book and hands the full EPUB->.rabook conversion to the M33 @ 250 MHz, so on a real import the M85 @ 1 GHz stays free to keep the UI live while the slow core grinds.
What the M85 does here:
ra8_emulator echoes only the primary core's ITM, so the M85 narrates the whole exchange; the blob it validates can only exist because the M33 ran the compile, so a PASS here proves the conversion ran byte-identically on the second core.
Definition in file main.c.
| enum m85_ipc_t : uint8_t |
IPC channel the M85 watches for the M33's compile-done wake.
The M33 (CPU1) pokes IPC0 channel 0 (the CPU1 -> CPU0 receive direction); the M85 arms this channel's IRQ-line-0 receive event so it can WFI-idle until the poke instead of busy-polling the mailbox.
| Enumerator | |
|---|---|
| k_ipc_wake_channel | IPC0 channel 0 (CPU1 -> CPU0 receive side). |
| enum m85_poll_t : uint32_t |
Bounded iteration limits for the M85 polling loops.
Large enough that a normally-running M33 always finishes the small emit within budget, yet finite so the M85 never hangs if the M33 does not boot. ra8_emulator interleaves the cores in instruction chunks, so the whole emit lands in a few dozen interleaves – far inside these.
| Enumerator | |
|---|---|
| k_m85_sig_poll_budget | Max iters waiting for M33 signature. |
| k_m85_done_poll_budget | Max iters waiting for M33 done flag. |
|
static |
Arm the IPC0 receive interrupt so the M85 can WFI-idle for the M33.
Initialises the ISR substrate, configures IPC0 channel 0 for the IRQ-line-0 event, attaches ipc_wake_handler to that line, routes the k_ra8_ipc_elc_event_irq0 ELC event to ipc0_receive_isr through the NVIC, then unmasks interrupts globally. Each step is its own guarded return so the failing stage is unambiguous (no compound decisions).
| true | IPC0 RX IRQ is routed, attached, and interrupts are enabled. |
| false | A setup stage failed; the caller should fall back to polling. |
Definition at line 170 of file main.c.
References ipc0_receive_isr(), ipc_wake_handler(), k_ipc_wake_channel, k_ra8_ipc_elc_event_irq0, k_ra8_ipc_event_irq0, k_ra8_ipc_irq_event_0, k_ra8_isr_prio_default, k_ra8_ok, ra8_ipc_attach_event_handler(), ra8_ipc_init(), ra8_isr_globals_enable(), ra8_isr_init(), and ra8_isr_register().
Referenced by main().
|
static |
IPC0 receive ISR trampoline: decode the channel's pending events.
| [in] | ctx | Unused registration context. |
Definition at line 143 of file main.c.
References k_ipc_wake_channel, and ra8_ipc_dispatch().
Referenced by arm_ipc_wake().
|
static |
IPC0 receive event callback: record that the M33's wake poke arrived.
| [in] | ctx | Unused registration context. |
| [in] | channel | Channel that fired (always k_ipc_wake_channel here). |
| [in] | event_id | IRQ line that fired (always line 0 here). |
Definition at line 120 of file main.c.
References s_m33_woke.
Referenced by arm_ipc_wake().
| void main | ( | void | ) |
CPU0 (Cortex-M85) application entry.
The application entry point Reset_Handler hands control to.
Publishes the mailbox, releases the Cortex-M33 into the emitter, yields until it signals done, validates the blob the M33 built, then logs the PASS/FAIL verdict and the chapter count read back from the blob. See the file header for the offload narrative.
Definition at line 423 of file main.c.
References arm_ipc_wake(), com33_mailbox_t::blob_len, com33_mailbox_t::chapter_count, com33_mailbox(), g_ra8_ls_cpu1_mram_start, g_ra8_ls_cpu1_stack_top, k_ra8_ok, park_forever(), prep_mailbox(), ra8_cpu1_release(), ra8_log_info, ra8_log_info_val, ra8_log_init(), com33_mailbox_t::status, verify_blob(), wait_for_done(), and wait_for_m33_sig().
|
static |
Park the M85 forever after the verdict (or an unrecoverable failure).
|
static |
Publish the mailbox, stage the source .epub, and post the compile job.
Zeros the response fields and stamps k_com33_magic, then copies the baked parity fixture .epub into the shared staged-input buffer, fills the request (epub base/len, output base/cap), and stamps k_com33_req_magic LAST behind a dsb so the M33 sees the job only once the staged bytes settle. The M33 compiles whatever is staged, so the same image serves any dispatched book.
| [out] | mb | Pointer to the shared mailbox (never NULL). |
mb is the fixed-address mailbox pointer. Definition at line 223 of file main.c.
References com33_mailbox_t::blob_base, com33_mailbox_t::blob_crc, com33_mailbox_t::blob_len, com33_mailbox_t::chapter_count, com33_epub(), com33_mailbox_t::done, com33_mailbox_t::epub_base, com33_mailbox_t::epub_len, k_com33_blob_addr, k_com33_blob_cap, k_com33_epub_addr, k_com33_magic, k_com33_req_magic, k_com33_status_running, k_m33_parity_epub_len, com33_mailbox_t::m33_sig, com33_mailbox_t::magic, memcpy(), com33_mailbox_t::out_base, com33_mailbox_t::out_cap, com33_mailbox_t::req_magic, s_m33_parity_epub, and com33_mailbox_t::status.
Referenced by main().
|
static |
Validate the M33-emitted blob and cross-check the mailbox report.
Confirms the M33 reported success and a plausible blob location, runs book_validate over the shared blob (magic, version, table extents, and the body CRC-32 – an independent recompute that catches any transfer corruption), then cross-checks that the blob header's CRC and chapter count match what the M33 published in the mailbox. Each check is an independent guard (no compound decisions) so the failing condition is unambiguous.
| [in] | mb | Pointer to the shared mailbox (never NULL, done == 1). |
| true | Status ok, blob validated, and CRC + chapter count agree. |
| false | Any check failed; the blob must not be treated as valid. |
mb is the fixed-address mailbox pointer and the M33 set done. Definition at line 346 of file main.c.
References com33_mailbox_t::blob_base, com33_mailbox_t::blob_crc, com33_mailbox_t::blob_len, book_header(), book_validate(), book_header_t::chapter_count, com33_mailbox_t::chapter_count, book_header_t::crc32_val, k_com33_blob_addr, k_com33_blob_cap, k_com33_status_ok, k_m33_parity_golden_len, k_ra8_ok, memcmp(), s_m33_parity_golden, and com33_mailbox_t::status.
Referenced by main().
|
static |
Idle in WFI until the M33's IPC poke signals the done flag.
Each iteration checks the mailbox done flag and, if it is not yet set, drops into wfi. The M33's compile-done poke of IPC0ISET0 raises the armed IPC0 receive interrupt (see arm_ipc_wake) which wakes the core; the loop then observes the done the M33 ordered ahead of the poke. The bounded count is the NASA Rule 2 backstop for a missed wake.
| [in] | mb | Pointer to the shared mailbox (never NULL). |
| true | done == 1 within k_m85_done_poll_budget iterations. |
| false | Poll budget exhausted before done was set. |
mb is the fixed-address mailbox pointer. Definition at line 304 of file main.c.
References com33_mailbox_t::done, k_m85_done_poll_budget, and RA8_LOOP_BOUND.
Referenced by main().
|
static |
Poll the mailbox until the M33 stamps its boot signature.
| [in] | mb | Pointer to the shared mailbox (never NULL). |
| true | m33_sig == k_com33_m33_sig within k_m85_sig_poll_budget. |
| false | Poll budget exhausted before the signature appeared. |
mb is the fixed-address mailbox pointer. Definition at line 269 of file main.c.
References k_com33_m33_sig, k_m85_sig_poll_budget, com33_mailbox_t::m33_sig, and RA8_LOOP_BOUND.
Referenced by main().
|
extern |
Base of the embedded M33 image / its vector table (MRAM_CPU1).
|
extern |
Initial stack pointer handed to the M33 at release.
|
static |
Set by the IPC0 receive callback when the M33 signals compile-done.
The WFI idle loop reads this only as a diagnostic wake hint; the authoritative exit condition remains the mailbox done flag, which the M33 publishes (and orders with a dsb) before it pokes the IPC, so a wake always observes a settled done.
Definition at line 101 of file main.c.
Referenced by ipc_wake_handler().