1 /*
2 * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "compiler_ext_defs.h"
9 #include "security_defs.h"
10 #include "tfm_arch.h"
11 #include "tfm_core_trustzone.h"
12 #include "utilities.h"
13 #include "config_impl.h"
14
15 #if defined(__ICCARM__) && (CONFIG_TFM_FP >= 1)
16 #pragma required = tfm_arch_clear_fp_data
17 #endif
18
tfm_arch_free_msp_and_exc_ret(uint32_t msp_base,uint32_t exc_return)19 __naked void tfm_arch_free_msp_and_exc_ret(uint32_t msp_base,
20 uint32_t exc_return)
21 {
22 __ASM volatile(
23 #if !defined(__ICCARM__)
24 ".syntax unified \n"
25 #endif
26 "mov r4, r0 \n"
27 "mov r5, r1 \n"
28 #if (CONFIG_TFM_FLOAT_ABI > 0)
29 "bl tfm_arch_clear_fp_data \n"
30 #endif
31 "mov sp, r4 \n"
32 "bx r5 \n"
33 );
34 }
35 #if CONFIG_TFM_SPM_BACKEND_IPC == 1
tfm_arch_set_context_ret_code(void * p_ctx_ctrl,uint32_t ret_code)36 void tfm_arch_set_context_ret_code(void *p_ctx_ctrl, uint32_t ret_code)
37 {
38 struct context_ctrl_t *ctx_ctrl = (struct context_ctrl_t *)p_ctx_ctrl;
39
40 /*
41 * If a cross call is pending (cross_frame != CROSS_RETCODE_EMPTY), write
42 * return value to the frame position.
43 * Otherwise, write the return value to the state context on stack.
44 */
45 if (ctx_ctrl->cross_frame) {
46 ((struct cross_call_abi_frame_t *)ctx_ctrl->cross_frame)->a0 = ret_code;
47 ctx_ctrl->retcode_status = CROSS_RETCODE_UPDATED;
48 } else {
49 ((struct full_context_t *)ctx_ctrl->sp)->stat_ctx.r0 = ret_code;
50 }
51 }
52
53 /* Caution: Keep 'uint32_t' always for collecting thread return values! */
tfm_arch_trigger_pendsv(void)54 __naked uint32_t tfm_arch_trigger_pendsv(void)
55 {
56 __ASM volatile(
57 #ifndef __ICCARM__
58 ".syntax unified \n"
59 #endif
60 "ldr r0, ="M2S(SCB_ICSR_ADDR)" \n"
61 "ldr r1, ="M2S(SCB_ICSR_PENDSVSET_BIT)" \n"
62 "str r1, [r0, #0] \n"
63 "dsb #0xf \n"
64 "isb \n"
65 "bx lr \n"
66 );
67 }
68 #endif
69
tfm_arch_init_context(void * p_ctx_ctrl,uintptr_t pfn,void * param,uintptr_t pfnlr)70 void tfm_arch_init_context(void *p_ctx_ctrl,
71 uintptr_t pfn, void *param, uintptr_t pfnlr)
72 {
73 uintptr_t sp = ((struct context_ctrl_t *)p_ctx_ctrl)->sp;
74 uintptr_t sp_limit = ((struct context_ctrl_t *)p_ctx_ctrl)->sp_limit;
75 struct full_context_t *p_tctx =
76 (struct full_context_t *)arch_seal_thread_stack(sp);
77
78 /* Check if enough space on stack */
79 if ((uintptr_t)p_tctx - sizeof(struct full_context_t) < sp_limit) {
80 tfm_core_panic();
81 }
82
83 p_tctx--;
84
85 spm_memset(p_tctx, 0, sizeof(*p_tctx));
86
87 ARCH_CTXCTRL_EXCRET_PATTERN(&p_tctx->stat_ctx, param, pfn, pfnlr);
88
89 ((struct context_ctrl_t *)p_ctx_ctrl)->exc_ret = EXC_RETURN_THREAD_PSP;
90 ((struct context_ctrl_t *)p_ctx_ctrl)->sp = (uintptr_t)p_tctx;
91 }
92
tfm_arch_refresh_hardware_context(void * p_ctx_ctrl)93 uint32_t tfm_arch_refresh_hardware_context(void *p_ctx_ctrl)
94 {
95 struct context_ctrl_t *ctx_ctrl;
96 struct tfm_state_context_t *sc;
97
98 ctx_ctrl = (struct context_ctrl_t *)p_ctx_ctrl;
99 sc = &(((struct full_context_t *)(ctx_ctrl->sp))->stat_ctx);
100
101 tfm_arch_set_psplim(ctx_ctrl->sp_limit);
102 __set_PSP((uintptr_t)sc);
103
104 return ctx_ctrl->exc_ret;
105 }
106