blob: d95bee49073032e761c938aa878825ef032d5019 [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"
Tamas Ban997aeb32018-11-19 13:28:32 +000014#include "secure_utilities.h"
Mate Toth-Pale1475332018-04-09 17:28:49 +020015#include "spm_db_setup.h"
Miklos Balint6a139ae2018-04-04 19:44:37 +020016#include "tfm_internal.h"
Mate Toth-Pal65291f32018-02-23 14:35:22 +010017#include "tfm_api.h"
Mate Toth-Palce61afa2018-08-03 13:51:01 +020018#include "tfm_nspm.h"
Miklos Balint386b8b52017-11-29 13:12:32 +000019#include "secure_fw/core/tfm_core.h"
Mate Toth-Pale1475332018-04-09 17:28:49 +020020#include "platform_retarget.h"
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020021#include "tfm_peripherals_def.h"
Mate Toth-Pale1475332018-04-09 17:28:49 +020022#include "spm_partition_defs.h"
23
Miklos Balint386b8b52017-11-29 13:12:32 +000024
Mate Toth-Pal349714a2018-02-23 15:30:24 +010025struct spm_partition_db_t g_spm_partition_db = {0,};
Miklos Balint386b8b52017-11-29 13:12:32 +000026
Miklos Balint386b8b52017-11-29 13:12:32 +000027typedef enum {
28 TFM_INIT_FAILURE,
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010029} sp_error_type_t;
Miklos Balint386b8b52017-11-29 13:12:32 +000030
31/*
Mate Toth-Pal349714a2018-02-23 15:30:24 +010032 * This function is called when a secure partition causes an error.
Mate Toth-Pal65291f32018-02-23 14:35:22 +010033 * In case of an error in the error handling, a non-zero value have to be
34 * returned.
Miklos Balint386b8b52017-11-29 13:12:32 +000035 */
Mate Toth-Pal349714a2018-02-23 15:30:24 +010036static void tfm_spm_partition_err_handler(
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020037 struct spm_partition_desc_t *partition,
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010038 sp_error_type_t err_type,
Mate Toth-Pal65291f32018-02-23 14:35:22 +010039 int32_t err_code)
Miklos Balint386b8b52017-11-29 13:12:32 +000040{
Miklos Balint386b8b52017-11-29 13:12:32 +000041#ifdef TFM_CORE_DEBUG
42 if (err_type == TFM_INIT_FAILURE) {
Mate Toth-Pal349714a2018-02-23 15:30:24 +010043 printf("Partition init failed for partition id 0x%08X\r\n",
Mate Toth-Pal18b83922018-02-26 17:58:18 +010044 partition->static_data.partition_id);
Miklos Balint386b8b52017-11-29 13:12:32 +000045 } else {
Mate Toth-Pal349714a2018-02-23 15:30:24 +010046 printf("Unknown partition error %d for partition id 0x%08X\r\n",
Mate Toth-Pal18b83922018-02-26 17:58:18 +010047 err_type, partition->static_data.partition_id);
Miklos Balint386b8b52017-11-29 13:12:32 +000048 }
49#endif
Mate Toth-Pal18b83922018-02-26 17:58:18 +010050 tfm_spm_partition_set_state(partition->static_data.partition_id,
Mate Toth-Pal349714a2018-02-23 15:30:24 +010051 SPM_PARTITION_STATE_CLOSED);
Miklos Balint386b8b52017-11-29 13:12:32 +000052}
53
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010054uint32_t get_partition_idx(uint32_t partition_id)
55{
56 int i;
57
58 if (partition_id == INVALID_PARTITION_ID) {
59 return SPM_INVALID_PARTITION_IDX;
60 }
61
62 for (i = 0; i < g_spm_partition_db.partition_count; ++i) {
63 if (g_spm_partition_db.partitions[i].static_data.partition_id ==
64 partition_id) {
65 return i;
66 }
67 }
68 return SPM_INVALID_PARTITION_IDX;
69}
70
Miklos Balint386b8b52017-11-29 13:12:32 +000071enum spm_err_t tfm_spm_db_init(void)
72{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020073 struct spm_partition_desc_t *part_ptr;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010074
Tamas Ban997aeb32018-11-19 13:28:32 +000075 tfm_memset (&g_spm_partition_db, 0, sizeof(g_spm_partition_db));
Mate Toth-Pal7345a4b2018-03-08 16:10:28 +010076
Mate Toth-Pal349714a2018-02-23 15:30:24 +010077 /* This function initialises partition db */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010078 g_spm_partition_db.running_partition_idx = SPM_INVALID_PARTITION_IDX;
79 g_spm_partition_db.partition_count = 0;
Miklos Balint386b8b52017-11-29 13:12:32 +000080
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010081 /* There are a few partitions that are used by TF-M internally.
82 * These are explicitly added to the partition db here.
83 */
84
85 /* For the non secure Execution environment */
Miklos Balint6a139ae2018-04-04 19:44:37 +020086#if TFM_LVL != 1
Tamas Ban56ef3022018-09-13 23:49:16 +010087 extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
88 extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit[];
89 uint32_t psp_stack_bottom = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Base;
90 uint32_t psp_stack_top = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Limit;
Miklos Balint6a139ae2018-04-04 19:44:37 +020091#endif
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010092 if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {
93 return SPM_ERR_INVALID_CONFIG;
94 }
95 part_ptr = &(g_spm_partition_db.partitions[
96 g_spm_partition_db.partition_count]);
97 part_ptr->static_data.partition_id = TFM_SP_NON_SECURE_ID;
Mate Toth-Pal59398712018-02-28 17:06:40 +010098 part_ptr->static_data.partition_flags = 0;
Miklos Balint6a139ae2018-04-04 19:44:37 +020099
100#if TFM_LVL != 1
Tamas Ban56ef3022018-09-13 23:49:16 +0100101 part_ptr->memory_data.stack_bottom = psp_stack_bottom;
102 part_ptr->memory_data.stack_top = psp_stack_top;
Miklos Balint6a139ae2018-04-04 19:44:37 +0200103 /* Since RW, ZI and stack are configured as one MPU region, configure
Tamas Ban56ef3022018-09-13 23:49:16 +0100104 * RW start address to psp_stack_bottom to get RW access to stack
Miklos Balint6a139ae2018-04-04 19:44:37 +0200105 */
Tamas Ban56ef3022018-09-13 23:49:16 +0100106 part_ptr->memory_data.rw_start = psp_stack_bottom;
Miklos Balint6a139ae2018-04-04 19:44:37 +0200107#endif
108
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100109 part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
Miklos Balint12735bc2018-08-01 15:45:18 +0200110 tfm_nspm_configure_clients();
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100111 ++g_spm_partition_db.partition_count;
112
113 /* For the TF-M core environment itself */
114 if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {
115 return SPM_ERR_INVALID_CONFIG;
116 }
117 part_ptr = &(g_spm_partition_db.partitions[
118 g_spm_partition_db.partition_count]);
119 part_ptr->static_data.partition_id = TFM_SP_CORE_ID;
Mate Toth-Pal59398712018-02-28 17:06:40 +0100120 part_ptr->static_data.partition_flags =
121 SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100122 part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
123 ++g_spm_partition_db.partition_count;
124
125 /* Add user-defined secure partitions */
Miklos Balintd306ab12018-05-18 16:58:18 +0200126 #include "secure_fw/services/tfm_partition_list.inc"
Miklos Balint386b8b52017-11-29 13:12:32 +0000127
Mate Toth-Pal7345a4b2018-03-08 16:10:28 +0100128 g_spm_partition_db.is_init = 1;
129
Miklos Balint386b8b52017-11-29 13:12:32 +0000130 return SPM_ERR_OK;
131}
132
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100133enum spm_err_t tfm_spm_partition_init(void)
Miklos Balint386b8b52017-11-29 13:12:32 +0000134{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200135 struct spm_partition_desc_t *part;
Miklos Balintace4c3f2018-07-30 12:31:15 +0200136 struct tfm_sfn_req_s desc;
Miklos Balint6a139ae2018-04-04 19:44:37 +0200137 int32_t args[4] = {0};
Miklos Balint386b8b52017-11-29 13:12:32 +0000138 int32_t fail_cnt = 0;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100139 uint32_t idx;
Miklos Balint386b8b52017-11-29 13:12:32 +0000140
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100141 /* Call the init function for each partition */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100142 for (idx = 0; idx < g_spm_partition_db.partition_count; ++idx) {
143 part = &g_spm_partition_db.partitions[idx];
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200144 tfm_spm_hal_configure_default_isolation(part->platform_data);
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100145 if (part->static_data.partition_init == NULL) {
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100146 tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
Miklos Balint6a139ae2018-04-04 19:44:37 +0200147 tfm_spm_partition_set_caller_partition_idx(idx,
148 SPM_INVALID_PARTITION_IDX);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100149 } else {
Miklos Balintace4c3f2018-07-30 12:31:15 +0200150 int32_t res;
Miklos Balint6a139ae2018-04-04 19:44:37 +0200151
152 desc.args = args;
Miklos Balint6a139ae2018-04-04 19:44:37 +0200153 desc.ns_caller = 0;
Mate Toth-Palb8ce0dd2018-07-25 10:18:34 +0200154 desc.iovec_api = TFM_SFN_API_IOVEC;
Miklos Balint6a139ae2018-04-04 19:44:37 +0200155 desc.sfn = (sfn_t)part->static_data.partition_init;
156 desc.sp_id = part->static_data.partition_id;
Miklos Balintace4c3f2018-07-30 12:31:15 +0200157 res = tfm_core_sfn_request(&desc);
158 if (res == TFM_SUCCESS) {
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100159 tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100160 } else {
Miklos Balintace4c3f2018-07-30 12:31:15 +0200161 tfm_spm_partition_err_handler(part, TFM_INIT_FAILURE, res);
Miklos Balint386b8b52017-11-29 13:12:32 +0000162 fail_cnt++;
163 }
164 }
165 }
166
Miklos Balint6a139ae2018-04-04 19:44:37 +0200167 tfm_secure_api_init_done();
168
Miklos Balint386b8b52017-11-29 13:12:32 +0000169 if (fail_cnt == 0) {
170 return SPM_ERR_OK;
171 } else {
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100172 return SPM_ERR_PARTITION_NOT_AVAILABLE;
Miklos Balint386b8b52017-11-29 13:12:32 +0000173 }
174}
175
176#if TFM_LVL != 1
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100177enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_idx)
Miklos Balint386b8b52017-11-29 13:12:32 +0000178{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200179 struct spm_partition_desc_t *part;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100180 if (!g_spm_partition_db.is_init) {
181 return SPM_ERR_PARTITION_DB_NOT_INIT;
Miklos Balint386b8b52017-11-29 13:12:32 +0000182 }
183
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100184 part = &g_spm_partition_db.partitions[partition_idx];
Miklos Balint386b8b52017-11-29 13:12:32 +0000185
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200186 return tfm_spm_hal_partition_sandbox_config(&(part->memory_data),
187 part->platform_data);
Miklos Balint386b8b52017-11-29 13:12:32 +0000188
Miklos Balint386b8b52017-11-29 13:12:32 +0000189}
190
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100191enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_idx)
Miklos Balint386b8b52017-11-29 13:12:32 +0000192{
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100193 /* This function takes a partition id and disables the
194 * SPM partition for that partition
Miklos Balint386b8b52017-11-29 13:12:32 +0000195 */
196
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200197 struct spm_partition_desc_t *part;
Miklos Balint386b8b52017-11-29 13:12:32 +0000198
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100199 part = &g_spm_partition_db.partitions[partition_idx];
Miklos Balint386b8b52017-11-29 13:12:32 +0000200
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200201 return tfm_spm_hal_partition_sandbox_deconfig(&(part->memory_data),
202 part->platform_data);
Miklos Balint386b8b52017-11-29 13:12:32 +0000203}
204
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100205uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx)
Miklos Balint386b8b52017-11-29 13:12:32 +0000206{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100207 return g_spm_partition_db.partitions[partition_idx].
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200208 memory_data.stack_bottom;
Miklos Balint386b8b52017-11-29 13:12:32 +0000209}
210
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100211uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx)
Miklos Balint386b8b52017-11-29 13:12:32 +0000212{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200213 return g_spm_partition_db.partitions[partition_idx].memory_data.stack_top;
Miklos Balint386b8b52017-11-29 13:12:32 +0000214}
215
Mate Toth-Pal21a74c92018-04-13 14:05:41 +0200216uint32_t tfm_spm_partition_get_zi_start(uint32_t partition_idx)
217{
218 return g_spm_partition_db.partitions[partition_idx].
219 memory_data.zi_start;
220}
221
222uint32_t tfm_spm_partition_get_zi_limit(uint32_t partition_idx)
223{
224 return g_spm_partition_db.partitions[partition_idx].
225 memory_data.zi_limit;
226}
227
228uint32_t tfm_spm_partition_get_rw_start(uint32_t partition_idx)
229{
230 return g_spm_partition_db.partitions[partition_idx].
231 memory_data.rw_start;
232}
233
234uint32_t tfm_spm_partition_get_rw_limit(uint32_t partition_idx)
235{
236 return g_spm_partition_db.partitions[partition_idx].
237 memory_data.rw_limit;
238}
239
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100240void tfm_spm_partition_set_stack(uint32_t partition_idx, uint32_t stack_ptr)
Miklos Balint386b8b52017-11-29 13:12:32 +0000241{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100242 g_spm_partition_db.partitions[partition_idx].
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100243 runtime_data.stack_ptr = stack_ptr;
Miklos Balint386b8b52017-11-29 13:12:32 +0000244}
245#endif
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100246
Miklos Balintace4c3f2018-07-30 12:31:15 +0200247void tfm_spm_partition_store_context(uint32_t partition_idx,
248 uint32_t stack_ptr, uint32_t lr)
249{
250 g_spm_partition_db.partitions[partition_idx].
251 runtime_data.stack_ptr = stack_ptr;
252 g_spm_partition_db.partitions[partition_idx].
253 runtime_data.lr = lr;
254}
255
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100256uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx)
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100257{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100258 return g_spm_partition_db.partitions[partition_idx].static_data.
259 partition_id;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100260}
261
Mate Toth-Pal59398712018-02-28 17:06:40 +0100262uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx)
263{
264 return g_spm_partition_db.partitions[partition_idx].static_data.
265 partition_flags;
266}
267
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100268const struct spm_partition_runtime_data_t *
Mate Toth-Pal59398712018-02-28 17:06:40 +0100269 tfm_spm_partition_get_runtime_data(uint32_t partition_idx)
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100270{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100271 return &(g_spm_partition_db.partitions[partition_idx].runtime_data);
272}
273
274void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state)
275{
276 g_spm_partition_db.partitions[partition_idx].runtime_data.partition_state =
277 state;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100278 if (state == SPM_PARTITION_STATE_RUNNING) {
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100279 g_spm_partition_db.running_partition_idx = partition_idx;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100280 }
281}
282
Miklos Balint6a139ae2018-04-04 19:44:37 +0200283void tfm_spm_partition_set_caller_partition_idx(uint32_t partition_idx,
284 uint32_t caller_partition_idx)
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100285{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100286 g_spm_partition_db.partitions[partition_idx].runtime_data.
287 caller_partition_idx = caller_partition_idx;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100288}
289
Mate Toth-Pal21a74c92018-04-13 14:05:41 +0200290void tfm_spm_partition_set_caller_client_id(uint32_t partition_idx,
291 int32_t caller_client_id)
292{
293 g_spm_partition_db.partitions[partition_idx].runtime_data.
294 caller_client_id = caller_client_id;
295}
296
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100297enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100298 uint32_t share)
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100299{
300 enum spm_err_t ret = SPM_ERR_OK;
301
302#if TFM_LVL != 1
303 /* Only need to set configuration on levels higher than 1 */
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200304 ret = tfm_spm_hal_set_share_region(share);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100305#endif
306
307 if (ret == SPM_ERR_OK) {
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100308 g_spm_partition_db.partitions[partition_idx].runtime_data.share = share;
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100309 }
310 return ret;
311}
312
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100313uint32_t tfm_spm_partition_get_running_partition_idx(void)
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100314{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100315 return g_spm_partition_db.running_partition_idx;
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100316}
317
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100318void tfm_spm_partition_cleanup_context(uint32_t partition_idx)
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100319{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200320 struct spm_partition_desc_t *partition =
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100321 &(g_spm_partition_db.partitions[partition_idx]);
322 partition->runtime_data.caller_partition_idx = SPM_INVALID_PARTITION_IDX;
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100323 partition->runtime_data.share = 0;
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100324}