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

Non-Secure Callable veneers – the only NS->S gateway. More...

#include <stdint.h>
#include "ra8_err.h"
#include "ra8_nsc_veneer.h"
Include dependency graph for ra8_nsc.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  ra8_nsc_limits_t : uint32_t {
  k_ra8_nsc_xspi_max_read = 4096U ,
  k_ra8_nsc_eth_frame_max = 1518U ,
  k_ra8_nsc_log_msg_max_len = 128U
}
 Boundary-policy limits exposed to NS callers. More...

Functions

ra8_err_t ra8_nsc_xspi_read (uint32_t flash_off, uint8_t *ns_dst, uint32_t len)
 NSC veneer: read len bytes from external XSPI flash.
ra8_err_t ra8_nsc_xspi_status (uint8_t instance, uint32_t *out_mask)
 NSC veneer: query secure-side XSPI status.
ra8_err_t ra8_nsc_eth_send (const uint8_t *ns_frame, uint16_t len)
 NSC veneer: hand a frame to the secure ESWM transmit path.
ra8_err_t ra8_nsc_eth_recv (uint8_t *ns_buf, uint16_t *inout_len)
 NSC veneer: pull the next received frame to NS memory.
ra8_err_t ra8_nsc_log_emit (const char *tag, const char *message)
 NSC veneer: emit a log line via the secure ITM channel.
ra8_err_t ra8_nsc_periph_init (void)
 NSC veneer: bring up the secure-side peripheral substrate.
ra8_err_t ra8_nsc_wdt_start (void)
 NSC veneer: arm the Secure WDT with the e-reader configuration.
void ra8_nsc_wdt_refresh (void)
 NSC veneer: refresh the Secure WDT down-counter.
ra8_err_t ra8_nsc_key_vault_challenge (uint16_t slot, const uint8_t *ns_chal, uint8_t *ns_digest)
 NSC veneer: SHA-256(key XOR challenge) for a stored slot.
ra8_err_t ra8_nsc_ota_commit (uint8_t target_bank)
 NSC veneer: commit OTA target bank as the boot bank.
ra8_err_t ra8_nsc_flash_bank_config (uint32_t raw_value)
 NSC veneer: write the flash bank-config word.

Detailed Description

Non-Secure Callable veneers – the only NS->S gateway.

Tag
[Ring 4 / NSC] {World: NSC}

The NSC layer is the only gateway through which Non-Secure code can reach Secure-side resources. Every function declared here is a veneer that:

  1. Lives in the .gnu.sgstubs output section, so the CPU accepts an NS->S transition at these entry points and nowhere else.
  2. Validates every argument against secure-world policy. NS code is untrusted: an "obviously safe" pointer may aim into the Secure region, and a length may be UINT32_MAX.
  3. Calls the underlying secure-side driver.
  4. Returns through the cmse_nonsecure_entry epilogue, which clears caller-saved registers so no Secure state rides back out.
Build modes:
RA8_NSC_VENEER (see ra8_nsc_veneer.h) expands to the real cmse_nonsecure_entry attribute – the thing that actually emits the secure gateway – only in a Secure-world compile, i.e. with both RA8_TRUSTZONE_ENABLE and -mcmse in effect. Non-Secure TUs and the host unit tests take the plain-declaration branch and call these as ordinary C functions; the range checks compile to no-ops there, which is correct because those builds have no S/NS boundary to police. ra8_nsc_veneer.h is the single authority for that macro and #undefs before defining, so include order cannot silently drop the cmse attribute.
Validation policy:
  • Raw pointers do cross, and every one is range-checked before it is dereferenced. RA8_NSC_CHECK_NS_RANGE_R / RA8_NSC_CHECK_NS_RANGE_RW wrap cmse_check_address_range (the Armv8-M TT instruction), which asks the SAU/MPU whether an NS caller could legitimately touch [ptr, ptr+len). Ordering is load-bearing: validate a pointer, then dereference it, then use that value to size the next check. Reversing those steps turns a veneer into an oracle that reads Secure memory one word at a time – see ra8_nsc_eth_recv().
  • Out-of-range lengths are rejected, never clamped. A silent clamp would hand the caller a short result it did not ask for; the veneers return k_ra8_err_invalid_arg.
  • NUL-terminated strings are checked against the copy cap, not their length – the length cannot be known without first reading NS memory. The veneer validates the longest prefix it may touch, then bounded-copies into secure scratch. See ra8_nsc_log_emit().
  • No Secure-side state leaks. Read paths copy only the bytes asked for. Status veneers return packed bit-masks, not addresses.

Definition in file ra8_nsc.h.

Enumeration Type Documentation

◆ ra8_nsc_limits_t

enum ra8_nsc_limits_t : uint32_t

Boundary-policy limits exposed to NS callers.

These are the hard caps the veneers enforce. NS code can read them directly so it never has to make a call that the secure side will reject.

Enumerator
k_ra8_nsc_xspi_max_read 

Max bytes per ra8_nsc_xspi_read.

k_ra8_nsc_eth_frame_max 

Max ethernet frame bytes.

k_ra8_nsc_log_msg_max_len 

Truncated copy size for logs.

Definition at line 407 of file ra8_nsc.h.

Function Documentation

◆ ra8_nsc_eth_recv()

ra8_err_t ra8_nsc_eth_recv ( uint8_t * ns_buf,
uint16_t * inout_len )
nodiscard

NSC veneer: pull the next received frame to NS memory.

Parameters
[out]ns_bufDestination buffer.
[in,out]inout_lenOn entry: capacity. On exit: bytes written.
Returns
ra8_err_t error code.
Return values
k_ra8_okBytes copied.
k_ra8_err_no_dataNo frame ready.
k_ra8_err_null_ptrns_buf / inout_len NULL.
k_ra8_err_invalid_argCapacity zero / too small.
Precondition
ns_buf and inout_len non-NULL.
Postcondition
On success, *inout_len holds the actual byte count.
TrustZone Safety:
  • Validates: capacity bound; both pointers in NS region.
  • Trusts: ESWM RX descriptor management.
  • Denies: secure-side scratch leakage – bytes are copied, not aliased.
Since
0.1.0

NSC veneer: pull the next received frame to NS memory.

Validates capacity and pointer ranges, then forwards to ra8_net_pal_recv_frame.

Parameters
[out]ns_bufNon-Secure destination buffer.
[in,out]inout_lenIn: capacity; out: bytes written.
Returns
ra8_err_t outcome.
Return values
k_ra8_okFrame copied; *inout_len updated.
k_ra8_err_null_ptrA pointer argument was NULL.
k_ra8_err_invalid_argCapacity below the frame max.
Precondition
TrustZone substrate has been initialized.
Both pointers lie in the NS data region.
Postcondition
On success *inout_len reflects the byte count copied.
On failure *ns_buf may still have been touched.
Note
Thread-safe: serialises through the secure ra8_net_pal lock.
Since
0.1.0

Definition at line 82 of file ra8_nsc_eth.c.

References k_ra8_err_invalid_arg, k_ra8_nsc_eth_frame_max, RA8_CHECK_NULL_PTR, ra8_net_pal_recv_frame(), RA8_NSC_CHECK_NS_RANGE_RW, RA8_NSC_VENEER, and s_tag.

◆ ra8_nsc_eth_send()

ra8_err_t ra8_nsc_eth_send ( const uint8_t * ns_frame,
uint16_t len )
nodiscard

NSC veneer: hand a frame to the secure ESWM transmit path.

Parameters
[in]ns_framePointer to a complete ethernet frame in NS RAM.
[in]lenFrame length in bytes.
Returns
ra8_err_t error code.
Return values
k_ra8_okFrame queued.
k_ra8_err_null_ptrns_frame NULL.
k_ra8_err_invalid_argLength out of range.
k_ra8_err_no_memTX ring full.
Precondition
ns_frame non-NULL and points into NS data region.
Length <= k_ra8_nsc_eth_frame_max.
Postcondition
On success, the frame is owned by the secure TX descriptor ring; the NS caller may free / overwrite ns_frame.
TrustZone Safety:
  • Validates: length cap; ns_frame is in NS region.
  • Trusts: ESWM driver descriptor management.
  • Denies: raw pointer pass-through – the secure side copies bytes into its own descriptor before the IRQ context fires.
Since
0.1.0

NSC veneer: hand a frame to the secure ESWM transmit path.

Validates the NS-side pointer/length, runs cmse_check_address_range (TZ builds), and forwards to ra8_net_pal_send_frame.

Parameters
[in]ns_frameNon-Secure source buffer holding the L2 frame.
[in]lenFrame length in bytes; 1..k_ra8_nsc_eth_frame_max.
Returns
ra8_err_t outcome.
Return values
k_ra8_okFrame queued for TX.
k_ra8_err_null_ptrns_frame was NULL.
k_ra8_err_invalid_arglen out of range.
Precondition
TrustZone substrate has been initialized.
ns_frame lies entirely within the NS data region.
Postcondition
On success the secure-side TX path owns a copy of the frame.
On failure no bytes were forwarded to ra8_net_pal.
Note
Thread-safe: serialises through the secure ra8_net_pal lock.
Since
0.1.0

Definition at line 50 of file ra8_nsc_eth.c.

References k_ra8_err_invalid_arg, k_ra8_nsc_eth_frame_max, RA8_CHECK_NULL_PTR, ra8_net_pal_send_frame(), RA8_NSC_CHECK_NS_RANGE_R, RA8_NSC_VENEER, and s_tag.

◆ ra8_nsc_flash_bank_config()

ra8_err_t ra8_nsc_flash_bank_config ( uint32_t raw_value)
nodiscard

NSC veneer: write the flash bank-config word.

Parameters
[in]raw_valueRaw value forwarded to the secure side.
Returns
ra8_err_t code.

Forwards the 32-bit raw value through ra8_ota_commit_set_bank_config which masks it down to the allowed bits inside the secure world. The veneer's value is in labelling the operation as crossing the security boundary, so static analysis can flag NS-side callers.

Parameters
[in]raw_valueCaller-supplied bank-config word.
Returns
ra8_err_t outcome.
Return values
k_ra8_okBank-config word latched (after secure mask).
k_ra8_err_invalid_argSecure side rejected the value.
Precondition
TrustZone substrate up.
Caller has authority to mutate the bank-config (policy is enforced in the secure world).
Postcondition
On success the persisted bank-config word is updated.
On failure no flash bytes were written.
TrustZone:
NS->S boundary via cmse_nonsecure_entry. Scalar argument only; the secure side is responsible for masking off bits the NS world is not permitted to flip.
Note
Thread-safe: serialised by the secure ra8_ota lock.
Since
0.1.0

Definition at line 89 of file ra8_nsc_ota.c.

References RA8_NSC_VENEER, and ra8_ota_commit_set_bank_config().

◆ ra8_nsc_key_vault_challenge()

ra8_err_t ra8_nsc_key_vault_challenge ( uint16_t slot,
const uint8_t * ns_chal,
uint8_t * ns_digest )
nodiscard

NSC veneer: SHA-256(key XOR challenge) for a stored slot.

The only operation the Non-Secure world can perform on the secure key vault. The raw key never leaves the secure world; this veneer copies the challenge into secure scratch, XORs it with the slot key, hashes the result, and copies the 32-byte digest back to NS memory. NS callers can then verify the digest matches their expected value (e.g., for HMAC or PBKDF2 style derivation) without ever seeing the key.

Parameters
[in]slotVault slot index 0..7.
[in]ns_chal32-byte challenge in NS memory.
[out]ns_digest32-byte digest buffer in NS memory.
Returns
ra8_err_t error code.
Return values
k_ra8_okDigest written.
k_ra8_err_null_ptrns_chal / ns_digest NULL.
k_ra8_err_invalid_argslot >= 8.
Precondition
PAL has been initialized; the secure key vault has been programmed with at least one key in the requested slot.
Postcondition
ns_digest[0..31] holds SHA-256(key XOR challenge).
TrustZone Safety:
  • Validates: slot in range; both NS pointers in NS region (cmse_check); buffer lengths fit 32-byte windows.
  • Trusts: the secure key vault's static slot array.
  • Denies: raw key access from NS. Only the digest crosses.
Note
Thread safety: not thread-safe; the SHA-256 sponge is single-instance.
Since
0.1.0

NSC veneer: SHA-256(key XOR challenge) for a stored slot.

Validates that the NS challenge buffer (read) and the NS digest buffer (read/write) lie inside the Non-Secure region, then forwards to ra8_key_vault_sha256_xor_challenge. The raw key never leaves the secure world; only the 32-byte SHA-256 digest crosses the boundary back to NS.

The 32-byte slot bound is published by k_ra8_key_vault_chal_bytes and k_ra8_key_vault_digest_bytes; the veneer enforces it on both buffers before calling into the secure key vault.

Parameters
[in]slotVault slot index.
[in]ns_chalNS challenge buffer (k_ra8_key_vault_chal_bytes).
[out]ns_digestNS destination for the SHA-256 digest (k_ra8_key_vault_digest_bytes).
Returns
ra8_err_t outcome.
Return values
k_ra8_okDigest copied to ns_digest.
k_ra8_err_null_ptrA pointer argument was NULL.
k_ra8_err_invalid_argBuffer outside NS region or bad slot.
Precondition
TrustZone substrate up.
Both buffers lie entirely within the NS data region.
Postcondition
On success ns_digest holds the SHA-256(key XOR challenge).
On failure ns_digest content is undefined and no key bytes are exposed.
TrustZone:
NS->S boundary via cmse_nonsecure_entry. Both NS pointers are cmse_check_address_range-validated. The raw slot key is read only inside the secure world; it is XORed with the challenge and hashed before any byte crosses back to NS, so a malicious NS caller cannot recover the key from the digest without breaking SHA-256.
Note
Thread-safe: serialised by the secure key-vault lock.
Since
0.1.0

Definition at line 65 of file ra8_nsc_key_vault.c.

References k_ra8_key_vault_chal_bytes, k_ra8_key_vault_digest_bytes, RA8_CHECK_NULL_PTR, ra8_key_vault_sha256_xor_challenge(), RA8_NSC_CHECK_NS_RANGE_R, RA8_NSC_CHECK_NS_RANGE_RW, RA8_NSC_VENEER, and s_tag.

◆ ra8_nsc_log_emit()

ra8_err_t ra8_nsc_log_emit ( const char * tag,
const char * message )
nodiscard

NSC veneer: emit a log line via the secure ITM channel.

NS code cannot reach the ITM stim ports directly because they live in the System control space (0xE0000000) which lives in the secure region. The veneer copies the (tag, message) pair to a small secure-side scratch area, calls ra8_log_info, and returns. Strings longer than the scratch are truncated.

Parameters
[in]tagModule tag (short string).
[in]messageFree-form message text.
Returns
ra8_err_t error code.
Return values
k_ra8_okLog line emitted.
k_ra8_err_null_ptrtag / message was NULL.
Precondition
tag and message are NS pointers.
Postcondition
Log scratch contains the truncated copy; ITM stim port has been written.
TrustZone Safety:
  • Validates: both pointers are in NS region; length is capped by the scratch buffer size.
  • Trusts: secure ra8_log driver.
  • Denies: direct ITM stim writes from NS world.
Since
0.1.0

NSC veneer: emit a log line via the secure ITM channel.

Copies (tag,message) into secure scratch buffers and forwards to ra8_log_info.

Parameters
[in]tagNUL-terminated NS string (subsystem tag).
[in]messageNUL-terminated NS string (log message body).
Returns
ra8_err_t outcome.
Return values
k_ra8_okMessage handed to the secure logger.
k_ra8_err_null_ptrA pointer argument was NULL.
Precondition
TrustZone substrate has been initialized.
Both strings reside in the NS data region.
Postcondition
Tag/message copied into secure scratch and forwarded.
Strings truncated to k_ra8_nsc_log_msg_max_len-1 if longer.
Note
Thread-safe: no; the secure scratch is shared.
Since
0.1.0

Definition at line 94 of file ra8_nsc_log.c.

References internal_safe_strcpy(), k_ra8_nsc_log_msg_max_len, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_info, RA8_NSC_CHECK_NS_RANGE_R, RA8_NSC_VENEER, s_msg_scratch, s_tag, and s_tag_scratch.

Referenced by internal_sys_thread_entry(), internal_ui_thread_entry(), ns_reset_handler(), ui_thread_entry(), and work_thread_entry().

◆ ra8_nsc_ota_commit()

ra8_err_t ra8_nsc_ota_commit ( uint8_t target_bank)
nodiscard

NSC veneer: commit OTA target bank as the boot bank.

Parameters
[in]target_bankTarget bank id (k_ra8_ota_bank_a or _b).
Returns
ra8_err_t code.

NSC veneer: commit OTA target bank as the boot bank.

Validates target_bank and forwards to ra8_ota_commit_swap_bank in the secure world.

Parameters
[in]target_bankBank to boot from (k_ra8_ota_bank_a/b).
Returns
ra8_err_t outcome.
Return values
k_ra8_okBank-swap latched.
k_ra8_err_invalid_argUnknown bank index.
Precondition
TrustZone substrate initialized.
Caller has verified the new image.
Postcondition
On success the next NVIC reset boots from target_bank.
On failure the active bank is unchanged.
Note
Thread-safe: serialised by the secure ra8_ota lock.
Since
0.1.0

Definition at line 52 of file ra8_nsc_ota.c.

References k_ra8_err_invalid_arg, k_ra8_ota_bank_a, k_ra8_ota_bank_b, RA8_NSC_VENEER, and ra8_ota_commit_swap_bank().

◆ ra8_nsc_periph_init()

ra8_err_t ra8_nsc_periph_init ( void )
nodiscard

NSC veneer: bring up the secure-side peripheral substrate.

Called once by NS code at boot. The veneer kicks off the substrate dance that NS code cannot do directly:

Once this returns success, NS code can call any of the other NSC veneers (ra8_nsc_eth_*, ra8_nsc_xspi_*, ra8_nsc_log_*).

Returns
ra8_err_t error code.
Return values
k_ra8_okSubstrate up.
k_ra8_err_hw_init_failedOne of the substrate inits failed.
Precondition
Called from NS world after vector_table init.
IRQs masked or single-threaded boot context.
Postcondition
All Ring-3 substrate modules are initialized on the secure side.
TrustZone Safety:
  • Validates: nothing – this is a parameterless call.
  • Trusts: the boot ROM has already configured the SAU.
  • Denies: repeat invocation past the first success (idempotent fast-path returns k_ra8_ok without re-init).
Since
0.1.0

Sequences the four substrate init calls that the Non-Secure world cannot perform because the MSTP / CGC / ICU / DMA register windows live in the secure region partitioning: ra8_mstp_init -> ra8_pwr_init -> ra8_isr_init -> ra8_dma_init.

The function is idempotent: subsequent calls return k_ra8_ok without redoing the work. On failure the latched s_initialized flag stays false so a future call may retry from scratch.

Returns
ra8_err_t outcome.
Return values
k_ra8_okSubstrate up (or already up).
k_ra8_err_hw_init_failedOne of the secure init steps failed.
Precondition
Reset vector has handed over to the firmware.
TrustZone SAU has been programmed (single-world or NS region carved).
Postcondition
On success the secure peripheral substrate is fully up.
On failure the substrate is in an indeterminate partial state; the caller may retry.
TrustZone:
NS->S boundary via cmse_nonsecure_entry. Argument-less, scalar return – nothing crosses the boundary that needs range-checking.
Note
Thread-safe: no – intended to be called once at boot.
Since
0.1.0

Definition at line 112 of file ra8_nsc_periph_init.c.

References k_ra8_err_hw_init_failed, k_ra8_ok, ra8_board_uart_console_init(), ra8_dma_init(), ra8_isr_init(), ra8_log_error_val, ra8_log_info, ra8_log_set_byte_sink(), ra8_mstp_init(), RA8_NSC_VENEER, ra8_pwr_init(), s_initialized, and s_tag.

Referenced by ns_reset_handler().

◆ ra8_nsc_wdt_refresh()

void ra8_nsc_wdt_refresh ( void )

NSC veneer: refresh the Secure WDT down-counter.

Forwards to ra8_wdt_refresh_deferred (WDTRR heartbeat). Installed as the ThreadX supervisor's ra8_wdt_sup_refresh_fn_t hook via ra8_wdt_supervisor_set_refresh_hook so the WDT is kicked only when every registered NS thread has checked in within its deadline. Returns void to match the hook signature.

Returns
Nothing.
Note
This function does not return a value.
Precondition
ra8_nsc_wdt_start has armed the WDT.
Called from the NS supervisor thread on its refresh cadence.
Postcondition
The WDT down-counter has been reloaded.
No Secure state other than the WDT refresh register is touched.
Note
Not thread-safe; call only from the single NS watchdog supervisor thread on its refresh cadence, never concurrently.
TrustZone Safety:
  • Validates: nothing – parameterless call.
  • Trusts: the NS supervisor's all-threads-alive decision.
  • Denies: any direct NS WDTRR write.
Since
0.1.0

Forwards to ra8_wdt_refresh_deferred (WDTRR heartbeat). Installed as the ThreadX supervisor's ra8_wdt_sup_refresh_fn_t hook so the supervisor kicks the WDT only when every registered NS thread has checked in on time.

Returns
Nothing.
Note
This function does not return a value.
Precondition
ra8_nsc_wdt_start has armed the WDT.
Called from the NS supervisor thread on its refresh cadence.
Postcondition
The WDT down-counter has been reloaded (refresh issued).
No NS-visible state is modified.
Note
Thread safety: the supervisor calls this from one thread only.
Since
0.1.0

Definition at line 106 of file ra8_nsc_wdt.c.

References RA8_NSC_VENEER, and ra8_wdt_refresh_deferred().

Referenced by internal_wdt_setup().

◆ ra8_nsc_wdt_start()

ra8_err_t ra8_nsc_wdt_start ( void )
nodiscard

NSC veneer: arm the Secure WDT with the e-reader configuration.

The WDT (HUM Ch 27) is Secure-owned; NS cannot programme WDTCR/WDTRR. This veneer forwards to ra8_wdt_init with a fixed Secure-side configuration (fully-open refresh window, expiry to NMI). In register-start mode that arms the down-counter, so NS must call this immediately before starting the ThreadX supervisor thread that will refresh it.

Returns
ra8_err_t error code.
Return values
k_ra8_okWDT configured and armed.
k_ra8_err_invalid_argThe fixed configuration was rejected by the driver.
Precondition
Called from NS world after ra8_nsc_periph_init succeeded.
The WDT has not already been armed this boot.
Postcondition
The WDT down-counter is running and expects a refresh within the timeout.
WDTCR reflects the fixed Secure configuration.
TrustZone Safety:
  • Validates: nothing – parameterless call.
  • Trusts: the Secure clock tree is up (ra8_nsc_periph_init ran).
  • Denies: any NS write to WDTCR/WDTRR (only this veneer arms it).
Since
0.1.0

Forwards to ra8_wdt_init with the fixed s_wdt_cfg. In register-start mode ra8_wdt_init programmes WDTCR/WDTRCR/WDTCSTPR and issues the unlock sequence that arms the down-counter, so the NS caller should invoke this immediately before starting the supervisor thread that refreshes it – keeping the arm-to-first-refresh gap small (as the flat demo does).

Returns
ra8_err_t outcome from ra8_wdt_init.
Return values
k_ra8_okWDT configured and armed.
k_ra8_err_invalid_argThe fixed configuration was rejected by the driver.
Precondition
The Secure substrate is initialized (clocks running).
No prior code has armed the WDT (single arm per boot).
Postcondition
The WDT down-counter is running and expects a refresh within the timeout.
WDTCR reflects s_wdt_cfg.
Note
Thread safety: call once, from the NS boot thread, before the supervisor starts. Not re-entrant.
Since
0.1.0

Definition at line 82 of file ra8_nsc_wdt.c.

References RA8_NSC_VENEER, ra8_wdt_init(), and s_wdt_cfg.

Referenced by internal_wdt_setup().

◆ ra8_nsc_xspi_read()

ra8_err_t ra8_nsc_xspi_read ( uint32_t flash_off,
uint8_t * ns_dst,
uint32_t len )
nodiscard

NSC veneer: read len bytes from external XSPI flash.

Wraps the secure-side ra8_xspi_* driver for Non-Secure callers (application). The veneer enforces:

  • flash_off + len must fit in the configured flash window.
  • len <= k_ra8_nsc_xspi_max_read.
  • ns_dst must point into the NS region; this is checked at runtime by reading TT (cmse_check_address_range). A rejected range returns k_ra8_err_invalid_arg before the secure-side XSPI driver can dereference the pointer.
Parameters
[in]flash_offByte offset inside the XSPI flash window.
[out]ns_dstDestination buffer in Non-Secure RAM.
[in]lenBytes to copy. Must be > 0.
Returns
ra8_err_t error code.
Return values
k_ra8_okBytes copied from flash.
k_ra8_err_null_ptrns_dst was NULL.
k_ra8_err_invalid_arglen zero / range out of bounds.
k_ra8_err_timeoutFlash COMSTT poll never cleared.
Precondition
ns_dst is non-NULL and points into the NS data region.
ra8_xspi_init has run on the secure side.
Postcondition
On success, ns_dst[0..len-1] contains flash bytes.
TrustZone Safety:
  • Validates: flash_off + len fits the flash window; ns_dst is within the NS region (cmse_check).
  • Trusts: the secure ra8_xspi state machine.
  • Denies: writes to flash, reads outside the configured window, reads larger than k_ra8_nsc_xspi_max_read.
Note
Host and single-world builds intentionally compile the range check to a no-op; Secure-world -mcmse builds execute the TT-based check.
Since
0.1.0

Validates len is in (0, k_ra8_nsc_xspi_max_read] and that the NS destination buffer is in writable NS memory, then forwards to ra8_xspi_flash_read for the single configured instance.

Parameters
[in]flash_offByte offset into XSPI flash.
[out]ns_dstNon-Secure destination buffer.
[in]lenBytes to read; 1..k_ra8_nsc_xspi_max_read.
Returns
ra8_err_t outcome.
Return values
k_ra8_okBytes copied to ns_dst.
k_ra8_err_null_ptrns_dst was NULL.
k_ra8_err_invalid_arglen zero / too large or range outside NS.
Precondition
TrustZone substrate up.
[ns_dst, ns_dst+len) lies in NS data region.
Postcondition
On success ns_dst holds len flash bytes from flash_off.
On failure ns_dst content is undefined.
TrustZone:
NS->S boundary via cmse_nonsecure_entry. The destination buffer is cmse_check_address_range-validated so the secure XSPI driver cannot be tricked into writing into secure memory.
Note
Thread-safe: serialised by the secure XSPI driver lock.
Since
0.1.0

Definition at line 64 of file ra8_nsc_xspi.c.

References k_ra8_err_invalid_arg, k_ra8_nsc_xspi_instance, k_ra8_nsc_xspi_max_read, RA8_CHECK_NULL_PTR, RA8_NSC_CHECK_NS_RANGE_RW, RA8_NSC_VENEER, ra8_xspi_flash_read(), and s_tag.

◆ ra8_nsc_xspi_status()

ra8_err_t ra8_nsc_xspi_status ( uint8_t instance,
uint32_t * out_mask )
nodiscard

NSC veneer: query secure-side XSPI status.

Parameters
[in]instanceXSPI instance number.
[out]out_maskStatus bits; OR of ra8_xspi status values.
Returns
ra8_err_t error code.
Return values
k_ra8_okStatus returned.
k_ra8_err_null_ptrout_mask was NULL.
k_ra8_err_invalid_argBad instance number.
Precondition
out_mask non-NULL.
Postcondition
No secure state is modified; only a 32-bit value crosses the boundary.
TrustZone Safety:
  • Validates: instance < num_instances; out_mask is in NS.
  • Trusts: secure-side ra8_xspi_get_status.
  • Denies: any reachability to the actual status register – the value is copied through the veneer, not aliased.
Since
0.1.0

Range-checks out_mask in NS memory and forwards to ra8_xspi_get_status.

Parameters
[in]instanceXSPI instance index.
[out]out_maskNS destination for the status mask.
Returns
ra8_err_t outcome.
Return values
k_ra8_okStatus copied to *out_mask.
k_ra8_err_null_ptrout_mask was NULL.
k_ra8_err_invalid_argRange outside NS region or bad instance.
Precondition
TrustZone substrate up.
out_mask lies in NS data region.
Postcondition
On success *out_mask reflects the live status bits.
On failure *out_mask unchanged.
TrustZone:
NS->S boundary via cmse_nonsecure_entry. out_mask is range-checked.
Note
Thread-safe: serialised by the secure XSPI driver lock.
Since
0.1.0

Definition at line 100 of file ra8_nsc_xspi.c.

References RA8_CHECK_NULL_PTR, RA8_NSC_CHECK_NS_RANGE_RW, RA8_NSC_VENEER, ra8_xspi_get_status(), and s_tag.