blob: d907e590088ec28db370aa89e4f6e1b78dab07ec [file] [log] [blame]
Mingyang Sunda01a972019-07-12 17:32:59 +08001/*
2 * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8/* All the APIs defined in this file are used for library model. */
9
10#include <inttypes.h>
11#include <limits.h>
12#include <stdbool.h>
13#include <stdlib.h>
14#include "tfm_utils.h"
15#include "tfm_spm_hal.h"
16#include "spm_api.h"
17#include "spm_db.h"
18#include "region_defs.h"
19#include "tfm_nspm.h"
20#include "tfm_memory_utils.h"
21#include "tfm_internal.h"
22
23extern struct spm_partition_db_t g_spm_partition_db;
24
25typedef enum {
26 TFM_INIT_FAILURE,
27} sp_error_type_t;
28
29/*
30 * This function is called when a secure partition causes an error.
31 * In case of an error in the error handling, a non-zero value have to be
32 * returned.
33 */
34static void tfm_spm_partition_err_handler(
35 const struct spm_partition_desc_t *partition,
36 sp_error_type_t err_type,
37 int32_t err_code)
38{
39#ifdef TFM_CORE_DEBUG
40 if (err_type == TFM_INIT_FAILURE) {
41 printf("Partition init failed for partition id 0x%08X\r\n",
Summer Qin423dbef2019-08-22 15:59:35 +080042 partition->static_data->partition_id);
Mingyang Sunda01a972019-07-12 17:32:59 +080043 } else {
44 printf(
45 "Unknown partition error %d (code: %d) for partition id 0x%08X\r\n",
Summer Qin423dbef2019-08-22 15:59:35 +080046 err_type, err_code, partition->static_data->partition_id);
Mingyang Sunda01a972019-07-12 17:32:59 +080047 }
48#else
49 (void)err_type;
50 (void)err_code;
51#endif
Summer Qin423dbef2019-08-22 15:59:35 +080052 tfm_spm_partition_set_state(partition->static_data->partition_id,
Mingyang Sunda01a972019-07-12 17:32:59 +080053 SPM_PARTITION_STATE_CLOSED);
54}
55
56enum spm_err_t tfm_spm_partition_init(void)
57{
58 struct spm_partition_desc_t *part;
59 struct tfm_sfn_req_s desc;
60 int32_t args[4] = {0};
61 int32_t fail_cnt = 0;
62 uint32_t idx;
Mate Toth-Pal8ac98a72019-11-21 17:30:10 +010063 const struct tfm_spm_partition_platform_data_t **platform_data_p;
Mingyang Sunda01a972019-07-12 17:32:59 +080064
65 /* Call the init function for each partition */
66 for (idx = 0; idx < g_spm_partition_db.partition_count; ++idx) {
67 part = &g_spm_partition_db.partitions[idx];
Mate Toth-Pal8ac98a72019-11-21 17:30:10 +010068 platform_data_p = part->platform_data_list;
69 if (platform_data_p != NULL) {
70 while ((*platform_data_p) != NULL) {
71 tfm_spm_hal_configure_default_isolation(*platform_data_p);
72 ++platform_data_p;
73 }
74 }
Summer Qin423dbef2019-08-22 15:59:35 +080075 if (part->static_data->partition_init == NULL) {
Mingyang Sunda01a972019-07-12 17:32:59 +080076 tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
77 tfm_spm_partition_set_caller_partition_idx(idx,
78 SPM_INVALID_PARTITION_IDX);
79 } else {
80 int32_t res;
81
82 desc.args = args;
Summer Qin43c185d2019-10-10 15:44:42 +080083 desc.ns_caller = false;
Summer Qin423dbef2019-08-22 15:59:35 +080084 desc.sfn = (sfn_t)part->static_data->partition_init;
85 desc.sp_id = part->static_data->partition_id;
Mingyang Sunda01a972019-07-12 17:32:59 +080086 res = tfm_core_sfn_request(&desc);
87 if (res == TFM_SUCCESS) {
88 tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
89 } else {
90 tfm_spm_partition_err_handler(part, TFM_INIT_FAILURE, res);
91 fail_cnt++;
92 }
93 }
94 }
95
96 tfm_secure_api_init_done();
97
98 if (fail_cnt == 0) {
99 return SPM_ERR_OK;
100 } else {
101 return SPM_ERR_PARTITION_NOT_AVAILABLE;
102 }
103}
104
105void tfm_spm_partition_push_interrupted_ctx(uint32_t partition_idx)
106{
107 struct spm_partition_runtime_data_t *runtime_data =
108 &g_spm_partition_db.partitions[partition_idx].runtime_data;
109 struct interrupted_ctx_stack_frame_t *stack_frame =
Edison Ai7aff9e82019-07-11 14:56:46 +0800110 (struct interrupted_ctx_stack_frame_t *)runtime_data->ctx_stack_ptr;
Mingyang Sunda01a972019-07-12 17:32:59 +0800111
112 stack_frame->partition_state = runtime_data->partition_state;
Mingyang Sunda01a972019-07-12 17:32:59 +0800113}
114
115void tfm_spm_partition_pop_interrupted_ctx(uint32_t partition_idx)
116{
117 struct spm_partition_runtime_data_t *runtime_data =
118 &g_spm_partition_db.partitions[partition_idx].runtime_data;
119 struct interrupted_ctx_stack_frame_t *stack_frame;
120
Mingyang Sunda01a972019-07-12 17:32:59 +0800121 stack_frame = (struct interrupted_ctx_stack_frame_t *)
122 runtime_data->ctx_stack_ptr;
123 tfm_spm_partition_set_state(partition_idx, stack_frame->partition_state);
124 stack_frame->partition_state = 0;
Mingyang Sunda01a972019-07-12 17:32:59 +0800125}
126
127void tfm_spm_partition_push_handler_ctx(uint32_t partition_idx)
128{
129 struct spm_partition_runtime_data_t *runtime_data =
130 &g_spm_partition_db.partitions[partition_idx].runtime_data;
131 struct handler_ctx_stack_frame_t *stack_frame =
132 (struct handler_ctx_stack_frame_t *)
133 runtime_data->ctx_stack_ptr;
134
135 stack_frame->partition_state = runtime_data->partition_state;
136 stack_frame->caller_partition_idx = runtime_data->caller_partition_idx;
137
138 runtime_data->ctx_stack_ptr +=
139 sizeof(struct handler_ctx_stack_frame_t) / sizeof(uint32_t);
140}
141
142void tfm_spm_partition_pop_handler_ctx(uint32_t partition_idx)
143{
144 struct spm_partition_runtime_data_t *runtime_data =
145 &g_spm_partition_db.partitions[partition_idx].runtime_data;
146 struct handler_ctx_stack_frame_t *stack_frame;
147
148 runtime_data->ctx_stack_ptr -=
149 sizeof(struct handler_ctx_stack_frame_t) / sizeof(uint32_t);
150
151 stack_frame = (struct handler_ctx_stack_frame_t *)
152 runtime_data->ctx_stack_ptr;
153
154 tfm_spm_partition_set_state(partition_idx, stack_frame->partition_state);
155 stack_frame->partition_state = 0;
156 tfm_spm_partition_set_caller_partition_idx(
157 partition_idx, stack_frame->caller_partition_idx);
158 stack_frame->caller_partition_idx = 0;
159}
160
Mingyang Sunda01a972019-07-12 17:32:59 +0800161void tfm_spm_partition_store_context(uint32_t partition_idx,
162 uint32_t stack_ptr, uint32_t lr)
163{
164 g_spm_partition_db.partitions[partition_idx].
165 runtime_data.stack_ptr = stack_ptr;
166 g_spm_partition_db.partitions[partition_idx].
167 runtime_data.lr = lr;
168}
169
170const struct spm_partition_runtime_data_t *
171 tfm_spm_partition_get_runtime_data(uint32_t partition_idx)
172{
173 return &(g_spm_partition_db.partitions[partition_idx].runtime_data);
174}
175
176void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state)
177{
178 g_spm_partition_db.partitions[partition_idx].runtime_data.partition_state =
179 state;
180 if (state == SPM_PARTITION_STATE_RUNNING ||
181 state == SPM_PARTITION_STATE_HANDLING_IRQ) {
182 g_spm_partition_db.running_partition_idx = partition_idx;
183 }
184}
185
186void tfm_spm_partition_set_caller_partition_idx(uint32_t partition_idx,
187 uint32_t caller_partition_idx)
188{
189 g_spm_partition_db.partitions[partition_idx].runtime_data.
190 caller_partition_idx = caller_partition_idx;
191}
192
193void tfm_spm_partition_set_signal_mask(uint32_t partition_idx,
194 uint32_t signal_mask)
195{
196 g_spm_partition_db.partitions[partition_idx].runtime_data.
197 signal_mask = signal_mask;
198}
199
200void tfm_spm_partition_set_caller_client_id(uint32_t partition_idx,
201 int32_t caller_client_id)
202{
203 g_spm_partition_db.partitions[partition_idx].runtime_data.
204 caller_client_id = caller_client_id;
205}
206
Mingyang Sunda01a972019-07-12 17:32:59 +0800207enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
208 const int32_t *args)
209{
210 struct spm_partition_runtime_data_t *runtime_data =
211 &g_spm_partition_db.partitions[partition_idx].runtime_data;
212 size_t i;
213
214 if ((args[1] < 0) || (args[3] < 0)) {
215 return SPM_ERR_INVALID_PARAMETER;
216 }
217
218 runtime_data->iovec_args.in_len = (size_t)args[1];
219 for (i = 0U; i < runtime_data->iovec_args.in_len; ++i) {
220 runtime_data->iovec_args.in_vec[i].base =
221 ((psa_invec *)args[0])[i].base;
222 runtime_data->iovec_args.in_vec[i].len = ((psa_invec *)args[0])[i].len;
223 }
224 runtime_data->iovec_args.out_len = (size_t)args[3];
225 for (i = 0U; i < runtime_data->iovec_args.out_len; ++i) {
226 runtime_data->iovec_args.out_vec[i].base =
227 ((psa_outvec *)args[2])[i].base;
228 runtime_data->iovec_args.out_vec[i].len =
229 ((psa_outvec *)args[2])[i].len;
230 }
231 runtime_data->orig_outvec = (psa_outvec *)args[2];
Mingyang Sunda01a972019-07-12 17:32:59 +0800232
233 return SPM_ERR_OK;
234}
235
236uint32_t tfm_spm_partition_get_running_partition_idx(void)
237{
238 return g_spm_partition_db.running_partition_idx;
239}
240
241void tfm_spm_partition_cleanup_context(uint32_t partition_idx)
242{
243 struct spm_partition_desc_t *partition =
244 &(g_spm_partition_db.partitions[partition_idx]);
245 int32_t i;
246
247 partition->runtime_data.caller_partition_idx = SPM_INVALID_PARTITION_IDX;
Mingyang Sunda01a972019-07-12 17:32:59 +0800248 partition->runtime_data.iovec_args.in_len = 0;
249 for (i = 0; i < PSA_MAX_IOVEC; ++i) {
250 partition->runtime_data.iovec_args.in_vec[i].base = 0;
251 partition->runtime_data.iovec_args.in_vec[i].len = 0;
252 }
253 partition->runtime_data.iovec_args.out_len = 0;
254 for (i = 0; i < PSA_MAX_IOVEC; ++i) {
255 partition->runtime_data.iovec_args.out_vec[i].base = 0;
256 partition->runtime_data.iovec_args.out_vec[i].len = 0;
257 }
258 partition->runtime_data.orig_outvec = 0;
Summer Qin423dbef2019-08-22 15:59:35 +0800259}