ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
cpu1_main.c
Go to the documentation of this file.
1
23
24#include <stdint.h>
25
27
28extern uint32_t g_ra8_ls_cpu1_stack_top;
29extern uint32_t g_ra8_ls_cpu1_data_start;
30extern uint32_t g_ra8_ls_cpu1_data_end;
31extern uint32_t g_ra8_ls_cpu1_data_load;
32extern uint32_t g_ra8_ls_cpu1_bss_start;
33extern uint32_t g_ra8_ls_cpu1_bss_end;
34
35[[noreturn]] void cpu1_reset_handler(void);
36
48[[noreturn]] RA8_INTERNAL static void internal_cpu1_main(void)
49{
50 volatile cache_coherency_shared_t* shared = internal_shared();
51 uint32_t last_observed = 0U;
52
53 while (1) {
54 /* Spin until CPU0 bumps the ping sequence. The reads are volatile,
55 * so the compiler emits a fresh load each iteration. */
56 while (shared->ping_seq == last_observed) {
57 __asm volatile("nop");
58 }
59 last_observed = shared->ping_seq;
60
61 /* Read the payload after the sequence advance, transform it by the
62 * fixed delta, and ack. The cacheless M33 sees SRAM directly; the
63 * M85 side keeps coherency via its non-cacheable MPU region. */
64 uint32_t got = shared->ping_payload;
65 shared->pong_payload = got + (uint32_t)k_cache_coherency_delta;
66 __asm volatile("dsb" ::: "memory");
67 shared->pong_seq = last_observed;
68 }
69}
70
90[[noreturn]] void cpu1_reset_handler(void)
91{
92 /* Copy .data from MRAM_CPU1 load address into SRAM_CPU1. */
93 uint32_t* dst = &g_ra8_ls_cpu1_data_start;
94 uint32_t* src = &g_ra8_ls_cpu1_data_load;
95 while (dst < &g_ra8_ls_cpu1_data_end) {
96 *dst = *src;
97 dst++;
98 src++;
99 }
100 /* Zero .bss in SRAM_CPU1. */
101 uint32_t* bss = &g_ra8_ls_cpu1_bss_start;
102 while (bss < &g_ra8_ls_cpu1_bss_end) {
103 *bss = 0U;
104 bss++;
105 }
107}
108
119[[noreturn]] RA8_INTERNAL static void internal_fault_handler(void)
120{
121 while (1) {
122 __asm volatile("nop");
123 }
124}
125
134#ifndef RA8_OFF_TARGET
135/* Vector table only built for the cross-compiled M33 image. The host
136 * build does not link this TU as an executable -- it is compile-checked
137 * only -- so we can drop the table without losing test coverage. */
138[[gnu::used, gnu::section(".cpu1_vectors")]] const uintptr_t g_cpu1_vector_table[] = {
139 (uintptr_t)&g_ra8_ls_cpu1_stack_top,
140 (uintptr_t)&cpu1_reset_handler,
141 (uintptr_t)&internal_fault_handler,
142 (uintptr_t)&internal_fault_handler,
143 (uintptr_t)&internal_fault_handler,
144 (uintptr_t)&internal_fault_handler,
145 (uintptr_t)&internal_fault_handler,
146 (uintptr_t)&internal_fault_handler,
147};
148#endif
Shared-SRAM message layout for the M85<->M33 cache-coherency HIL test.
@ k_cache_coherency_delta
pong_base - ping_base (CPU1 add).
static volatile cache_coherency_shared_t * internal_shared(void)
Typed pointer to the fixed-address shared message block.
void cpu1_reset_handler(void)
CPU1 reset handler.
Definition cpu1_main.c:266
uint32_t g_ra8_ls_cpu1_data_end
uint32_t g_ra8_ls_cpu1_bss_start
uint32_t g_ra8_ls_cpu1_data_load
static void internal_cpu1_main(void)
Run the CPU1 side of the ping-pong exchange.
Definition cpu1_main.c:204
uint32_t g_ra8_ls_cpu1_bss_end
const uintptr_t g_cpu1_vector_table[]
Minimal Armv8-M vector table for CPU1.
Definition cpu1_main.c:337
uint32_t g_ra8_ls_cpu1_stack_top
uint32_t g_ra8_ls_cpu1_data_start
static void internal_fault_handler(void)
Default fault handler.
Definition cpu1_main.c:119
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Cross-CPU message struct backed by a fixed non-cacheable SRAM address.
volatile uint32_t ping_payload
CPU0 writes ping_base + r, CPU1 reads.
volatile uint32_t ping_seq
CPU0 increments after writing payload.
volatile uint32_t pong_seq
CPU1 sets to match ping_seq after reply.
volatile uint32_t pong_payload
CPU1 writes ping_payload + delta.