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

TrustZone S/NS seam implementation (see emu_tz.h). More...

#include "emu_tz.h"
#include <stdio.h>
#include "emu_console.h"
#include "emu_elf.h"
#include "emu_exc.h"
#include "emu_host_io_internal.h"
#include "emu_memory_access.h"
Include dependency graph for emu_tz.c:

Go to the source code of this file.

Enumerations

enum  vtor_ns_addr_t : uint64_t { k_scb_vtor_ns_addr = 0xE002ED08UL }
 SCB VTOR_NS alias address (ARMv8-M B3.2.4; Secure-state view). More...
enum  blxns_op_t : uint32_t {
  k_blxns_mask = 0xFF87U ,
  k_blxns_match = 0x4784U
}
 Thumb encoding of the BLXNS instruction (scanned in jump_ns). More...

Functions

static void internal_on_blxns (uc_engine *uc, uint64_t address, uint32_t size, void *user)
 UC_HOOK_CODE at the Secure->NS BLXNS – hand-emulate the world switch.
static uint32_t internal_emu_tz_find_blxns (uc_engine *uc, uint32_t from, uint32_t size)
 Scan a Thumb function image for its first BLXNS instruction.
void emu_tz_install (uc_engine *uc, const emu_elf_source_t *elf)
 Implementation of emu_tz_install() – SAU seed + BLXNS scan/hook.
void emu_tz_patch_cmse (uc_engine *uc, const emu_elf_source_t *elf)
 Implementation of emu_tz_patch_cmse() – flat-domain range check.
void emu_tz_set_ns_vector_base (uint32_t base)
 Implementation of emu_tz_set_ns_vector_base() – –ns override.
uint32_t emu_tz_ns_vector_base (void)
 Implementation of emu_tz_ns_vector_base() – plain state read.

Variables

static uint32_t s_ns_vector_base = (uint32_t)k_ns_sram2_base
 Fallback NS vector-table base for the BLXNS world switch.

Detailed Description

TrustZone S/NS seam implementation (see emu_tz.h).

The NS vector-base tracking, the hand-emulated BLXNS world switch, the SAU_TYPE seed + BLXNS scan installer, and the cmse_check_address_range BX-LR patch – moved verbatim out of the ra8_emulator main translation unit.

Since
0.1.0

Definition in file emu_tz.c.

Enumeration Type Documentation

◆ blxns_op_t

enum blxns_op_t : uint32_t

Thumb encoding of the BLXNS instruction (scanned in jump_ns).

BLXNS Rm = 0x4780 | (Rm << 3) | 0x04; masking with k_blxns_mask isolates the fixed bits (0x4784) so any Rm matches.

Since
0.1.0
Enumerator
k_blxns_mask 

Mask isolating the BLXNS fixed bits.

k_blxns_match 

BLXNS fixed-bit pattern (any Rm).

Definition at line 55 of file emu_tz.c.

◆ vtor_ns_addr_t

enum vtor_ns_addr_t : uint64_t

SCB VTOR_NS alias address (ARMv8-M B3.2.4; Secure-state view).

Enumerator
k_scb_vtor_ns_addr 

VTOR_NS: NS vector-table base.

Definition at line 44 of file emu_tz.c.

Function Documentation

◆ emu_tz_install()

void emu_tz_install ( uc_engine * uc,
const emu_elf_source_t * elf )

Implementation of emu_tz_install() – SAU seed + BLXNS scan/hook.

Arm the TrustZone S->NS boot seams (SAU_TYPE seed + BLXNS hook).

Definition at line 152 of file emu_tz.c.

References elf_sym_addr(), emu_mem_write(), internal_emu_tz_find_blxns(), internal_on_blxns(), k_sau_type_addr, k_sau_type_regs, k_thumb_hw_bytes, and priv_emu_io_errf().

Referenced by internal_main_install_core_seams().

◆ emu_tz_ns_vector_base()

uint32_t emu_tz_ns_vector_base ( void )

Implementation of emu_tz_ns_vector_base() – plain state read.

The tracked NS vector-table fallback base.

Definition at line 228 of file emu_tz.c.

References s_ns_vector_base.

Referenced by internal_main_load_ns().

◆ emu_tz_patch_cmse()

void emu_tz_patch_cmse ( uc_engine * uc,
const emu_elf_source_t * elf )

Implementation of emu_tz_patch_cmse() – flat-domain range check.

Patch cmse_check_address_range to BX LR (flat-domain model).

Definition at line 194 of file emu_tz.c.

References elf_sym_addr(), emu_mem_write(), and k_thumb_bx_lr.

Referenced by internal_main_run_loaded().

◆ emu_tz_set_ns_vector_base()

void emu_tz_set_ns_vector_base ( uint32_t base)

Implementation of emu_tz_set_ns_vector_base() – –ns override.

Track the NS image's actual vector base (–ns load path).

Definition at line 222 of file emu_tz.c.

References s_ns_vector_base.

Referenced by internal_main_load_ns().

◆ internal_emu_tz_find_blxns()

uint32_t internal_emu_tz_find_blxns ( uc_engine * uc,
uint32_t from,
uint32_t size )
static

Scan a Thumb function image for its first BLXNS instruction.

Walks size bytes from from a halfword at a time, reading each through Unicorn (the image is already loaded there by load_elf) and matching it against the BLXNS encoding. Only the first match matters: the secure boot's jump routine issues exactly one.

Parameters
[in]ucUnicorn engine holding the loaded image.
[in]fromFunction entry address.
[in]sizeFunction size in bytes, from the ELF symbol table.
Returns
Address of the first BLXNS, or 0 when the image contains none.
Return values
0No BLXNS in the scanned range.
Precondition
uc is non-null.
size is at least k_thumb_hw_bytes, so one halfword is readable.
Postcondition
Emulated memory is unchanged (reads only).
Any returned address lies within [from, from + size).
Note
Not thread-safe.
Since
0.1.0

Definition at line 137 of file emu_tz.c.

References emu_mem_read(), k_blxns_mask, k_blxns_match, k_thumb_hw_bytes, and RA8_INTERNAL.

Referenced by emu_tz_install().

◆ internal_on_blxns()

void internal_on_blxns ( uc_engine * uc,
uint64_t address,
uint32_t size,
void * user )
static

UC_HOOK_CODE at the Secure->NS BLXNS – hand-emulate the world switch.

Unicorn's emulated M33 is all-Secure with no IDAU, so the real BLXNS in ra8_tz_secure_boot_jump_ns cannot transition to the Non-Secure world (it stalls / wanders). This hook fires on that instruction and performs the switch by hand in ra8_emulator's single flat domain: it reads the NS initial MSP (NS vector[0]) and the NS reset handler (NS vector[1]) from the NS run base, sets SP + PC to them (Thumb bit masked), and stops the chunk so the run loop resumes executing the NS reset handler – ThreadX and the e-reader threads then run directly. Mirrors the existing SG-stub-by-address TrustZone workaround.

Parameters
[in]ucUnicorn engine mid-chunk at the BLXNS.
[in]addressThe BLXNS instruction address; unused.
[in]sizeInstruction size in bytes; unused.
[in]userHook user pointer; unused.
Returns
Nothing.
Precondition
The NS vectors are live at s_ns_vector_base – either copied to the RAM run alias by the Secure boot, or XIP-resident in the OSPI window.
The hook is registered only for the jump_ns BLXNS site (under –ns).
Postcondition
SP = NS MSP, PC = NS reset handler, and the chunk is stopped.
The next run-loop chunk executes the Non-Secure reset handler.
Note
Not thread-safe; ra8_emulator is single-threaded.
Since
0.1.0

Definition at line 88 of file emu_tz.c.

References emu_mem_read(), k_scb_vtor_ns_addr, and s_ns_vector_base.

Referenced by emu_tz_install().

Variable Documentation

◆ s_ns_vector_base

uint32_t s_ns_vector_base = (uint32_t)k_ns_sram2_base
static

Fallback NS vector-table base for the BLXNS world switch.

internal_on_blxns first reads the live VTOR_NS word (the Secure boot's ra8_tz_secure_boot_jump_ns stores the NS vector base to the 0xE002ED08 alias – plain PPB RAM here – right before its BLXNS), so a single-image TZ app whose NS half lives at its MRAM LMA (cpu1_pingpong_ipc: 0x02080000) and a two-image app whose NS image was copied to the SRAM2 run alias both resolve without flags. This fallback covers a zero VTOR_NS: it defaults to the RAM-resident NS run alias (k_ns_sram2_base) and is overridden at --ns load to the loaded NS image's minimum PT_LOAD p_vaddr, so an XIP NS image linked at the OSPI window (0x90000000, VMA == LMA, no copy) still transitions correctly.

Note
Single-threaded; set once before the run loop and read in internal_on_blxns.
Since
0.1.0

Definition at line 41 of file emu_tz.c.

Referenced by emu_tz_ns_vector_base(), emu_tz_set_ns_vector_base(), and internal_on_blxns().