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

FSP-style TrustZone secure-boot implementation for RA8D2. More...

#include "ra8_tz_secure_boot.h"
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_log.h"
Include dependency graph for ra8_tz_secure_boot.c:

Go to the source code of this file.

Enumerations

enum  ra8_tz_secure_boot_addr_t : uintptr_t {
  k_ra8_tz_sau_ctrl_addr = 0xE000EDD0UL ,
  k_ra8_tz_sau_type_addr = 0xE000EDD4UL ,
  k_ra8_tz_sau_rnr_addr = 0xE000EDD8UL ,
  k_ra8_tz_sau_rbar_addr = 0xE000EDDCUL ,
  k_ra8_tz_sau_rlar_addr = 0xE000EDE0UL ,
  k_ra8_tz_scb_vtor_ns_addr = 0xE002ED08UL ,
  k_ra8_tz_ipcsar_addr = 0x40008610UL ,
  k_ra8_tz_ipcpar_addr = 0x40008614UL ,
  k_ra8_tz_prcr_s_addr = 0x4001E3FAUL
}
 Memory-mapped register addresses used by the secure-boot. More...
enum  ra8_tz_secure_boot_sau_bit_t : uint32_t {
  k_ra8_tz_sau_ctrl_enable = 0x00000001U ,
  k_ra8_tz_sau_ctrl_allns = 0x00000002U ,
  k_ra8_tz_sau_rlar_enable = 0x00000001U ,
  k_ra8_tz_sau_rlar_nsc = 0x00000002U ,
  k_ra8_tz_sau_type_mask = 0x000000FFU
}
 Bit positions used to enable / configure each SAU region. More...
enum  ra8_tz_secure_boot_prcr_t : uint16_t {
  k_ra8_tz_prcr_s_key = 0xA500U ,
  k_ra8_tz_prcr_s_prc4_open = 0x0010U ,
  k_ra8_tz_prcr_s_open = 0xA510U ,
  k_ra8_tz_prcr_s_close = 0xA500U
}
 PRCR_S unlock key + per-group enable bits (HUM Ch 13.2.1). More...
enum  ra8_tz_secure_boot_partition_t : uint32_t {
  k_ra8_tz_part_code_nsc_base = 0x10000000U ,
  k_ra8_tz_part_code_nsc_limit = 0x100FFFE0U ,
  k_ra8_tz_part_ns_mram_base = 0x02080000U ,
  k_ra8_tz_part_ns_mram_limit = 0x020FFFE0U ,
  k_ra8_tz_part_sram_nsc_base = 0x12000000U ,
  k_ra8_tz_part_sram_nsc_limit = 0x1200FFE0U ,
  k_ra8_tz_part_ns_sram_base = 0x22100000U ,
  k_ra8_tz_part_ns_sram_limit = 0x221FFFE0U ,
  k_ra8_tz_part_ns_per_base = 0x50000000U ,
  k_ra8_tz_part_ns_per_limit = 0x5FFFFFE0U
}
 Canonical SAU region base / limit addresses (HUM Ch 4). More...

Functions

void ra8_tz_secure_boot_host_reset (void)
 Reset the host-side state for unit-test fixtures.
uint32_t ra8_tz_secure_boot_host_blxns_target (void)
 Read the captured BLXNS target (host / test).
static void internal_write32 (uintptr_t addr, uint32_t value)
 Write a 32-bit MMIO register (or capture on host).
static uint32_t internal_read32 (uintptr_t addr)
 Read a 32-bit MMIO register (or canned host value).
static void internal_write16 (uintptr_t addr, uint16_t value)
 Write a 16-bit MMIO register (or capture on host).
static void internal_dsb (void)
 Emit a Data Synchronisation Barrier (no-op on host).
static void internal_isb (void)
 Emit an Instruction Synchronisation Barrier (no-op on host).
static void internal_sau_set_region (uint8_t region, uint32_t base, uint32_t limit, bool is_nsc)
 Programme one SAU region via RNR/RBAR/RLAR.
ra8_err_t ra8_tz_secure_boot_sau_init (void)
 Programme the SAU regions documented in ra8_tz_sau_region_t.
ra8_err_t ra8_tz_secure_boot_security_init (uint32_t ipcsar_value, uint32_t ipcpar_value)
 Unlock PRCR_S.PRC4 and write IPCSAR + IPCPAR.
uint32_t ra8_tz_ns_signed_body_len (const uint32_t *ns_vector_table)
 Read the NS image's self-describing signed-body length.
static ra8_err_t internal_ns_verify_or_deny (const uint32_t *ns_vector_table)
 Authenticate the Non-Secure image before BLXNS (default-deny gate).
ra8_err_t ra8_tz_secure_boot_jump_ns (const uint32_t *ns_vector_table)
 Switch to NS state and jump to the NS image's reset vector.
ra8_err_t ra8_tz_secure_boot_run (uint32_t ipcsar_value, uint32_t ipcpar_value, const uint32_t *ns_vector_table)
 Run the full secure-boot sequence and (on target) BLXNS.
ra8_tz_secure_boot_step_t ra8_tz_secure_boot_get_step (void)
 Read the boot progress counter (debug / test).

Variables

static const char * s_tag = "TZBOOT"
 Logger tag for the secure-boot module.
static volatile ra8_tz_secure_boot_step_t s_step = k_ra8_tz_secure_boot_step_idle
 Progress counter exposed via ra8_tz_secure_boot_get_step.

Detailed Description

FSP-style TrustZone secure-boot implementation for RA8D2.

Tag
[Ring 1 / Boot] {World: S}

See ra8_tz_secure_boot.h for the full contract. This file owns the actual MMIO writes. The implementation is split into three phases (SAU init, security init, BLXNS) so unit tests can drive each phase against the host-side fake mmap.

The host-build path uses RA8_OFF_TARGET to swap the SAU / CPSCU MMIO writes for in-memory captures, lets the tests assert on the documented PRCR-unlock / IPCSAR-write sequence, and replaces the BLXNS instruction with a captured-target-then-return path.

Definition in file ra8_tz_secure_boot.c.

Enumeration Type Documentation

◆ ra8_tz_secure_boot_addr_t

enum ra8_tz_secure_boot_addr_t : uintptr_t

Memory-mapped register addresses used by the secure-boot.

SAU registers live in the System Control Space at 0xE000EDD0 (ARMv8-M architectural address). The Cortex-M85 Secure VTOR_NS is at 0xE000ED08 (the regular VTOR; writes to it from Secure state set VTOR_NS when SAU is enabled per ARMv8-M ARM section B3.2.4). CPSCU.IPCSAR / IPCPAR follow the layout in HUM Ch 3.2.1 / 3.2.2. PRCR_S lives in the SYSC block at base 0x4001E000 (HUM Ch 13.2.1).

Enumerator
k_ra8_tz_sau_ctrl_addr 

SAU Control.

k_ra8_tz_sau_type_addr 

SAU Type.

k_ra8_tz_sau_rnr_addr 

Region Num.

k_ra8_tz_sau_rbar_addr 

Region Base.

k_ra8_tz_sau_rlar_addr 

Region Lim.

k_ra8_tz_scb_vtor_ns_addr 

VTOR Non-Secure alias.

k_ra8_tz_ipcsar_addr 

CPSCU IPCSAR.

k_ra8_tz_ipcpar_addr 

CPSCU IPCPAR.

k_ra8_tz_prcr_s_addr 

SYSC PRCR_S (16-bit).

Definition at line 77 of file ra8_tz_secure_boot.c.

◆ ra8_tz_secure_boot_partition_t

Canonical SAU region base / limit addresses (HUM Ch 4).

Region 3 (NSC alias) deliberately targets the unused 0x10000000 IDAU alias rather than the actual .gnu.sgstubs placement. See project_sau_sgstubs_brick in project memory for the bench fault that drove that choice. RLAR limits are the upper bound minus the ARMv8-M 32-byte region quantum.

Enumerator
k_ra8_tz_part_code_nsc_base 

RA8 TrustZone part code NSC base.

k_ra8_tz_part_code_nsc_limit 

RA8 TrustZone part code NSC limit.

k_ra8_tz_part_ns_mram_base 

RA8 TrustZone part ns MRAM base.

k_ra8_tz_part_ns_mram_limit 

RA8 TrustZone part ns MRAM limit.

k_ra8_tz_part_sram_nsc_base 

RA8 TrustZone part SRAM NSC base.

k_ra8_tz_part_sram_nsc_limit 

RA8 TrustZone part SRAM NSC limit.

k_ra8_tz_part_ns_sram_base 

RA8 TrustZone part ns SRAM base.

k_ra8_tz_part_ns_sram_limit 

RA8 TrustZone part ns SRAM limit.

k_ra8_tz_part_ns_per_base 

RA8 TrustZone part ns per base.

k_ra8_tz_part_ns_per_limit 

RA8 TrustZone part ns per limit.

Definition at line 133 of file ra8_tz_secure_boot.c.

◆ ra8_tz_secure_boot_prcr_t

enum ra8_tz_secure_boot_prcr_t : uint16_t

PRCR_S unlock key + per-group enable bits (HUM Ch 13.2.1).

PRCR_S is a 16-bit register. The upper byte must equal the write key 0xA5 on every write or the entire transaction is dropped. Bit 4 (PRC4) is the gate for CPSCU security-attribution registers.

Enumerator
k_ra8_tz_prcr_s_key 

Unlock key (top byte).

k_ra8_tz_prcr_s_prc4_open 

PRC4 gate open (bit 4).

k_ra8_tz_prcr_s_open 

Key | PRC4 (unlock value).

k_ra8_tz_prcr_s_close 

Key with PRC4 = 0 (lock).

Definition at line 115 of file ra8_tz_secure_boot.c.

◆ ra8_tz_secure_boot_sau_bit_t

Bit positions used to enable / configure each SAU region.

Mirrors the ARMv8-M ARM register-field encoding (D.4.5 SAU_CTRL, D.4.7 SAU_RLAR). Names are kept identical to the FSP equivalents so the bench-debug trail is easy to follow.

Enumerator
k_ra8_tz_sau_ctrl_enable 

CTRL.ENABLE.

k_ra8_tz_sau_ctrl_allns 

CTRL.ALLNS (kept 0).

k_ra8_tz_sau_rlar_enable 

RLAR.ENABLE.

k_ra8_tz_sau_rlar_nsc 

RLAR.NSC.

k_ra8_tz_sau_type_mask 

TYPE.SREGION lower 8b.

Definition at line 98 of file ra8_tz_secure_boot.c.

Function Documentation

◆ internal_dsb()

void internal_dsb ( void )
inlinestatic

Emit a Data Synchronisation Barrier (no-op on host).

Wraps the dsb 0xF inline-asm so the file's hot path stays readable. Host build compiles to a true no-op.

Precondition
Caller is in Secure state (any context valid on host).
Used only inside the secure-boot sequence.
Postcondition
All outstanding stores have completed before the next access.
On host: no-op.
Note
Not thread-safe.
Since
0.1.0

Definition at line 369 of file ra8_tz_secure_boot.c.

References RA8_INTERNAL.

Referenced by ra8_trustzone_init(), ra8_tz_secure_boot_sau_init(), and ra8_tz_secure_boot_security_init().

◆ internal_isb()

void internal_isb ( void )
inlinestatic

Emit an Instruction Synchronisation Barrier (no-op on host).

Wraps the isb 0xF inline-asm so the file's hot path stays readable. Host build compiles to a true no-op.

Precondition
Caller is in Secure state (any context valid on host).
Used only inside the secure-boot sequence.
Postcondition
Pipeline flushed; subsequent fetches see post-write SAU state.
On host: no-op.
Note
Not thread-safe.
Since
0.1.0

Definition at line 389 of file ra8_tz_secure_boot.c.

References RA8_INTERNAL.

Referenced by ra8_trustzone_init(), and ra8_tz_secure_boot_sau_init().

◆ internal_ns_verify_or_deny()

ra8_err_t internal_ns_verify_or_deny ( const uint32_t * ns_vector_table)
static

Authenticate the Non-Secure image before BLXNS (default-deny gate).

Root-of-trust gate factored out of ra8_tz_secure_boot_jump_ns so the caller stays within the function-length budget. On a target build with RA8_ENABLE_ROOT_OF_TRUST enabled it reads the NS image's self-describing signed-body length via ra8_tz_ns_signed_body_len (an ra8_ns_rot_header_t the NS linker emits at k_ra8_tz_ns_rot_header_offset), locates the trailer that the signing tool appended immediately after that body via ra8_rot_trailer_after, then re-computes SHA-256 and verifies the NS image's ECDSA-P256 signature against the provisioned root public key via ra8_rot_verify_image. This mirrors the copy-to-run boundary exactly (the trailer sits at ns_vector_table + body_len). Any failure – a missing / bad header, or a failed verify – returns a non-k_ra8_ok error and the caller must NOT BLXNS.

Security:
body_len is read from the untrusted NS image, but this is safe for the identical reason it is safe in copy-to-run (which reads it from the untrusted trailer): a lie about body_len merely changes which bytes get hashed, and the attacker still cannot produce a valid ECDSA-P256 signature over any body without the held-out private key. A wrong body_len therefore fails the signature check and default-denies. (Here body_len is additionally covered by the signature, since the header word sits inside the signed body.)

With the flag OFF (default) – or under RA8_OFF_TARGET, where the NS image and trailer do not exist at a real address on the unit-test host – the gate is absent and this returns k_ra8_ok so the jump proceeds unverified, exactly as before. The gate's decision logic is covered directly in tests/security/src/test_ra8_root_of_trust.c and the header read in tests/security/src/test_tz_secure_boot.c.

Parameters
[in]ns_vector_tableBase of the NS image (its vector table); non-NULL.
Returns
ra8_err_t Error code.
Return values
k_ra8_okImage authentic, or verification is disabled.
k_ra8_err_null_ptrns_vector_table is NULL.
k_ra8_err_validation_failedNS RoT header missing / wrong magic.
k_ra8_err_invalid_sizeHeader body length out of range.
k_ra8_err_*Root-of-trust gate denied the NS image.
Precondition
ns_vector_table is non-NULL.
On an enabled target build, the NS image carries an ra8_ns_rot_header_t at k_ra8_tz_ns_rot_header_offset and a signed ra8_rot_trailer_t at ns_vector_table + body_len.
Postcondition
On any non-k_ra8_ok return the caller does NOT BLXNS.
No NS image bytes are modified.
Note
Not thread-safe; runs once at boot.
Since
0.1.0

Definition at line 589 of file ra8_tz_secure_boot.c.

References k_ra8_err_invalid_size, k_ra8_err_validation_failed, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_INTERNAL, ra8_log_error, ra8_rot_trailer_after(), ra8_rot_verify_image(), ra8_tz_ns_signed_body_len(), and s_tag.

Referenced by ra8_tz_secure_boot_jump_ns().

◆ internal_read32()

uint32_t internal_read32 ( uintptr_t addr)
static

Read a 32-bit MMIO register (or canned host value).

On target the function dereferences the MMIO address. On host (RA8_OFF_TARGET) it returns the canned values tests expect for SAU_TYPE (= 8 regions) and IPCSAR.

Parameters
[in]addrTarget address.
Returns
Read value (host: documented constant for SAU_TYPE).
Return values
8UWhen addr == k_ra8_tz_sau_type_addr on host.
s_host.ipcsar_valueWhen addr == k_ra8_tz_ipcsar_addr on host.
0UFor any other addr on host.
Precondition
addr is one of the documented SAU / CPSCU addresses.
Caller is in Secure state on target.
Postcondition
No state change.
Returned value matches the most recent write on host.
Note
Not thread-safe.
Since
0.1.0

Definition at line 304 of file ra8_tz_secure_boot.c.

References k_ra8_tz_ipcsar_addr, k_ra8_tz_sau_type_addr, and RA8_INTERNAL.

Referenced by ra8_trustzone_init(), and ra8_tz_secure_boot_sau_init().

◆ internal_sau_set_region()

void internal_sau_set_region ( uint8_t region,
uint32_t base,
uint32_t limit,
bool is_nsc )
static

Programme one SAU region via RNR/RBAR/RLAR.

Selects region via SAU_RNR, writes the base address into SAU_RBAR, and writes limit | ENABLE [| NSC] into SAU_RLAR. Captures the values into s_host on host so the layout-sanity unit test can inspect them.

Parameters
[in]regionRegion index (0..SAU_TYPE.SREGION - 1).
[in]baseBase address (32-byte aligned).
[in]limitUpper-bound minus 32 (32-byte aligned).
[in]is_nsctrue to mark the region as Non-Secure Callable.
Precondition
region < k_ra8_tz_sau_region_count.
Caller is in Secure state.
Postcondition
Region's RBAR + RLAR loaded.
Region enabled (RLAR.ENABLE = 1).
Note
Not thread-safe.
Since
0.1.0

Definition at line 422 of file ra8_tz_secure_boot.c.

References internal_write32(), k_ra8_tz_sau_rbar_addr, k_ra8_tz_sau_region_count, k_ra8_tz_sau_rlar_addr, k_ra8_tz_sau_rlar_enable, k_ra8_tz_sau_rlar_nsc, and k_ra8_tz_sau_rnr_addr.

Referenced by ra8_trustzone_init(), and ra8_tz_secure_boot_sau_init().

◆ internal_write16()

void internal_write16 ( uintptr_t addr,
uint16_t value )
static

Write a 16-bit MMIO register (or capture on host).

On target the value is stored at addr. On host the PRCR_S write is captured in s_host and the unlock / relock counts are incremented based on the PRC4 bit.

Parameters
[in]addrTarget address.
[in]valueValue to write.
Precondition
PRCR_S is the only 16-bit writer; addr must equal k_ra8_tz_prcr_s_addr.
Caller is in Secure state.
Postcondition
Target write lands; host capture updated.
Caller can verify via the host-state accessors.
Note
Not thread-safe.
Since
0.1.0

Definition at line 340 of file ra8_tz_secure_boot.c.

References k_ra8_tz_prcr_s_prc4_open, and RA8_INTERNAL.

Referenced by ra8_tz_secure_boot_security_init().

◆ internal_write32()

void internal_write32 ( uintptr_t addr,
uint32_t value )
static

Write a 32-bit MMIO register (or capture on host).

On target the value is stored directly into the MMIO register at addr. On host (RA8_OFF_TARGET) the value is captured in s_host so unit tests can inspect the write.

Parameters
[in]addrTarget address.
[in]valueValue to write.
Precondition
addr is one of the documented SAU / CPSCU / VTOR addresses.
Caller is in Secure state (target) / unit-test context (host).
Postcondition
Target write lands; host capture updated.
Caller can verify via the host-state accessors.
Note
Not thread-safe; runs only during secure boot.
Since
0.1.0

Definition at line 263 of file ra8_tz_secure_boot.c.

References k_ra8_tz_ipcpar_addr, k_ra8_tz_ipcsar_addr, k_ra8_tz_sau_ctrl_addr, k_ra8_tz_scb_vtor_ns_addr, and RA8_INTERNAL.

Referenced by internal_sau_set_region(), ra8_trustzone_init(), ra8_tz_secure_boot_jump_ns(), ra8_tz_secure_boot_sau_init(), and ra8_tz_secure_boot_security_init().

◆ ra8_tz_ns_signed_body_len()

uint32_t ra8_tz_ns_signed_body_len ( const uint32_t * ns_vector_table)
nodiscard

Read the NS image's self-describing signed-body length.

Reads the ra8_ns_rot_header_t the NS linker embedded at k_ra8_tz_ns_rot_header_offset from ns_vector_table and returns its body_len field after confirming the header magic. This is the BLXNS boundary's analog of the DFU header's body-length word on the copy-to-run boundary: it tells the root-of-trust gate exactly how many bytes to hash and where the appended ra8_rot_trailer_t begins (ns_vector_table + body_len).

Reading body_len from the untrusted NS image is safe: a lie about it only changes which bytes are hashed, and no attacker can forge a valid ECDSA-P256 signature over any body without the held-out private key – so a wrong length simply default-denies at the signature check.

Parameters
[in]ns_vector_tableBase of the NS image (its vector table). May be NULL (handled: returns 0).
Returns
Signed body length in bytes, or 0 on any failure (deny sentinel).
Return values
0ns_vector_table is NULL, or the header magic is wrong (no RoT header present) – the caller must NOT BLXNS.
non-zeroThe body_len recorded in the NS RoT header.
Precondition
ns_vector_table addresses at least k_ra8_tz_ns_rot_header_offset + sizeof(ra8_ns_rot_header_t) bytes, or is NULL.
The NS image was linked with a .ns_rot_header section (RoT builds).
Postcondition
No state is mutated; the result depends only on the header bytes.
A 0 return unambiguously signals "no valid header" to the caller.
Note
Thread-safe (pure read; no statics). Performs no MMIO – it reads the already-resident NS image, so no HUM citation applies.
See also
ra8_ns_rot_header_t
ra8_rot_trailer_after
Since
0.1.0

Definition at line 510 of file ra8_tz_secure_boot.c.

References ra8_ns_rot_header_t::body_len, k_ra8_tz_ns_rot_header_magic, k_ra8_tz_ns_rot_header_offset, ra8_log_error, and s_tag.

Referenced by internal_ns_verify_or_deny().

◆ ra8_tz_secure_boot_get_step()

ra8_tz_secure_boot_step_t ra8_tz_secure_boot_get_step ( void )

Read the boot progress counter (debug / test).

Returns the most-recent ra8_tz_secure_boot_step_t value stored in the internal progress counter. Useful for J-Link memprobe scripts on the bench and for unit-test assertions on the host.

Returns
Current progress step.
Return values
k_ra8_tz_secure_boot_step_idlePre-run.
k_ra8_tz_secure_boot_step_sau_doneSAU init complete.
k_ra8_tz_secure_boot_step_ipcsar_writtenIPCSAR landed.
k_ra8_tz_secure_boot_step_branchedBLXNS executed.
Precondition
None.
None.
Postcondition
No state change.
Caller-visible state matches the most recent boot step.
Note
Thread-safe (single 32-bit load).
Since
0.1.0

Definition at line 691 of file ra8_tz_secure_boot.c.

References s_step.

Referenced by ra8_trustzone_init().

◆ ra8_tz_secure_boot_host_blxns_target()

uint32_t ra8_tz_secure_boot_host_blxns_target ( void )

Read the captured BLXNS target (host / test).

Host-only accessor: returns the NS reset vector that ra8_tz_secure_boot_jump_ns was last asked to branch to. On target builds this returns 0 because BLXNS does not return.

Returns
Captured reset-vector address, or 0 if not yet armed.
Return values
0BLXNS not yet armed (or running on target).
non-zeroNS reset vector that was loaded for BLXNS.
Precondition
None.
None.
Postcondition
No state change.
Caller-visible state matches the most recent BLXNS arm.
Note
Test-only on host; returns 0 on target.
Since
0.1.0

Definition at line 233 of file ra8_tz_secure_boot.c.

◆ ra8_tz_secure_boot_host_reset()

void ra8_tz_secure_boot_host_reset ( void )

Reset the host-side state for unit-test fixtures.

Host-only helper that clears the fake PRCR_S / IPCSAR / IPCPAR captures and the BLXNS target so each test starts from a known baseline. Cross-compiled (target) builds expose the symbol but the body is empty.

Precondition
None.
None.
Postcondition
Host state reset to k_ra8_tz_secure_boot_step_idle.
BLXNS target capture cleared.
Note
Test-only on host; no-op on target.
Since
0.1.0

Definition at line 225 of file ra8_tz_secure_boot.c.

References s_tag.

◆ ra8_tz_secure_boot_jump_ns()

ra8_err_t ra8_tz_secure_boot_jump_ns ( const uint32_t * ns_vector_table)
nodiscard

Switch to NS state and jump to the NS image's reset vector.

Reads the initial-SP slot of the NS vector table into MSP_NS, sets VTOR_NS to ns_vector_table, then performs a BLXNS to the reset-vector slot. The function is declared [[noreturn]] and does not return on hardware.

On target, a root-of-trust gate runs BEFORE VTOR_NS is armed and BEFORE the BLXNS: ra8_rot_verify_image must authenticate the Non-Secure image (SHA-256 + ECDSA-P256) against the provisioned root public key. This is default-deny – any failure (missing / malformed signature trailer, tampered body, or an invalid signature) returns the verify error and the function does NOT branch into the NS world. The signed body length is read from the NS image's own ra8_ns_rot_header_t (emitted by the NS linker at k_ra8_tz_ns_rot_header_offset, see ra8_tz_ns_signed_body_len), and the ra8_rot_trailer_t sits immediately after that body at ns_vector_table + body_len – the same self-describing [ body ] [ trailer ] layout the copy-to-run boundary uses.

On the host (RA8_OFF_TARGET defined) the function stamps the progress counter, sets s_ra8_tz_secure_boot_blxns_target to the supplied reset vector, and returns k_ra8_ok so unit tests can assert the documented transition state; the gate's decision logic is covered directly in tests/security/src/test_ra8_root_of_trust.c.

Parameters
[in]ns_vector_tablePointer to the NS image's vector table.
Returns
ra8_err_t On host only – never reached on target.
Return values
k_ra8_okOn host: BLXNS state captured.
k_ra8_err_null_ptrns_vector_table is NULL.
k_ra8_err_invalid_argns_vector_table is not 4-byte aligned, or the reset-vector slot holds an obviously bogus value (0 or 0xFFFFFFFF).
k_ra8_err_*On target: the root-of-trust gate denied the NS image (e.g. k_ra8_err_crc_mismatch for a bad signature) – BLXNS is not performed.
Precondition
ns_vector_table is non-NULL and 4-byte aligned.
ns_vector_table[0] (initial SP) and ns_vector_table[1] (reset vector) hold valid values for the NS image.
Postcondition
On hardware: control transfers to the NS image and never returns to the caller.
On host: s_ra8_tz_secure_boot_blxns_target captures the NS reset vector for test inspection.
Note
Not thread-safe; runs once at boot from a single-threaded context.
Since
0.1.0

Definition at line 612 of file ra8_tz_secure_boot.c.

References internal_ns_verify_or_deny(), internal_write32(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_tz_scb_vtor_ns_addr, k_ra8_tz_secure_boot_step_blxns_armed, k_ra8_tz_secure_boot_step_branched, RA8_CHECK_NULL_PTR, ra8_log_error, ra8_log_error_val, s_step, and s_tag.

Referenced by main(), ra8_trustzone_init(), and ra8_tz_secure_boot_run().

◆ ra8_tz_secure_boot_run()

ra8_err_t ra8_tz_secure_boot_run ( uint32_t ipcsar_value,
uint32_t ipcpar_value,
const uint32_t * ns_vector_table )
nodiscard

Run the full secure-boot sequence and (on target) BLXNS.

Convenience wrapper: ra8_tz_secure_boot_sau_init -> ra8_tz_secure_boot_security_init -> ra8_tz_secure_boot_jump_ns, returning the first non-OK status.

Parameters
[in]ipcsar_valueForwarded to security_init.
[in]ipcpar_valueForwarded to security_init.
[in]ns_vector_tableForwarded to jump_ns.
Returns
ra8_err_t First failing step's status; never returns on target in the happy path.
Return values
k_ra8_okOn host happy path (BLXNS captured).
k_ra8_err_null_ptrns_vector_table is NULL.
k_ra8_err_not_supportedSAU_TYPE.SREGION < 5.
k_ra8_err_invalid_argNS vector table mis-aligned / invalid.
Precondition
Secure state, single-threaded boot context.
ns_vector_table non-NULL.
Postcondition
On hardware happy path: NS image running, no return.
On any failure step: SAU left in whatever partial state the failing call established; caller logs and halts.
Note
Not thread-safe; runs once at boot.
Since
0.1.0

Definition at line 671 of file ra8_tz_secure_boot.c.

References k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_tz_secure_boot_jump_ns(), ra8_tz_secure_boot_sau_init(), ra8_tz_secure_boot_security_init(), and s_tag.

◆ ra8_tz_secure_boot_sau_init()

ra8_err_t ra8_tz_secure_boot_sau_init ( void )
nodiscard

Programme the SAU regions documented in ra8_tz_sau_region_t.

Equivalent to the FSP R_BSP_SAUInit function: writes each region's RBAR / RLAR, then enables the SAU with ALLNS = 0. Does NOT touch CPSCU or jump to the NS image – callers issue ra8_tz_secure_boot_security_init and ra8_tz_secure_boot_jump_ns separately so unit tests can exercise each phase in isolation.

Returns
ra8_err_t Error code.
Return values
k_ra8_okSAU programmed and enabled.
k_ra8_err_not_supportedSAU_TYPE.SREGION < 5.
Precondition
Caller is in Secure state (the SAU window lives at 0xE000EDD0 which is secure-only).
This function has not been called previously in the current boot (SAU programming is one-shot per reset).
Postcondition
On success, SAU_CTRL.ENABLE = 1 and the five regions cover the canonical layout.
On failure, the SAU stays disabled (default-allow Secure).
Note
Not thread-safe; runs once at boot.
Since
0.1.0

Definition at line 441 of file ra8_tz_secure_boot.c.

References internal_dsb(), internal_isb(), internal_read32(), internal_sau_set_region(), internal_write32(), k_ra8_err_not_supported, k_ra8_ok, k_ra8_tz_part_code_nsc_base, k_ra8_tz_part_code_nsc_limit, k_ra8_tz_part_ns_mram_base, k_ra8_tz_part_ns_mram_limit, k_ra8_tz_part_ns_per_base, k_ra8_tz_part_ns_per_limit, k_ra8_tz_part_ns_sram_base, k_ra8_tz_part_ns_sram_limit, k_ra8_tz_part_sram_nsc_base, k_ra8_tz_part_sram_nsc_limit, k_ra8_tz_sau_ctrl_addr, k_ra8_tz_sau_ctrl_enable, k_ra8_tz_sau_region_code_nsc, k_ra8_tz_sau_region_count, k_ra8_tz_sau_region_ns_mram, k_ra8_tz_sau_region_ns_periph, k_ra8_tz_sau_region_ns_sram, k_ra8_tz_sau_region_sram_nsc, k_ra8_tz_sau_type_addr, k_ra8_tz_sau_type_mask, k_ra8_tz_secure_boot_step_sau_done, ra8_log_error, s_step, and s_tag.

Referenced by ra8_trustzone_init(), and ra8_tz_secure_boot_run().

◆ ra8_tz_secure_boot_security_init()

ra8_err_t ra8_tz_secure_boot_security_init ( uint32_t ipcsar_value,
uint32_t ipcpar_value )
nodiscard

Unlock PRCR_S.PRC4 and write IPCSAR + IPCPAR.

Writes ipcsar_value to CPSCU.IPCSAR and ipcpar_value to CPSCU.IPCPAR after first opening the PRCR_S.PRC4 write-protect gate (HUM Ch 13.2.1 "PRCR_S" – key 0xA510 at address 0x4001E3FA). The gate is closed again before the function returns.

For the cpu1_pingpong_ipc app the canonical value is ipcsar_value = 0x00050000, which sets SAIPCIR0 (IPC0 channel 0, CPU1 -> CPU0) and SAIPCIR2 (IPC1 channel 0, CPU0 -> CPU1) – the two channels CPU1 (always-NS) must reach. ipcpar_value stays at 0 so the channels remain Privileged-only.

Parameters
[in]ipcsar_valueValue to write into CPSCU.IPCSAR.
[in]ipcpar_valueValue to write into CPSCU.IPCPAR.
Returns
ra8_err_t Error code.
Return values
k_ra8_okAlways (the unlock + write + relock sequence cannot fail in software; bench bring-up may still observe read-back mismatches if the chip's CPSCU is in an unexpected state).
Precondition
Caller is in Secure state (CPSCU and PRCR_S are secure-only).
Caller has already programmed the SAU partition.
Postcondition
IPCSAR contains ipcsar_value (verifiable via JTAG read).
PRCR_S.PRC4 is cleared (write-protect restored).
Note
Not thread-safe; runs once at boot.
Since
0.1.0

Definition at line 481 of file ra8_tz_secure_boot.c.

References internal_dsb(), internal_write16(), internal_write32(), k_ra8_ok, k_ra8_tz_ipcpar_addr, k_ra8_tz_ipcsar_addr, k_ra8_tz_prcr_s_addr, k_ra8_tz_prcr_s_close, k_ra8_tz_prcr_s_open, k_ra8_tz_secure_boot_step_ipcsar_written, k_ra8_tz_secure_boot_step_prcr_relocked, k_ra8_tz_secure_boot_step_prcr_unlocked, and s_step.

Referenced by ra8_trustzone_init(), and ra8_tz_secure_boot_run().

Variable Documentation

◆ s_step

Progress counter exposed via ra8_tz_secure_boot_get_step.

Stamped at each forward-progress milestone in the secure boot. Bench scripts read this through SWD to find out which phase wedged when bring-up never reaches the NS image.

Note
File-private; modify only via the internal steppers.
Warning
Do not modify directly.
Since
0.1.0

Definition at line 58 of file ra8_tz_secure_boot.c.

Referenced by ra8_tz_secure_boot_get_step(), ra8_tz_secure_boot_jump_ns(), ra8_tz_secure_boot_sau_init(), and ra8_tz_secure_boot_security_init().

◆ s_tag

const char* s_tag = "TZBOOT"
static

Logger tag for the secure-boot module.

Component identifier used by ra8_log_* so secure-boot log lines are easy to grep for in JTAG-captured RTT output.

Note
File-private; never accessed from outside.
Warning
Do not modify.
Since
0.1.0

Definition at line 45 of file ra8_tz_secure_boot.c.