blob: 91d30e0ab534819c89096f794e327cc380efaa83 [file] [log] [blame]
Miklos Balint386b8b52017-11-29 13:12:32 +00001/*
Mate Toth-Pal65291f32018-02-23 14:35:22 +01002 * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
Miklos Balint386b8b52017-11-29 13:12:32 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
Mate Toth-Pal349714a2018-02-23 15:30:24 +01008/* This file contains the APIs exported by the SPM to tfm core */
Miklos Balint386b8b52017-11-29 13:12:32 +00009
10#include <stdio.h>
Mate Toth-Pal7345a4b2018-03-08 16:10:28 +010011#include <string.h>
Miklos Balint386b8b52017-11-29 13:12:32 +000012#include "spm_api.h"
Mate Toth-Pale1475332018-04-09 17:28:49 +020013#include "platform/include/tfm_spm_hal.h"
14#include "spm_db_setup.h"
Miklos Balint6a139ae2018-04-04 19:44:37 +020015#include "tfm_internal.h"
Mate Toth-Pal65291f32018-02-23 14:35:22 +010016#include "tfm_api.h"
Miklos Balint386b8b52017-11-29 13:12:32 +000017#include "secure_fw/core/tfm_core.h"
Mate Toth-Pale1475332018-04-09 17:28:49 +020018#include "platform_retarget.h"
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020019#include "tfm_peripherals_def.h"
Mate Toth-Pale1475332018-04-09 17:28:49 +020020#include "spm_partition_defs.h"
21
Miklos Balint386b8b52017-11-29 13:12:32 +000022
Mate Toth-Pal349714a2018-02-23 15:30:24 +010023struct spm_partition_db_t g_spm_partition_db = {0,};
Miklos Balint386b8b52017-11-29 13:12:32 +000024
Miklos Balint386b8b52017-11-29 13:12:32 +000025typedef enum {
26 TFM_INIT_FAILURE,
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010027} sp_error_type_t;
Miklos Balint386b8b52017-11-29 13:12:32 +000028
29/*
Mate Toth-Pal349714a2018-02-23 15:30:24 +010030 * This function is called when a secure partition causes an error.
Mate Toth-Pal65291f32018-02-23 14:35:22 +010031 * In case of an error in the error handling, a non-zero value have to be
32 * returned.
Miklos Balint386b8b52017-11-29 13:12:32 +000033 */
Mate Toth-Pal349714a2018-02-23 15:30:24 +010034static void tfm_spm_partition_err_handler(
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020035 struct spm_partition_desc_t *partition,
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010036 sp_error_type_t err_type,
Mate Toth-Pal65291f32018-02-23 14:35:22 +010037 int32_t err_code)
Miklos Balint386b8b52017-11-29 13:12:32 +000038{
Miklos Balint386b8b52017-11-29 13:12:32 +000039#ifdef TFM_CORE_DEBUG
40 if (err_type == TFM_INIT_FAILURE) {
Mate Toth-Pal349714a2018-02-23 15:30:24 +010041 printf("Partition init failed for partition id 0x%08X\r\n",
Mate Toth-Pal18b83922018-02-26 17:58:18 +010042 partition->static_data.partition_id);
Miklos Balint386b8b52017-11-29 13:12:32 +000043 } else {
Mate Toth-Pal349714a2018-02-23 15:30:24 +010044 printf("Unknown partition error %d for partition id 0x%08X\r\n",
Mate Toth-Pal18b83922018-02-26 17:58:18 +010045 err_type, partition->static_data.partition_id);
Miklos Balint386b8b52017-11-29 13:12:32 +000046 }
47#endif
Mate Toth-Pal18b83922018-02-26 17:58:18 +010048 tfm_spm_partition_set_state(partition->static_data.partition_id,
Mate Toth-Pal349714a2018-02-23 15:30:24 +010049 SPM_PARTITION_STATE_CLOSED);
Miklos Balint386b8b52017-11-29 13:12:32 +000050}
51
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010052uint32_t get_partition_idx(uint32_t partition_id)
53{
54 int i;
55
56 if (partition_id == INVALID_PARTITION_ID) {
57 return SPM_INVALID_PARTITION_IDX;
58 }
59
60 for (i = 0; i < g_spm_partition_db.partition_count; ++i) {
61 if (g_spm_partition_db.partitions[i].static_data.partition_id ==
62 partition_id) {
63 return i;
64 }
65 }
66 return SPM_INVALID_PARTITION_IDX;
67}
68
Miklos Balint386b8b52017-11-29 13:12:32 +000069enum spm_err_t tfm_spm_db_init(void)
70{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020071 struct spm_partition_desc_t *part_ptr;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010072
Mate Toth-Pal7345a4b2018-03-08 16:10:28 +010073 memset (&g_spm_partition_db, 0, sizeof(g_spm_partition_db));
74
Mate Toth-Pal349714a2018-02-23 15:30:24 +010075 /* This function initialises partition db */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010076 g_spm_partition_db.running_partition_idx = SPM_INVALID_PARTITION_IDX;
77 g_spm_partition_db.partition_count = 0;
Miklos Balint386b8b52017-11-29 13:12:32 +000078
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010079 /* There are a few partitions that are used by TF-M internally.
80 * These are explicitly added to the partition db here.
81 */
82
83 /* For the non secure Execution environment */
Miklos Balint6a139ae2018-04-04 19:44:37 +020084#if TFM_LVL != 1
85 extern uint32_t Stack_Mem[];
86 extern uint32_t Stack_top[];
87#endif
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010088 if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {
89 return SPM_ERR_INVALID_CONFIG;
90 }
91 part_ptr = &(g_spm_partition_db.partitions[
92 g_spm_partition_db.partition_count]);
93 part_ptr->static_data.partition_id = TFM_SP_NON_SECURE_ID;
Mate Toth-Pal59398712018-02-28 17:06:40 +010094 part_ptr->static_data.partition_flags = 0;
Miklos Balint6a139ae2018-04-04 19:44:37 +020095
96#if TFM_LVL != 1
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020097 part_ptr->memory_data.stack_bottom = (uint32_t)Stack_Mem;
98 part_ptr->memory_data.stack_top = (uint32_t)Stack_top;
Miklos Balint6a139ae2018-04-04 19:44:37 +020099 /* Since RW, ZI and stack are configured as one MPU region, configure
100 * RW start address to Stack_Mem to get RW access to stack
101 */
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200102 part_ptr->memory_data.rw_start = (uint32_t)Stack_Mem;
Miklos Balint6a139ae2018-04-04 19:44:37 +0200103#endif
104
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100105 part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
106 ++g_spm_partition_db.partition_count;
107
108 /* For the TF-M core environment itself */
109 if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {
110 return SPM_ERR_INVALID_CONFIG;
111 }
112 part_ptr = &(g_spm_partition_db.partitions[
113 g_spm_partition_db.partition_count]);
114 part_ptr->static_data.partition_id = TFM_SP_CORE_ID;
Mate Toth-Pal59398712018-02-28 17:06:40 +0100115 part_ptr->static_data.partition_flags =
116 SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100117 part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
118 ++g_spm_partition_db.partition_count;
119
120 /* Add user-defined secure partitions */
Miklos Balintd306ab12018-05-18 16:58:18 +0200121 #include "secure_fw/services/tfm_partition_list.inc"
Miklos Balint386b8b52017-11-29 13:12:32 +0000122
Mate Toth-Pal7345a4b2018-03-08 16:10:28 +0100123 g_spm_partition_db.is_init = 1;
124
Miklos Balint386b8b52017-11-29 13:12:32 +0000125 return SPM_ERR_OK;
126}
127
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100128enum spm_err_t tfm_spm_partition_init(void)
Miklos Balint386b8b52017-11-29 13:12:32 +0000129{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200130 struct spm_partition_desc_t *part;
Miklos Balint6a139ae2018-04-04 19:44:37 +0200131 struct tfm_sfn_req_s desc, *desc_ptr = &desc;
132 int32_t args[4] = {0};
Miklos Balint386b8b52017-11-29 13:12:32 +0000133 int32_t fail_cnt = 0;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100134 uint32_t idx;
Miklos Balint386b8b52017-11-29 13:12:32 +0000135
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100136 /* Call the init function for each partition */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100137 for (idx = 0; idx < g_spm_partition_db.partition_count; ++idx) {
138 part = &g_spm_partition_db.partitions[idx];
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200139 tfm_spm_hal_configure_default_isolation(part->platform_data);
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100140 if (part->static_data.partition_init == NULL) {
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100141 tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
Miklos Balint6a139ae2018-04-04 19:44:37 +0200142 tfm_spm_partition_set_caller_partition_idx(idx,
143 SPM_INVALID_PARTITION_IDX);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100144 } else {
Miklos Balint6a139ae2018-04-04 19:44:37 +0200145 int32_t ret;
146
147 desc.args = args;
148 desc.exc_num = EXC_NUM_THREAD_MODE;
149 desc.ns_caller = 0;
150 desc.sfn = (sfn_t)part->static_data.partition_init;
151 desc.sp_id = part->static_data.partition_id;
152 __ASM("MOV r0, %1\n"
153 "SVC %2\n"
154 "MOV %0, r0\n"
155 : "=r" (ret)
156 : "r" (desc_ptr), "I" (TFM_SVC_SFN_REQUEST)
157 : "r0");
Miklos Balint386b8b52017-11-29 13:12:32 +0000158
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100159 if (ret == TFM_SUCCESS) {
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100160 tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100161 } else {
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100162 tfm_spm_partition_err_handler(part, TFM_INIT_FAILURE, ret);
Miklos Balint386b8b52017-11-29 13:12:32 +0000163 fail_cnt++;
164 }
165 }
166 }
167
Miklos Balint6a139ae2018-04-04 19:44:37 +0200168 tfm_secure_api_init_done();
169
Miklos Balint386b8b52017-11-29 13:12:32 +0000170 if (fail_cnt == 0) {
171 return SPM_ERR_OK;
172 } else {
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100173 return SPM_ERR_PARTITION_NOT_AVAILABLE;
Miklos Balint386b8b52017-11-29 13:12:32 +0000174 }
175}
176
177#if TFM_LVL != 1
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100178enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_idx)
Miklos Balint386b8b52017-11-29 13:12:32 +0000179{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200180 struct spm_partition_desc_t *part;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100181 if (!g_spm_partition_db.is_init) {
182 return SPM_ERR_PARTITION_DB_NOT_INIT;
Miklos Balint386b8b52017-11-29 13:12:32 +0000183 }
184
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100185 part = &g_spm_partition_db.partitions[partition_idx];
Miklos Balint386b8b52017-11-29 13:12:32 +0000186
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200187 return tfm_spm_hal_partition_sandbox_config(&(part->memory_data),
188 part->platform_data);
Miklos Balint386b8b52017-11-29 13:12:32 +0000189
Miklos Balint386b8b52017-11-29 13:12:32 +0000190}
191
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100192enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_idx)
Miklos Balint386b8b52017-11-29 13:12:32 +0000193{
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100194 /* This function takes a partition id and disables the
195 * SPM partition for that partition
Miklos Balint386b8b52017-11-29 13:12:32 +0000196 */
197
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200198 struct spm_partition_desc_t *part;
Miklos Balint386b8b52017-11-29 13:12:32 +0000199
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100200 part = &g_spm_partition_db.partitions[partition_idx];
Miklos Balint386b8b52017-11-29 13:12:32 +0000201
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200202 return tfm_spm_hal_partition_sandbox_deconfig(&(part->memory_data),
203 part->platform_data);
Miklos Balint386b8b52017-11-29 13:12:32 +0000204}
205
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100206uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx)
Miklos Balint386b8b52017-11-29 13:12:32 +0000207{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100208 return g_spm_partition_db.partitions[partition_idx].
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200209 memory_data.stack_bottom;
Miklos Balint386b8b52017-11-29 13:12:32 +0000210}
211
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100212uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx)
Miklos Balint386b8b52017-11-29 13:12:32 +0000213{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200214 return g_spm_partition_db.partitions[partition_idx].memory_data.stack_top;
Miklos Balint386b8b52017-11-29 13:12:32 +0000215}
216
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100217void tfm_spm_partition_set_stack(uint32_t partition_idx, uint32_t stack_ptr)
Miklos Balint386b8b52017-11-29 13:12:32 +0000218{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100219 g_spm_partition_db.partitions[partition_idx].
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100220 runtime_data.stack_ptr = stack_ptr;
Miklos Balint386b8b52017-11-29 13:12:32 +0000221}
222#endif
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100223
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100224uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx)
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100225{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100226 return g_spm_partition_db.partitions[partition_idx].static_data.
227 partition_id;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100228}
229
Mate Toth-Pal59398712018-02-28 17:06:40 +0100230uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx)
231{
232 return g_spm_partition_db.partitions[partition_idx].static_data.
233 partition_flags;
234}
235
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100236const struct spm_partition_runtime_data_t *
Mate Toth-Pal59398712018-02-28 17:06:40 +0100237 tfm_spm_partition_get_runtime_data(uint32_t partition_idx)
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100238{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100239 return &(g_spm_partition_db.partitions[partition_idx].runtime_data);
240}
241
242void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state)
243{
244 g_spm_partition_db.partitions[partition_idx].runtime_data.partition_state =
245 state;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100246 if (state == SPM_PARTITION_STATE_RUNNING) {
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100247 g_spm_partition_db.running_partition_idx = partition_idx;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100248 }
249}
250
Miklos Balint6a139ae2018-04-04 19:44:37 +0200251void tfm_spm_partition_set_caller_partition_idx(uint32_t partition_idx,
252 uint32_t caller_partition_idx)
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100253{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100254 g_spm_partition_db.partitions[partition_idx].runtime_data.
255 caller_partition_idx = caller_partition_idx;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100256}
257
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100258void tfm_spm_partition_set_orig_psp(uint32_t partition_idx,
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100259 uint32_t orig_psp)
260{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100261 g_spm_partition_db.partitions[partition_idx].runtime_data.orig_psp =
262 orig_psp;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100263}
264
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100265void tfm_spm_partition_set_orig_psplim(uint32_t partition_idx,
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100266 uint32_t orig_psplim)
267{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100268 g_spm_partition_db.partitions[partition_idx].runtime_data.orig_psplim =
269 orig_psplim;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100270}
271
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100272void tfm_spm_partition_set_orig_lr(uint32_t partition_idx, uint32_t orig_lr)
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100273{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100274 g_spm_partition_db.partitions[partition_idx].runtime_data.orig_lr = orig_lr;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100275}
276
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100277enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100278 uint32_t share)
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100279{
280 enum spm_err_t ret = SPM_ERR_OK;
281
282#if TFM_LVL != 1
283 /* Only need to set configuration on levels higher than 1 */
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200284 ret = tfm_spm_hal_set_share_region(share);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100285#endif
286
287 if (ret == SPM_ERR_OK) {
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100288 g_spm_partition_db.partitions[partition_idx].runtime_data.share = share;
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100289 }
290 return ret;
291}
292
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100293uint32_t tfm_spm_partition_get_running_partition_idx(void)
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100294{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100295 return g_spm_partition_db.running_partition_idx;
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100296}
297
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100298void tfm_spm_partition_cleanup_context(uint32_t partition_idx)
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100299{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200300 struct spm_partition_desc_t *partition =
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100301 &(g_spm_partition_db.partitions[partition_idx]);
302 partition->runtime_data.caller_partition_idx = SPM_INVALID_PARTITION_IDX;
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100303 partition->runtime_data.orig_psp = 0;
304 partition->runtime_data.orig_psplim = 0;
305 partition->runtime_data.orig_lr = 0;
306 partition->runtime_data.share = 0;
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100307}