|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Every source file in libs/ra8_hal/, libs/ra8_*_pal/, libs/ra8_nsc/, and libs/ra8_secure_app/ carries a two-part tag in its file-level Doxygen header:
The pair is enforced by scripts/checks/check_world_tags.py, which runs in the pre-commit hook and refuses commits whose Ring-3+ files are missing either tag (or carry a tag that's inconsistent with where the file lives).
The project organises code into numbered rings, similar in spirit to OS privilege rings but used here for layered architecture. Lower ring = closer to the metal; higher ring = consumer of lower-ring services.
| Ring | Layer | Where it lives | What it does |
|---|---|---|---|
| 0 | BSP | libs/ra8_board_<board>/src/boot/*.c + ld/linker_script.ld, with optional examples/ek_ra8d2/<tier>/.../<app>/src/{vector_table,system_init,secure_exception,nmi_exception,trustzone_init}.c and app-root linker-script overrides | Vector table, SystemInit, linker script. CPU-state setup before C runtime is live. Apps inherit board defaults unless they explicitly diverge. |
| 1 | Core fundamentals | libs/ra8_core/ | Pure-C utilities with no hardware dependencies (err codes, log, time, pin validator, register-protection helpers). Compiles identically on host and target. |
| 2 | Register layer | libs/ra8_hal/inc/ra8_*_regs.h | Hand-written register layouts derived from the HUM. No code paths – just typed enums + accessor inline functions. |
| 3 | HAL drivers | libs/ra8_hal/src/ra8_*.c | Hardware Abstraction Layer. Programmes peripherals via Ring-2 register headers. The vast majority of driver code lives here. |
| 4 | NSC veneers | libs/ra8_nsc/ | TrustZone Non-Secure-Callable veneers. Bridges between {World: S} and {World: NS} – the only place where __attribute__((cmse_nonsecure_entry)) is allowed. |
| 5 | Secure app | libs/ra8_secure_app/ | Secure-side application code (key vault, secure-boot trust anchor). Sits above the HAL but below the NS-callable veneer surface. |
| 6 | Application | Canonical inventory from scripts/dev/ra8_apps.py (for example, examples/ek_ra8d2/hw_validated/hil/blink/src/main.c), plus test mocks | The firmware "user code" – whatever drives the HAL to do something useful. The blink demo, board-bringup smoke tests, and unit-test harnesses all live at Ring 6. |
The numbering doesn't have to be contiguous; it's a coordinate system, not a rule book. A Ring 3 driver can include Ring 1 / Ring 2 headers freely. A Ring 6 application uses Ring 3 drivers via their public headers. Crossing down is fine; crossing up – a Ring 3 driver calling Ring 6 application code – is a layering violation.
The RA8D2 implements the Armv8-M Security Extension (TrustZone-M), which partitions execution into two worlds: Secure (S) and Non-Secure (NS). The SAU (Security Attribution Unit) plus the peripheral xxxSAR registers determine which world owns each address.
The tag declares the world a file expects to run in:
| Tag | Meaning | Where allowed |
|---|---|---|
| {World: S} | Runs in the Secure world. Has full access to all peripherals and memory. Cannot be called directly from NS code – only via NSC veneers. | libs/ra8_hal/, libs/ra8_*_pal/ (when serving the secure side), libs/ra8_secure_app/, per-app boot overrides (examples/ek_ra8d2/<tier>/.../<app>/src/{vector_table,system_init,...}.c), secure-side apps. |
| {World: NS} | Runs in the Non-Secure world. Reaches into Secure code only through __cmse_nonsecure_entry veneers in libs/ra8_nsc/. | libs/ra8_hal/ driver TUs that the SAU partition keeps NS, NS-side apps. |
| {World: NSC} | Non-Secure-Callable veneer code. The bridge between worlds. The .gnu.sgstubs section lands here at link time. | Only under libs/ra8_nsc/. |
| {World: MIXED} | A file that legitimately straddles both worlds (rare – typically a header consumed by both sides). | Header files only, sparingly. |
Three concrete rules the linter enforces:
GLCDC programming runs in the NS partition once SAU is up because the display layer is NS-attributed by default. The HAL TU itself is built to land in the NS image.
Holds 256-bit symmetric keys in a static array that's unreachable from NS after the SAU partition is enabled. Strictly Secure.
Carries cmse_nonsecure_entry attributes; lives under libs/ra8_nsc/ so the linker can place it in .gnu.sgstubs.
The Cortex-M85 boots in Secure mode on RA8D2; the blink demo never transitions to NS so it stays Secure-side.
Without these tags, a driver author can accidentally:
The pre-commit hook catches all three cases at the file-header level before the diff has a chance to hide the mistake.
When you add a .c or .h under libs/ra8_hal/, libs/ra8_*_pal/, libs/ra8_nsc/, libs/ra8_secure_app/, or a per-app dir (examples/<app>/):
That's the whole system.