blob: 45059d16e69de0dd603ab6b013280f73ee4c6307 [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{
Mingyang Sunda01a972019-07-12 17:32:59 +080039 (void)err_type;
40 (void)err_code;
Ken Liuf250b8b2019-12-27 16:31:24 +080041
Summer Qin423dbef2019-08-22 15:59:35 +080042 tfm_spm_partition_set_state(partition->static_data->partition_id,
Mingyang Sunda01a972019-07-12 17:32:59 +080043 SPM_PARTITION_STATE_CLOSED);
44}
45
46enum spm_err_t tfm_spm_partition_init(void)
47{
48 struct spm_partition_desc_t *part;
49 struct tfm_sfn_req_s desc;
50 int32_t args[4] = {0};
51 int32_t fail_cnt = 0;
52 uint32_t idx;
Mate Toth-Pal8ac98a72019-11-21 17:30:10 +010053 const struct tfm_spm_partition_platform_data_t **platform_data_p;
Mingyang Sunda01a972019-07-12 17:32:59 +080054
55 /* Call the init function for each partition */
56 for (idx = 0; idx < g_spm_partition_db.partition_count; ++idx) {
57 part = &g_spm_partition_db.partitions[idx];
Mate Toth-Pal8ac98a72019-11-21 17:30:10 +010058 platform_data_p = part->platform_data_list;
59 if (platform_data_p != NULL) {
60 while ((*platform_data_p) != NULL) {
61 tfm_spm_hal_configure_default_isolation(*platform_data_p);
62 ++platform_data_p;
63 }
64 }
Summer Qin423dbef2019-08-22 15:59:35 +080065 if (part->static_data->partition_init == NULL) {
Mingyang Sunda01a972019-07-12 17:32:59 +080066 tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
67 tfm_spm_partition_set_caller_partition_idx(idx,
68 SPM_INVALID_PARTITION_IDX);
69 } else {
70 int32_t res;
71
72 desc.args = args;
Summer Qin43c185d2019-10-10 15:44:42 +080073 desc.ns_caller = false;
Summer Qin423dbef2019-08-22 15:59:35 +080074 desc.sfn = (sfn_t)part->static_data->partition_init;
75 desc.sp_id = part->static_data->partition_id;
Mingyang Sunda01a972019-07-12 17:32:59 +080076 res = tfm_core_sfn_request(&desc);
77 if (res == TFM_SUCCESS) {
78 tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
79 } else {
80 tfm_spm_partition_err_handler(part, TFM_INIT_FAILURE, res);
81 fail_cnt++;
82 }
83 }
84 }
85
86 tfm_secure_api_init_done();
87
88 if (fail_cnt == 0) {
89 return SPM_ERR_OK;
90 } else {
91 return SPM_ERR_PARTITION_NOT_AVAILABLE;
92 }
93}
94
95void tfm_spm_partition_push_interrupted_ctx(uint32_t partition_idx)
96{
97 struct spm_partition_runtime_data_t *runtime_data =
98 &g_spm_partition_db.partitions[partition_idx].runtime_data;
99 struct interrupted_ctx_stack_frame_t *stack_frame =
Edison Ai7aff9e82019-07-11 14:56:46 +0800100 (struct interrupted_ctx_stack_frame_t *)runtime_data->ctx_stack_ptr;
Mingyang Sunda01a972019-07-12 17:32:59 +0800101
102 stack_frame->partition_state = runtime_data->partition_state;
Matt463ed582019-12-20 12:31:25 +0800103
104 runtime_data->ctx_stack_ptr +=
105 sizeof(struct interrupted_ctx_stack_frame_t) / sizeof(uint32_t);
Mingyang Sunda01a972019-07-12 17:32:59 +0800106}
107
108void tfm_spm_partition_pop_interrupted_ctx(uint32_t partition_idx)
109{
110 struct spm_partition_runtime_data_t *runtime_data =
111 &g_spm_partition_db.partitions[partition_idx].runtime_data;
112 struct interrupted_ctx_stack_frame_t *stack_frame;
113
Matt463ed582019-12-20 12:31:25 +0800114 runtime_data->ctx_stack_ptr -=
115 sizeof(struct interrupted_ctx_stack_frame_t) / sizeof(uint32_t);
116
Mingyang Sunda01a972019-07-12 17:32:59 +0800117 stack_frame = (struct interrupted_ctx_stack_frame_t *)
118 runtime_data->ctx_stack_ptr;
119 tfm_spm_partition_set_state(partition_idx, stack_frame->partition_state);
120 stack_frame->partition_state = 0;
Mingyang Sunda01a972019-07-12 17:32:59 +0800121}
122
123void tfm_spm_partition_push_handler_ctx(uint32_t partition_idx)
124{
125 struct spm_partition_runtime_data_t *runtime_data =
126 &g_spm_partition_db.partitions[partition_idx].runtime_data;
127 struct handler_ctx_stack_frame_t *stack_frame =
128 (struct handler_ctx_stack_frame_t *)
129 runtime_data->ctx_stack_ptr;
130
131 stack_frame->partition_state = runtime_data->partition_state;
132 stack_frame->caller_partition_idx = runtime_data->caller_partition_idx;
133
134 runtime_data->ctx_stack_ptr +=
135 sizeof(struct handler_ctx_stack_frame_t) / sizeof(uint32_t);
136}
137
138void tfm_spm_partition_pop_handler_ctx(uint32_t partition_idx)
139{
140 struct spm_partition_runtime_data_t *runtime_data =
141 &g_spm_partition_db.partitions[partition_idx].runtime_data;
142 struct handler_ctx_stack_frame_t *stack_frame;
143
144 runtime_data->ctx_stack_ptr -=
145 sizeof(struct handler_ctx_stack_frame_t) / sizeof(uint32_t);
146
147 stack_frame = (struct handler_ctx_stack_frame_t *)
148 runtime_data->ctx_stack_ptr;
149
150 tfm_spm_partition_set_state(partition_idx, stack_frame->partition_state);
151 stack_frame->partition_state = 0;
152 tfm_spm_partition_set_caller_partition_idx(
153 partition_idx, stack_frame->caller_partition_idx);
154 stack_frame->caller_partition_idx = 0;
155}
156
Mingyang Sunda01a972019-07-12 17:32:59 +0800157void tfm_spm_partition_store_context(uint32_t partition_idx,
158 uint32_t stack_ptr, uint32_t lr)
159{
160 g_spm_partition_db.partitions[partition_idx].
161 runtime_data.stack_ptr = stack_ptr;
162 g_spm_partition_db.partitions[partition_idx].
163 runtime_data.lr = lr;
164}
165
166const struct spm_partition_runtime_data_t *
167 tfm_spm_partition_get_runtime_data(uint32_t partition_idx)
168{
169 return &(g_spm_partition_db.partitions[partition_idx].runtime_data);
170}
171
172void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state)
173{
174 g_spm_partition_db.partitions[partition_idx].runtime_data.partition_state =
175 state;
176 if (state == SPM_PARTITION_STATE_RUNNING ||
177 state == SPM_PARTITION_STATE_HANDLING_IRQ) {
178 g_spm_partition_db.running_partition_idx = partition_idx;
179 }
180}
181
182void tfm_spm_partition_set_caller_partition_idx(uint32_t partition_idx,
183 uint32_t caller_partition_idx)
184{
185 g_spm_partition_db.partitions[partition_idx].runtime_data.
186 caller_partition_idx = caller_partition_idx;
187}
188
189void tfm_spm_partition_set_signal_mask(uint32_t partition_idx,
190 uint32_t signal_mask)
191{
192 g_spm_partition_db.partitions[partition_idx].runtime_data.
193 signal_mask = signal_mask;
194}
195
196void tfm_spm_partition_set_caller_client_id(uint32_t partition_idx,
197 int32_t caller_client_id)
198{
199 g_spm_partition_db.partitions[partition_idx].runtime_data.
200 caller_client_id = caller_client_id;
201}
202
Mingyang Sunda01a972019-07-12 17:32:59 +0800203enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
204 const int32_t *args)
205{
206 struct spm_partition_runtime_data_t *runtime_data =
207 &g_spm_partition_db.partitions[partition_idx].runtime_data;
208 size_t i;
209
210 if ((args[1] < 0) || (args[3] < 0)) {
211 return SPM_ERR_INVALID_PARAMETER;
212 }
213
214 runtime_data->iovec_args.in_len = (size_t)args[1];
215 for (i = 0U; i < runtime_data->iovec_args.in_len; ++i) {
216 runtime_data->iovec_args.in_vec[i].base =
217 ((psa_invec *)args[0])[i].base;
218 runtime_data->iovec_args.in_vec[i].len = ((psa_invec *)args[0])[i].len;
219 }
220 runtime_data->iovec_args.out_len = (size_t)args[3];
221 for (i = 0U; i < runtime_data->iovec_args.out_len; ++i) {
222 runtime_data->iovec_args.out_vec[i].base =
223 ((psa_outvec *)args[2])[i].base;
224 runtime_data->iovec_args.out_vec[i].len =
225 ((psa_outvec *)args[2])[i].len;
226 }
227 runtime_data->orig_outvec = (psa_outvec *)args[2];
Mingyang Sunda01a972019-07-12 17:32:59 +0800228
229 return SPM_ERR_OK;
230}
231
232uint32_t tfm_spm_partition_get_running_partition_idx(void)
233{
234 return g_spm_partition_db.running_partition_idx;
235}
236
237void tfm_spm_partition_cleanup_context(uint32_t partition_idx)
238{
239 struct spm_partition_desc_t *partition =
240 &(g_spm_partition_db.partitions[partition_idx]);
241 int32_t i;
242
243 partition->runtime_data.caller_partition_idx = SPM_INVALID_PARTITION_IDX;
Mingyang Sunda01a972019-07-12 17:32:59 +0800244 partition->runtime_data.iovec_args.in_len = 0;
245 for (i = 0; i < PSA_MAX_IOVEC; ++i) {
246 partition->runtime_data.iovec_args.in_vec[i].base = 0;
247 partition->runtime_data.iovec_args.in_vec[i].len = 0;
248 }
249 partition->runtime_data.iovec_args.out_len = 0;
250 for (i = 0; i < PSA_MAX_IOVEC; ++i) {
251 partition->runtime_data.iovec_args.out_vec[i].base = 0;
252 partition->runtime_data.iovec_args.out_vec[i].len = 0;
253 }
254 partition->runtime_data.orig_outvec = 0;
Summer Qin423dbef2019-08-22 15:59:35 +0800255}