|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
CPU0 (Cortex-M85) cache-coherency validator against CPU1 (Cortex-M33). More...
#include <stddef.h>#include <stdint.h>#include "cache_coherency_shared.h"#include "ra8_board_ek_ra8d2_peripherals.h"#include "ra8_boot_entry.h"#include "ra8_cgc.h"#include "ra8_dual_core.h"#include "ra8_err.h"#include "ra8_log.h"Go to the source code of this file.
Enumerations | |
| enum | cache_coherency_hil_const_t : uint32_t { k_cache_coherency_hil_baud = 115200U } |
| VCOM-console line rate for the deterministic HIL banner. More... | |
Functions | |
| static RA8_INTERNAL bool | internal_console_init (void) |
| Bring up the SCI8 / J-Link OB VCOM console for the HIL banner. | |
| static RA8_INTERNAL void | internal_emit_pass (void) |
| Emit the deterministic HIL success banner over the VCOM console + ITM. | |
| static RA8_INTERNAL void | internal_park_forever (void) |
| Park the M85 forever after an unrecoverable startup failure. | |
| static RA8_INTERNAL bool | internal_wait_for_pong (const volatile cache_coherency_shared_t *shared, uint32_t target) |
| Poll until pong_seq reaches target or the budget runs out. | |
| static RA8_INTERNAL void | internal_round (volatile cache_coherency_shared_t *shared, uint32_t round, uint32_t *next_seq) |
| Run one cross-core round and update the HIL counters. | |
| 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. | |
| volatile uint32_t | g_cache_coherency_match = 0U |
| HIL liveness counter – incremented on every verified M85 -> M33 -> M85 round-trip (echo == pong_base + round). | |
| volatile uint32_t | g_cache_coherency_mismatch = 0U |
| HIL failure counter – incremented whenever a round cannot complete: the bounded pong wait timed out, or the echoed payload was not pong_base + round. | |
| static const uint8_t | s_cache_coherency_pass_banner [] = "cache_coherency_hil: 8 rounds PASS\r\n" |
| Deterministic HIL success banner (uart_scrape / emulator-scrape). | |
CPU0 (Cortex-M85) cache-coherency validator against CPU1 (Cortex-M33).
This M85 image is built with RA8_BOOT_ENABLE_CACHE_MPU defined (see the per-app CMakeLists.txt), so the shared boot (system_init.c) brings up the MPU + I-cache + D-cache before main runs. With the D-cache ON, the only way a cross-core hand-off through SRAM stays coherent with the cacheless Cortex-M33 is for the shared bytes to live in a non-cacheable region – which the boot's MPU region 4 maps over 0x22100000..0x2219FFFF. This test exercises exactly that path and proves it works without any software cache maintenance.
Flow:
Two-phase loop (the design reconciles the two HIL surfaces):
Definition in file main.c.
| enum cache_coherency_hil_const_t : uint32_t |
|
static |
Bring up the SCI8 / J-Link OB VCOM console for the HIL banner.
Configures the clock tree (ra8_cgc_init) then the EK-RA8D2 debug console (ra8_board_uart_console_init at k_cache_coherency_hil_baud). Best-effort: a failure only means the additive banner cannot reach the host; the memprobe counters and the M33 hand-off are unaffected.
| true | Clock + SCI8 console are up. |
| false | A bring-up step failed (the banner is then silently skipped). |
Definition at line 148 of file main.c.
References k_cache_coherency_hil_baud, k_ra8_ok, ra8_board_uart_console_init(), ra8_cgc_init(), and RA8_INTERNAL.
|
static |
Emit the deterministic HIL success banner over the VCOM console + ITM.
Writes s_cache_coherency_pass_banner to the SCI8 / J-Link OB VCOM console and flushes it, then mirrors the same verdict over ra8_log so ra8_emulator surfaces it as an [itm] line. A no-op on the wire if the console never came up (the write returns k_ra8_err_not_initialized, ignored).
Definition at line 177 of file main.c.
References ra8_board_uart_console_flush(), ra8_board_uart_console_write(), RA8_INTERNAL, ra8_log_info, and s_cache_coherency_pass_banner.
|
static |
Park the M85 forever after an unrecoverable startup failure.
Reached only if ra8_cpu1_release fails, so the M33 never started.
Definition at line 201 of file main.c.
References RA8_INTERNAL.
|
static |
Run one cross-core round and update the HIL counters.
Writes ping_base + round (no cache clean – region 4 is non-cacheable), bumps ping_seq, waits (bounded) for the M33 echo, and verifies it equals pong_base + round. Bumps g_cache_coherency_match on success or g_cache_coherency_mismatch on a timeout / wrong echo. The two checks are split (no compound decision) so each is independently visible.
| [in] | shared | Pointer to the shared message struct (never NULL). |
| [in] | round | Zero-based round index; selects the payload values. |
| [in,out] | next_seq | Next ping_seq value to publish; advanced by one. |
Definition at line 269 of file main.c.
References g_cache_coherency_match, g_cache_coherency_mismatch, internal_wait_for_pong(), k_cache_coherency_ping_base, k_cache_coherency_pong_base, cache_coherency_shared_t::ping_payload, cache_coherency_shared_t::ping_seq, and cache_coherency_shared_t::pong_payload.
Referenced by main().
|
static |
Poll until pong_seq reaches target or the budget runs out.
Re-reads the volatile sequence field up to the fixed budget and returns immediately on the target value; a null pointer is treated as a bounded failure without dereferencing shared SRAM.
| [in] | shared | Pointer to the shared message struct (never NULL). |
| [in] | target | Sequence value to wait for (the value just written to ping_seq). |
| true | pong_seq == target was observed inside the budget. |
| false | k_cache_coherency_poll_budget iters elapsed first. |
Definition at line 231 of file main.c.
References k_cache_coherency_poll_budget, cache_coherency_shared_t::pong_seq, and RA8_INTERNAL.
Referenced by internal_round(), and main().
| void main | ( | void | ) |
CPU0 (Cortex-M85) application entry.
The application entry point Reset_Handler hands control to.
See the file header for the full behaviour summary.
Definition at line 303 of file main.c.
References g_cache_coherency_match, g_ra8_ls_cpu1_mram_start, g_ra8_ls_cpu1_stack_top, internal_console_init(), internal_emit_pass(), internal_park_forever(), internal_round(), internal_shared(), k_cache_coherency_rounds, k_ra8_board_led1, k_ra8_ok, cache_coherency_shared_t::ping_payload, cache_coherency_shared_t::ping_seq, cache_coherency_shared_t::pong_payload, cache_coherency_shared_t::pong_seq, ra8_board_led_init(), ra8_board_led_toggle(), ra8_cpu1_release(), ra8_log_info, ra8_log_info_val, and ra8_log_init().
| volatile uint32_t g_cache_coherency_match = 0U |
HIL liveness counter – incremented on every verified M85 -> M33 -> M85 round-trip (echo == pong_base + round).
Read externally by scripts/hil/jlink_memprobe.sh via SWD. The probe asserts this counter advances by >= k_cache_coherency_rounds across its sample window, proving the Cortex-M33 was released and is servicing the non-cacheable shared block coherently with the M85 D-cache on. If the shared region were cacheable, a stale M85 read would land in g_cache_coherency_mismatch instead.
Definition at line 96 of file main.c.
Referenced by internal_round(), and main().
| volatile uint32_t g_cache_coherency_mismatch = 0U |
HIL failure counter – incremented whenever a round cannot complete: the bounded pong wait timed out, or the echoed payload was not pong_base + round.
The memprobe asserts this stays at 0. On silicon with the D-cache on and a (wrongly) cacheable shared region this would climb as the M85 reads stale pong values; the non-cacheable region 4 keeps it at 0.
Definition at line 113 of file main.c.
Referenced by internal_round().
|
extern |
Base of the embedded M33 image / its vector table (MRAM_CPU1).
|
extern |
Initial stack pointer handed to the M33 at release.
|
static |
Deterministic HIL success banner (uart_scrape / emulator-scrape).
Emitted once, after k_cache_coherency_rounds rounds verify, on the success path only. Additive to the ra8_log ITM trace so a rig with no SWO capture can still gate the boot + cache + dual-core path.
Definition at line 126 of file main.c.
Referenced by internal_emit_pass().