blob: 39446c0deda4d9a779715e2734189b477b605c75 [file] [log] [blame]
Summer Qin90602de2020-08-04 10:23:39 +08001/*
Summer Qindea1f2c2021-01-11 14:46:34 +08002 * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
Summer Qin90602de2020-08-04 10:23:39 +08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
Summer Qin9c1fba12020-08-12 15:49:12 +08008#include "arch.h"
Xinyu Zhang3a453242021-04-16 17:57:09 +08009#include "compiler_ext_defs.h"
Øyvind Rønningstadf2c8dad2021-01-15 15:33:33 +010010#include "exception_info.h"
Summer Qin90602de2020-08-04 10:23:39 +080011#include "tfm_secure_api.h"
Summer Qin90602de2020-08-04 10:23:39 +080012
TTornblom18b3bf02020-09-03 17:42:11 +020013#if defined(__ICCARM__)
Kevin Peng414523f2021-03-04 14:00:34 +080014uint32_t tfm_core_svc_handler(uint32_t *msp, uint32_t *psp, uint32_t exc_return);
Xinyu Zhang3a453242021-04-16 17:57:09 +080015#pragma required = tfm_core_svc_handler
TTornblom18b3bf02020-09-03 17:42:11 +020016#endif
17
Summer Qin90602de2020-08-04 10:23:39 +080018nsfptr_t ns_entry;
19
20void jump_to_ns_code(void)
21{
22 /* Calls the non-secure Reset_Handler to jump to the non-secure binary */
23 ns_entry();
Ken Liu92e46a32020-07-25 22:58:00 +080024
25 tfm_core_panic();
Summer Qin90602de2020-08-04 10:23:39 +080026}
27
28__attribute__((naked))
Summer Qin90602de2020-08-04 10:23:39 +080029void tfm_enable_irq(psa_signal_t irq_signal)
30{
31 __ASM("SVC %0\n"
32 "BX LR\n"
33 : : "I" (TFM_SVC_ENABLE_IRQ));
34}
35
36__attribute__((naked))
37void tfm_disable_irq(psa_signal_t irq_signal)
38{
39 __ASM("SVC %0\n"
40 "BX LR\n"
41 : : "I" (TFM_SVC_DISABLE_IRQ));
42}
43
44__attribute__((naked))
Antonio de Angelisa4f23f82021-05-05 22:40:39 +010045void tfm_sfn_completion(enum tfm_status_e res, uint32_t exc_return, uintptr_t msp)
46{
47 __ASM volatile("MSR msp, r2\n"
48 "SVC %0\n"
49 "BX LR\n"
50 : : "I" (TFM_SVC_SFN_COMPLETION) : );
51}
52
53__attribute__((naked))
Summer Qin90602de2020-08-04 10:23:39 +080054static psa_signal_t psa_wait_internal(psa_signal_t signal_mask,
55 uint32_t timeout)
56{
57 __ASM("SVC %0\n"
58 "BX LR\n"
59 : : "I" (TFM_SVC_PSA_WAIT));
60}
61
62psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
63{
64 /* FIXME: By using the 'WFI' instruction this function blocks until an
65 * interrupt happens. It is necessary to do this here as tfm_core_psa_wait
66 * runs with the priority of the SVC, so it cannot be interrupted, so
67 * waiting in it for the required interrupt to happen is not an option.
68 */
69 psa_signal_t actual_signal_mask;
70
71 while (1) {
72 actual_signal_mask = psa_wait_internal(signal_mask, timeout);
73 if ((actual_signal_mask & signal_mask) != 0) {
74 return actual_signal_mask;
75 }
76 __WFI();
77 }
78}
79
80__attribute__((naked))
Antonio de Angelisa4f23f82021-05-05 22:40:39 +010081void tfm_arch_trigger_exc_return(uint32_t exc_return)
82{
83 __ASM volatile("BX R0");
84}
85
86__attribute__((naked))
Summer Qin90602de2020-08-04 10:23:39 +080087void psa_eoi(psa_signal_t irq_signal)
88{
89 __ASM("SVC %0\n"
90 "BX LR\n"
91 : : "I" (TFM_SVC_PSA_EOI));
92}
93
94#if defined(__ARM_ARCH_8_1M_MAIN__) || defined(__ARM_ARCH_8M_MAIN__)
Xinyu Zhang3a453242021-04-16 17:57:09 +080095__section("SFN") __naked
Summer Qin90602de2020-08-04 10:23:39 +080096int32_t tfm_core_sfn_request(const struct tfm_sfn_req_s *desc_ptr)
97{
98 __ASM volatile(
99 "PUSH {r4-r12, lr} \n"
100 "SVC %[SVC_REQ] \n"
101 "MOV r4, #0 \n"
102 "MOV r5, r4 \n"
103 "MOV r6, r4 \n"
104 "MOV r7, r4 \n"
105 "MOV r8, r4 \n"
106 "MOV r9, r4 \n"
107 "MOV r10, r4 \n"
108 "MOV r11, r4 \n"
109 "BLX lr \n"
110 "SVC %[SVC_RET] \n"
111 "POP {r4-r12, pc} \n"
112 : : [SVC_REQ] "I" (TFM_SVC_SFN_REQUEST),
113 [SVC_RET] "I" (TFM_SVC_SFN_RETURN)
114 );
115}
116
Xinyu Zhang3a453242021-04-16 17:57:09 +0800117__section("SFN") __naked
Summer Qin90602de2020-08-04 10:23:39 +0800118void priv_irq_handler_main(uint32_t partition_id, uint32_t unpriv_handler,
119 uint32_t irq_signal, uint32_t irq_line)
120{
121 __ASM(
122 /* Save the callee saved registers*/
123 "PUSH {r4-r12, lr} \n"
124 /* Request SVC to configure environment for the unpriv IRQ handler */
125 "SVC %[SVC_REQ] \n"
126 /* clear the callee saved registers to prevent information leak */
127 "MOV r4, #0 \n"
128 "MOV r5, r4 \n"
129 "MOV r6, r4 \n"
130 "MOV r7, r4 \n"
131 "MOV r8, r4 \n"
132 "MOV r9, r4 \n"
133 "MOV r10, r4 \n"
134 "MOV r11, r4 \n"
135 /* Branch to the unprivileged handler */
136 "BLX lr \n"
137 /* Request SVC to reconfigure the environment of the interrupted
138 * partition
139 */
140 "SVC %[SVC_RET] \n"
141 /* restore callee saved registers and return */
142 "POP {r4-r12, pc} \n"
143 : : [SVC_REQ] "I" (TFM_SVC_DEPRIV_REQ)
144 , [SVC_RET] "I" (TFM_SVC_DEPRIV_RET)
145 );
146}
147#elif defined(__ARM_ARCH_8M_BASE__)
Xinyu Zhang3a453242021-04-16 17:57:09 +0800148__section("SFN") __naked
Summer Qin90602de2020-08-04 10:23:39 +0800149int32_t tfm_core_sfn_request(const struct tfm_sfn_req_s *desc_ptr)
150{
151 __ASM volatile(
152 "PUSH {lr} \n"
153 "PUSH {r4-r7} \n"
154 "MOV r4, r8 \n"
155 "MOV r5, r9 \n"
156 "MOV r6, r10 \n"
157 "MOV r7, r11 \n"
158 "PUSH {r4-r7} \n"
159 "MOV r4, r12 \n"
160 "PUSH {r4} \n"
161 "SVC %[SVC_REQ] \n"
162 "MOVS r4, #0 \n"
163 "MOV r5, r4 \n"
164 "MOV r6, r4 \n"
165 "MOV r7, r4 \n"
166 "MOV r8, r4 \n"
167 "MOV r9, r4 \n"
168 "MOV r10, r4 \n"
169 "MOV r11, r4 \n"
170 "BLX lr \n"
171 "SVC %[SVC_RET] \n"
172 "POP {r4} \n"
173 "MOV r12, r4 \n"
174 "POP {r4-r7} \n"
175 "MOV r8, r4 \n"
176 "MOV r9, r5 \n"
177 "MOV r10, r6 \n"
178 "MOV r11, r7 \n"
179 "POP {r4-r7} \n"
180 "POP {pc} \n"
181 : : [SVC_REQ] "I" (TFM_SVC_SFN_REQUEST),
182 [SVC_RET] "I" (TFM_SVC_SFN_RETURN)
183 );
184}
185
Xinyu Zhang3a453242021-04-16 17:57:09 +0800186__section("SFN") __naked
Summer Qin90602de2020-08-04 10:23:39 +0800187void priv_irq_handler_main(uint32_t partition_id, uint32_t unpriv_handler,
188 uint32_t irq_signal, uint32_t irq_line)
189{
190 __ASM(
191 /* Save the callee saved registers*/
192 "PUSH {r4-r7, lr} \n"
193 "MOV r4, r8 \n"
194 "MOV r5, r9 \n"
195 "MOV r6, r10 \n"
196 "MOV r7, r11 \n"
197 "PUSH {r4-r7} \n"
198 "MOV r4, r12 \n"
199 "PUSH {r4} \n"
200 /* Request SVC to configure environment for the unpriv IRQ handler */
201 "SVC %[SVC_REQ] \n"
202 /* clear the callee saved registers to prevent information leak */
203 "MOVS r4, #0 \n"
204 "MOV r5, r4 \n"
205 "MOV r6, r4 \n"
206 "MOV r7, r4 \n"
207 "MOV r8, r4 \n"
208 "MOV r9, r4 \n"
209 "MOV r10, r4 \n"
210 "MOV r11, r4 \n"
211 /* Branch to the unprivileged handler */
212 "BLX lr \n"
213 /* Request SVC to reconfigure the environment of the interrupted
214 * partition
215 */
216 "SVC %[SVC_RET] \n"
217 /* restore callee saved registers and return */
218 "POP {r4} \n"
219 "MOV r12, r4 \n"
220 "POP {r4-r7} \n"
221 "MOV r8, r4 \n"
222 "MOV r9, r5 \n"
223 "MOV r10, r6 \n"
224 "MOV r11, r7 \n"
225 "POP {r4-r7, pc} \n"
226 : : [SVC_REQ] "I" (TFM_SVC_DEPRIV_REQ)
227 , [SVC_RET] "I" (TFM_SVC_DEPRIV_RET)
228 );
229}
230#endif
231
232#if defined(__ARM_ARCH_8_1M_MAIN__) || \
233 defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
Ken Liu50e21092020-10-14 16:42:15 +0800234void tfm_arch_set_secure_exception_priorities(void)
Summer Qin90602de2020-08-04 10:23:39 +0800235{
236 uint32_t VECTKEY;
237 SCB_Type *scb = SCB;
238 uint32_t AIRCR;
239
240 /* Set PRIS flag in AIRCR */
241 AIRCR = scb->AIRCR;
242 VECTKEY = (~AIRCR & SCB_AIRCR_VECTKEYSTAT_Msk);
243 scb->AIRCR = SCB_AIRCR_PRIS_Msk |
244 VECTKEY |
245 (AIRCR & ~SCB_AIRCR_VECTKEY_Msk);
Summer Qin90602de2020-08-04 10:23:39 +0800246
Ken Liu50e21092020-10-14 16:42:15 +0800247#ifndef __ARM_ARCH_8M_BASE__
Jamie Fox3ede9712020-09-28 23:14:54 +0100248 NVIC_SetPriority(MemoryManagement_IRQn, 0);
249 NVIC_SetPriority(BusFault_IRQn, 0);
Jamie Fox3ede9712020-09-28 23:14:54 +0100250 NVIC_SetPriority(SecureFault_IRQn, 0);
251#endif
Ken Liu50e21092020-10-14 16:42:15 +0800252
253 /*
254 * Function based model needs no PendSV for scheduling,
255 * set its priority just higher than thread mode.
256 */
257 NVIC_SetPriority(SVCall_IRQn, 0);
258 NVIC_SetPriority(PendSV_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
Jamie Fox3ede9712020-09-28 23:14:54 +0100259}
Ken Liu50e21092020-10-14 16:42:15 +0800260#else
261#error Function based model works on V8M series only.
262#endif
Jamie Fox3ede9712020-09-28 23:14:54 +0100263
Summer Qindea1f2c2021-01-11 14:46:34 +0800264void tfm_arch_config_extensions(void)
Jamie Fox45587672020-08-17 18:31:14 +0100265{
Xinyu Zhang3a453242021-04-16 17:57:09 +0800266#if defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)
Jamie Fox45587672020-08-17 18:31:14 +0100267 /* Configure Secure access to the FPU only if the secure image is being
268 * built with the FPU in use. This avoids introducing extra interrupt
269 * latency when the FPU is not used by the SPE.
270 */
Xinyu Zhang3a453242021-04-16 17:57:09 +0800271#if defined(__FPU_USED) && (__FPU_USED == 1U)
Jamie Fox45587672020-08-17 18:31:14 +0100272 /* Enable Secure privileged and unprivilged access to the FP Extension */
273 SCB->CPACR |= (3U << 10U*2U) /* enable CP10 full access */
274 | (3U << 11U*2U); /* enable CP11 full access */
275
276#if defined(__ARM_ARCH_8_1M_MAIN__) || defined(__ARM_ARCH_8M_MAIN__)
277 /* If the SPE will ever use the floating-point registers for sensitive data,
278 * then FPCCR.TS, FPCCR.CLRONRET and FPCCR.CLRONRETS must be set at
279 * initialisation and not changed again afterwards.
280 */
281 FPU->FPCCR |= FPU_FPCCR_TS_Msk
282 | FPU_FPCCR_CLRONRET_Msk
283 | FPU_FPCCR_CLRONRETS_Msk;
284#endif
285#endif
286
287#if defined(__ARM_ARCH_8_1M_MAIN__) || defined(__ARM_ARCH_8M_MAIN__)
288 /* Permit Non-secure access to the Floating-point Extension.
289 * Note: It is still necessary to set CPACR_NS to enable the FP Extension in
290 * the NSPE. This configuration is left to NS privileged software.
291 */
292 SCB->NSACR |= SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk;
293#endif
Summer Qindea1f2c2021-01-11 14:46:34 +0800294
295#if defined(__ARM_ARCH_8_1M_MAIN__)
296 SCB->CCR |= SCB_CCR_TRD_Msk;
297#endif
Jamie Fox45587672020-08-17 18:31:14 +0100298#endif
299}
300
Xinyu Zhang3a453242021-04-16 17:57:09 +0800301#if defined(__ARM_ARCH_8M_BASE__) || \
302 defined(__ARM_ARCH_8_1M_MAIN__) || \
303 defined(__ARM_ARCH_8M_MAIN__)
Summer Qin90602de2020-08-04 10:23:39 +0800304__attribute__((naked)) void SVC_Handler(void)
305{
306 __ASM volatile(
Ken Liue0af44c2020-07-25 22:51:30 +0800307#if !defined(__ICCARM__)
308 ".syntax unified \n"
309#endif
Kevin Peng414523f2021-03-04 14:00:34 +0800310 "MRS r0, MSP \n"
311 "MOV r2, lr \n"
312 "MOVS r3, #8 \n"
313 "TST r2, r3 \n"
Ken Liue0af44c2020-07-25 22:51:30 +0800314 "BNE from_thread \n"
315 /*
316 * This branch is taken when the code is being invoked from handler mode.
317 * This happens when a de-privileged interrupt handler is to be run. Seal
318 * the stack before de-privileging.
319 */
Kevin Peng414523f2021-03-04 14:00:34 +0800320 "LDR r1, =0xFEF5EDA5 \n"
321 "MOVS r3, r1 \n"
322 "PUSH {r1, r3} \n"
Ken Liue0af44c2020-07-25 22:51:30 +0800323 "from_thread: \n"
Kevin Peng414523f2021-03-04 14:00:34 +0800324 "MRS r1, PSP \n"
Summer Qin90602de2020-08-04 10:23:39 +0800325 "BL tfm_core_svc_handler \n"
Kevin Peng414523f2021-03-04 14:00:34 +0800326 "MOVS r1, #8 \n"
Ken Liue0af44c2020-07-25 22:51:30 +0800327 "TST r1, r0 \n"
328 "BNE to_thread \n"
329 /*
330 * This branch is taken when the code is going to return to handler mode.
331 * This happens after a de-privileged interrupt handler had been run. Pop
332 * the sealing from the stack.
333 */
334 "POP {r1, r2} \n"
335 "to_thread: \n"
Summer Qin90602de2020-08-04 10:23:39 +0800336 "BX r0 \n"
337 );
338}
339#elif defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_7M__) || \
340 defined(__ARM_ARCH_7EM__)
341__attribute__((naked)) void SVC_Handler(void)
342{
343 __ASM volatile(
Kevin Peng414523f2021-03-04 14:00:34 +0800344 "MRS r0, MSP \n"
345 "MRS r1, PSP \n"
346 "MOV r2, lr \n"
347 "BL tfm_core_svc_handler \n"
348 "BX r0 \n"
Summer Qin90602de2020-08-04 10:23:39 +0800349 );
350}
351#endif
Jamie Foxb78795a2020-09-28 20:39:06 +0100352
353__attribute__((naked)) void HardFault_Handler(void)
354{
Øyvind Rønningstadf2c8dad2021-01-15 15:33:33 +0100355 EXCEPTION_INFO(EXCEPTION_TYPE_HARDFAULT);
356
Jamie Foxb78795a2020-09-28 20:39:06 +0100357 /* A HardFault may indicate corruption of secure state, so it is essential
358 * that Non-secure code does not regain control after one is raised.
359 * Returning from this exception could allow a pending NS exception to be
360 * taken, so the current solution is not to return.
361 */
362 __ASM volatile("b .");
363}
364
365__attribute__((naked)) void MemManage_Handler(void)
366{
Øyvind Rønningstadf2c8dad2021-01-15 15:33:33 +0100367 EXCEPTION_INFO(EXCEPTION_TYPE_MEMFAULT);
368
Jamie Foxb78795a2020-09-28 20:39:06 +0100369 /* A MemManage fault may indicate corruption of secure state, so it is
370 * essential that Non-secure code does not regain control after one is
371 * raised. Returning from this exception could allow a pending NS exception
372 * to be taken, so the current solution is not to return.
373 */
374 __ASM volatile("b .");
375}
376
377__attribute__((naked)) void BusFault_Handler(void)
378{
Øyvind Rønningstadf2c8dad2021-01-15 15:33:33 +0100379 EXCEPTION_INFO(EXCEPTION_TYPE_BUSFAULT);
380
Jamie Foxb78795a2020-09-28 20:39:06 +0100381 /* A BusFault may indicate corruption of secure state, so it is essential
382 * that Non-secure code does not regain control after one is raised.
383 * Returning from this exception could allow a pending NS exception to be
384 * taken, so the current solution is not to return.
385 */
386 __ASM volatile("b .");
387}
388
389__attribute__((naked)) void SecureFault_Handler(void)
390{
Øyvind Rønningstadf2c8dad2021-01-15 15:33:33 +0100391 EXCEPTION_INFO(EXCEPTION_TYPE_SECUREFAULT);
392
Jamie Foxb78795a2020-09-28 20:39:06 +0100393 /* A SecureFault may indicate corruption of secure state, so it is essential
394 * that Non-secure code does not regain control after one is raised.
395 * Returning from this exception could allow a pending NS exception to be
396 * taken, so the current solution is not to return.
397 */
398 __ASM volatile("b .");
399}
Øyvind Rønningstadf2c8dad2021-01-15 15:33:33 +0100400
401__attribute__((naked)) void UsageFault_Handler(void)
402{
403 EXCEPTION_INFO(EXCEPTION_TYPE_USAGEFAULT);
404 __ASM volatile("b .");
405}