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
43
44#include <stddef.h>
45#include <stdint.h>
46#include <string.h>
47
48#include "ra8_arena.h"
49#include "ra8_board_ek_ra8d2.h"
50#include "ra8_boot_entry.h"
51#include "ra8_cgc.h"
52#include "ra8_err.h"
53#include "ra8_isr.h"
54#include "ra8_mstp.h"
55#include "ra8_slab.h"
56#include "ra8_tile_cache.h"
57#include "ra8_time.h"
58#include "ra8_vmem_stream.h"
59#include "ra8_vsource.h"
60
62typedef enum : uint32_t {
63 k_mem_uart_baud = 115200U,
64 k_mem_crc_init = 0xFFFFFFFFU,
65 k_mem_crc_xorout = 0xFFFFFFFFU,
66 k_mem_crc_poly = 0xEDB88320U,
73
81
91
102
104typedef enum : uint16_t {
107
126
128typedef enum : uint32_t {
129 k_mem_gen_mul = 0x9E3779B1U,
130 k_mem_gen_add = 0x00A5A5A5U,
134} mem_gen_t;
135
140typedef struct {
141 uint32_t slab_free;
142 uint32_t arena_free;
143 uint32_t tile_hits;
144 uint32_t tile_misses;
145 uint32_t tile_evictions;
146 uint32_t vmem_crc;
147 uint32_t vmem_evictions;
149
150/* --- Backing storage, carved once at file scope (NASA P10 Rule 3) --------- */
151
153[[gnu::aligned(8)]] static uint8_t s_slab_pool[k_mem_slab_pool_bytes];
155[[gnu::aligned(8)]] static uint8_t s_arena_pool[k_mem_arena_pool_bytes];
157[[gnu::aligned(
158 8)]] static uint8_t s_tile_cells[(size_t)k_mem_tile_cells * (size_t)k_mem_tile_cell_bytes];
168[[gnu::aligned(
169 8)]] static uint8_t s_vmem_frames[(size_t)k_mem_vmem_frames * (size_t)k_mem_vmem_frame_bytes];
180
181static const uint8_t k_msg_boot[] = "mem-subsystem: boot 2KiB-resident-1MiB-paged\r\n";
182static const uint8_t k_msg_fail_init[] = "mem: FAIL init\r\n";
183static const uint8_t k_msg_fail_slab[] = "mem: FAIL slab\r\n";
184static const uint8_t k_msg_fail_arena[] = "mem: FAIL arena\r\n";
185static const uint8_t k_msg_fail_tile[] = "mem: FAIL tile\r\n";
186static const uint8_t k_msg_fail_vmem[] = "mem: FAIL vmem\r\n";
187static const uint8_t k_msg_slab[] = "mem: slab_free=";
188static const uint8_t k_msg_arena[] = " arena_free=";
189static const uint8_t k_msg_tile[] = " tile_evict=";
190static const uint8_t k_msg_vmem[] = " vmem_crc=";
191static const uint8_t k_msg_ok[] = " PASS\r\n";
192
194static void mem_print(const uint8_t* msg, uint32_t len)
195{
196 (void)ra8_board_uart_console_write(msg, (size_t)len);
197}
198
200static void mem_panic_halt(const uint8_t* msg, uint32_t len)
201{
202 mem_print(msg, len);
203 __asm__ volatile("bkpt #0");
204 while (1) {
205 __asm__ volatile("wfi");
206 }
207}
208
210static uint32_t mem_crc32_byte(uint32_t crc, uint8_t b)
211{
212 crc ^= (uint32_t)b;
213 for (uint32_t bit = 0U; bit < (uint32_t)k_mem_crc_bits; bit++) {
214 const uint32_t mask = (uint32_t)(-(int32_t)(crc & 1U));
215 crc = (crc >> 1U) ^ ((uint32_t)k_mem_crc_poly & mask);
216 }
217 return crc;
218}
219
221static uint8_t mem_gen_byte(uint64_t off)
222{
223 const uint32_t x = (uint32_t)off;
224 uint32_t h = x ^ (x >> (uint32_t)k_mem_gen_shift_a) ^ (x >> (uint32_t)k_mem_gen_shift_b);
225 h = (h * (uint32_t)k_mem_gen_mul) + (uint32_t)k_mem_gen_add;
226 return (uint8_t)(h >> (uint32_t)k_mem_gen_shift_out);
227}
228
230static void mem_print_hex(uint32_t value)
231{
232 uint8_t buf[k_mem_hex_nibbles];
233 for (uint32_t i = 0U; i < (uint32_t)k_mem_hex_nibbles; i++) {
234 const uint32_t shift = ((uint32_t)k_mem_hex_nibbles - 1U - i) * (uint32_t)k_mem_nibble_bits;
235 const uint32_t nib = (value >> shift) & (uint32_t)k_mem_nibble_mask;
236 buf[i] =
237 (uint8_t)((nib < (uint32_t)k_mem_dec_base) ? ('0' + nib) : ('A' + (nib - k_mem_dec_base)));
238 }
239 mem_print(buf, (uint32_t)k_mem_hex_nibbles);
240}
241
243static void mem_print_uint(uint32_t value)
244{
245 uint8_t buf[k_mem_dec_base];
246 uint32_t n = 0U;
247 if (value == 0U) {
248 buf[n] = '0';
249 n++;
250 }
251 while ((value > 0U) && (n < (uint32_t)k_mem_dec_base)) {
252 buf[n] = (uint8_t)('0' + (value % (uint32_t)k_mem_dec_base));
253 n++;
254 value /= (uint32_t)k_mem_dec_base;
255 }
256 for (uint32_t i = 0U; i < n; i++) {
257 mem_print(&buf[n - 1U - i], 1U);
258 }
259}
260
268{
269 ra8_slab_t slab = {};
270 if (ra8_slab_init(&slab,
272 (uint32_t)sizeof(s_slab_pool),
273 (uint32_t)k_mem_slab_cell_bytes) != k_ra8_ok) {
274 return false;
275 }
276 void* cells[k_mem_slab_cells] = {};
277 for (uint32_t i = 0U; i < (uint32_t)k_mem_slab_cells; i++) {
278 if (ra8_slab_alloc(&slab, &cells[i]) != k_ra8_ok) {
279 return false;
280 }
281 }
282 void* extra = nullptr;
283 if (ra8_slab_alloc(&slab, &extra) != k_ra8_err_no_mem) {
284 return false;
285 }
286 for (uint32_t i = 0U; i < (uint32_t)k_mem_slab_freed; i++) {
287 if (ra8_slab_free(&slab, cells[i]) != k_ra8_ok) {
288 return false;
289 }
290 }
291 uint32_t free_before = 0U;
292 if ((ra8_slab_stats(&slab, &free_before, nullptr) != k_ra8_ok) ||
293 (free_before != (uint32_t)k_mem_slab_freed)) {
294 return false;
295 }
296 /* Reset: re-init re-threads every cell back onto the freelist. */
297 if (ra8_slab_init(&slab,
299 (uint32_t)sizeof(s_slab_pool),
300 (uint32_t)k_mem_slab_cell_bytes) != k_ra8_ok) {
301 return false;
302 }
303 uint32_t total = 0U;
304 if (ra8_slab_stats(&slab, &r->slab_free, &total) != k_ra8_ok) {
305 return false;
306 }
307 return (total == (uint32_t)k_mem_slab_cells) && (r->slab_free == (uint32_t)k_mem_slab_cells);
308}
309
317{
318 ra8_arena_t arena = {};
319 if (ra8_arena_init(&arena, s_arena_pool, (uint32_t)sizeof(s_arena_pool)) != k_ra8_ok) {
320 return false;
321 }
322 void* b0 = nullptr;
323 void* b1 = nullptr;
324 if (ra8_arena_carve(&arena, (uint32_t)k_mem_arena_carve0, (uint32_t)k_mem_arena_align0, &b0) !=
325 k_ra8_ok) {
326 return false;
327 }
328 if (ra8_arena_carve(&arena, (uint32_t)k_mem_arena_carve1, (uint32_t)k_mem_arena_align1, &b1) !=
329 k_ra8_ok) {
330 return false;
331 }
332 void* big = nullptr;
333 if (ra8_arena_carve(&arena, (uint32_t)k_mem_arena_big, (uint32_t)k_mem_arena_align0, &big) !=
335 return false;
336 }
337 /* Reset: re-init drops the high-water mark back to zero. */
338 if (ra8_arena_init(&arena, s_arena_pool, (uint32_t)sizeof(s_arena_pool)) != k_ra8_ok) {
339 return false;
340 }
341 if (ra8_arena_remaining(&arena, &r->arena_free) != k_ra8_ok) {
342 return false;
343 }
344 return r->arena_free == (uint32_t)k_mem_arena_pool_bytes;
345}
346
348static ra8_err_t mem_tile_decode(void* ctx,
349 const ra8_tile_key_t* key,
350 uint8_t* cell,
351 uint32_t cell_bytes,
352 uint16_t* out_w,
353 uint16_t* out_h)
354{
355 (void)ctx;
356 (void)memset(cell, 0, (size_t)cell_bytes);
357 cell[0] = (uint8_t)key->tile_x;
358 *out_w = (uint16_t)k_mem_tile_dim;
359 *out_h = (uint16_t)k_mem_tile_dim;
360 return k_ra8_ok;
361}
362
365{
366 ra8_tile_key_t k = {};
367 k.tile_x = tx;
368 ra8_tile_t t = {};
369 const ra8_err_t err = ra8_tile_cache_get(tc, &k, &t);
370 if (err != k_ra8_ok) {
371 return err;
372 }
373 return ra8_tile_cache_put(tc, t.pixels);
374}
375
383{
384 ra8_tile_cache_t tc = {};
385 const ra8_tile_cache_cfg_t cfg = {
386 .cell_mem = s_tile_cells,
387 .cell_bytes = (uint32_t)k_mem_tile_cell_bytes,
388 .cell_count = (uint32_t)k_mem_tile_cells,
389 .meta = s_tile_meta,
390 .keys = s_tile_keys,
391 .dims = s_tile_dims,
392 .buckets = s_tile_buckets,
393 .bucket_count = (uint32_t)k_mem_tile_buckets,
394 .decode = mem_tile_decode,
395 .decode_ctx = nullptr,
396 };
397 if (ra8_tile_cache_init(&tc, &cfg) != k_ra8_ok) {
398 return false;
399 }
400 /* Overfill: more distinct tiles than cells forces LRU eviction. */
401 for (uint32_t i = 0U; i < (uint32_t)k_mem_tile_distinct; i++) {
402 if (mem_tile_touch(&tc, (uint16_t)i) != k_ra8_ok) {
403 return false;
404 }
405 }
406 /* The most-recent k_mem_tile_cells tiles are still resident: re-touch them
407 * (MRU-first) so each is a hit and none evicts. */
408 for (uint32_t i = 0U; i < (uint32_t)k_mem_tile_cells; i++) {
409 const uint16_t tx = (uint16_t)((uint32_t)k_mem_tile_distinct - 1U - i);
410 if (mem_tile_touch(&tc, tx) != k_ra8_ok) {
411 return false;
412 }
413 }
414 /* Re-touch the very first tile (long evicted): one more miss + eviction. */
415 if (mem_tile_touch(&tc, 0U) != k_ra8_ok) {
416 return false;
417 }
419 return false;
420 }
421 return (r->tile_hits == (uint32_t)k_mem_tile_exp_hits) &&
422 (r->tile_misses == (uint32_t)k_mem_tile_exp_miss) &&
423 (r->tile_evictions == (uint32_t)k_mem_tile_exp_evict);
424}
425
427static ra8_err_t mem_backing_read(void* ctx, uint64_t offset, uint8_t* buf, uint32_t len)
428{
429 (void)ctx;
430 if (buf == nullptr) {
431 return k_ra8_err_null_ptr;
432 }
433 for (uint32_t i = 0U; i < len; i++) {
434 buf[i] = mem_gen_byte(offset + (uint64_t)i);
435 }
436 return k_ra8_ok;
437}
438
449static bool
450mem_stream_window(ra8_vmem_stream_t* st, uint64_t off, uint32_t len, uint32_t* crc, size_t* out_got)
451{
452 if (len > (uint32_t)k_mem_win_buf_bytes) {
453 return false;
454 }
455 const size_t got = ra8_vmem_stream_read(st, off, s_win_buf, (size_t)len);
456 for (size_t i = 0U; i < got; i++) {
457 if (s_win_buf[i] != mem_gen_byte(off + (uint64_t)i)) {
458 return false;
459 }
460 *crc = mem_crc32_byte(*crc, s_win_buf[i]);
461 }
462 *out_got = got;
463 return true;
464}
465
473static bool mem_vmem_read_windows(ra8_vmem_stream_t* st, uint32_t* crc)
474{
475 size_t got = 0U;
476 if (!mem_stream_window(st, (uint64_t)k_mem_win0_off, (uint32_t)k_mem_win0_len, crc, &got) ||
477 (got != (size_t)k_mem_win0_len)) {
478 return false;
479 }
480 if (!mem_stream_window(st, (uint64_t)k_mem_win1_off, (uint32_t)k_mem_win1_len, crc, &got) ||
481 (got != (size_t)k_mem_win1_len)) {
482 return false;
483 }
484 if (!mem_stream_window(st, (uint64_t)k_mem_win2_off, (uint32_t)k_mem_win2_len, crc, &got) ||
485 (got != (size_t)k_mem_win2_len)) {
486 return false;
487 }
488 const uint64_t eof_off = (uint64_t)k_mem_vmem_obj_bytes - (uint64_t)k_mem_win_eof_back;
489 if (!mem_stream_window(st, eof_off, (uint32_t)k_mem_win_eof_len, crc, &got) ||
490 (got != (size_t)k_mem_win_eof_back)) {
491 return false;
492 }
493 if (!mem_stream_window(st,
494 (uint64_t)k_mem_vmem_obj_bytes,
495 (uint32_t)k_mem_win_past_len,
496 crc,
497 &got) ||
498 (got != 0U)) {
499 return false;
500 }
501 return true;
502}
503
511{
512 ra8_vsource_t vs = {};
513 if (ra8_vsource_init(&vs, s_vmem_objs, (uint32_t)k_mem_vmem_objs) != k_ra8_ok) {
514 return false;
515 }
516 uint32_t obj_id = 0U;
517 if (ra8_vsource_add_paged(&vs,
519 nullptr,
520 0U,
521 (uint64_t)k_mem_vmem_obj_bytes,
522 &obj_id) != k_ra8_ok) {
523 return false;
524 }
525 ra8_vmem_t vm = {};
526 const ra8_vmem_cfg_t vcfg = {
527 .frame_mem = s_vmem_frames,
528 .frame_bytes = (uint32_t)k_mem_vmem_frame_bytes,
529 .frame_count = (uint32_t)k_mem_vmem_frames,
530 .meta = s_vmem_fmeta,
531 .keys = s_vmem_fkeys,
532 .buckets = s_vmem_fbuckets,
533 .bucket_count = (uint32_t)k_mem_vmem_buckets,
534 .loader = ra8_vsource_loader,
535 .loader_ctx = &vs,
536 };
537 if (ra8_vmem_init(&vm, &vcfg) != k_ra8_ok) {
538 return false;
539 }
540 ra8_vmem_stream_t st = {};
541 if (ra8_vmem_stream_init(&st, &vm, obj_id, (uint64_t)k_mem_vmem_obj_bytes) != k_ra8_ok) {
542 return false;
543 }
544 uint32_t crc = (uint32_t)k_mem_crc_init;
545 if (!mem_vmem_read_windows(&st, &crc)) {
546 return false;
547 }
548 r->vmem_crc = crc ^ (uint32_t)k_mem_crc_xorout;
549 if (ra8_vmem_stats(&vm, nullptr, nullptr, &r->vmem_evictions) != k_ra8_ok) {
550 return false;
551 }
552 /* A 1 MiB object read through a 4-frame pool must have paged at least once. */
553 return r->vmem_evictions >= 1U;
554}
555
557static void mem_setup_or_halt(void)
558{
559 uint32_t cpuclk0_hz = 0U;
560 if ((ra8_cgc_init() != k_ra8_ok) || (ra8_mstp_init() != k_ra8_ok)) {
561 mem_panic_halt(k_msg_fail_init, (uint32_t)sizeof(k_msg_fail_init) - 1U);
562 }
564 mem_panic_halt(k_msg_fail_init, (uint32_t)sizeof(k_msg_fail_init) - 1U);
565 }
566 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
567 mem_panic_halt(k_msg_fail_init, (uint32_t)sizeof(k_msg_fail_init) - 1U);
568 }
570 mem_panic_halt(k_msg_fail_init, (uint32_t)sizeof(k_msg_fail_init) - 1U);
571 }
572}
573
582void main(void)
583{
586 mem_print(k_msg_boot, (uint32_t)sizeof(k_msg_boot) - 1U);
587
588 mem_report_t r = {};
589 if (!mem_run_slab(&r)) {
590 mem_panic_halt(k_msg_fail_slab, (uint32_t)sizeof(k_msg_fail_slab) - 1U);
591 }
592 if (!mem_run_arena(&r)) {
593 mem_panic_halt(k_msg_fail_arena, (uint32_t)sizeof(k_msg_fail_arena) - 1U);
594 }
595 if (!mem_run_tiles(&r)) {
596 mem_panic_halt(k_msg_fail_tile, (uint32_t)sizeof(k_msg_fail_tile) - 1U);
597 }
598 if (!mem_run_vmem(&r)) {
599 mem_panic_halt(k_msg_fail_vmem, (uint32_t)sizeof(k_msg_fail_vmem) - 1U);
600 }
601
602 mem_print(k_msg_slab, (uint32_t)sizeof(k_msg_slab) - 1U);
604 mem_print(k_msg_arena, (uint32_t)sizeof(k_msg_arena) - 1U);
606 mem_print(k_msg_tile, (uint32_t)sizeof(k_msg_tile) - 1U);
608 mem_print(k_msg_vmem, (uint32_t)sizeof(k_msg_vmem) - 1U);
610 mem_print(k_msg_ok, (uint32_t)sizeof(k_msg_ok) - 1U);
611
612 while (1) {
613 __asm__ volatile("wfi");
614 }
615}
void main(void)
Secure fallback main entry point.
Definition main.c:37
static const uint8_t k_msg_ok[]
Definition main.c:153
static const uint8_t k_msg_boot[]
Definition main.c:140
static const uint8_t k_msg_arena[]
Definition main.c:188
static ra8_tile_dims_t s_tile_dims[k_mem_tile_cells]
Tile-cache per-cell dimension descriptors.
Definition main.c:162
static bool mem_stream_window(ra8_vmem_stream_t *st, uint64_t off, uint32_t len, uint32_t *crc, size_t *out_got)
Read one byte window through the stream, verify it, and fold it in.
Definition main.c:450
static uint8_t s_arena_pool[k_mem_arena_pool_bytes]
Arena-exercise region.
Definition main.c:155
static ra8_vmem_key_t s_vmem_fkeys[k_mem_vmem_frames]
Page-cache per-frame key storage.
Definition main.c:173
mem_slab_cfg_t
Slab-exercise sizing.
Definition main.c:75
@ k_mem_slab_pool_bytes
Backing pool size.
Definition main.c:76
@ k_mem_slab_freed
Cells freed before the reset.
Definition main.c:79
@ k_mem_slab_cell_bytes
Bytes per cell (512/64 = 8).
Definition main.c:77
@ k_mem_slab_cells
Cells the pool divides into.
Definition main.c:78
static ra8_err_t mem_tile_touch(ra8_tile_cache_t *tc, uint16_t tx)
Fetch (get + immediately put) tile column tx, so it is unpinned.
Definition main.c:364
static const uint8_t k_msg_slab[]
Definition main.c:187
static ra8_tile_key_t s_tile_keys[k_mem_tile_cells]
Tile-cache per-cell key storage.
Definition main.c:160
static void mem_panic_halt(const uint8_t *msg, uint32_t len)
Print the fail banner and trap (ra8_emulator halts on the BKPT).
Definition main.c:200
mem_gen_t
Deterministic backing-byte generator constants.
Definition main.c:128
@ k_mem_gen_add
Additive constant.
Definition main.c:130
@ k_mem_gen_shift_a
First xor-fold shift.
Definition main.c:131
@ k_mem_gen_shift_out
Output byte select shift.
Definition main.c:133
@ k_mem_gen_shift_b
Second xor-fold shift.
Definition main.c:132
@ k_mem_gen_mul
Odd multiplicative mixer.
Definition main.c:129
static uint8_t s_tile_cells[(size_t) k_mem_tile_cells *(size_t) k_mem_tile_cell_bytes]
Tile-cache decoded-pixel cells.
Definition main.c:158
static const uint8_t k_msg_tile[]
Definition main.c:189
static ra8_keycache_cell_t s_tile_meta[k_mem_tile_cells]
Tile-cache per-cell link metadata.
Definition main.c:164
static ra8_vmem_frame_t s_vmem_fmeta[k_mem_vmem_frames]
Page-cache per-frame metadata.
Definition main.c:171
static uint8_t mem_gen_byte(uint64_t off)
Deterministic backing byte at absolute off (host/emulator/silicon-equal).
Definition main.c:221
static bool mem_vmem_read_windows(ra8_vmem_stream_t *st, uint32_t *crc)
Read every window and confirm the stream returned the expected lengths.
Definition main.c:473
static int32_t s_vmem_fbuckets[k_mem_vmem_buckets]
Page-cache hash buckets.
Definition main.c:175
static const uint8_t k_msg_vmem[]
Definition main.c:190
static const uint8_t k_msg_fail_init[]
Definition main.c:182
static void mem_setup_or_halt(void)
Bring up clocks / MSTP / time + the board console; halt on failure.
Definition main.c:557
mem_vmem_cfg_t
vmem_stream-exercise sizing + read windows.
Definition main.c:109
@ k_mem_vmem_buckets
Page-cache hash buckets.
Definition main.c:112
@ k_mem_win1_len
Window 1 length.
Definition main.c:119
@ k_mem_win2_off
Window 2 offset (spans several frames).
Definition main.c:120
@ k_mem_win1_off
Window 1 offset (crosses frame boundary).
Definition main.c:118
@ k_mem_vmem_objs
Registry slots.
Definition main.c:113
@ k_mem_win_past_len
Past-EOF window length (reads 0).
Definition main.c:124
@ k_mem_vmem_frame_bytes
Page-cache frame size.
Definition main.c:110
@ k_mem_win2_len
Window 2 length.
Definition main.c:121
@ k_mem_vmem_obj_bytes
Synthetic backing object size (1 MiB).
Definition main.c:114
@ k_mem_win0_off
Window 0 offset (within frame 0).
Definition main.c:116
@ k_mem_win_eof_len
Near-EOF window length (clamps to 50).
Definition main.c:123
@ k_mem_win_eof_back
Bytes before EOF the near-EOF window starts.
Definition main.c:122
@ k_mem_vmem_frames
Frames in the fixed pool (2 KiB resident).
Definition main.c:111
@ k_mem_win_buf_bytes
Read scratch (>= the widest window).
Definition main.c:115
@ k_mem_win0_len
Window 0 length.
Definition main.c:117
mem_arena_cfg_t
Arena-exercise sizing.
Definition main.c:83
@ k_mem_arena_big
Over-subscribed carve (must fail).
Definition main.c:87
@ k_mem_arena_pool_bytes
Backing region size.
Definition main.c:84
@ k_mem_arena_align0
First / big carve alignment.
Definition main.c:88
@ k_mem_arena_align1
Second carve alignment.
Definition main.c:89
@ k_mem_arena_carve1
Second carve size.
Definition main.c:86
@ k_mem_arena_carve0
First carve size.
Definition main.c:85
static ra8_vsource_obj_t s_vmem_objs[k_mem_vmem_objs]
Object-source registry slots.
Definition main.c:177
static bool mem_run_vmem(mem_report_t *r)
Exercise 4: stream byte windows out of a 1 MiB object via a 2 KiB cache.
Definition main.c:510
static bool mem_run_slab(mem_report_t *r)
Exercise 1: slab alloc-to-exhaustion, free, and reset-by-reinit.
Definition main.c:267
static void mem_print_hex(uint32_t value)
Print a 32-bit value as 8 upper-case hex digits.
Definition main.c:230
static uint32_t mem_crc32_byte(uint32_t crc, uint8_t b)
Fold one byte into a running CRC-32 (reflected, poly 0xEDB88320).
Definition main.c:210
mem_console_t
Console + banner-format knobs (no magic numbers).
Definition main.c:62
@ k_mem_crc_bits
Bits folded per byte.
Definition main.c:67
@ k_mem_nibble_mask
Low-nibble mask.
Definition main.c:70
@ k_mem_dec_base
Decimal base / hex-digit split.
Definition main.c:71
@ k_mem_uart_baud
Console baud.
Definition main.c:63
@ k_mem_hex_nibbles
Hex digits in a 32-bit value.
Definition main.c:68
@ k_mem_crc_init
CRC-32 initial value.
Definition main.c:64
@ k_mem_crc_xorout
CRC-32 final xor (== bitwise not).
Definition main.c:65
@ k_mem_crc_poly
CRC-32 reflected polynomial.
Definition main.c:66
@ k_mem_nibble_bits
Bits per hex nibble.
Definition main.c:69
static ra8_err_t mem_tile_decode(void *ctx, const ra8_tile_key_t *key, uint8_t *cell, uint32_t cell_bytes, uint16_t *out_w, uint16_t *out_h)
Synthetic tile decoder: stamps the key column into the cell.
Definition main.c:348
static const uint8_t k_msg_fail_arena[]
Definition main.c:184
mem_tile_cfg_t
Tile-cache-exercise sizing + expected counters.
Definition main.c:93
@ k_mem_tile_buckets
Hash buckets.
Definition main.c:96
@ k_mem_tile_exp_hits
Expected hits after the drive.
Definition main.c:98
@ k_mem_tile_cells
Cells in the cache.
Definition main.c:95
@ k_mem_tile_distinct
Distinct tiles faulted (> cells).
Definition main.c:97
@ k_mem_tile_cell_bytes
Bytes per tile cell.
Definition main.c:94
@ k_mem_tile_exp_miss
Expected misses after the drive.
Definition main.c:99
@ k_mem_tile_exp_evict
Expected evictions after the drive.
Definition main.c:100
static const uint8_t k_msg_fail_tile[]
Definition main.c:185
mem_tile_dim_t
Synthetic decoded-tile dimensions.
Definition main.c:104
@ k_mem_tile_dim
Synthetic decoded tile edge length.
Definition main.c:105
static void mem_print_uint(uint32_t value)
Print a small unsigned integer in decimal.
Definition main.c:243
static const uint8_t k_msg_fail_slab[]
Definition main.c:183
static bool mem_run_tiles(mem_report_t *r)
Exercise 3: overfill the tile cache to observe LRU eviction.
Definition main.c:382
static uint8_t s_vmem_frames[(size_t) k_mem_vmem_frames *(size_t) k_mem_vmem_frame_bytes]
Page-cache frame storage (2 KiB resident).
Definition main.c:169
static const uint8_t k_msg_fail_vmem[]
Definition main.c:186
static bool mem_run_arena(mem_report_t *r)
Exercise 2: arena bump carves, over-subscription, and reset-by-reinit.
Definition main.c:316
static uint8_t s_slab_pool[k_mem_slab_pool_bytes]
Slab-exercise pool.
Definition main.c:153
static uint8_t s_win_buf[k_mem_win_buf_bytes]
Stream read scratch (>= the widest window).
Definition main.c:179
static int32_t s_tile_buckets[k_mem_tile_buckets]
Tile-cache hash buckets.
Definition main.c:166
static void mem_print(const uint8_t *msg, uint32_t len)
Emit a byte run on the board console.
Definition main.c:194
static ra8_err_t mem_backing_read(void *ctx, uint64_t offset, uint8_t *buf, uint32_t len)
Backing read callback: fill buf with the deterministic generator.
Definition main.c:427
Init-time bump arena – carves per-tier slab backing, zero-heap.
ra8_err_t ra8_arena_carve(ra8_arena_t *arena, uint32_t bytes, uint32_t align, void **out_ptr)
Carve an aligned sub-block from the arena (bump; no free).
Definition ra8_arena.c:69
ra8_err_t ra8_arena_remaining(const ra8_arena_t *arena, uint32_t *out_remaining)
Report the bytes still available in the arena.
Definition ra8_arena.c:94
ra8_err_t ra8_arena_init(ra8_arena_t *arena, void *base, uint32_t size)
Bind a bump arena over a caller-owned tier region.
Definition ra8_arena.c:56
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.
Boot entry points shared between a vector table and its startup code.
High-level Clock Generation Circuit driver.
ra8_err_t ra8_cgc_get_clock_hz(ra8_clock_id_t id, uint32_t *out_hz)
Query the current frequency of a clock-tree domain.
Definition ra8_cgc.c:132
@ k_ra8_clock_id_cpuclk0
Cortex-M85 CPUCLK0.
Definition ra8_cgc.h:70
ra8_err_t ra8_cgc_init(void)
Configure the clock tree to a safe default.
Definition ra8_cgc.c:727
Error Code Definitions for ra8-firmware.
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
Definition ra8_err.h:142
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
Definition ra8_err.h:478
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
NVIC + ICU IELSR allocator.
void ra8_isr_globals_enable(void)
Globally enable maskable interrupts (PRIMASK = 0).
Definition ra8_isr.c:439
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_init(void)
Re-establish the ra8_mstp ref-count table from current hardware state.
Definition ra8_mstp.c:291
Fixed-cell slab allocator – O(1), zero-fragmentation, zero-heap.
ra8_err_t ra8_slab_alloc(ra8_slab_t *slab, void **out_cell)
Allocate one cell from the slab (O(1)).
Definition ra8_slab.c:111
ra8_err_t ra8_slab_free(ra8_slab_t *slab, void *cell)
Return a previously-allocated cell to the slab (O(1)).
Definition ra8_slab.c:125
ra8_err_t ra8_slab_init(ra8_slab_t *slab, void *buffer, uint32_t buffer_bytes, uint32_t cell_bytes)
Initialise a slab over a caller-owned buffer.
Definition ra8_slab.c:85
ra8_err_t ra8_slab_stats(const ra8_slab_t *slab, uint32_t *out_free, uint32_t *out_total)
Report the slab's free / total cell counts.
Definition ra8_slab.c:149
Fixed-RAM-budget image-tile cache with LRU eviction (Layer 3b, #147).
ra8_err_t ra8_tile_cache_get(ra8_tile_cache_t *tc, const ra8_tile_key_t *key, ra8_tile_t *out_tile)
Get (and pin) the decoded tile for key.
ra8_err_t ra8_tile_cache_stats(const ra8_tile_cache_t *tc, uint32_t *out_hits, uint32_t *out_misses, uint32_t *out_evictions)
Report the cache hit / miss / eviction counters.
ra8_err_t ra8_tile_cache_put(ra8_tile_cache_t *tc, const uint8_t *pixels)
Release one pin on a tile previously returned by ra8_tile_cache_get.
ra8_err_t ra8_tile_cache_init(ra8_tile_cache_t *tc, const ra8_tile_cache_cfg_t *cfg)
Initialise a tile cache over caller-supplied storage.
SysTick-based tick counter, delay and timestamp helpers.
ra8_err_t ra8_time_init(uint32_t cpu_hz)
Initialise SysTick for a 1 kHz tick interrupt.
Definition ra8_time.c:59
ra8_err_t ra8_vmem_init(ra8_vmem_t *vm, const ra8_vmem_cfg_t *cfg)
Initialise a page cache over caller-supplied storage.
Definition ra8_vmem.c:131
ra8_err_t ra8_vmem_stats(const ra8_vmem_t *vm, uint32_t *out_hits, uint32_t *out_misses, uint32_t *out_evictions)
Report the cache hit / miss / eviction counters.
Definition ra8_vmem.c:199
ra8_keycache_cell_t ra8_vmem_frame_t
Per-frame cache metadata (one caller-owned array entry per frame).
Definition ra8_vmem.h:122
Read a page-cached object as a seekable byte stream (Layer 2 helper, #147/#151).
ra8_err_t ra8_vmem_stream_init(ra8_vmem_stream_t *st, ra8_vmem_t *vm, uint32_t object_id, uint64_t size)
Bind a page-cached paged object to the byte-stream reader.
size_t ra8_vmem_stream_read(void *ctx, uint64_t offset, void *buf, size_t len)
Read len bytes at absolute offset through the page cache.
Virtual-memory object sources – the page-cache storage seam (Layer 1, #147).
ra8_err_t ra8_vsource_loader(void *ctx, uint32_t object_id, uint64_t offset, uint8_t *frame, uint32_t frame_bytes)
Fill a page frame from an object – the ra8_vmem_loader_fn adapter.
Definition ra8_vsource.c:84
ra8_err_t ra8_vsource_add_paged(ra8_vsource_t *vs, ra8_vsource_read_fn read, void *ctx, uint64_t base, uint64_t size, uint32_t *out_id)
Register a storage-paged object; returns its object_id.
Definition ra8_vsource.c:42
ra8_err_t ra8_vsource_init(ra8_vsource_t *vs, ra8_vsource_obj_t *objs, uint32_t cap)
Initialise an empty source registry over a caller-owned object array.
Definition ra8_vsource.c:29
Observables gathered from the four exercises.
Definition main.c:140
uint32_t tile_evictions
Tile-cache eviction count.
Definition main.c:145
uint32_t tile_hits
Tile-cache hit count.
Definition main.c:143
uint32_t vmem_evictions
Page-cache evictions (paging proof).
Definition main.c:147
uint32_t tile_misses
Tile-cache miss count.
Definition main.c:144
uint32_t vmem_crc
CRC-32 over the streamed byte windows.
Definition main.c:146
uint32_t arena_free
Bytes remaining after the arena reset.
Definition main.c:142
uint32_t slab_free
Free cells after the slab reset.
Definition main.c:141
Caller-owned bump-arena state over one tier region.
Definition ra8_arena.h:56
Per-cell link metadata (one caller-owned array entry per cell).
Caller-owned state for one fixed-cell pool.
Definition ra8_slab.h:75
Caller-supplied storage + decoder for ra8_tile_cache_init.
Tile-cache state (caller-owned; treat as private).
Per-cell user descriptor: the decoded tile dimensions.
Identifies one decoded image tile.
uint16_t tile_x
Tile column index (in tile units).
A pinned view of a cached tile returned by ra8_tile_cache_get.
const uint8_t * pixels
Decoded tile pixels (cell payload).
Caller-supplied storage + loader for ra8_vmem_init.
Definition ra8_vmem.h:151
The (object_id, frame-aligned offset) key the page cache hashes on.
Definition ra8_vmem.h:136
Binds one page-cached object to the byte-stream read adapter.
Page-cache state (caller-owned; treat as private).
Definition ra8_vmem.h:179
One registered object's backing (paged or XIP).
Definition ra8_vsource.h:90
Object-source registry (caller-owned; treat as private).