blob: 802657b048875dbbfaf49303b7362d2389741c6c [file] [log] [blame]
Kevin Peng3f67b2e2021-10-18 17:47:27 +08001/*
Kevin Penga40d29f2022-01-19 14:44:34 +08002 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
Kevin Peng3f67b2e2021-10-18 17:47:27 +08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include "interrupt.h"
9
10#include "bitops.h"
Kevin Pengca59ec02021-12-09 14:35:50 +080011#include "current.h"
Kevin Pengb42ed862022-08-08 14:44:02 +080012#include "svc_num.h"
Kevin Peng3f67b2e2021-10-18 17:47:27 +080013#include "tfm_arch.h"
14#include "tfm_hal_interrupt.h"
15#include "tfm_hal_isolation.h"
16#include "thread.h"
17#include "utilities.h"
18
19#include "load/spm_load_api.h"
20
Sherry Zhangd6dbe512022-03-23 16:42:32 +080021#if TFM_LVL != 1
22extern void tfm_flih_func_return(psa_flih_result_t result);
23
Kevin Peng3f67b2e2021-10-18 17:47:27 +080024__attribute__((naked))
25static psa_flih_result_t tfm_flih_deprivileged_handling(void *p_pt,
26 uintptr_t fn_flih,
Kevin Pengca59ec02021-12-09 14:35:50 +080027 void *curr_component)
Kevin Peng3f67b2e2021-10-18 17:47:27 +080028{
Sherry Zhang9714d962022-03-02 10:52:46 +080029 __ASM volatile("SVC "M2S(TFM_SVC_PREPARE_DEPRIV_FLIH)" \n"
30 "BX LR \n"
31 );
Kevin Peng3f67b2e2021-10-18 17:47:27 +080032}
33
Kevin Pengf7a20d82021-12-13 14:38:37 +080034uint32_t tfm_flih_prepare_depriv_flih(struct partition_t *p_owner_sp,
35 uintptr_t flih_func)
Kevin Peng3f67b2e2021-10-18 17:47:27 +080036{
37 struct partition_t *p_curr_sp;
Kevin Pengca59ec02021-12-09 14:35:50 +080038 uintptr_t sp_base, sp_limit, curr_stack, ctx_stack;
Kevin Peng3f67b2e2021-10-18 17:47:27 +080039 struct context_ctrl_t flih_ctx_ctrl;
Xinyu Zhang6ad07032022-08-10 14:45:56 +080040 fih_int fih_rc = FIH_FAILURE;
Kevin Peng3f67b2e2021-10-18 17:47:27 +080041
42 /* Come too early before runtime setup, should not happen. */
43 if (!CURRENT_THREAD) {
44 tfm_core_panic();
45 }
46
Kevin Pengca59ec02021-12-09 14:35:50 +080047 p_curr_sp = GET_CURRENT_COMPONENT();
48 sp_base = LOAD_ALLOCED_STACK_ADDR(p_owner_sp->p_ldinf)
49 + p_owner_sp->p_ldinf->stack_size;
50 sp_limit = LOAD_ALLOCED_STACK_ADDR(p_owner_sp->p_ldinf);
Kevin Peng3f67b2e2021-10-18 17:47:27 +080051
Kevin Pengca59ec02021-12-09 14:35:50 +080052 curr_stack = (uintptr_t)__get_PSP();
53 if (curr_stack < sp_base && curr_stack > sp_limit) {
54 /* The IRQ Partition's stack is being used */
55 ctx_stack = curr_stack;
Kevin Peng3f67b2e2021-10-18 17:47:27 +080056 } else {
Kevin Pengca59ec02021-12-09 14:35:50 +080057 ctx_stack =
58 ((struct context_ctrl_t *)p_owner_sp->thrd.p_context_ctrl)->sp;
Kevin Peng3f67b2e2021-10-18 17:47:27 +080059 }
60
Ken Liu967ffa92022-05-25 15:13:34 +080061 if (p_owner_sp->boundary != p_curr_sp->boundary) {
Xinyu Zhang6ad07032022-08-10 14:45:56 +080062 FIH_CALL(tfm_hal_activate_boundary, fih_rc,
63 p_owner_sp->p_ldinf, p_owner_sp->boundary);
Kevin Pengca59ec02021-12-09 14:35:50 +080064 }
65
66 /*
67 * The CURRENT_COMPONENT has been stored on MSP by the SVC call, safe to
68 * update it.
69 */
70 SET_CURRENT_COMPONENT(p_owner_sp);
71
Ken Liubf4681f2022-02-11 11:15:03 +080072 flih_ctx_ctrl.sp_limit = sp_limit;
73 flih_ctx_ctrl.sp = ctx_stack;
74
Kevin Peng3f67b2e2021-10-18 17:47:27 +080075 tfm_arch_init_context(&flih_ctx_ctrl,
Kevin Pengf7a20d82021-12-13 14:38:37 +080076 flih_func, NULL,
Ken Liubf4681f2022-02-11 11:15:03 +080077 (uintptr_t)tfm_flih_func_return);
Kevin Peng3f67b2e2021-10-18 17:47:27 +080078
79 (void)tfm_arch_refresh_hardware_context(&flih_ctx_ctrl);
80
81 return flih_ctx_ctrl.exc_ret;
82}
83
84/* Go back to ISR from FLIH functions */
Kevin Pengf7a20d82021-12-13 14:38:37 +080085uint32_t tfm_flih_return_to_isr(psa_flih_result_t result,
86 struct context_flih_ret_t *p_ctx_flih_ret)
Kevin Peng3f67b2e2021-10-18 17:47:27 +080087{
88 struct partition_t *p_prev_sp, *p_owner_sp;
Xinyu Zhang6ad07032022-08-10 14:45:56 +080089 fih_int fih_rc = FIH_FAILURE;
Kevin Peng3f67b2e2021-10-18 17:47:27 +080090
Kevin Pengca59ec02021-12-09 14:35:50 +080091 p_prev_sp = (struct partition_t *)(p_ctx_flih_ret->state_ctx.r2);
92 p_owner_sp = GET_CURRENT_COMPONENT();
Kevin Peng3f67b2e2021-10-18 17:47:27 +080093
Ken Liu967ffa92022-05-25 15:13:34 +080094 if (p_owner_sp->boundary != p_prev_sp->boundary) {
Xinyu Zhang6ad07032022-08-10 14:45:56 +080095 FIH_CALL(tfm_hal_activate_boundary, fih_rc,
96 p_prev_sp->p_ldinf, p_prev_sp->boundary);
Kevin Peng3f67b2e2021-10-18 17:47:27 +080097 }
98
Kevin Pengca59ec02021-12-09 14:35:50 +080099 /* Restore current component */
100 SET_CURRENT_COMPONENT(p_prev_sp);
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800101
Kevin Pengca59ec02021-12-09 14:35:50 +0800102 tfm_arch_set_psplim(p_ctx_flih_ret->psplim);
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800103 __set_PSP(p_ctx_flih_ret->psp);
104
105 /* Set FLIH result to the ISR */
106 p_ctx_flih_ret->state_ctx.r0 = (uint32_t)result;
107
Kevin Pengca59ec02021-12-09 14:35:50 +0800108 return EXC_RETURN_HANDLER_S_MSP;
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800109}
Sherry Zhangd6dbe512022-03-23 16:42:32 +0800110#endif
111
112struct irq_load_info_t *get_irq_info_for_signal(
113 const struct partition_load_info_t *p_ldinf,
114 psa_signal_t signal)
115{
116 size_t i;
117 struct irq_load_info_t *irq_info;
118
119 if (!IS_ONLY_ONE_BIT_IN_UINT32(signal)) {
120 return NULL;
121 }
122
123 irq_info = (struct irq_load_info_t *)LOAD_INFO_IRQ(p_ldinf);
124 for (i = 0; i < p_ldinf->nirqs; i++) {
125 if (irq_info[i].signal == signal) {
126 return &irq_info[i];
127 }
128 }
129
130 return NULL;
131}
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800132
133void spm_handle_interrupt(void *p_pt, struct irq_load_info_t *p_ildi)
134{
135 psa_flih_result_t flih_result;
136 struct partition_t *p_part;
137
138 if (!p_pt || !p_ildi) {
139 tfm_core_panic();
140 }
141
142 p_part = (struct partition_t *)p_pt;
143
144 if (p_ildi->pid != p_part->p_ldinf->pid) {
145 tfm_core_panic();
146 }
147
148 if (p_ildi->flih_func == NULL) {
149 /* SLIH Model Handling */
150 tfm_hal_irq_disable(p_ildi->source);
151 flih_result = PSA_FLIH_SIGNAL;
152 } else {
153 /* FLIH Model Handling */
Sherry Zhangd6dbe512022-03-23 16:42:32 +0800154#if TFM_LVL == 1
155 flih_result = p_ildi->flih_func();
156#else
Kevin Penga40d29f2022-01-19 14:44:34 +0800157 if (GET_PARTITION_PRIVILEGED_MODE(p_part->p_ldinf) ==
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800158 TFM_PARTITION_PRIVILEGED_MODE) {
159 flih_result = p_ildi->flih_func();
160 } else {
161 flih_result = tfm_flih_deprivileged_handling(
162 p_part,
163 (uintptr_t)p_ildi->flih_func,
Kevin Pengca59ec02021-12-09 14:35:50 +0800164 GET_CURRENT_COMPONENT());
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800165 }
Sherry Zhangd6dbe512022-03-23 16:42:32 +0800166#endif
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800167 }
168
169 if (flih_result == PSA_FLIH_SIGNAL) {
170 spm_assert_signal(p_pt, p_ildi->signal);
Sherry Zhang049733e2022-04-20 21:37:51 +0800171 /* In SFN backend, there is only one thread, no thread switch. */
172#if CONFIG_TFM_SPM_BACKEND_SFN != 1
Kevin Peng8a579692021-12-15 13:44:42 +0800173 if (THRD_EXPECTING_SCHEDULE()) {
174 tfm_arch_trigger_pendsv();
175 }
Sherry Zhang049733e2022-04-20 21:37:51 +0800176#endif
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800177 }
178}