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
18
19#include <stdint.h>
20
21#include "ra8_err.h"
22#include "shared_pingpong.h"
23
24extern uint32_t g_ra8_ls_cpu1_stack_top;
25extern uint32_t g_ra8_ls_cpu1_data_start;
26extern uint32_t g_ra8_ls_cpu1_data_end;
27extern uint32_t g_ra8_ls_cpu1_data_load;
28extern uint32_t g_ra8_ls_cpu1_bss_start;
29extern uint32_t g_ra8_ls_cpu1_bss_end;
30
31[[noreturn]] void cpu1_reset_handler(void);
32
43[[noreturn]] RA8_INTERNAL static void internal_cpu1_main(void)
44{
45 volatile cpu1_pingpong_shared_t* shared = internal_shared();
46 uint32_t last_observed = 0U;
47
48 while (1) {
49 /* Spin until CPU0 bumps the ping sequence. The reads are volatile,
50 * so the compiler emits a fresh load each iteration. */
51 while (shared->ping_seq == last_observed) {
52 __asm volatile("nop");
53 }
54 last_observed = shared->ping_seq;
55
56 /* Read the payload after the sequence advance so we know CPU0's
57 * write of the payload preceded its sequence bump. */
58 uint32_t got = shared->ping_payload;
59 if (got != (uint32_t)k_cpu1_pingpong_magic_ping) {
60 /* Wrong magic -- still ack so CPU0's poll doesn't block. CPU0
61 * will count the mismatch via the payload check on its side. */
62 shared->pong_payload = 0U;
63 } else {
64 shared->pong_payload = (uint32_t)k_cpu1_pingpong_magic_pong;
65 }
66 __asm volatile("dsb" ::: "memory");
67 shared->pong_seq = last_observed;
68 }
69}
70
99[[noreturn]] void cpu1_reset_handler(void)
100{
101 /* Copy .data from MRAM_CPU1 load address into SRAM_CPU1. The linker
102 * defines ``g_ra8_ls_cpu1_data_load`` as LOADADDR(.data) so this
103 * works regardless of the absolute MRAM_CPU1 base. */
104 uint32_t* dst = &g_ra8_ls_cpu1_data_start;
105 uint32_t* src = &g_ra8_ls_cpu1_data_load;
106 while (dst < &g_ra8_ls_cpu1_data_end) {
107 *dst = *src;
108 dst++;
109 src++;
110 }
111 /* Zero .bss in SRAM_CPU1. */
112 uint32_t* bss = &g_ra8_ls_cpu1_bss_start;
113 while (bss < &g_ra8_ls_cpu1_bss_end) {
114 *bss = 0U;
115 bss++;
116 }
118}
119
130[[noreturn]] RA8_INTERNAL static void internal_fault_handler(void)
131{
132 while (1) {
133 __asm volatile("nop");
134 }
135}
136
145#ifndef RA8_OFF_TARGET
146/* Vector table only built for the cross-compiled M33 image. The host
147 * build does not link this TU as an executable -- it is compile-checked
148 * only -- so we can drop the table without losing test coverage. */
149[[gnu::used, gnu::section(".cpu1_vectors")]] const uintptr_t g_cpu1_vector_table[] = {
150 (uintptr_t)&g_ra8_ls_cpu1_stack_top,
151 (uintptr_t)&cpu1_reset_handler,
152 (uintptr_t)&internal_fault_handler,
153 (uintptr_t)&internal_fault_handler,
154 (uintptr_t)&internal_fault_handler,
155 (uintptr_t)&internal_fault_handler,
156 (uintptr_t)&internal_fault_handler,
157 (uintptr_t)&internal_fault_handler,
158};
159#endif
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
@ k_cpu1_pingpong_magic_ping
Cpu1 pingpong magic ping.
Definition cpu1_main.c:32
@ k_cpu1_pingpong_magic_pong
Cpu1 pingpong magic pong.
Definition cpu1_main.c:33
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).
Error Code Definitions for ra8-firmware.
Shared-SRAM message layout for the CPU0 <-> CPU1 ping-pong demo.
Cross-CPU message struct backed by a fixed SRAM address.
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 ping_payload
CPU0 writes, CPU1 reads.
volatile uint32_t pong_payload
CPU1 writes, CPU0 reads.