ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
trustzone_init.c
Go to the documentation of this file.
1
57
58#include "trustzone_init.h"
59
60#include <stdint.h>
61
62#include "ra8_attributes.h"
63
64#ifdef RA8_TRUSTZONE_ENABLE
65
66/* =============================================================================
67 * SAU register addresses (System Control Space, secure alias)
68 * =============================================================================
69 */
70
71typedef enum : uintptr_t {
72 k_ra8_sau_ctrl_addr = 0xE000EDD0UL,
73 k_ra8_sau_type_addr = 0xE000EDD4UL,
74 k_ra8_sau_rnr_addr = 0xE000EDD8UL,
75 k_ra8_sau_rbar_addr = 0xE000EDDCUL,
76 k_ra8_sau_rlar_addr = 0xE000EDE0UL,
77 k_ra8_sfsr_addr = 0xE000EDE4UL,
78} ra8_tz_sau_addr_t;
79
84typedef enum : uint32_t {
85 k_ra8_sau_ctrl_enable = 1UL << 0,
86 k_ra8_sau_ctrl_allns = 1UL << 1,
87} ra8_tz_sau_ctrl_bit_t;
88
93typedef enum : uint32_t {
94 k_ra8_sau_rlar_enable = 1UL << 0,
95 k_ra8_sau_rlar_nsc = 1UL << 1,
96} ra8_tz_sau_rlar_bit_t;
97
106typedef enum : uint32_t {
107 k_ra8_tz_ns_mram_base = 0x02080000UL,
108 k_ra8_tz_ns_mram_limit = 0x020FFFE0UL,
109 k_ra8_tz_ns_sram_base = 0x22100000UL,
110 k_ra8_tz_ns_sram_limit = 0x221FFFE0UL,
111 k_ra8_tz_ns_sdram_base = 0x6A000000UL,
112 k_ra8_tz_ns_sdram_limit = 0x6BFFFFE0UL,
113 k_ra8_tz_nsc_veneer_base = 0x10000000UL,
114 k_ra8_tz_nsc_veneer_lim = 0x100FFFE0UL,
115} ra8_tz_partition_t;
116
117/* =============================================================================
118 * Internal helpers
119 * =============================================================================
120 */
121
133RA8_INTERNAL static inline void internal_dsb(void)
134{
135 __asm__ volatile("dsb 0xF" ::: "memory");
136}
137
149RA8_INTERNAL static inline void internal_isb(void)
150{
151 __asm__ volatile("isb 0xF" ::: "memory");
152}
153
166RA8_INTERNAL static void internal_write32(uintptr_t addr, uint32_t value)
167{
168 *(volatile uint32_t*)addr = value;
169}
170
184RA8_INTERNAL static uint32_t internal_read32(uintptr_t addr)
185{
186 return *(volatile uint32_t*)addr;
187}
188
205RA8_INTERNAL static void
206internal_sau_set_region(uint32_t region, uint32_t base, uint32_t limit, bool is_nsc)
207{
208 internal_write32(k_ra8_sau_rnr_addr, region);
209 internal_write32(k_ra8_sau_rbar_addr, base);
210 uint32_t rlar = limit | (uint32_t)k_ra8_sau_rlar_enable;
211 if (is_nsc) {
212 rlar |= (uint32_t)k_ra8_sau_rlar_nsc;
213 }
214 internal_write32(k_ra8_sau_rlar_addr, rlar);
215}
216
217/* =============================================================================
218 * Public entry point
219 * =============================================================================
220 */
221
222#endif /* RA8_TRUSTZONE_ENABLE */
223
225{
226#ifdef RA8_TRUSTZONE_ENABLE
227 /* Sanity check: SAU_TYPE.SREGION must report >= 4 implemented
228 * regions for our partition to fit. The Cortex-M85 always has 8,
229 * but a chip-specific override could trim the count. */
230 const uint32_t sau_type = internal_read32(k_ra8_sau_type_addr);
231 if ((sau_type & 0xFFU) < 4U) {
232 /* Refuse to bring up TrustZone on an SAU we cannot use. The
233 * caller will see SAU_CTRL.ENABLE clear and fall back to the
234 * single-world model. */
235 return;
236 }
237
238 /* Region 0: NS upper MRAM */
240 (uint32_t)k_ra8_tz_ns_mram_base,
241 (uint32_t)k_ra8_tz_ns_mram_limit,
242 /*is_nsc=*/false);
243
244 /* Region 1: NS upper SRAM */
246 (uint32_t)k_ra8_tz_ns_sram_base,
247 (uint32_t)k_ra8_tz_ns_sram_limit,
248 /*is_nsc=*/false);
249
250 /* Region 2: NS upper SDRAM */
252 (uint32_t)k_ra8_tz_ns_sdram_base,
253 (uint32_t)k_ra8_tz_ns_sdram_limit,
254 /*is_nsc=*/false);
255
256 /* Region 3: NSC veneer alias ( will place .gnu.sgstubs
257 * here via the linker script). */
259 (uint32_t)k_ra8_tz_nsc_veneer_base,
260 (uint32_t)k_ra8_tz_nsc_veneer_lim,
261 /*is_nsc=*/true);
262
263 /* Enable the SAU. Leave ALLNS clear: anything we have not
264 * explicitly carved out stays secure (default-deny). */
265 internal_dsb();
266 internal_write32(k_ra8_sau_ctrl_addr, (uint32_t)k_ra8_sau_ctrl_enable);
267 internal_dsb();
268 internal_isb();
269#endif
270}
@ k_ra8_sfsr_addr
SecureFault Status Register.
void ra8_trustzone_init(void)
Programme + enable the SAU per the partition.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
static void internal_dsb(void)
Emit a Data Synchronisation Barrier (no-op on host).
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_sau_set_region(uint8_t region, uint32_t base, uint32_t limit, bool is_nsc)
Programme one SAU region via RNR/RBAR/RLAR.
static void internal_isb(void)
Emit an Instruction Synchronisation Barrier (no-op on host).