blob: c9b45638f190d5360353da81c69cdf3a952a8bb2 [file] [log] [blame]
Mingyang Sundeae45d2021-09-06 15:31:07 +08001/*
Mingyang Sunbb4a42a2021-12-14 15:18:52 +08002 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
Chris Brandb4c2b002022-07-21 12:54:00 -07003 * Copyright (c) 2021-2022 Cypress Semiconductor Corporation (an Infineon
4 * company) or an affiliate of Cypress Semiconductor Corporation. All rights
5 * reserved.
Mingyang Sundeae45d2021-09-06 15:31:07 +08006 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10
11#include <stdint.h>
Sherry Zhang049733e2022-04-20 21:37:51 +080012#include "aapcs_local.h"
Mingyang Sun620c8562021-11-10 11:44:58 +080013#include "critical_section.h"
Ken Liue07c3b72021-10-14 16:19:13 +080014#include "compiler_ext_defs.h"
Summer Qin596f5552022-01-27 18:04:06 +080015#include "runtime_defs.h"
Chris Brand30106ba2022-01-13 13:48:50 -080016#include "ffm/stack_watermark.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080017#include "spm_ipc.h"
Sherry Zhang049733e2022-04-20 21:37:51 +080018#include "tfm_hal_memory_symbols.h"
Ken Liu62bae592021-10-19 22:15:43 +080019#include "tfm_hal_isolation.h"
Kevin Pengb288c522021-09-26 16:18:23 +080020#include "tfm_hal_platform.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080021#include "tfm_rpc.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080022#include "ffm/backend.h"
Ken Liu62bae592021-10-19 22:15:43 +080023#include "utilities.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080024#include "load/partition_defs.h"
25#include "load/service_defs.h"
26#include "load/spm_load_api.h"
27#include "psa/error.h"
28
29/* Declare the global component list */
30struct partition_head_t partition_listhead;
31
Kevin Peng9f1a7542022-02-07 16:32:27 +080032#if CONFIG_TFM_PSA_API_CROSS_CALL == 1
Ken Liu63a176b2022-06-09 22:36:56 +080033/* Instance for SPM_THREAD_CONTEXT */
Ken Liue07c3b72021-10-14 16:19:13 +080034
35#ifdef TFM_MULTI_CORE_TOPOLOGY
Ken Liu63a176b2022-06-09 22:36:56 +080036
37static uint8_t spm_thread_stack[CONFIG_TFM_SPM_THREAD_STACK_SIZE] __aligned(8);
38ARCH_CLAIM_CTXCTRL_INSTANCE(spm_thread_context,
39 spm_thread_stack,
40 sizeof(spm_thread_stack));
41
Ken Liue07c3b72021-10-14 16:19:13 +080042struct context_ctrl_t *p_spm_thread_context = &spm_thread_context;
43#else
44struct context_ctrl_t *p_spm_thread_context;
45#endif
46
47#endif
48
Sherry Zhang049733e2022-04-20 21:37:51 +080049/* Indicator point to the partition meta */
50uintptr_t *partition_meta_indicator_pos;
51
52extern uint32_t scheduler_lock;
53
Summer Qin596f5552022-01-27 18:04:06 +080054static void prv_process_metadata(struct partition_t *p_pt)
55{
Kevin Peng43160d52022-02-11 13:35:56 +080056 const struct partition_load_info_t *p_pt_ldi;
57 const struct service_load_info_t *p_srv_ldi;
58 struct context_ctrl_t *ctx_ctrl;
59 struct runtime_metadata_t *p_rt_meta;
60 service_fn_t *p_sfn_table;
61 uint32_t allocate_size;
Summer Qin596f5552022-01-27 18:04:06 +080062
Kevin Peng43160d52022-02-11 13:35:56 +080063 p_pt_ldi = p_pt->p_ldinf;
Chris Brand1fb796d2022-10-18 16:54:25 -070064 p_srv_ldi = LOAD_INFO_SERVICE(p_pt_ldi);
Kevin Peng43160d52022-02-11 13:35:56 +080065 ctx_ctrl = &p_pt->ctx_ctrl;
66
67 /* common runtime metadata */
68 allocate_size = sizeof(*p_rt_meta);
69
70 if (!IS_PARTITION_IPC_MODEL(p_pt_ldi)) {
71 /* SFN specific metadata - SFN function table */
72 allocate_size += sizeof(service_fn_t) * p_pt_ldi->nservices;
Summer Qin596f5552022-01-27 18:04:06 +080073 }
74
Kevin Peng43160d52022-02-11 13:35:56 +080075 ARCH_CTXCTRL_ALLOCATE_STACK(ctx_ctrl, allocate_size);
76 p_rt_meta = (struct runtime_metadata_t *)
77 ARCH_CTXCTRL_ALLOCATED_PTR(ctx_ctrl);
78
79 p_rt_meta->entry = p_pt_ldi->entry;
80 p_rt_meta->n_sfn = 0;
81 p_sfn_table = p_rt_meta->sfn_table;
82
83 if (!IS_PARTITION_IPC_MODEL(p_pt_ldi)) {
84 /* SFN table. The signal bit of the service is the same index of SFN. */
85 for (int i = 0; i < p_pt_ldi->nservices; i++) {
86 p_sfn_table[i] = (service_fn_t)p_srv_ldi[i].sfn;
87 }
88
89 p_rt_meta->n_sfn = p_pt_ldi->nservices;
90 }
91
92 p_pt->p_metadata = (void *)p_rt_meta;
Summer Qin596f5552022-01-27 18:04:06 +080093}
94
Mingyang Sundeae45d2021-09-06 15:31:07 +080095/*
96 * Send message and wake up the SP who is waiting on message queue, block the
Ken Liuf39d8eb2021-10-07 12:55:33 +080097 * current thread and trigger scheduler.
Mingyang Sundeae45d2021-09-06 15:31:07 +080098 */
Ken Liu995a9742022-05-18 19:28:30 +080099psa_status_t backend_messaging(struct service_t *service,
100 struct conn_handle_t *handle)
Mingyang Sundeae45d2021-09-06 15:31:07 +0800101{
102 struct partition_t *p_owner = NULL;
103 psa_signal_t signal = 0;
Mingyang Sun620c8562021-11-10 11:44:58 +0800104 struct critical_section_t cs_assert = CRITICAL_SECTION_STATIC_INIT;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800105
Mingyang Suna09adda2022-02-16 18:11:33 +0800106 if (!handle || !service || !service->p_ldinf || !service->partition) {
Mingyang Sunbb4a42a2021-12-14 15:18:52 +0800107 return PSA_ERROR_PROGRAMMER_ERROR;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800108 }
109
110 p_owner = service->partition;
111 signal = service->p_ldinf->signal;
112
Mingyang Sun620c8562021-11-10 11:44:58 +0800113 CRITICAL_SECTION_ENTER(cs_assert);
Ken Liu5a28da32022-01-19 14:37:05 +0800114
Mingyang Suna09adda2022-02-16 18:11:33 +0800115 UNI_LIST_INSERT_AFTER(p_owner, handle, p_handles);
Mingyang Sundeae45d2021-09-06 15:31:07 +0800116
117 /* Messages put. Update signals */
118 p_owner->signals_asserted |= signal;
119
120 if (p_owner->signals_waiting & signal) {
121 thrd_wake_up(&p_owner->waitobj,
122 (p_owner->signals_asserted & p_owner->signals_waiting));
123 p_owner->signals_waiting &= ~signal;
124 }
Mingyang Sun620c8562021-11-10 11:44:58 +0800125 CRITICAL_SECTION_LEAVE(cs_assert);
Mingyang Sundeae45d2021-09-06 15:31:07 +0800126
127 /*
128 * If it is a NS request via RPC, it is unnecessary to block current
129 * thread.
130 */
131
Mingyang Suna09adda2022-02-16 18:11:33 +0800132 if (!is_tfm_rpc_msg(handle)) {
Mingyang Sunac1114e2022-03-23 17:32:07 +0800133 thrd_set_wait(&handle->ack_evnt, CURRENT_THREAD);
Mingyang Sundeae45d2021-09-06 15:31:07 +0800134 }
135
Mingyang Sunaeca8e02022-02-24 14:47:56 +0800136 handle->status = TFM_HANDLE_STATUS_ACTIVE;
137
Mingyang Sundeae45d2021-09-06 15:31:07 +0800138 return PSA_SUCCESS;
139}
140
Ken Liu995a9742022-05-18 19:28:30 +0800141psa_status_t backend_replying(struct conn_handle_t *handle, int32_t status)
Ken Liu802a3702021-10-15 12:09:56 +0800142{
Mingyang Suna09adda2022-02-16 18:11:33 +0800143 if (is_tfm_rpc_msg(handle)) {
144 tfm_rpc_client_call_reply(handle, status);
Ken Liu802a3702021-10-15 12:09:56 +0800145 } else {
Mingyang Suna09adda2022-02-16 18:11:33 +0800146 thrd_wake_up(&handle->ack_evnt, status);
Ken Liu802a3702021-10-15 12:09:56 +0800147 }
Ken Liuf39d8eb2021-10-07 12:55:33 +0800148
149 /*
150 * 'psa_reply' exists in IPC model only and returns 'void'. Return
151 * 'PSA_SUCCESS' here always since SPM does not forward the status
152 * to the caller.
153 */
154 return PSA_SUCCESS;
Ken Liu802a3702021-10-15 12:09:56 +0800155}
156
Summer Qin596f5552022-01-27 18:04:06 +0800157extern void sprt_main(void);
158
Mingyang Sundeae45d2021-09-06 15:31:07 +0800159/* Parameters are treated as assuredly */
Ken Liu995a9742022-05-18 19:28:30 +0800160void backend_init_comp_assuredly(struct partition_t *p_pt,
161 uint32_t service_setting)
Mingyang Sundeae45d2021-09-06 15:31:07 +0800162{
163 const struct partition_load_info_t *p_pldi = p_pt->p_ldinf;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800164
Kevin Peng613b4172022-02-15 14:41:44 +0800165#if CONFIG_TFM_DOORBELL_API == 1
166 p_pt->signals_allowed |= PSA_DOORBELL;
167#endif /* CONFIG_TFM_DOORBELL_API == 1 */
168
169 p_pt->signals_allowed |= service_setting;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800170
171 THRD_SYNC_INIT(&p_pt->waitobj);
Ken Liu0bed7e02022-02-10 12:38:07 +0800172 UNI_LISI_INIT_NODE(p_pt, p_handles);
Mingyang Sundeae45d2021-09-06 15:31:07 +0800173
Ken Liubf4681f2022-02-11 11:15:03 +0800174 ARCH_CTXCTRL_INIT(&p_pt->ctx_ctrl,
175 LOAD_ALLOCED_STACK_ADDR(p_pldi),
176 p_pldi->stack_size);
177
Chris Brand30106ba2022-01-13 13:48:50 -0800178 watermark_stack(p_pt);
179
Summer Qin596f5552022-01-27 18:04:06 +0800180 prv_process_metadata(p_pt);
181
Mingyang Sundeae45d2021-09-06 15:31:07 +0800182 THRD_INIT(&p_pt->thrd, &p_pt->ctx_ctrl,
183 TO_THREAD_PRIORITY(PARTITION_PRIORITY(p_pldi->flags)));
184
Kevin Peng9f1a7542022-02-07 16:32:27 +0800185#if (CONFIG_TFM_PSA_API_CROSS_CALL == 1) && !defined(TFM_MULTI_CORE_TOPOLOGY)
Chris Brandb4c2b002022-07-21 12:54:00 -0700186 if (IS_PARTITION_NS_AGENT(p_pldi)) {
Ken Liue07c3b72021-10-14 16:19:13 +0800187 SPM_THREAD_CONTEXT = &p_pt->ctx_ctrl;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800188 }
Summer Qin95444822022-01-27 11:22:00 +0800189#endif
Mingyang Sundeae45d2021-09-06 15:31:07 +0800190
191 thrd_start(&p_pt->thrd,
Summer Qin596f5552022-01-27 18:04:06 +0800192 POSITION_TO_ENTRY(sprt_main, thrd_fn_t),
Ken Liubf4681f2022-02-11 11:15:03 +0800193 THRD_GENERAL_EXIT);
Mingyang Sundeae45d2021-09-06 15:31:07 +0800194}
195
Ken Liu995a9742022-05-18 19:28:30 +0800196uint32_t backend_system_run(void)
Mingyang Sundeae45d2021-09-06 15:31:07 +0800197{
Ken Liu62bae592021-10-19 22:15:43 +0800198 uint32_t control;
199 struct partition_t *p_cur_pt;
Xinyu Zhang6ad07032022-08-10 14:45:56 +0800200 fih_int fih_rc = FIH_FAILURE;
Ken Liu62bae592021-10-19 22:15:43 +0800201
Sherry Zhang68681642022-06-24 13:36:33 +0800202#if CONFIG_TFM_PSA_API_CROSS_CALL == 1
Summer Qin1056d1c2022-10-19 16:07:15 +0800203 SPM_ASSERT(SPM_THREAD_CONTEXT);
Chris Brand3778bc12021-12-15 17:01:05 -0800204#endif
205
Sherry Zhang049733e2022-04-20 21:37:51 +0800206 partition_meta_indicator_pos = (uintptr_t *)hal_mem_sp_meta_start;
Ken Liu62bae592021-10-19 22:15:43 +0800207 control = thrd_start_scheduler(&CURRENT_THREAD);
208
209 p_cur_pt = TO_CONTAINER(CURRENT_THREAD->p_context_ctrl,
210 struct partition_t, ctx_ctrl);
211
Xinyu Zhang6ad07032022-08-10 14:45:56 +0800212 FIH_CALL(tfm_hal_activate_boundary, fih_rc, p_cur_pt->p_ldinf, p_cur_pt->boundary);
213 if (fih_not_eq(fih_rc, fih_int_encode(TFM_HAL_SUCCESS))) {
Ken Liu62bae592021-10-19 22:15:43 +0800214 tfm_core_panic();
215 }
216
217 return control;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800218}
219
Ken Liu995a9742022-05-18 19:28:30 +0800220psa_signal_t backend_wait(struct partition_t *p_pt, psa_signal_t signal_mask)
Kevin Pengdef92de2021-11-10 16:14:48 +0800221{
Mingyang Sun5c9529f2022-03-15 17:51:56 +0800222 struct critical_section_t cs_assert = CRITICAL_SECTION_STATIC_INIT;
223 psa_signal_t ret_signal;
Kevin Pengdef92de2021-11-10 16:14:48 +0800224
Mingyang Sun5c9529f2022-03-15 17:51:56 +0800225 /*
Ken Liu995a9742022-05-18 19:28:30 +0800226 * 'backend_wait()' sets the waiting signal mask for partition, and
Mingyang Sun5c9529f2022-03-15 17:51:56 +0800227 * blocks the partition thread state to wait for signals.
228 * These changes should be inside the ciritical section to avoid
229 * 'signal_waiting' or the thread state to be changed by interrupts
230 * while this function is reading or writing values.
231 */
232 CRITICAL_SECTION_ENTER(cs_assert);
233
234 ret_signal = p_pt->signals_asserted & signal_mask;
235 if (ret_signal == 0) {
236 p_pt->signals_waiting = signal_mask;
Mingyang Sunac1114e2022-03-23 17:32:07 +0800237 thrd_set_wait(&p_pt->waitobj, CURRENT_THREAD);
Mingyang Sun5c9529f2022-03-15 17:51:56 +0800238 }
239 CRITICAL_SECTION_LEAVE(cs_assert);
240
241 return ret_signal;
Kevin Pengdef92de2021-11-10 16:14:48 +0800242}
243
Ken Liu995a9742022-05-18 19:28:30 +0800244void backend_wake_up(struct partition_t *p_pt)
Kevin Pengdef92de2021-11-10 16:14:48 +0800245{
246 thrd_wake_up(&p_pt->waitobj,
247 p_pt->signals_asserted & p_pt->signals_waiting);
Mingyang Sun09328bd2022-03-25 11:55:13 +0800248 p_pt->signals_waiting = 0;
Kevin Pengdef92de2021-11-10 16:14:48 +0800249}
250
Sherry Zhang049733e2022-04-20 21:37:51 +0800251uint64_t ipc_schedule(void)
252{
Xinyu Zhang6ad07032022-08-10 14:45:56 +0800253 fih_int fih_rc = FIH_FAILURE;
Sherry Zhang049733e2022-04-20 21:37:51 +0800254 AAPCS_DUAL_U32_T ctx_ctrls;
255 struct partition_t *p_part_curr, *p_part_next;
256 struct context_ctrl_t *p_curr_ctx;
257 struct thread_t *pth_next = thrd_next();
258 struct critical_section_t cs = CRITICAL_SECTION_STATIC_INIT;
259
260 p_curr_ctx = (struct context_ctrl_t *)(CURRENT_THREAD->p_context_ctrl);
261
262 AAPCS_DUAL_U32_SET(ctx_ctrls, (uint32_t)p_curr_ctx, (uint32_t)p_curr_ctx);
263
264 p_part_curr = GET_CURRENT_COMPONENT();
265 p_part_next = GET_THRD_OWNER(pth_next);
266
267 if (scheduler_lock != SCHEDULER_LOCKED && pth_next != NULL &&
268 p_part_curr != p_part_next) {
269 /* Check if there is enough room on stack to save more context */
270 if ((p_curr_ctx->sp_limit +
271 sizeof(struct tfm_additional_context_t)) > __get_PSP()) {
272 tfm_core_panic();
273 }
274
275 CRITICAL_SECTION_ENTER(cs);
276 /*
277 * If required, let the platform update boundary based on its
278 * implementation. Change privilege, MPU or other configurations.
279 */
Chendi Sun0f7d2822022-10-28 12:24:12 +0800280 if (tfm_hal_boundary_need_switch(p_part_curr->boundary,
281 p_part_next->boundary)) {
Xinyu Zhang6ad07032022-08-10 14:45:56 +0800282 FIH_CALL(tfm_hal_activate_boundary, fih_rc,
283 p_part_next->p_ldinf, p_part_next->boundary);
284 if (fih_not_eq(fih_rc, fih_int_encode(TFM_HAL_SUCCESS))) {
Sherry Zhang049733e2022-04-20 21:37:51 +0800285 tfm_core_panic();
286 }
287 }
288 ARCH_FLUSH_FP_CONTEXT();
289
290 AAPCS_DUAL_U32_SET_A1(ctx_ctrls, (uint32_t)pth_next->p_context_ctrl);
291
292 CURRENT_THREAD = pth_next;
293 CRITICAL_SECTION_LEAVE(cs);
294 }
295
296 /* Update meta indicator */
297 if (partition_meta_indicator_pos && (p_part_next->p_metadata)) {
298 *partition_meta_indicator_pos = (uintptr_t)(p_part_next->p_metadata);
299 }
300 return AAPCS_DUAL_U32_AS_U64(ctx_ctrls);
301}