blob: 4570f95f95775eaee92eff414ad9ceee51aba613 [file] [log] [blame]
Mingyang Sundeae45d2021-09-06 15:31:07 +08001/*
2 * Copyright (c) 2021, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <stdint.h>
Mingyang Sun620c8562021-11-10 11:44:58 +08009#include "critical_section.h"
Ken Liue07c3b72021-10-14 16:19:13 +080010#include "compiler_ext_defs.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080011#include "spm_ipc.h"
Ken Liu62bae592021-10-19 22:15:43 +080012#include "tfm_hal_isolation.h"
Kevin Pengb288c522021-09-26 16:18:23 +080013#include "tfm_hal_platform.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080014#include "tfm_rpc.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080015#include "ffm/backend.h"
Ken Liu62bae592021-10-19 22:15:43 +080016#include "utilities.h"
Mingyang Sundeae45d2021-09-06 15:31:07 +080017#include "load/partition_defs.h"
18#include "load/service_defs.h"
19#include "load/spm_load_api.h"
20#include "psa/error.h"
21
22/* Declare the global component list */
23struct partition_head_t partition_listhead;
24
Ken Liue07c3b72021-10-14 16:19:13 +080025#ifdef CONFIG_TFM_PSA_API_THREAD_CALL
26
27#ifdef TFM_MULTI_CORE_TOPOLOGY
28/* TODO: To be checked when RPC design updates. */
29static uint8_t spm_stack_local[CONFIG_TFM_SPM_THREAD_STACK_SIZE] __aligned(8);
30struct context_ctrl_t spm_thread_context = {
31 .sp = (uint32_t)&spm_stack_local[CONFIG_TFM_SPM_THREAD_STACK_SIZE],
32 .sp_limit = (uint32_t)spm_stack_local,
33 .reserved = 0,
34 .exc_ret = 0,
35};
36struct context_ctrl_t *p_spm_thread_context = &spm_thread_context;
37#else
38struct context_ctrl_t *p_spm_thread_context;
39#endif
40
41#endif
42
Mingyang Sundeae45d2021-09-06 15:31:07 +080043/*
44 * Send message and wake up the SP who is waiting on message queue, block the
Ken Liuf39d8eb2021-10-07 12:55:33 +080045 * current thread and trigger scheduler.
Mingyang Sundeae45d2021-09-06 15:31:07 +080046 */
47static psa_status_t ipc_messaging(struct service_t *service,
48 struct tfm_msg_body_t *msg)
49{
50 struct partition_t *p_owner = NULL;
51 psa_signal_t signal = 0;
Mingyang Sun620c8562021-11-10 11:44:58 +080052 struct critical_section_t cs_assert = CRITICAL_SECTION_STATIC_INIT;
Mingyang Sundeae45d2021-09-06 15:31:07 +080053
54 if (!msg || !service || !service->p_ldinf || !service->partition) {
55 tfm_core_panic();
56 }
57
58 p_owner = service->partition;
59 signal = service->p_ldinf->signal;
60
Mingyang Sun620c8562021-11-10 11:44:58 +080061 CRITICAL_SECTION_ENTER(cs_assert);
Mingyang Sundeae45d2021-09-06 15:31:07 +080062 /* Add message to partition message list tail */
63 BI_LIST_INSERT_BEFORE(&p_owner->msg_list, &msg->msg_node);
64
65 /* Messages put. Update signals */
66 p_owner->signals_asserted |= signal;
67
68 if (p_owner->signals_waiting & signal) {
69 thrd_wake_up(&p_owner->waitobj,
70 (p_owner->signals_asserted & p_owner->signals_waiting));
71 p_owner->signals_waiting &= ~signal;
72 }
Mingyang Sun620c8562021-11-10 11:44:58 +080073 CRITICAL_SECTION_LEAVE(cs_assert);
Mingyang Sundeae45d2021-09-06 15:31:07 +080074
75 /*
76 * If it is a NS request via RPC, it is unnecessary to block current
77 * thread.
78 */
79
80 if (!is_tfm_rpc_msg(msg)) {
81 thrd_wait_on(&msg->ack_evnt, CURRENT_THREAD);
82 }
83
84 return PSA_SUCCESS;
85}
86
Ken Liuf39d8eb2021-10-07 12:55:33 +080087static int32_t ipc_replying(struct tfm_msg_body_t *p_msg, int32_t status)
Ken Liu802a3702021-10-15 12:09:56 +080088{
89 if (is_tfm_rpc_msg(p_msg)) {
90 tfm_rpc_client_call_reply(p_msg, status);
91 } else {
92 thrd_wake_up(&p_msg->ack_evnt, status);
93 }
Ken Liuf39d8eb2021-10-07 12:55:33 +080094
95 /*
96 * 'psa_reply' exists in IPC model only and returns 'void'. Return
97 * 'PSA_SUCCESS' here always since SPM does not forward the status
98 * to the caller.
99 */
100 return PSA_SUCCESS;
Ken Liu802a3702021-10-15 12:09:56 +0800101}
102
Mingyang Sundeae45d2021-09-06 15:31:07 +0800103/* Parameters are treated as assuredly */
104static void ipc_comp_init_assuredly(struct partition_t *p_pt,
105 uint32_t service_setting)
106{
107 const struct partition_load_info_t *p_pldi = p_pt->p_ldinf;
108 void *p_param = NULL;
109
110 p_pt->signals_allowed |= PSA_DOORBELL | service_setting;
111
112 THRD_SYNC_INIT(&p_pt->waitobj);
113 BI_LIST_INIT_NODE(&p_pt->msg_list);
114
115 THRD_INIT(&p_pt->thrd, &p_pt->ctx_ctrl,
116 TO_THREAD_PRIORITY(PARTITION_PRIORITY(p_pldi->flags)));
117
118 if (p_pldi->pid == TFM_SP_NON_SECURE_ID) {
Kevin Pengb288c522021-09-26 16:18:23 +0800119 p_param = (void *)tfm_hal_get_ns_entry_point();
Ken Liue07c3b72021-10-14 16:19:13 +0800120
121#ifdef CONFIG_TFM_PSA_API_THREAD_CALL
122 SPM_THREAD_CONTEXT = &p_pt->ctx_ctrl;
123#endif
124
Mingyang Sundeae45d2021-09-06 15:31:07 +0800125 }
126
127 thrd_start(&p_pt->thrd,
128 POSITION_TO_ENTRY(p_pldi->entry, thrd_fn_t), p_param,
129 LOAD_ALLOCED_STACK_ADDR(p_pldi),
130 LOAD_ALLOCED_STACK_ADDR(p_pldi) + p_pldi->stack_size);
131}
132
133static uint32_t ipc_system_run(void)
134{
Ken Liu62bae592021-10-19 22:15:43 +0800135 uint32_t control;
136 struct partition_t *p_cur_pt;
137
138 control = thrd_start_scheduler(&CURRENT_THREAD);
139
140 p_cur_pt = TO_CONTAINER(CURRENT_THREAD->p_context_ctrl,
141 struct partition_t, ctx_ctrl);
142
143 if (tfm_hal_update_boundaries(p_cur_pt->p_ldinf, p_cur_pt->p_boundaries)
144 != TFM_HAL_SUCCESS) {
145 tfm_core_panic();
146 }
147
148 return control;
Mingyang Sundeae45d2021-09-06 15:31:07 +0800149}
150
151const struct backend_ops_t backend_instance = {
152 .comp_init_assuredly = ipc_comp_init_assuredly,
153 .system_run = ipc_system_run,
154 .messaging = ipc_messaging,
Ken Liu802a3702021-10-15 12:09:56 +0800155 .replying = ipc_replying,
Mingyang Sundeae45d2021-09-06 15:31:07 +0800156};