Contiki-NG
Loading...
Searching...
No Matches
tz-target-cfg.c
1/*
2 * Copyright (c) 2018-2020 Arm Limited. All rights reserved.
3 * Copyright (c) 2020 Nordic Semiconductor ASA.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/* This file has been modified for use in the Contiki-NG operating system. */
19
20#include "contiki.h"
21
22#include "tz-target-cfg.h"
23#include "region_defs.h"
24#include "trustzone/tz-api.h"
25
26#include <spu.h>
27#include <nrfx.h>
28#include <hal/nrf_gpio.h>
29
30#include "nrf5340_application_bitfields.h"
31
32/******************************************************************************/
33#if NRF_GPIO_HAS_SEL
34#define gpio_pin_select nrf_gpio_pin_control_select
35#define GPIO_PIN_SEL_PERIPHERAL NRF_GPIO_PIN_SEL_PERIPHERAL
36#else
37#define gpio_pin_select nrf_gpio_pin_mcu_select
38#define GPIO_PIN_SEL_PERIPHERAL NRF_GPIO_PIN_MCUSEL_PERIPHERAL
39#endif
40/******************************************************************************/
41#include "sys/log.h"
42#define LOG_MODULE "TZSecureWorld"
43#define LOG_LEVEL LOG_LEVEL_DBG
44/******************************************************************************/
45
46#define PIN_XL1 0
47#define PIN_XL2 1
48
49/* To write into AIRCR register, 0x5FA value must be write to the VECTKEY field,
50 * otherwise the processor ignores the write.
51 */
52#define SCB_AIRCR_WRITE_MASK ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos))
53/******************************************************************************/
54void
55enable_fault_handlers(void)
56{
57 /* Explicitly set secure fault priority to the highest */
58 NVIC_SetPriority(SecureFault_IRQn, 0);
59
60 /* Enables BUS, MEM, USG and Secure faults */
61 SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk | SCB_SHCSR_MEMFAULTENA_Msk | SCB_SHCSR_SECUREFAULTENA_Msk;
62}
63/******************************************************************************/
64void
65system_reset_cfg(void)
66{
67 uint32_t reg_value = SCB->AIRCR;
68
69 /* Clear SCB_AIRCR_VECTKEY value */
70 reg_value &= ~(uint32_t)(SCB_AIRCR_VECTKEY_Msk);
71
72 /* Enable system reset request only to the secure world */
73 reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk);
74
75 SCB->AIRCR = reg_value;
76}
77/******************************************************************************/
78/*----------------- NVIC interrupt target state to NS configuration ----------*/
79void
80nvic_interrupt_target_state_cfg(void)
81{
82 /*
83 * Target all interrupts to NS by default; unimplemented interrupts
84 * will be Write-Ignored. Peripherals that must remain secure are
85 * cleared explicitly below.
86 */
87 for(uint8_t i = 0; i < sizeof(NVIC->ITNS) / sizeof(NVIC->ITNS[0]); i++) {
88 NVIC->ITNS[i] = 0xffffffff;
89 }
90
91 /* Keep secure-world peripherals targeting secure state. */
92 NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_SPU));
93
94 /* IPC IRQ must target secure state since IPC is a secure peripheral. */
95 NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_IPC));
96
97 /* RTC1 and TIMER1 are used by the secure world's clock/rtimer. */
98 NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_RTC1));
99 NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_TIMER1));
100
101#ifdef SECURE_UART0
102 /* UARTE0 is a secure peripheral, so its IRQ has to target S state */
103 NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_UARTE0));
104#endif
105
106#ifdef SECURE_UART1
107 /* UARTE1 is a secure peripheral, so its IRQ has to target S state */
108 NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_UARTE1));
109#endif
110
111 /* TIMER1 is kept secure for the secure-world rtimer. */
112 NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_TIMER1));
113
114 /* RTC1 is kept secure for the secure-world clock. */
115 NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_RTC1));
116}
117/******************************************************************************/
118/*----------------- NVIC interrupt enabling for S peripherals ----------------*/
119void
120nvic_interrupt_enable(void)
121{
122 /* SPU interrupt enabling */
123 spu_enable_interrupts();
124
125 NVIC_ClearPendingIRQ(NRFX_IRQ_NUMBER_GET(NRF_SPU));
126 NVIC_EnableIRQ(NRFX_IRQ_NUMBER_GET(NRF_SPU));
127}
128/******************************************************************************/
129/*----------------- TrustZone API platform hooks -----------------------------*/
130/*
131 * Borrow EGU0_IRQn as a software-pended doorbell to wake the normal
132 * world from a secure ISR. The EGU peripheral itself is left unused;
133 * we only need an NS-targeted NVIC slot. EGU0 is configured non-secure
134 * and the ITNS bit is set by nvic_interrupt_target_state_cfg above.
135 */
136void
137tz_arch_signal_ns(void)
138{
139 TZ_NVIC_SetPendingIRQ_NS(EGU0_IRQn);
140}
141/******************************************************************************/
142/*----------------- SPU violation diagnostics --------------------------------*/
143#define SPU_VIOLATION_MAGIC 0x5BADACCEUL
144struct spu_violation_info {
145 uint32_t magic;
146 uint32_t flashaccerr;
147 uint32_t ramaccerr;
148 uint32_t periphaccerr;
149};
150__attribute__((section(".noinit"))) static volatile struct spu_violation_info
151 spu_violation_info;
152
153void
154spu_report_violation(void)
155{
156 if(spu_violation_info.magic != SPU_VIOLATION_MAGIC) {
157 return;
158 }
159 spu_violation_info.magic = 0;
160
161 LOG_WARN("Reboot caused by SPU violation:%s%s%s\n",
162 spu_violation_info.flashaccerr ? " FLASHACCERR" : "",
163 spu_violation_info.ramaccerr ? " RAMACCERR" : "",
164 spu_violation_info.periphaccerr ? " PERIPHACCERR" : "");
165}
166/******************************************************************************/
167/*----------------- SPU interrupt handler ------------------------------------*/
168void
169SPU_IRQHandler(void)
170{
171 /*
172 * Stash the violation type in .noinit for spu_report_violation() to
173 * print on the next boot. No log call here: the UARTE TX path would
174 * block waiting for an ENDTX ISR that cannot run while this handler
175 * is active.
176 */
177 spu_violation_info.flashaccerr = NRF_SPU->EVENTS_FLASHACCERR;
178 spu_violation_info.ramaccerr = NRF_SPU->EVENTS_RAMACCERR;
179 spu_violation_info.periphaccerr = NRF_SPU->EVENTS_PERIPHACCERR;
180 spu_violation_info.magic = SPU_VIOLATION_MAGIC;
181
182 spu_clear_events();
183 NVIC_SystemReset();
184}
185/******************************************************************************/
186/*------------------- SAU/IDAU configuration functions -----------------------*/
187void
188sau_and_idau_cfg(void)
189{
190 /* IDAU (SPU) is always enabled. SAU is non-existent.
191 * Allow SPU to have precedence over (non-existing) ARMv8-M SAU.
192 */
193 TZ_SAU_Disable();
194 SAU->CTRL |= SAU_CTRL_ALLNS_Msk;
195}
196/******************************************************************************/
197void
198spu_periph_init_cfg(void)
199{
200 /* Peripheral configuration */
201
202 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_FPU));
203 spu_peripheral_config_non_secure((uint32_t)NRF_FPU, false);
204
205 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_REGULATORS));
206 spu_peripheral_config_non_secure((uint32_t)NRF_REGULATORS, false);
207
208 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_CLOCK));
209 spu_peripheral_config_non_secure((uint32_t)NRF_CLOCK, true); /* Necessary */
210
211#ifndef SECURE_UART0
212 /* If UART0 is a secure peripheral, we need to leave Serial-Box 0 as Secure */
213 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_SPIM0));
214 spu_peripheral_config_non_secure((uint32_t)NRF_SPIM0, false);
215#endif
216
217#ifndef SECURE_UART1
218 /* If UART1 is a secure peripheral, we need to leave Serial-Box 1 as Secure */
219 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_SPIM1));
220 spu_peripheral_config_non_secure((uint32_t)NRF_SPIM1, false);
221#endif
222
223 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_SPIM4));
224 spu_peripheral_config_non_secure((uint32_t)NRF_SPIM4, false);
225
226 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_SPIM2));
227 spu_peripheral_config_non_secure((uint32_t)NRF_SPIM2, false);
228
229 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_SPIM3));
230 spu_peripheral_config_non_secure((uint32_t)NRF_SPIM3, false);
231
232 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_SAADC));
233 spu_peripheral_config_non_secure((uint32_t)NRF_SAADC, false);
234
235 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_TIMER0));
236 spu_peripheral_config_non_secure((uint32_t)NRF_TIMER0, false);
237
238 /* TIMER1 is kept secure: used by the secure world for rtimer. */
239
240 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_TIMER2));
241 spu_peripheral_config_non_secure((uint32_t)NRF_TIMER2, false);
242
243 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_RTC0));
244 spu_peripheral_config_non_secure((uint32_t)NRF_RTC0, false);
245
246 /* RTC1 is kept secure: used by the secure world for the clock. */
247
248 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_DPPIC));
249 spu_peripheral_config_non_secure((uint32_t)NRF_DPPIC, false);
250
251 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_WDT0));
252 spu_peripheral_config_non_secure((uint32_t)NRF_WDT0, false);
253
254 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_WDT1));
255 spu_peripheral_config_non_secure((uint32_t)NRF_WDT1, false);
256
257 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_COMP));
258 spu_peripheral_config_non_secure((uint32_t)NRF_COMP, false);
259
260 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_EGU0));
261 spu_peripheral_config_non_secure((uint32_t)NRF_EGU0, false);
262
263 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_EGU1));
264 spu_peripheral_config_non_secure((uint32_t)NRF_EGU1, false);
265
266 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_EGU2));
267 spu_peripheral_config_non_secure((uint32_t)NRF_EGU2, false);
268
269 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_EGU3));
270 spu_peripheral_config_non_secure((uint32_t)NRF_EGU3, false);
271
272 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_EGU4));
273 spu_peripheral_config_non_secure((uint32_t)NRF_EGU4, false);
274#ifndef PSA_API_TEST_IPC
275 /* EGU5 is used as a secure peripheral in PSA FF tests */
276
277 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_EGU5));
278 spu_peripheral_config_non_secure((uint32_t)NRF_EGU5, false);
279#endif
280
281 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_PWM0));
282 spu_peripheral_config_non_secure((uint32_t)NRF_PWM0, false); /* Necessary */
283
284 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_PWM1));
285 spu_peripheral_config_non_secure((uint32_t)NRF_PWM1, false);
286
287 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_PWM2));
288 spu_peripheral_config_non_secure((uint32_t)NRF_PWM2, false);
289
290 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_PWM3));
291 spu_peripheral_config_non_secure((uint32_t)NRF_PWM3, false);
292
293 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_PDM0));
294 spu_peripheral_config_non_secure((uint32_t)NRF_PDM0, false);
295
296 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_I2S0));
297 spu_peripheral_config_non_secure((uint32_t)NRF_I2S0, false);
298
299 /* IPC remains secure so the radio driver runs in the secure world. */
300
301 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_QSPI));
302 spu_peripheral_config_non_secure((uint32_t)NRF_QSPI, false);
303
304 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_NFCT));
305 spu_peripheral_config_non_secure((uint32_t)NRF_NFCT, false);
306
307 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_GPIOTE1_NS));
308 spu_peripheral_config_non_secure((uint32_t)NRF_GPIOTE1_NS, false);
309
310 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_MUTEX));
311 spu_peripheral_config_non_secure((uint32_t)NRF_MUTEX, false);
312
313 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_QDEC0));
314 spu_peripheral_config_non_secure((uint32_t)NRF_QDEC0, false);
315
316 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_QDEC1));
317 spu_peripheral_config_non_secure((uint32_t)NRF_QDEC1, false);
318
319 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_USBD));
320 spu_peripheral_config_non_secure((uint32_t)NRF_USBD, false);
321
322 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_USBREGULATOR));
323 spu_peripheral_config_non_secure((uint32_t)NRF_USBREGULATOR, false);
324
325 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_NVMC));
326 spu_peripheral_config_non_secure((uint32_t)NRF_NVMC, false); /* Necessary */
327
328 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_P0));
329 spu_peripheral_config_non_secure((uint32_t)NRF_P0, false); /* Necessary */
330
331 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_P1));
332 spu_peripheral_config_non_secure((uint32_t)NRF_P1, false);
333
334 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_VMC));
335 spu_peripheral_config_non_secure((uint32_t)NRF_VMC, false);
336
337#ifndef SECURE_UART1
338 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_UARTE1));
339 spu_peripheral_config_non_secure((uint32_t)NRF_UARTE1, false);
340#endif /* SECURE_UART1 */
341
342 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_UARTE2));
343 spu_peripheral_config_non_secure((uint32_t)NRF_UARTE2, false);
344
345 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_TWIM2));
346 spu_peripheral_config_non_secure((uint32_t)NRF_TWIM2, false);
347
348 /* IPC_S remains secure (see IPC comment above). */
349
350 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_VMC_S));
351 spu_peripheral_config_non_secure((uint32_t)NRF_VMC_S, false);
352
353 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_FPU_S));
354 spu_peripheral_config_non_secure((uint32_t)NRF_FPU_S, false);
355
356 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_EGU1_S));
357 spu_peripheral_config_non_secure((uint32_t)NRF_EGU1_S, false);
358
359 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_EGU2_S));
360 spu_peripheral_config_non_secure((uint32_t)NRF_EGU2_S, false);
361
362 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_DPPIC_S));
363 spu_peripheral_config_non_secure((uint32_t)NRF_DPPIC_S, false);
364
365 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_REGULATORS_S));
366 spu_peripheral_config_non_secure((uint32_t)NRF_REGULATORS_S, false);
367
368 /* DPPI channel configuration */
369 spu_dppi_config_non_secure(false);
370
371 /* GPIO pin configuration (P0 and P1 ports) */
372 spu_gpio_config_non_secure(0, true); /* P0.00 to P0.31 */
373 spu_gpio_config_non_secure(1, true); /* P1.00 to P1.15 */
374
375 /*
376 * Configure properly the XL1 and XL2 pins so that the low-frequency
377 * crystal oscillator (LFXO) can be used. This configuration can be
378 * done only from secure code, as otherwise those register fields
379 * are not accessible. That's why it is placed here.
380 */
381 gpio_pin_select(PIN_XL1, GPIO_PIN_SEL_PERIPHERAL);
382 gpio_pin_select(PIN_XL2, GPIO_PIN_SEL_PERIPHERAL);
383
384 /*
385 * Enable the instruction and data cache (this can be done only from secure
386 * code; that's why it is placed here).
387 */
388 NRF_CACHE->ENABLE = CACHE_ENABLE_ENABLE_Enabled;
389}
390/******************************************************************************/
391void
392spu_periph_configure_to_secure(uint32_t periph_num)
393{
394 spu_peripheral_config_secure(periph_num, true);
395}
396/******************************************************************************/
397void
398spu_periph_configure_to_non_secure(uint32_t periph_num)
399{
400 spu_peripheral_config_non_secure(periph_num, true);
401}
402/******************************************************************************/
403void
404spu_periph_config_uarte(void)
405{
406#ifndef SECURE_UART0
407 NVIC_DisableIRQ(NRFX_IRQ_NUMBER_GET(NRF_UARTE0));
408 spu_peripheral_config_non_secure((uint32_t)NRF_UARTE0, false);
409#endif /* SECURE_UART0 */
410}
411/******************************************************************************/
412void
413non_secure_configuration(void)
414{
415 spu_regions_reset_all_secure();
416 /* Hard coded linker script addresses. */
417 spu_regions_flash_config_non_secure((uint32_t)NS_CODE_START,
418 (uint32_t)NS_ROM_LIMIT_ADDR);
419 spu_regions_sram_config_non_secure((uint32_t)NS_DATA_START,
420 (uint32_t)NS_DATA_LIMIT);
421 spu_periph_init_cfg();
422}
423/******************************************************************************/
424void
425configure_nonsecure_vtor_offset(uint32_t vtor_ns)
426{
427 SCB_NS->VTOR = vtor_ns;
428}
429/******************************************************************************/
430void
431configure_nonsecure_msp(uint32_t msp_ns)
432{
433 __TZ_set_MSP_NS(msp_ns);
434}
435/******************************************************************************/
436static void
437configure_nonsecure_psp(uint32_t psp_ns)
438{
439 __TZ_set_PSP_NS(psp_ns);
440}
441/******************************************************************************/
442static void
443configure_nonsecure_control(uint32_t spsel_ns, uint32_t npriv_ns)
444{
445 uint32_t control_ns = __TZ_get_CONTROL_NS();
446
447 /* Only nPRIV and SPSEL bits are banked between security states. */
448 control_ns &= ~(CONTROL_SPSEL_Msk | CONTROL_nPRIV_Msk);
449
450 if(spsel_ns) {
451 control_ns |= CONTROL_SPSEL_Msk;
452 }
453 if(npriv_ns) {
454 control_ns |= CONTROL_nPRIV_Msk;
455 }
456
457 __TZ_set_CONTROL_NS(control_ns);
458}
459/******************************************************************************/
460void
461tz_nonsecure_state_setup(const tz_nonsecure_setup_conf_t *p_ns_conf)
462{
463 configure_nonsecure_vtor_offset(p_ns_conf->vtor_ns);
464 configure_nonsecure_msp(p_ns_conf->msp_ns);
465 configure_nonsecure_psp(p_ns_conf->psp_ns);
466
467 /* Select which stack pointer to use (MSP or PSP) and the privilege
468 level for thread mode. */
469 configure_nonsecure_control(p_ns_conf->control_ns.spsel,
470 p_ns_conf->control_ns.npriv);
471}
472/******************************************************************************/
Header file for the logging system.
A convenient struct to include all required Non-Secure state configuration.
nRF5340 target configuration header