Contiki-NG
Loading...
Searching...
No Matches
tz-secure.c
1/*
2 * Copyright (c) 2022 RISE Research Institutes of Sweden
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided
14 * with the distribution.
15 * 3. The name of the author may not be used to endorse or promote
16 * products derived from this software without specific prior
17 * written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
20 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*
33 * Authors: John Kanwar <johnkanwar@hotmail.com>
34 * Nicolas Tsiftes <nicolas.tsiftes@ri.se>
35 * Niclas Finne <niclas.finne@ri.se>
36 */
37
38#include "contiki.h"
39#include "dev/uarte-arch.h"
40#include "region_defs.h"
41#include "spu.h"
42#include "tz-api.h"
43#include "tz-fault.h"
44#include "tz-target-cfg.h"
45
46#include <arm_cmse.h>
47
48/*---------------------------------------------------------------------------*/
49#include "sys/log.h"
50#define LOG_MODULE "TZSecureWorld"
51#define LOG_LEVEL LOG_LEVEL_INFO
52/*---------------------------------------------------------------------------*/
53typedef void __attribute__((cmse_nonsecure_call)) (*tz_ns_func_ptr_t)(void);
54#define TZ_NONSECURE_FUNC_PTR_DECLARE(fptr) tz_ns_func_ptr_t fptr
55#define TZ_NONSECURE_FUNC_PTR_CREATE(fptr) \
56 ((tz_ns_func_ptr_t)(cmse_nsfptr_create(fptr)))
57/*---------------------------------------------------------------------------*/
58static uintptr_t *
59setup(void)
60{
61 LOG_INFO("Initializing TrustZone\n");
62
63 LOG_INFO("Enabling fault handlers\n");
64 enable_fault_handlers();
65
66 /*
67 * Set flash and RAM secure.
68 * Set non-secure partition non-secure for both flash and RAM.
69 * Set all peripherals non-secure.
70 */
71#ifndef SECURE_UART0
72 /*
73 * If UART will be handed to the normal world, uninitialize the
74 * secure UART driver before changing the SPU security attributes.
75 * This stops any pending DMA, disables the peripheral, and
76 * prevents the secure world from accidentally accessing UART
77 * after it becomes non-secure (which would cause a BusFault).
78 */
80#endif
81
82 sau_and_idau_cfg();
83 non_secure_configuration();
84
85 /*
86 * After non_secure_configuration(), UART may be non-secure
87 * (unless SECURE_UART0 is defined). The secure world must not
88 * attempt to print via a non-secure UART as it will hang in
89 * the TX-in-progress polling loop.
90 */
91
92 /* Verify that the start of the vector table of the non-secure world
93 now has non-secure permissions. */
94 void *ptr = (void *)NS_CODE_START;
95 if(cmse_check_address_range(ptr, sizeof(ptr), CMSE_NONSECURE) != ptr) {
96#ifdef SECURE_UART0
97 LOG_ERR("Non-secure image has incorrect permissions\n");
98#endif
99 return NULL;
100 }
101
102 system_reset_cfg();
103 nvic_interrupt_target_state_cfg();
104 nvic_interrupt_enable();
105
106 uintptr_t *vtor_ns = (uintptr_t *)NS_CODE_START;
107 LOG_DBG("NS image at %p\n", vtor_ns);
108 LOG_DBG("NS main stack pointer at 0x%"PRIxPTR"\n", vtor_ns[0]);
109 LOG_DBG("NS reset vector at 0x%"PRIxPTR"\n", vtor_ns[1]);
110
111 /*
112 * Initialize the Non-Secure Callable (NSC) region in order to enable
113 * function calls from the non-secure world to the secure world.
114 */
115 LOG_DBG("Secure gateway region: %p - %p\n", &__sg_start, &__sg_end);
116 LOG_DBG("NSC size %p\n", &__nsc_size);
117 spu_regions_flash_config_non_secure_callable((uint32_t)&__sg_start,
118 (uint32_t)&__sg_end - 1);
119
120 LOG_DBG("__ARM_FEATURE_CMSE = %d\n", __ARM_FEATURE_CMSE);
121
122 /* Configure non-secure stack */
123 tz_nonsecure_setup_conf_t spm_ns_conf = {
124 .vtor_ns = (uintptr_t)vtor_ns,
125 .msp_ns = vtor_ns[0],
126 .psp_ns = vtor_ns[0], /* Was: 0 */
127 .control_ns.npriv = 0, /* Privileged mode */
128 .control_ns.spsel = 0, /* Use MSP in Thread mode */
129 };
130
131 tz_nonsecure_state_setup(&spm_ns_conf);
132
133 return vtor_ns;
134}
135/*---------------------------------------------------------------------------*/
136void
138{
139 tz_fault_init();
140 spu_report_violation();
141
142 /* Process all events before switching to non-secure */
143 process_num_events_t r;
144 do {
145 r = process_run();
147 } while(r > 0);
148
149 uintptr_t *vtor_ns = setup();
150 if(vtor_ns == NULL) {
151 LOG_ERR("Not jumping to the normal world due to initialization error\n");
152 return;
153 }
154
155 TZ_NONSECURE_FUNC_PTR_DECLARE(reset_ns);
156 reset_ns = TZ_NONSECURE_FUNC_PTR_CREATE(vtor_ns[1]);
157 if(!cmse_is_nsfptr(reset_ns)) {
158 LOG_ERR("Invalid non-secure pointer type\n");
159 return;
160 }
161
162#ifdef SECURE_UART0
163 LOG_INFO("Preparing to jump to the normal world\n");
164#endif
165 spu_periph_config_uarte();
166
167 __DSB();
168 __ISB();
169 reset_ns();
170}
171/*---------------------------------------------------------------------------*/
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition watchdog.c:85
void platform_main_loop(void)
The platform's main loop, if provided.
Definition tz-secure.c:137
void uarte_uninit(void)
Tear down the UARTE driver, releasing the peripheral.
process_num_events_t process_run(void)
Run the system once - call poll handlers and process one event.
Definition process.c:305
Header file for the logging system.
A convenient struct to include all required Non-Secure state configuration.
nRF5340 target configuration header
UARTE header file for the nRF.