ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1
44
45#include <stdint.h>
46
47#include "ra8_attributes.h"
48#include "ra8_board_ek_ra8d2.h"
49#include "ra8_boot_entry.h"
50#include "ra8_cgc.h"
51#include "ra8_device.h"
52#include "ra8_err.h"
53#include "ra8_npu.h"
54#include "ra8_npu_blob.h"
55#include "ra8_npu_fake_cmd.h"
56#include "ra8_npu_loader.h"
58#include "ra8_npu_regs.h"
59
60#ifndef RA8_HAS_NPU
61#error "npu_vela must be built with cmake/toolchain-ra8p1.cmake (RA8_DEVICE_RA8P1)."
62#endif
63
77
82typedef enum : uint32_t {
83 k_npu_vela_fnv_offset = 0x811C9DC5U,
84 k_npu_vela_fnv_prime = 0x01000193U,
86
96
104volatile uint32_t g_npu_vela_id = 0U;
105
113volatile uint32_t g_npu_vela_check = 0U;
114
122volatile uint32_t g_npu_vela_pass = 0U;
123
139{
140 while (1) {
141 __asm__ volatile("wfi");
142 }
143}
144
161{
162 while (1) {
163 __asm__ volatile("wfi");
164 }
165}
166
189
209{
210 return ra8_npu_blob_read_word((const uint8_t*)job->cmd_stream,
211 (uint32_t)widx * (uint32_t)k_npu_vela_word_bytes);
212}
213
235RA8_INTERNAL static bool internal_npu_vela_verify(const ra8_npu_job_t* job, uint32_t* out_check)
236{
237 const uint8_t* input = (const uint8_t*)(uintptr_t)job->region_base[k_ra8_npu_region_1];
238 const uint8_t* output = (const uint8_t*)(uintptr_t)job->region_base[k_ra8_npu_region_2];
239 const uint32_t konst = internal_npu_vela_cmd_word(job, k_ra8_npu_fake_word_const);
240 const uint32_t count = internal_npu_vela_cmd_word(job, k_ra8_npu_fake_word_count);
241 uint32_t check = (uint32_t)k_npu_vela_fnv_offset;
242 bool ok = true;
243 for (uint32_t i = 0U; i < count; i++) {
244 const uint8_t expected = (uint8_t)((input[i] + konst) & (uint32_t)k_npu_vela_byte_mask);
245 if (output[i] != expected) {
246 ok = false;
247 }
248 check = (check ^ (uint32_t)output[i]) * (uint32_t)k_npu_vela_fnv_prime;
249 }
250 *out_check = check;
251 return ok;
252}
253
272{
273 const ra8_npu_arena_t arena = {.base = s_npu_vela_arena, .bytes = (uint32_t)k_npu_vela_arena};
274 const ra8_err_t ld =
276 if (ld != k_ra8_ok) {
277 return ld;
278 }
279 const ra8_err_t sub = ra8_npu_submit(out_job);
280 if (sub != k_ra8_ok) {
281 return sub;
282 }
283 const ra8_err_t run = ra8_npu_run();
284 if (run != k_ra8_ok) {
285 return run;
286 }
287 return ra8_npu_wait();
288}
289
290RA8_INTERNAL static void internal_npu_vela_write(const uint8_t* data, size_t len)
291{
292 (void)ra8_board_uart_console_write(data, len);
293}
294
296{
297 static const uint8_t k_hex[] = "0123456789ABCDEF";
298 uint8_t digits[k_npu_vela_hex_digits] = {};
299 for (uint8_t i = 0U; i < (uint8_t)k_npu_vela_hex_digits; ++i) {
300 const uint8_t shift =
301 (uint8_t)(((uint8_t)k_npu_vela_hex_digits - 1U - i) * (uint8_t)k_npu_vela_hex_shift);
302 digits[i] = k_hex[(value >> shift) & (uint32_t)k_npu_vela_hex_mask];
303 }
305}
306
308{
309 const uint8_t* text = ok ? (const uint8_t*)"OK" : (const uint8_t*)"FAIL";
310 const size_t len = ok ? 2U : 4U;
311 internal_npu_vela_write(text, len);
312}
313
315{
316 const uint8_t* text = pass ? (const uint8_t*)"PASS" : (const uint8_t*)"FAIL";
317 internal_npu_vela_write(text, 4U);
318}
319
340RA8_INTERNAL static void
341internal_npu_vela_emit(uint32_t id, bool load_ok, bool run_ok, uint32_t check, bool pass)
342{
343 internal_npu_vela_write((const uint8_t*)"npu-vela: id=0x", sizeof("npu-vela: id=0x") - 1U);
345 internal_npu_vela_write((const uint8_t*)" load=", sizeof(" load=") - 1U);
347 internal_npu_vela_write((const uint8_t*)" run=", sizeof(" run=") - 1U);
349 internal_npu_vela_write((const uint8_t*)" out=0x", sizeof(" out=0x") - 1U);
351 internal_npu_vela_write((const uint8_t*)" verdict=", sizeof(" verdict=") - 1U);
353 internal_npu_vela_write((const uint8_t*)"\r\n", sizeof("\r\n") - 1U);
355}
356
364void main(void)
365{
367
368 bool load_ok = false;
369 bool run_ok = false;
370 uint32_t id = 0U;
371 uint32_t check = 0U;
372 bool pass = false;
373
374 if (ra8_npu_init() == k_ra8_ok) {
375 (void)ra8_npu_read_id(&id);
376 g_npu_vela_id = id;
377
378 ra8_npu_job_t job = {};
379 const ra8_err_t rc = internal_npu_vela_run_job(&job);
380 load_ok = (job.cmd_stream != nullptr); /* load leaves it null on failure */
381 run_ok = (rc == k_ra8_ok);
382
383 /* Gate verify on load_ok as well: a successful run implies the load
384 * populated cmd_stream, but stating it explicitly lets the static analyzer
385 * see that internal_npu_vela_verify() never dereferences a null cmd_stream. */
386 const bool matched = run_ok && load_ok && internal_npu_vela_verify(&job, &check);
388 pass = load_ok && run_ok && matched && (id != 0U);
389 }
390
391 g_npu_vela_pass = pass ? 1U : 0U;
392 internal_npu_vela_emit(id, load_ok, run_ok, check, pass);
393
395}
void main(void)
Secure fallback main entry point.
Definition main.c:37
static void internal_npu_vela_panic_halt(void)
Park the CPU forever in WFI after a fatal init error (a real panic).
Definition main.c:138
npu_vela_fnv_t
FNV-1a 32-bit constants for the displayed output checkword.
Definition main.c:82
@ k_npu_vela_fnv_prime
FNV-1a 32-bit prime.
Definition main.c:84
@ k_npu_vela_fnv_offset
FNV-1a 32-bit offset basis.
Definition main.c:83
static void internal_npu_vela_write(const uint8_t *data, size_t len)
Definition main.c:290
static void internal_npu_vela_emit(uint32_t id, bool load_ok, bool run_ok, uint32_t check, bool pass)
Print the one-line verdict banner over the SCI8 console.
Definition main.c:341
npu_vela_size_t
Console baud, runtime-arena size, banner width, and word geometry.
Definition main.c:68
@ k_npu_vela_hex_digits
Fixed-width hexadecimal word digits.
Definition main.c:73
@ k_npu_vela_word_bytes
Bytes in one little-endian word.
Definition main.c:71
@ k_npu_vela_arena
Runtime arena for output activation.
Definition main.c:70
@ k_npu_vela_baud
SCI8 J-Link OB console baud.
Definition main.c:69
@ k_npu_vela_byte_mask
8-bit element wrap (matches the op).
Definition main.c:72
@ k_npu_vela_hex_shift
Bits per hexadecimal nibble.
Definition main.c:74
@ k_npu_vela_hex_mask
Mask for one hexadecimal nibble.
Definition main.c:75
volatile uint32_t g_npu_vela_check
Output checkword captured after verify, for external inspection.
Definition main.c:113
static void internal_npu_vela_write_verdict(bool pass)
Definition main.c:314
volatile uint32_t g_npu_vela_pass
Final verdict (1 = PASS, 0 = FAIL), for external inspection.
Definition main.c:122
static uint8_t s_npu_vela_arena[k_npu_vela_arena]
Runtime arena the loader carves the output activation from.
Definition main.c:95
static uint32_t internal_npu_vela_cmd_word(const ra8_npu_job_t *job, ra8_npu_fake_word_idx_t widx)
Read a little-endian command-stream word from the loaded job.
Definition main.c:207
static void internal_npu_vela_park(void)
Park the CPU forever in WFI after the verdict banner (a clean stop).
Definition main.c:160
static void internal_npu_vela_write_hex32(uint32_t value)
Definition main.c:295
volatile uint32_t g_npu_vela_id
NPU_ID captured after init, for external (J-Link) inspection.
Definition main.c:104
static ra8_err_t internal_npu_vela_run_job(ra8_npu_job_t *out_job)
Load the golden blob, submit + run + wait for the NPU job.
Definition main.c:271
static void internal_npu_vela_setup_or_halt(void)
Bring up CGC + the SCI8 console.
Definition main.c:180
static bool internal_npu_vela_verify(const ra8_npu_job_t *job, uint32_t *out_check)
Verify the output arena equals input+K and fold it into a checkword.
Definition main.c:235
static void internal_npu_vela_write_status(bool ok)
Definition main.c:307
-copyright
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
ra8_err_t ra8_board_uart_console_write(const uint8_t *data, size_t len)
Polled blocking write to the J-Link OB VCOM console.
ra8_err_t ra8_board_uart_console_init(uint32_t baud)
Configure SCI8 + PD02/PD03 as the debug-console UART.
ra8_err_t ra8_board_uart_console_flush(void)
Block until every byte queued on the J-Link OB VCOM console has finished clocking out on the wire.
Boot entry points shared between a vector table and its startup code.
High-level Clock Generation Circuit driver.
ra8_err_t ra8_cgc_init(void)
Configure the clock tree to a safe default.
Definition ra8_cgc.c:727
Compile-time device selection for the RA8 multi-chip build (RA8D2 / RA8P1).
Error Code Definitions for ra8-firmware.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Arm Ethos-U55 NPU command/queue driver foundation (RA8P1-only).
ra8_err_t ra8_npu_submit(const ra8_npu_job_t *job)
Program the command queue and tensor region base pointers for a job.
ra8_err_t ra8_npu_run(void)
Kick the currently-submitted job (transition the NPU to running).
ra8_err_t ra8_npu_read_id(uint32_t *out_id)
Read the Ethos-U55 NPU_ID (architecture / product revision) register.
ra8_err_t ra8_npu_init(void)
Bring the NPU out of module-stop and soft-reset it.
ra8_err_t ra8_npu_wait(void)
Bounded busy-wait until the running job completes or faults.
.npub linkable-blob container for a Vela-compiled Ethos-U55 model
static uint32_t ra8_npu_blob_read_word(const uint8_t *buf, uint32_t byte_off)
Read one little-endian 32-bit word from a .npub byte buffer.
ra8_emulator / host-test command-stream convention for the Ethos-U55 model
ra8_npu_fake_word_idx_t
32-bit word indices of the fixed stand-in command-stream header.
@ k_ra8_npu_fake_word_count
Byte count to process.
@ k_ra8_npu_fake_word_const
Constant addend (add-constant op).
On-target loader: .npub Vela blob -> ra8_npu_job_t (RA8P1-only).
ra8_err_t ra8_npu_load(const void *blob, uint32_t blob_bytes, const ra8_npu_arena_t *arena, ra8_npu_job_t *out_job)
Validate a .npub blob and map it into an ra8_npu_job_t.
static uint32_t ra8_npu_model_addk_fake_bytes(void)
Byte length of the 'addk_fake' .npub blob.
static const uint8_t * ra8_npu_model_addk_fake_blob(void)
Base pointer of the 'addk_fake' .npub blob.
Arm Ethos-U55 NPU register window on the Renesas RA8P1 (RA8P1-only).
@ k_ra8_npu_region_2
AXI region 2.
@ k_ra8_npu_region_1
AXI region 1.
Caller-provided runtime arena for a model's RUNTIME regions.
One Ethos-U55 inference job: a command stream plus its tensor arenas.
Definition ra8_npu.h:87
uint64_t region_base[k_ra8_npu_region_count]
AXI base of each BASEPn arena.
Definition ra8_npu.h:91
const void * cmd_stream
Vela command stream base in SRAM.
Definition ra8_npu.h:88