blob: 22a7794b6e22f6525e08a943f936e75096bafe09 [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 Brand3778bc12021-12-15 17:01:05 -08003 * Copyright (c) 2021, 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"
Mingyang Sundeae45d2021-09-06 15:31:07 +080013#include "spm_ipc.h"
Ken Liu62bae592021-10-19 22:15:43 +080014#include "tfm_hal_isolation.h"
Kevin Pengb288c522021-09-26 16:18:23 +080015#include "tfm_hal_platform.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080016#include "tfm_rpc.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080017#include "ffm/backend.h"
Ken Liu62bae592021-10-19 22:15:43 +080018#include "utilities.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080019#include "load/partition_defs.h"
20#include "load/service_defs.h"
21#include "load/spm_load_api.h"
22#include "psa/error.h"
23
24/* Declare the global component list */
25struct partition_head_t partition_listhead;
26
Kevin Peng9f1a7542022-02-07 16:32:27 +080027#if CONFIG_TFM_PSA_API_CROSS_CALL == 1
Ken Liue07c3b72021-10-14 16:19:13 +080028
29#ifdef TFM_MULTI_CORE_TOPOLOGY
30/* TODO: To be checked when RPC design updates. */
31static uint8_t spm_stack_local[CONFIG_TFM_SPM_THREAD_STACK_SIZE] __aligned(8);
32struct context_ctrl_t spm_thread_context = {
Ken Liubf4681f2022-02-11 11:15:03 +080033 .sp = (uint32_t)&spm_stack_local[CONFIG_TFM_SPM_THREAD_STACK_SIZE],
34 .sp_limit = (uint32_t)spm_stack_local,
35 .allocated = 0,
36 .exc_ret = 0,
Ken Liue07c3b72021-10-14 16:19:13 +080037};
38struct context_ctrl_t *p_spm_thread_context = &spm_thread_context;
39#else
40struct context_ctrl_t *p_spm_thread_context;
41#endif
42
43#endif
44
Summer Qin596f5552022-01-27 18:04:06 +080045static void prv_process_metadata(struct partition_t *p_pt)
46{
47 struct runtime_metadata_t *p_rtmd = NULL;
48
49 if (p_pt->p_ldinf->entry) {
50 ARCH_CTXCTRL_ALLOCATE_STACK(&p_pt->ctx_ctrl, sizeof(*p_rtmd));
51 p_rtmd = (struct runtime_metadata_t *)ARCH_CTXCTRL_ALLOCATED_PTR(
52 &p_pt->ctx_ctrl);
53 p_rtmd->entry = p_pt->p_ldinf->entry;
54 }
55
56 p_pt->p_metadata = p_rtmd;
57}
58
Mingyang Sundeae45d2021-09-06 15:31:07 +080059/*
60 * Send message and wake up the SP who is waiting on message queue, block the
Ken Liuf39d8eb2021-10-07 12:55:33 +080061 * current thread and trigger scheduler.
Mingyang Sundeae45d2021-09-06 15:31:07 +080062 */
63static psa_status_t ipc_messaging(struct service_t *service,
Mingyang Suna09adda2022-02-16 18:11:33 +080064 struct conn_handle_t *handle)
Mingyang Sundeae45d2021-09-06 15:31:07 +080065{
66 struct partition_t *p_owner = NULL;
67 psa_signal_t signal = 0;
Mingyang Sun620c8562021-11-10 11:44:58 +080068 struct critical_section_t cs_assert = CRITICAL_SECTION_STATIC_INIT;
Mingyang Sundeae45d2021-09-06 15:31:07 +080069
Mingyang Suna09adda2022-02-16 18:11:33 +080070 if (!handle || !service || !service->p_ldinf || !service->partition) {
Mingyang Sunbb4a42a2021-12-14 15:18:52 +080071 return PSA_ERROR_PROGRAMMER_ERROR;
Mingyang Sundeae45d2021-09-06 15:31:07 +080072 }
73
74 p_owner = service->partition;
75 signal = service->p_ldinf->signal;
76
Mingyang Sun620c8562021-11-10 11:44:58 +080077 CRITICAL_SECTION_ENTER(cs_assert);
Ken Liu5a28da32022-01-19 14:37:05 +080078
Mingyang Suna09adda2022-02-16 18:11:33 +080079 UNI_LIST_INSERT_AFTER(p_owner, handle, p_handles);
Mingyang Sundeae45d2021-09-06 15:31:07 +080080
81 /* Messages put. Update signals */
82 p_owner->signals_asserted |= signal;
83
84 if (p_owner->signals_waiting & signal) {
85 thrd_wake_up(&p_owner->waitobj,
86 (p_owner->signals_asserted & p_owner->signals_waiting));
87 p_owner->signals_waiting &= ~signal;
88 }
Mingyang Sun620c8562021-11-10 11:44:58 +080089 CRITICAL_SECTION_LEAVE(cs_assert);
Mingyang Sundeae45d2021-09-06 15:31:07 +080090
91 /*
92 * If it is a NS request via RPC, it is unnecessary to block current
93 * thread.
94 */
95
Mingyang Suna09adda2022-02-16 18:11:33 +080096 if (!is_tfm_rpc_msg(handle)) {
97 thrd_wait_on(&handle->ack_evnt, CURRENT_THREAD);
Mingyang Sundeae45d2021-09-06 15:31:07 +080098 }
99
100 return PSA_SUCCESS;
101}
102
Mingyang Suna09adda2022-02-16 18:11:33 +0800103static psa_status_t ipc_replying(struct conn_handle_t *handle, int32_t status)
Ken Liu802a3702021-10-15 12:09:56 +0800104{
Mingyang Suna09adda2022-02-16 18:11:33 +0800105 if (is_tfm_rpc_msg(handle)) {
106 tfm_rpc_client_call_reply(handle, status);
Ken Liu802a3702021-10-15 12:09:56 +0800107 } else {
Mingyang Suna09adda2022-02-16 18:11:33 +0800108 thrd_wake_up(&handle->ack_evnt, status);
Ken Liu802a3702021-10-15 12:09:56 +0800109 }
Ken Liuf39d8eb2021-10-07 12:55:33 +0800110
111 /*
112 * 'psa_reply' exists in IPC model only and returns 'void'. Return
113 * 'PSA_SUCCESS' here always since SPM does not forward the status
114 * to the caller.
115 */
116 return PSA_SUCCESS;
Ken Liu802a3702021-10-15 12:09:56 +0800117}
118
Summer Qin596f5552022-01-27 18:04:06 +0800119extern void sprt_main(void);
120
Mingyang Sundeae45d2021-09-06 15:31:07 +0800121/* Parameters are treated as assuredly */
122static void ipc_comp_init_assuredly(struct partition_t *p_pt,
123 uint32_t service_setting)
124{
125 const struct partition_load_info_t *p_pldi = p_pt->p_ldinf;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800126
Kevin Peng613b4172022-02-15 14:41:44 +0800127#if CONFIG_TFM_DOORBELL_API == 1
128 p_pt->signals_allowed |= PSA_DOORBELL;
129#endif /* CONFIG_TFM_DOORBELL_API == 1 */
130
131 p_pt->signals_allowed |= service_setting;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800132
133 THRD_SYNC_INIT(&p_pt->waitobj);
Ken Liu0bed7e02022-02-10 12:38:07 +0800134 UNI_LISI_INIT_NODE(p_pt, p_handles);
Mingyang Sundeae45d2021-09-06 15:31:07 +0800135
Ken Liubf4681f2022-02-11 11:15:03 +0800136 ARCH_CTXCTRL_INIT(&p_pt->ctx_ctrl,
137 LOAD_ALLOCED_STACK_ADDR(p_pldi),
138 p_pldi->stack_size);
139
Summer Qin596f5552022-01-27 18:04:06 +0800140 prv_process_metadata(p_pt);
141
Mingyang Sundeae45d2021-09-06 15:31:07 +0800142 THRD_INIT(&p_pt->thrd, &p_pt->ctx_ctrl,
143 TO_THREAD_PRIORITY(PARTITION_PRIORITY(p_pldi->flags)));
144
Kevin Peng9f1a7542022-02-07 16:32:27 +0800145#if (CONFIG_TFM_PSA_API_CROSS_CALL == 1) && !defined(TFM_MULTI_CORE_TOPOLOGY)
Ken Liu897e8f12022-02-10 03:21:17 +0100146 if (p_pldi->pid == TFM_SP_NON_SECURE_ID) {
Ken Liue07c3b72021-10-14 16:19:13 +0800147 SPM_THREAD_CONTEXT = &p_pt->ctx_ctrl;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800148 }
Summer Qin95444822022-01-27 11:22:00 +0800149#endif
Mingyang Sundeae45d2021-09-06 15:31:07 +0800150
151 thrd_start(&p_pt->thrd,
Summer Qin596f5552022-01-27 18:04:06 +0800152 POSITION_TO_ENTRY(sprt_main, thrd_fn_t),
Ken Liubf4681f2022-02-11 11:15:03 +0800153 THRD_GENERAL_EXIT);
Mingyang Sundeae45d2021-09-06 15:31:07 +0800154}
155
156static uint32_t ipc_system_run(void)
157{
Ken Liu62bae592021-10-19 22:15:43 +0800158 uint32_t control;
159 struct partition_t *p_cur_pt;
160
Kevin Peng9f1a7542022-02-07 16:32:27 +0800161#if CONFIG_TFM_PSA_API_THREAD_CALL == 1
Chris Brand3778bc12021-12-15 17:01:05 -0800162 TFM_CORE_ASSERT(SPM_THREAD_CONTEXT);
163#endif
164
Ken Liu62bae592021-10-19 22:15:43 +0800165 control = thrd_start_scheduler(&CURRENT_THREAD);
166
167 p_cur_pt = TO_CONTAINER(CURRENT_THREAD->p_context_ctrl,
168 struct partition_t, ctx_ctrl);
169
170 if (tfm_hal_update_boundaries(p_cur_pt->p_ldinf, p_cur_pt->p_boundaries)
171 != TFM_HAL_SUCCESS) {
172 tfm_core_panic();
173 }
174
175 return control;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800176}
177
178const struct backend_ops_t backend_instance = {
179 .comp_init_assuredly = ipc_comp_init_assuredly,
180 .system_run = ipc_system_run,
181 .messaging = ipc_messaging,
Ken Liu802a3702021-10-15 12:09:56 +0800182 .replying = ipc_replying,
Mingyang Sundeae45d2021-09-06 15:31:07 +0800183};