ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
cache_coherency_shared.h File Reference

Shared-SRAM message layout for the M85<->M33 cache-coherency HIL test. More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_board_ek_ra8d2_dualcore.h"
Include dependency graph for cache_coherency_shared.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  cache_coherency_shared_t
 Cross-CPU message struct backed by a fixed non-cacheable SRAM address. More...

Enumerations

enum  cache_coherency_addr_t : uintptr_t { k_cache_coherency_shared_addr }
 Where this app puts its shared block inside the board's window. More...
enum  cache_coherency_shared_const_t : uint32_t {
  k_cache_coherency_ping_base = 0x1234U ,
  k_cache_coherency_pong_base = 0x4321U ,
  k_cache_coherency_delta = 0x30EDU ,
  k_cache_coherency_rounds = 8UL ,
  k_cache_coherency_poll_budget = 2000000UL ,
  k_cache_coherency_align_bytes = 32UL
}
 Compile-time magics + budgets for the shared block. More...

Functions

static volatile cache_coherency_shared_tinternal_shared (void)
 Typed pointer to the fixed-address shared message block.

Detailed Description

Shared-SRAM message layout for the M85<->M33 cache-coherency HIL test.

Tag
[Ring 6 / APP] {World: NS}

This app proves that the Cortex-M85 (CPU0) and Cortex-M33 (CPU1) stay coherent across the shared on-chip SRAM bank with the M85 D-cache ENABLED, by routing every cross-core hand-off through the non-cacheable MPU region (region 4) that the shared boot maps over 0x22100000..0x2219FFFF when RA8_BOOT_ENABLE_CACHE_MPU is set (see libs/ra8_board_ek_ra8d2/src/boot/system_init.c).

Like cpu1_pingpong, the cross-core channel is a small message struct pinned at the start of the upper on-chip SRAM region (0x22100000 = SRAM2), just above CPU0's allocated SRAM (which ends at 0x22100000) and below CPU1's dedicated 64 KiB bank at the top of SRAM (0x22190000..0x221A0000). Both CPUs' linker scripts leave 0x22100000 unclaimed, so the same physical bytes back the same struct on both sides. The IPC peripheral is intentionally NOT used (CPU1 has SECEXT disabled and IPC channel attribution is mutually exclusive S xor NS – see cpu1_pingpong for the full rationale).

Protocol (monotonic sequence counters carry the wakeup signal; the payload words carry the data being checked end-to-end):

  1. CPU0 writes ping_payload = k_cache_coherency_ping_base + r, issues DSB, increments ping_seq.
  2. CPU1 spins on ping_seq; on each advance it reads ping_payload, writes the transformed echo pong_payload = ping_payload + k_cache_coherency_delta, issues DSB, and sets pong_seq = ping_seq.
  3. CPU0 spins on pong_seq; on each advance it verifies pong_payload == k_cache_coherency_pong_base + r.

Because the struct lives in the non-cacheable region, no manual ra8_cache_dcache_clean_by_addr / ..._invalidate_by_addr dance (ra8_cache.h) is needed even though the M85 D-cache is on: a cacheable placement would let the M85 read a stale pong_payload out of its own dirty/clean line (or hide its ping_payload write from the cacheless M33), and the test would log a mismatch. The non-cacheable region is exactly what removes that hazard.

Definition in file cache_coherency_shared.h.

Enumeration Type Documentation

◆ cache_coherency_addr_t

enum cache_coherency_addr_t : uintptr_t

Where this app puts its shared block inside the board's window.

The block sits at the base of the CPU0 <-> CPU1 window, which the boot MPU marks Normal non-cacheable – the property this test exercises. The window itself is a board fact, declared once in ra8_board_ek_ra8d2_dualcore.h along with why both linker scripts leave it free; this app only names its own slice of it.

Invariant
The address is 32-byte (cache-line) aligned; asserted below.
See also
ra8_board_dualcore_addr_t
Since
0.1.0
Enumerator
k_cache_coherency_shared_addr 

Shared block = window base.

Definition at line 76 of file cache_coherency_shared.h.

◆ cache_coherency_shared_const_t

Compile-time magics + budgets for the shared block.

The payload check is data-carrying, not a constant magic: CPU0 sends ping_base + r for round r and expects pong_base + r back, where pong_base - ping_base == k_cache_coherency_delta. CPU1 produces that by adding the fixed delta to whatever it reads, so a stale/garbage read on either side surfaces as a payload mismatch.

Enumerator
k_cache_coherency_ping_base 

CPU0 round-0 ping payload.

k_cache_coherency_pong_base 

Expected round-0 pong payload.

k_cache_coherency_delta 

pong_base - ping_base (CPU1 add).

k_cache_coherency_rounds 

Verified rounds before PASS.

k_cache_coherency_poll_budget 

Max spin iters per direction.

k_cache_coherency_align_bytes 

Cache-line / region quantum.

Definition at line 92 of file cache_coherency_shared.h.

Function Documentation

◆ internal_shared()

volatile cache_coherency_shared_t * internal_shared ( void )
inlinestatic

Typed pointer to the fixed-address shared message block.

Inlined so both CPUs land on identical addressing without needing a separate translation unit.

Returns
Pointer to the shared struct at k_cache_coherency_shared_addr.
Precondition
None.
Module state is consistent.
Postcondition
Returns a valid volatile pointer; never NULL.
No side effects.
Note
Both CPUs call this; the pointer arithmetic is identical.
Since
0.1.0

Definition at line 155 of file cache_coherency_shared.h.

References k_cache_coherency_shared_addr, and RA8_INTERNAL.

Referenced by internal_cpu1_main(), and main().