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

Cortex-M85 L1 cache brought up through the ra8_cache HAL (issue #577). More...

#include <stddef.h>
#include <stdint.h>
#include "ra8_board_ek_ra8d2.h"
#include "ra8_boot_entry.h"
#include "ra8_cache.h"
#include "ra8_cgc.h"
#include "ra8_err.h"
#include "ra8_log.h"
Include dependency graph for main.c:

Go to the source code of this file.

Enumerations

enum  cache_hal_config_t : uint32_t {
  k_cache_hal_baud = 115200U ,
  k_cache_hal_buf_bytes = 4096U ,
  k_cache_hal_buf_min = 4096U
}
 Compile-time scalar parameters for the cache-via-HAL self-test. More...
enum  cache_hal_pattern_t : uint8_t {
  k_cache_hal_pat_mul = 31U ,
  k_cache_hal_pat_add = 7U
}
 Affine byte-pattern coefficients: buf[i] = i * MUL + ADD. More...

Functions

static void cache_hal_wfi_forever (void)
 Park the Cortex-M85 forever in a WFI idle loop.
static bool cache_hal_test_cacheable_rw (void)
 Prove cacheable RW works with the HAL-enabled D-cache (SRAM region 1).
static bool cache_hal_setup (void)
 Bring up the clock tree and the VCOM console for the banner.
static void cache_hal_emit (const uint8_t *line, size_t len)
 Emit one banner line over the VCOM console and flush it.
void main (void)
 Application entry: prove the HAL-enabled L1 caches compute correctly.

Variables

static uint8_t s_cache_hal_buf [k_cache_hal_buf_bytes]
 4 KiB cacheable scratch buffer in M85-private SRAM (MPU region 1).
static const uint8_t k_cache_hal_pass_banner [] = "cache_hal_enable_demo: L1-cache-via-HAL PASS\r\n"
 Deterministic one-shot HIL success banner (uart_scrape gate).
static const uint8_t k_cache_hal_fail_setup [] = "cache_hal_enable_demo: setup FAIL\r\n"
 Failure banner: clock / console bring-up failed before the self-test.
static const uint8_t k_cache_hal_fail_rw [] = "cache_hal_enable_demo: cacheable-RW FAIL\r\n"
 Failure banner: the cacheable-SRAM readback mismatched.

Detailed Description

Cortex-M85 L1 cache brought up through the ra8_cache HAL (issue #577).

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

Single-core (Cortex-M85) HIL demo that boots with the L1 I-cache + D-cache enabled through the ra8_cache HAL primitives rather than the shared boot's hand-rolled register pokes. The app's build defines both RA8_BOOT_ENABLE_CACHE_MPU and RA8_BOOT_CACHE_VIA_HAL (see CMakeLists.txt), so the shared SystemInit() programmes the 5-region MPU and then calls ra8_cache_icache_enable() / ra8_cache_dcache_enable() (each of which runs its architectural invalidate before setting the CCR enable bit) before main() runs. This is the Liskov-equivalent of the raw-poke cache_mpu_hil boot: the same ICIALLU + CCR.IC / CCR.DC sequence, now lifted into the HAL. The raw internal_enable_icache / internal_enable_dcache helpers stay compiled as the reference path and are simply not called here.

Self-test (runs once, then the core parks in WFI):

  1. Cacheable RW (M85-private SRAM @ 0x22000000, MPU region 1). Fill a 4 KiB static buffer (in .bss, region 1) with a deterministic affine pattern buf[i] = (uint8_t)(i * 31 + 7), clean+invalidate those (now dirty) D-cache lines back to SRAM via ra8_cache_dcache_clean_invalidate_by_addr(), then read every byte back – the read misses the cache and refills from memory, exercising the full write-back + refill path with the HAL-enabled D-cache live.

On success the app emits "cache_hal_enable_demo: L1-cache-via-HAL PASS\r\n" over the J-Link OB VCOM console (SCI8, PD02/PD03 @ 115200 8N1) and mirrors the verdict over ra8_log (the emulator echoes it as an [itm] line). On any mismatch it emits a distinct ... FAIL line (never containing "PASS") and parks. Every path ends in WFI so ra8_emulator's RA8_EMU_IDLE_STOP terminates the run after the one-shot banner is scraped.

Note
ra8_emulator models memory byte-exact and does not model the L1 D-cache, so the cacheable-RW step passes there trivially; the point of the emulator run is to prove the app boots and reports PASS with the HAL-driven cache boot path compiled in. The cache hazard is only real on silicon.
Author
Brighton Sikarskie
Date
2026-08-02
Since
0.1.0

Definition in file main.c.

Enumeration Type Documentation

◆ cache_hal_config_t

enum cache_hal_config_t : uint32_t

Compile-time scalar parameters for the cache-via-HAL self-test.

Groups the console baud and the cacheable buffer size the round-trip fills, cleans, and reads back.

Since
0.1.0
Enumerator
k_cache_hal_baud 

VCOM console line rate (8N1).

k_cache_hal_buf_bytes 

Cacheable self-test buffer size (>= 4 KiB).

k_cache_hal_buf_min 

Self-test buffer floor (4 KiB minimum).

Definition at line 68 of file main.c.

◆ cache_hal_pattern_t

enum cache_hal_pattern_t : uint8_t

Affine byte-pattern coefficients: buf[i] = i * MUL + ADD.

A per-index affine pattern makes every byte distinct modulo 256, so a stuck or swapped line is caught by the readback compare.

Since
0.1.0
Enumerator
k_cache_hal_pat_mul 

Pattern multiplier.

k_cache_hal_pat_add 

Pattern addend.

Definition at line 81 of file main.c.

Function Documentation

◆ cache_hal_emit()

void cache_hal_emit ( const uint8_t * line,
size_t len )
static

Emit one banner line over the VCOM console and flush it.

Writes line then drains the SCI8 TX so the bytes clock out before the core parks. A no-op if line is NULL or len is 0, or if the console never came up (the write returns an error that is ignored here).

Parameters
[in]linePointer to the ASCII banner bytes (no NUL sent). Must be non-NULL for output.
[in]lenNumber of bytes to send; 0 sends nothing.
Returns
Nothing.
Precondition
line points to at least len readable bytes when len > 0.
cache_hal_setup was attempted during bring-up.
Postcondition
The bytes have been handed to SCI8 and the TX FIFO drained (if up).
No application state is modified.
Note
Not thread-safe; single-threaded boot context.
Since
0.1.0

Definition at line 250 of file main.c.

References ra8_board_uart_console_flush(), and ra8_board_uart_console_write().

Referenced by main().

◆ cache_hal_setup()

bool cache_hal_setup ( void )
static

Bring up the clock tree and the VCOM console for the banner.

ra8_cgc_init() programmes the FSP-quickstart clock tree and publishes PCLKA; the EK-RA8D2 debug console (SCI8 on PD02/PD03 @ k_cache_hal_baud) then comes up over the J-Link OB VCOM bridge.

Returns
Whether the clock + console are ready to carry the banner.
Return values
trueCGC and SCI8 console are up.
falseA bring-up step failed.
Precondition
Called once during M85 bring-up, before the self-test.
ra8_log_init() has run (failures are narrated over ITM).
Postcondition
On true SCI8 is enabled and PD02/PD03 route to it.
On false no console state persists.
Note
Not thread-safe; single-threaded boot context.
Since
0.1.0

Definition at line 218 of file main.c.

References k_cache_hal_baud, k_ra8_ok, ra8_board_uart_console_init(), and ra8_cgc_init().

Referenced by main().

◆ cache_hal_test_cacheable_rw()

bool cache_hal_test_cacheable_rw ( void )
static

Prove cacheable RW works with the HAL-enabled D-cache (SRAM region 1).

Fills s_cache_hal_buf with the affine pattern, cleans + invalidates the now-dirty D-cache lines back to SRAM through the HAL by-address primitive, then verifies every byte on read-back so the refill path from memory is exercised with the D-cache (enabled at boot via ra8_cache_dcache_enable()) live.

Returns
Whether the buffer read back exactly as written.
Return values
trueEvery byte matched the pattern after the cache round-trip.
falseA byte mismatched, or the cache maintenance call failed.
Precondition
The D-cache + MPU are enabled (HAL cache boot path active).
s_cache_hal_buf lies in cacheable SRAM (MPU region 1).
Postcondition
On true the buffer holds the affine pattern in SRAM.
No memory outside s_cache_hal_buf is modified.
Note
Not thread-safe; single-threaded boot context.
Since
0.1.0

Definition at line 174 of file main.c.

References k_cache_hal_buf_bytes, k_cache_hal_pat_add, k_cache_hal_pat_mul, k_ra8_ok, ra8_cache_dcache_clean_invalidate_by_addr(), and s_cache_hal_buf.

Referenced by main().

◆ cache_hal_wfi_forever()

void cache_hal_wfi_forever ( void )
static

Park the Cortex-M85 forever in a WFI idle loop.

Reached after the one-shot banner has been emitted (pass or fail). The WFI lets ra8_emulator's idle detector stop the run cleanly and models the low-power posture on silicon.

Returns
This function never returns.
Precondition
The self-test verdict has been emitted over the console.
No further forward progress is required of the M85.
Postcondition
The core makes no further architectural progress.
Any pending console bytes have already been flushed by the caller.
Note
Not thread-safe; single-threaded boot context.
Since
0.1.0

Definition at line 146 of file main.c.

Referenced by main().

◆ main()

void main ( void )

Application entry: prove the HAL-enabled L1 caches compute correctly.

The application entry point Reset_Handler hands control to.

Brings up logging, the clock tree, and the VCOM console, runs the cacheable-SRAM round-trip with the D-cache that SystemInit() enabled through ra8_cache_dcache_enable(), emits the matching PASS / FAIL banner over the console and ra8_log, then parks in WFI. Every byte the self-test touches runs with the L1 caches + MPU enabled by the shared boot (RA8_BOOT_ENABLE_CACHE_MPU + RA8_BOOT_CACHE_VIA_HAL).

Precondition
Reset_Handler has copied .data and zeroed .bss.
SystemInit enabled the MPU + I-cache + D-cache via the ra8_cache HAL.
Postcondition
Exactly one banner (PASS or FAIL) has been emitted.
The core is parked in WFI.
Note
Single-threaded; no RTOS and no IRQ sources in this template.
Since
0.1.0

Definition at line 280 of file main.c.

References cache_hal_emit(), cache_hal_setup(), cache_hal_test_cacheable_rw(), cache_hal_wfi_forever(), k_cache_hal_fail_rw, k_cache_hal_fail_setup, k_cache_hal_pass_banner, ra8_log_info, and ra8_log_init().

Variable Documentation

◆ k_cache_hal_fail_rw

const uint8_t k_cache_hal_fail_rw[] = "cache_hal_enable_demo: cacheable-RW FAIL\r\n"
static

Failure banner: the cacheable-SRAM readback mismatched.

Distinct from the PASS banner and free of "PASS".

Since
0.1.0

Definition at line 127 of file main.c.

Referenced by main().

◆ k_cache_hal_fail_setup

const uint8_t k_cache_hal_fail_setup[] = "cache_hal_enable_demo: setup FAIL\r\n"
static

Failure banner: clock / console bring-up failed before the self-test.

Distinct from the PASS banner and free of "PASS"; matched by the hil.conf HIL_EXPECT_NEGATIVE "FAIL" alternative.

Since
0.1.0

Definition at line 119 of file main.c.

Referenced by main().

◆ k_cache_hal_pass_banner

const uint8_t k_cache_hal_pass_banner[] = "cache_hal_enable_demo: L1-cache-via-HAL PASS\r\n"
static

Deterministic one-shot HIL success banner (uart_scrape gate).

Emitted only on the pass path over the VCOM console. The trailing CRLF terminates the line on the wire; the HIL gate matches the text exactly. Contains "PASS" and is not a substring of any FAIL banner.

Warning
Do not modify; hil.conf HIL_EXPECT matches it verbatim.
Since
0.1.0

Definition at line 110 of file main.c.

Referenced by main().

◆ s_cache_hal_buf

uint8_t s_cache_hal_buf[k_cache_hal_buf_bytes]
static

4 KiB cacheable scratch buffer in M85-private SRAM (MPU region 1).

Lives in .bss (SRAM @ 0x22000000, cacheable per MPU region 1). Cache-line aligned (32 bytes) so the clean+invalidate covers whole lines with no partial-line surprises.

Note
Mutated only by the cacheable-RW self-test on the single boot thread.
Warning
Not for cross-core use – region 1 is M85-private cacheable.
Since
0.1.0

Definition at line 99 of file main.c.

Referenced by cache_hal_test_cacheable_rw().