blob: 0b5e04304470794d6ef1213ef33178ee9690ee16 [file] [log] [blame]
Kevin Peng3f67b2e2021-10-18 17:47:27 +08001/*
Xinyu Zhanga16228b2023-01-12 14:54:04 +08002 * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
Chris Brand8b58ebd2022-10-18 17:02:25 -07003 * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon
4 * company) or an affiliate of Cypress Semiconductor Corporation. All rights
5 * reserved.
Kevin Peng3f67b2e2021-10-18 17:47:27 +08006 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10
11#include "interrupt.h"
12
13#include "bitops.h"
Kevin Pengca59ec02021-12-09 14:35:50 +080014#include "current.h"
Kevin Pengb42ed862022-08-08 14:44:02 +080015#include "svc_num.h"
Kevin Peng3f67b2e2021-10-18 17:47:27 +080016#include "tfm_arch.h"
17#include "tfm_hal_interrupt.h"
18#include "tfm_hal_isolation.h"
19#include "thread.h"
20#include "utilities.h"
21
22#include "load/spm_load_api.h"
shejia0195a88bc2023-01-16 15:44:46 +080023#include "ffm/backend.h"
Jianliang Shen9e389352023-02-09 16:58:08 +080024#include "internal_status_code.h"
Kevin Peng3f67b2e2021-10-18 17:47:27 +080025
Chendi Sun0f7d2822022-10-28 12:24:12 +080026extern uintptr_t spm_boundary;
27
Sherry Zhangd6dbe512022-03-23 16:42:32 +080028#if TFM_LVL != 1
29extern void tfm_flih_func_return(psa_flih_result_t result);
30
Kevin Peng3f67b2e2021-10-18 17:47:27 +080031__attribute__((naked))
32static psa_flih_result_t tfm_flih_deprivileged_handling(void *p_pt,
33 uintptr_t fn_flih,
Kevin Pengca59ec02021-12-09 14:35:50 +080034 void *curr_component)
Kevin Peng3f67b2e2021-10-18 17:47:27 +080035{
Sherry Zhang9714d962022-03-02 10:52:46 +080036 __ASM volatile("SVC "M2S(TFM_SVC_PREPARE_DEPRIV_FLIH)" \n"
37 "BX LR \n"
38 );
Kevin Peng3f67b2e2021-10-18 17:47:27 +080039}
40
Kevin Pengf7a20d82021-12-13 14:38:37 +080041uint32_t tfm_flih_prepare_depriv_flih(struct partition_t *p_owner_sp,
42 uintptr_t flih_func)
Kevin Peng3f67b2e2021-10-18 17:47:27 +080043{
44 struct partition_t *p_curr_sp;
Kevin Pengca59ec02021-12-09 14:35:50 +080045 uintptr_t sp_base, sp_limit, curr_stack, ctx_stack;
Kevin Peng3f67b2e2021-10-18 17:47:27 +080046 struct context_ctrl_t flih_ctx_ctrl;
Xinyu Zhang6ad07032022-08-10 14:45:56 +080047 fih_int fih_rc = FIH_FAILURE;
Kevin Peng3f67b2e2021-10-18 17:47:27 +080048
49 /* Come too early before runtime setup, should not happen. */
50 if (!CURRENT_THREAD) {
51 tfm_core_panic();
52 }
53
Kevin Pengca59ec02021-12-09 14:35:50 +080054 p_curr_sp = GET_CURRENT_COMPONENT();
55 sp_base = LOAD_ALLOCED_STACK_ADDR(p_owner_sp->p_ldinf)
56 + p_owner_sp->p_ldinf->stack_size;
57 sp_limit = LOAD_ALLOCED_STACK_ADDR(p_owner_sp->p_ldinf);
Kevin Peng3f67b2e2021-10-18 17:47:27 +080058
Kevin Pengca59ec02021-12-09 14:35:50 +080059 curr_stack = (uintptr_t)__get_PSP();
60 if (curr_stack < sp_base && curr_stack > sp_limit) {
61 /* The IRQ Partition's stack is being used */
62 ctx_stack = curr_stack;
Kevin Peng3f67b2e2021-10-18 17:47:27 +080063 } else {
Kevin Pengca59ec02021-12-09 14:35:50 +080064 ctx_stack =
65 ((struct context_ctrl_t *)p_owner_sp->thrd.p_context_ctrl)->sp;
Kevin Peng3f67b2e2021-10-18 17:47:27 +080066 }
67
Chendi Sun0f7d2822022-10-28 12:24:12 +080068 if (tfm_hal_boundary_need_switch(p_curr_sp->boundary,
69 p_owner_sp->boundary)) {
Xinyu Zhang6ad07032022-08-10 14:45:56 +080070 FIH_CALL(tfm_hal_activate_boundary, fih_rc,
71 p_owner_sp->p_ldinf, p_owner_sp->boundary);
Kevin Pengca59ec02021-12-09 14:35:50 +080072 }
73
74 /*
75 * The CURRENT_COMPONENT has been stored on MSP by the SVC call, safe to
76 * update it.
77 */
78 SET_CURRENT_COMPONENT(p_owner_sp);
79
Ken Liubf4681f2022-02-11 11:15:03 +080080 flih_ctx_ctrl.sp_limit = sp_limit;
81 flih_ctx_ctrl.sp = ctx_stack;
82
Kevin Peng3f67b2e2021-10-18 17:47:27 +080083 tfm_arch_init_context(&flih_ctx_ctrl,
Kevin Pengf7a20d82021-12-13 14:38:37 +080084 flih_func, NULL,
Ken Liubf4681f2022-02-11 11:15:03 +080085 (uintptr_t)tfm_flih_func_return);
Kevin Peng3f67b2e2021-10-18 17:47:27 +080086
87 (void)tfm_arch_refresh_hardware_context(&flih_ctx_ctrl);
88
89 return flih_ctx_ctrl.exc_ret;
90}
91
92/* Go back to ISR from FLIH functions */
Kevin Pengf7a20d82021-12-13 14:38:37 +080093uint32_t tfm_flih_return_to_isr(psa_flih_result_t result,
94 struct context_flih_ret_t *p_ctx_flih_ret)
Kevin Peng3f67b2e2021-10-18 17:47:27 +080095{
96 struct partition_t *p_prev_sp, *p_owner_sp;
Xinyu Zhang6ad07032022-08-10 14:45:56 +080097 fih_int fih_rc = FIH_FAILURE;
Kevin Peng3f67b2e2021-10-18 17:47:27 +080098
Kevin Pengca59ec02021-12-09 14:35:50 +080099 p_prev_sp = (struct partition_t *)(p_ctx_flih_ret->state_ctx.r2);
100 p_owner_sp = GET_CURRENT_COMPONENT();
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800101
Chendi Sun0f7d2822022-10-28 12:24:12 +0800102 if (tfm_hal_boundary_need_switch(p_owner_sp->boundary,
103 p_prev_sp->boundary)) {
Xinyu Zhang6ad07032022-08-10 14:45:56 +0800104 FIH_CALL(tfm_hal_activate_boundary, fih_rc,
105 p_prev_sp->p_ldinf, p_prev_sp->boundary);
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800106 }
107
Kevin Pengca59ec02021-12-09 14:35:50 +0800108 /* Restore current component */
109 SET_CURRENT_COMPONENT(p_prev_sp);
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800110
Kevin Pengca59ec02021-12-09 14:35:50 +0800111 tfm_arch_set_psplim(p_ctx_flih_ret->psplim);
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800112 __set_PSP(p_ctx_flih_ret->psp);
113
114 /* Set FLIH result to the ISR */
115 p_ctx_flih_ret->state_ctx.r0 = (uint32_t)result;
116
Xinyu Zhanga16228b2023-01-12 14:54:04 +0800117 return EXC_RETURN_HANDLER;
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800118}
Sherry Zhangd6dbe512022-03-23 16:42:32 +0800119#endif
120
Chris Brand10a2acb2022-10-18 17:12:27 -0700121const struct irq_load_info_t *get_irq_info_for_signal(
Sherry Zhangd6dbe512022-03-23 16:42:32 +0800122 const struct partition_load_info_t *p_ldinf,
123 psa_signal_t signal)
124{
125 size_t i;
Chris Brand10a2acb2022-10-18 17:12:27 -0700126 const struct irq_load_info_t *irq_info;
Sherry Zhangd6dbe512022-03-23 16:42:32 +0800127
128 if (!IS_ONLY_ONE_BIT_IN_UINT32(signal)) {
129 return NULL;
130 }
131
Chris Brand8b58ebd2022-10-18 17:02:25 -0700132 irq_info = LOAD_INFO_IRQ(p_ldinf);
Sherry Zhangd6dbe512022-03-23 16:42:32 +0800133 for (i = 0; i < p_ldinf->nirqs; i++) {
134 if (irq_info[i].signal == signal) {
135 return &irq_info[i];
136 }
137 }
138
139 return NULL;
140}
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800141
Chris Brand10a2acb2022-10-18 17:12:27 -0700142void spm_handle_interrupt(void *p_pt, const struct irq_load_info_t *p_ildi)
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800143{
144 psa_flih_result_t flih_result;
145 struct partition_t *p_part;
Jianliang Shen9e389352023-02-09 16:58:08 +0800146 psa_status_t ret = 0;
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800147
148 if (!p_pt || !p_ildi) {
149 tfm_core_panic();
150 }
151
152 p_part = (struct partition_t *)p_pt;
153
154 if (p_ildi->pid != p_part->p_ldinf->pid) {
155 tfm_core_panic();
156 }
157
158 if (p_ildi->flih_func == NULL) {
159 /* SLIH Model Handling */
160 tfm_hal_irq_disable(p_ildi->source);
161 flih_result = PSA_FLIH_SIGNAL;
162 } else {
163 /* FLIH Model Handling */
Sherry Zhangd6dbe512022-03-23 16:42:32 +0800164#if TFM_LVL == 1
165 flih_result = p_ildi->flih_func();
166#else
Roman Mazurak830b06e2022-11-21 20:06:16 +0200167 if (!tfm_hal_boundary_need_switch(spm_boundary,
Chendi Sun0f7d2822022-10-28 12:24:12 +0800168 p_part->boundary)) {
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800169 flih_result = p_ildi->flih_func();
170 } else {
171 flih_result = tfm_flih_deprivileged_handling(
172 p_part,
173 (uintptr_t)p_ildi->flih_func,
Kevin Pengca59ec02021-12-09 14:35:50 +0800174 GET_CURRENT_COMPONENT());
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800175 }
Sherry Zhangd6dbe512022-03-23 16:42:32 +0800176#endif
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800177 }
178
179 if (flih_result == PSA_FLIH_SIGNAL) {
Jianliang Shen9e389352023-02-09 16:58:08 +0800180 ret = backend_assert_signal(p_pt, p_ildi->signal);
Sherry Zhang049733e2022-04-20 21:37:51 +0800181 /* In SFN backend, there is only one thread, no thread switch. */
182#if CONFIG_TFM_SPM_BACKEND_SFN != 1
Jianliang Shen9e389352023-02-09 16:58:08 +0800183 if (ret == STATUS_NEED_SCHEDULE) {
Kevin Peng8a579692021-12-15 13:44:42 +0800184 tfm_arch_trigger_pendsv();
185 }
Sherry Zhang049733e2022-04-20 21:37:51 +0800186#endif
Kevin Peng3f67b2e2021-10-18 17:47:27 +0800187 }
188}