blob: 597016db9062834551f894951aaf092308c9d10e [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 Brand30106ba2022-01-13 13:48:50 -08003 * Copyright (c) 2021-2022, Cypress Semiconductor Corporation. All rights reserved.
Mingyang Sundeae45d2021-09-06 15:31:07 +08004 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 */
8
9#include <stdint.h>
Mingyang Sun620c8562021-11-10 11:44:58 +080010#include "critical_section.h"
Ken Liue07c3b72021-10-14 16:19:13 +080011#include "compiler_ext_defs.h"
Summer Qin596f5552022-01-27 18:04:06 +080012#include "runtime_defs.h"
Chris Brand30106ba2022-01-13 13:48:50 -080013#include "ffm/stack_watermark.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080014#include "spm_ipc.h"
Ken Liu62bae592021-10-19 22:15:43 +080015#include "tfm_hal_isolation.h"
Kevin Pengb288c522021-09-26 16:18:23 +080016#include "tfm_hal_platform.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080017#include "tfm_rpc.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080018#include "ffm/backend.h"
Ken Liu62bae592021-10-19 22:15:43 +080019#include "utilities.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080020#include "load/partition_defs.h"
21#include "load/service_defs.h"
22#include "load/spm_load_api.h"
23#include "psa/error.h"
24
25/* Declare the global component list */
26struct partition_head_t partition_listhead;
27
Kevin Peng9f1a7542022-02-07 16:32:27 +080028#if CONFIG_TFM_PSA_API_CROSS_CALL == 1
Ken Liue07c3b72021-10-14 16:19:13 +080029
30#ifdef TFM_MULTI_CORE_TOPOLOGY
31/* TODO: To be checked when RPC design updates. */
32static uint8_t spm_stack_local[CONFIG_TFM_SPM_THREAD_STACK_SIZE] __aligned(8);
33struct context_ctrl_t spm_thread_context = {
Ken Liubf4681f2022-02-11 11:15:03 +080034 .sp = (uint32_t)&spm_stack_local[CONFIG_TFM_SPM_THREAD_STACK_SIZE],
35 .sp_limit = (uint32_t)spm_stack_local,
36 .allocated = 0,
37 .exc_ret = 0,
Ken Liue07c3b72021-10-14 16:19:13 +080038};
39struct context_ctrl_t *p_spm_thread_context = &spm_thread_context;
40#else
41struct context_ctrl_t *p_spm_thread_context;
42#endif
43
44#endif
45
Summer Qin596f5552022-01-27 18:04:06 +080046static void prv_process_metadata(struct partition_t *p_pt)
47{
Kevin Peng43160d52022-02-11 13:35:56 +080048 const struct partition_load_info_t *p_pt_ldi;
49 const struct service_load_info_t *p_srv_ldi;
50 struct context_ctrl_t *ctx_ctrl;
51 struct runtime_metadata_t *p_rt_meta;
52 service_fn_t *p_sfn_table;
53 uint32_t allocate_size;
Summer Qin596f5552022-01-27 18:04:06 +080054
Kevin Peng43160d52022-02-11 13:35:56 +080055 p_pt_ldi = p_pt->p_ldinf;
56 p_srv_ldi = (struct service_load_info_t *)LOAD_INFO_SERVICE(p_pt_ldi);
57 ctx_ctrl = &p_pt->ctx_ctrl;
58
59 /* common runtime metadata */
60 allocate_size = sizeof(*p_rt_meta);
61
62 if (!IS_PARTITION_IPC_MODEL(p_pt_ldi)) {
63 /* SFN specific metadata - SFN function table */
64 allocate_size += sizeof(service_fn_t) * p_pt_ldi->nservices;
Summer Qin596f5552022-01-27 18:04:06 +080065 }
66
Kevin Peng43160d52022-02-11 13:35:56 +080067 ARCH_CTXCTRL_ALLOCATE_STACK(ctx_ctrl, allocate_size);
68 p_rt_meta = (struct runtime_metadata_t *)
69 ARCH_CTXCTRL_ALLOCATED_PTR(ctx_ctrl);
70
71 p_rt_meta->entry = p_pt_ldi->entry;
72 p_rt_meta->n_sfn = 0;
73 p_sfn_table = p_rt_meta->sfn_table;
74
75 if (!IS_PARTITION_IPC_MODEL(p_pt_ldi)) {
76 /* SFN table. The signal bit of the service is the same index of SFN. */
77 for (int i = 0; i < p_pt_ldi->nservices; i++) {
78 p_sfn_table[i] = (service_fn_t)p_srv_ldi[i].sfn;
79 }
80
81 p_rt_meta->n_sfn = p_pt_ldi->nservices;
82 }
83
84 p_pt->p_metadata = (void *)p_rt_meta;
Summer Qin596f5552022-01-27 18:04:06 +080085}
86
Mingyang Sundeae45d2021-09-06 15:31:07 +080087/*
88 * Send message and wake up the SP who is waiting on message queue, block the
Ken Liuf39d8eb2021-10-07 12:55:33 +080089 * current thread and trigger scheduler.
Mingyang Sundeae45d2021-09-06 15:31:07 +080090 */
91static psa_status_t ipc_messaging(struct service_t *service,
Mingyang Suna09adda2022-02-16 18:11:33 +080092 struct conn_handle_t *handle)
Mingyang Sundeae45d2021-09-06 15:31:07 +080093{
94 struct partition_t *p_owner = NULL;
95 psa_signal_t signal = 0;
Mingyang Sun620c8562021-11-10 11:44:58 +080096 struct critical_section_t cs_assert = CRITICAL_SECTION_STATIC_INIT;
Mingyang Sundeae45d2021-09-06 15:31:07 +080097
Mingyang Suna09adda2022-02-16 18:11:33 +080098 if (!handle || !service || !service->p_ldinf || !service->partition) {
Mingyang Sunbb4a42a2021-12-14 15:18:52 +080099 return PSA_ERROR_PROGRAMMER_ERROR;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800100 }
101
102 p_owner = service->partition;
103 signal = service->p_ldinf->signal;
104
Mingyang Sun620c8562021-11-10 11:44:58 +0800105 CRITICAL_SECTION_ENTER(cs_assert);
Ken Liu5a28da32022-01-19 14:37:05 +0800106
Mingyang Suna09adda2022-02-16 18:11:33 +0800107 UNI_LIST_INSERT_AFTER(p_owner, handle, p_handles);
Mingyang Sundeae45d2021-09-06 15:31:07 +0800108
109 /* Messages put. Update signals */
110 p_owner->signals_asserted |= signal;
111
112 if (p_owner->signals_waiting & signal) {
113 thrd_wake_up(&p_owner->waitobj,
114 (p_owner->signals_asserted & p_owner->signals_waiting));
115 p_owner->signals_waiting &= ~signal;
116 }
Mingyang Sun620c8562021-11-10 11:44:58 +0800117 CRITICAL_SECTION_LEAVE(cs_assert);
Mingyang Sundeae45d2021-09-06 15:31:07 +0800118
119 /*
120 * If it is a NS request via RPC, it is unnecessary to block current
121 * thread.
122 */
123
Mingyang Suna09adda2022-02-16 18:11:33 +0800124 if (!is_tfm_rpc_msg(handle)) {
Mingyang Sunac1114e2022-03-23 17:32:07 +0800125 thrd_set_wait(&handle->ack_evnt, CURRENT_THREAD);
Mingyang Sundeae45d2021-09-06 15:31:07 +0800126 }
127
Mingyang Sunaeca8e02022-02-24 14:47:56 +0800128 handle->status = TFM_HANDLE_STATUS_ACTIVE;
129
Mingyang Sundeae45d2021-09-06 15:31:07 +0800130 return PSA_SUCCESS;
131}
132
Mingyang Suna09adda2022-02-16 18:11:33 +0800133static psa_status_t ipc_replying(struct conn_handle_t *handle, int32_t status)
Ken Liu802a3702021-10-15 12:09:56 +0800134{
Mingyang Suna09adda2022-02-16 18:11:33 +0800135 if (is_tfm_rpc_msg(handle)) {
136 tfm_rpc_client_call_reply(handle, status);
Ken Liu802a3702021-10-15 12:09:56 +0800137 } else {
Mingyang Suna09adda2022-02-16 18:11:33 +0800138 thrd_wake_up(&handle->ack_evnt, status);
Ken Liu802a3702021-10-15 12:09:56 +0800139 }
Ken Liuf39d8eb2021-10-07 12:55:33 +0800140
141 /*
142 * 'psa_reply' exists in IPC model only and returns 'void'. Return
143 * 'PSA_SUCCESS' here always since SPM does not forward the status
144 * to the caller.
145 */
146 return PSA_SUCCESS;
Ken Liu802a3702021-10-15 12:09:56 +0800147}
148
Summer Qin596f5552022-01-27 18:04:06 +0800149extern void sprt_main(void);
150
Mingyang Sundeae45d2021-09-06 15:31:07 +0800151/* Parameters are treated as assuredly */
152static void ipc_comp_init_assuredly(struct partition_t *p_pt,
153 uint32_t service_setting)
154{
155 const struct partition_load_info_t *p_pldi = p_pt->p_ldinf;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800156
Kevin Peng613b4172022-02-15 14:41:44 +0800157#if CONFIG_TFM_DOORBELL_API == 1
158 p_pt->signals_allowed |= PSA_DOORBELL;
159#endif /* CONFIG_TFM_DOORBELL_API == 1 */
160
161 p_pt->signals_allowed |= service_setting;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800162
163 THRD_SYNC_INIT(&p_pt->waitobj);
Ken Liu0bed7e02022-02-10 12:38:07 +0800164 UNI_LISI_INIT_NODE(p_pt, p_handles);
Mingyang Sundeae45d2021-09-06 15:31:07 +0800165
Ken Liubf4681f2022-02-11 11:15:03 +0800166 ARCH_CTXCTRL_INIT(&p_pt->ctx_ctrl,
167 LOAD_ALLOCED_STACK_ADDR(p_pldi),
168 p_pldi->stack_size);
169
Chris Brand30106ba2022-01-13 13:48:50 -0800170 watermark_stack(p_pt);
171
Summer Qin596f5552022-01-27 18:04:06 +0800172 prv_process_metadata(p_pt);
173
Mingyang Sundeae45d2021-09-06 15:31:07 +0800174 THRD_INIT(&p_pt->thrd, &p_pt->ctx_ctrl,
175 TO_THREAD_PRIORITY(PARTITION_PRIORITY(p_pldi->flags)));
176
Kevin Peng9f1a7542022-02-07 16:32:27 +0800177#if (CONFIG_TFM_PSA_API_CROSS_CALL == 1) && !defined(TFM_MULTI_CORE_TOPOLOGY)
Ken Liu897e8f12022-02-10 03:21:17 +0100178 if (p_pldi->pid == TFM_SP_NON_SECURE_ID) {
Ken Liue07c3b72021-10-14 16:19:13 +0800179 SPM_THREAD_CONTEXT = &p_pt->ctx_ctrl;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800180 }
Summer Qin95444822022-01-27 11:22:00 +0800181#endif
Mingyang Sundeae45d2021-09-06 15:31:07 +0800182
183 thrd_start(&p_pt->thrd,
Summer Qin596f5552022-01-27 18:04:06 +0800184 POSITION_TO_ENTRY(sprt_main, thrd_fn_t),
Ken Liubf4681f2022-02-11 11:15:03 +0800185 THRD_GENERAL_EXIT);
Mingyang Sundeae45d2021-09-06 15:31:07 +0800186}
187
188static uint32_t ipc_system_run(void)
189{
Ken Liu62bae592021-10-19 22:15:43 +0800190 uint32_t control;
191 struct partition_t *p_cur_pt;
192
Kevin Peng9f1a7542022-02-07 16:32:27 +0800193#if CONFIG_TFM_PSA_API_THREAD_CALL == 1
Chris Brand3778bc12021-12-15 17:01:05 -0800194 TFM_CORE_ASSERT(SPM_THREAD_CONTEXT);
195#endif
196
Ken Liu62bae592021-10-19 22:15:43 +0800197 control = thrd_start_scheduler(&CURRENT_THREAD);
198
199 p_cur_pt = TO_CONTAINER(CURRENT_THREAD->p_context_ctrl,
200 struct partition_t, ctx_ctrl);
201
202 if (tfm_hal_update_boundaries(p_cur_pt->p_ldinf, p_cur_pt->p_boundaries)
203 != TFM_HAL_SUCCESS) {
204 tfm_core_panic();
205 }
206
207 return control;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800208}
209
Mingyang Sun5c9529f2022-03-15 17:51:56 +0800210static psa_signal_t ipc_wait(struct partition_t *p_pt, psa_signal_t signal_mask)
Kevin Pengdef92de2021-11-10 16:14:48 +0800211{
Mingyang Sun5c9529f2022-03-15 17:51:56 +0800212 struct critical_section_t cs_assert = CRITICAL_SECTION_STATIC_INIT;
213 psa_signal_t ret_signal;
Kevin Pengdef92de2021-11-10 16:14:48 +0800214
Mingyang Sun5c9529f2022-03-15 17:51:56 +0800215 /*
216 * 'ipc_wait()' sets the waiting signal mask for partition, and
217 * blocks the partition thread state to wait for signals.
218 * These changes should be inside the ciritical section to avoid
219 * 'signal_waiting' or the thread state to be changed by interrupts
220 * while this function is reading or writing values.
221 */
222 CRITICAL_SECTION_ENTER(cs_assert);
223
224 ret_signal = p_pt->signals_asserted & signal_mask;
225 if (ret_signal == 0) {
226 p_pt->signals_waiting = signal_mask;
Mingyang Sunac1114e2022-03-23 17:32:07 +0800227 thrd_set_wait(&p_pt->waitobj, CURRENT_THREAD);
Mingyang Sun5c9529f2022-03-15 17:51:56 +0800228 }
229 CRITICAL_SECTION_LEAVE(cs_assert);
230
231 return ret_signal;
Kevin Pengdef92de2021-11-10 16:14:48 +0800232}
233
Mingyang Sun09328bd2022-03-25 11:55:13 +0800234static void ipc_wake_up(struct partition_t *p_pt)
Kevin Pengdef92de2021-11-10 16:14:48 +0800235{
236 thrd_wake_up(&p_pt->waitobj,
237 p_pt->signals_asserted & p_pt->signals_waiting);
Mingyang Sun09328bd2022-03-25 11:55:13 +0800238 p_pt->signals_waiting = 0;
Kevin Pengdef92de2021-11-10 16:14:48 +0800239}
240
Mingyang Sundeae45d2021-09-06 15:31:07 +0800241const struct backend_ops_t backend_instance = {
242 .comp_init_assuredly = ipc_comp_init_assuredly,
243 .system_run = ipc_system_run,
244 .messaging = ipc_messaging,
Ken Liu802a3702021-10-15 12:09:56 +0800245 .replying = ipc_replying,
Kevin Pengdef92de2021-11-10 16:14:48 +0800246 .wait = ipc_wait,
247 .wake_up = ipc_wake_up,
Mingyang Sundeae45d2021-09-06 15:31:07 +0800248};