blob: 83d44144d3abe8b335fefc9a2851f2879f4fcd3c [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"
Mate Toth-Palce61afa2018-08-03 13:51:01 +020017#include "tfm_nspm.h"
Miklos Balint386b8b52017-11-29 13:12:32 +000018#include "secure_fw/core/tfm_core.h"
Mate Toth-Pale1475332018-04-09 17:28:49 +020019#include "platform_retarget.h"
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020020#include "tfm_peripherals_def.h"
Mate Toth-Pale1475332018-04-09 17:28:49 +020021#include "spm_partition_defs.h"
22
Miklos Balint386b8b52017-11-29 13:12:32 +000023
Mate Toth-Pal349714a2018-02-23 15:30:24 +010024struct spm_partition_db_t g_spm_partition_db = {0,};
Miklos Balint386b8b52017-11-29 13:12:32 +000025
Miklos Balint386b8b52017-11-29 13:12:32 +000026typedef enum {
27 TFM_INIT_FAILURE,
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010028} sp_error_type_t;
Miklos Balint386b8b52017-11-29 13:12:32 +000029
30/*
Mate Toth-Pal349714a2018-02-23 15:30:24 +010031 * This function is called when a secure partition causes an error.
Mate Toth-Pal65291f32018-02-23 14:35:22 +010032 * In case of an error in the error handling, a non-zero value have to be
33 * returned.
Miklos Balint386b8b52017-11-29 13:12:32 +000034 */
Mate Toth-Pal349714a2018-02-23 15:30:24 +010035static void tfm_spm_partition_err_handler(
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020036 struct spm_partition_desc_t *partition,
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010037 sp_error_type_t err_type,
Mate Toth-Pal65291f32018-02-23 14:35:22 +010038 int32_t err_code)
Miklos Balint386b8b52017-11-29 13:12:32 +000039{
Miklos Balint386b8b52017-11-29 13:12:32 +000040#ifdef TFM_CORE_DEBUG
41 if (err_type == TFM_INIT_FAILURE) {
Mate Toth-Pal349714a2018-02-23 15:30:24 +010042 printf("Partition init failed for partition id 0x%08X\r\n",
Mate Toth-Pal18b83922018-02-26 17:58:18 +010043 partition->static_data.partition_id);
Miklos Balint386b8b52017-11-29 13:12:32 +000044 } else {
Mate Toth-Pal349714a2018-02-23 15:30:24 +010045 printf("Unknown partition error %d for partition id 0x%08X\r\n",
Mate Toth-Pal18b83922018-02-26 17:58:18 +010046 err_type, partition->static_data.partition_id);
Miklos Balint386b8b52017-11-29 13:12:32 +000047 }
48#endif
Mate Toth-Pal18b83922018-02-26 17:58:18 +010049 tfm_spm_partition_set_state(partition->static_data.partition_id,
Mate Toth-Pal349714a2018-02-23 15:30:24 +010050 SPM_PARTITION_STATE_CLOSED);
Miklos Balint386b8b52017-11-29 13:12:32 +000051}
52
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010053uint32_t get_partition_idx(uint32_t partition_id)
54{
55 int i;
56
57 if (partition_id == INVALID_PARTITION_ID) {
58 return SPM_INVALID_PARTITION_IDX;
59 }
60
61 for (i = 0; i < g_spm_partition_db.partition_count; ++i) {
62 if (g_spm_partition_db.partitions[i].static_data.partition_id ==
63 partition_id) {
64 return i;
65 }
66 }
67 return SPM_INVALID_PARTITION_IDX;
68}
69
Miklos Balint386b8b52017-11-29 13:12:32 +000070enum spm_err_t tfm_spm_db_init(void)
71{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020072 struct spm_partition_desc_t *part_ptr;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010073
Mate Toth-Pal7345a4b2018-03-08 16:10:28 +010074 memset (&g_spm_partition_db, 0, sizeof(g_spm_partition_db));
75
Mate Toth-Pal349714a2018-02-23 15:30:24 +010076 /* This function initialises partition db */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010077 g_spm_partition_db.running_partition_idx = SPM_INVALID_PARTITION_IDX;
78 g_spm_partition_db.partition_count = 0;
Miklos Balint386b8b52017-11-29 13:12:32 +000079
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010080 /* There are a few partitions that are used by TF-M internally.
81 * These are explicitly added to the partition db here.
82 */
83
84 /* For the non secure Execution environment */
Miklos Balint6a139ae2018-04-04 19:44:37 +020085#if TFM_LVL != 1
86 extern uint32_t Stack_Mem[];
87 extern uint32_t Stack_top[];
88#endif
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010089 if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {
90 return SPM_ERR_INVALID_CONFIG;
91 }
92 part_ptr = &(g_spm_partition_db.partitions[
93 g_spm_partition_db.partition_count]);
94 part_ptr->static_data.partition_id = TFM_SP_NON_SECURE_ID;
Mate Toth-Pal59398712018-02-28 17:06:40 +010095 part_ptr->static_data.partition_flags = 0;
Miklos Balint6a139ae2018-04-04 19:44:37 +020096
97#if TFM_LVL != 1
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020098 part_ptr->memory_data.stack_bottom = (uint32_t)Stack_Mem;
99 part_ptr->memory_data.stack_top = (uint32_t)Stack_top;
Miklos Balint6a139ae2018-04-04 19:44:37 +0200100 /* Since RW, ZI and stack are configured as one MPU region, configure
101 * RW start address to Stack_Mem to get RW access to stack
102 */
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200103 part_ptr->memory_data.rw_start = (uint32_t)Stack_Mem;
Miklos Balint6a139ae2018-04-04 19:44:37 +0200104#endif
105
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100106 part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
Miklos Balint12735bc2018-08-01 15:45:18 +0200107 tfm_nspm_configure_clients();
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100108 ++g_spm_partition_db.partition_count;
109
110 /* For the TF-M core environment itself */
111 if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {
112 return SPM_ERR_INVALID_CONFIG;
113 }
114 part_ptr = &(g_spm_partition_db.partitions[
115 g_spm_partition_db.partition_count]);
116 part_ptr->static_data.partition_id = TFM_SP_CORE_ID;
Mate Toth-Pal59398712018-02-28 17:06:40 +0100117 part_ptr->static_data.partition_flags =
118 SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100119 part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
120 ++g_spm_partition_db.partition_count;
121
122 /* Add user-defined secure partitions */
Miklos Balintd306ab12018-05-18 16:58:18 +0200123 #include "secure_fw/services/tfm_partition_list.inc"
Miklos Balint386b8b52017-11-29 13:12:32 +0000124
Mate Toth-Pal7345a4b2018-03-08 16:10:28 +0100125 g_spm_partition_db.is_init = 1;
126
Miklos Balint386b8b52017-11-29 13:12:32 +0000127 return SPM_ERR_OK;
128}
129
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100130enum spm_err_t tfm_spm_partition_init(void)
Miklos Balint386b8b52017-11-29 13:12:32 +0000131{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200132 struct spm_partition_desc_t *part;
Miklos Balintace4c3f2018-07-30 12:31:15 +0200133 struct tfm_sfn_req_s desc;
Miklos Balint6a139ae2018-04-04 19:44:37 +0200134 int32_t args[4] = {0};
Miklos Balint386b8b52017-11-29 13:12:32 +0000135 int32_t fail_cnt = 0;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100136 uint32_t idx;
Miklos Balint386b8b52017-11-29 13:12:32 +0000137
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100138 /* Call the init function for each partition */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100139 for (idx = 0; idx < g_spm_partition_db.partition_count; ++idx) {
140 part = &g_spm_partition_db.partitions[idx];
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200141 tfm_spm_hal_configure_default_isolation(part->platform_data);
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100142 if (part->static_data.partition_init == NULL) {
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100143 tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
Miklos Balint6a139ae2018-04-04 19:44:37 +0200144 tfm_spm_partition_set_caller_partition_idx(idx,
145 SPM_INVALID_PARTITION_IDX);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100146 } else {
Miklos Balintace4c3f2018-07-30 12:31:15 +0200147 int32_t res;
Miklos Balint6a139ae2018-04-04 19:44:37 +0200148
149 desc.args = args;
Miklos Balint6a139ae2018-04-04 19:44:37 +0200150 desc.ns_caller = 0;
151 desc.sfn = (sfn_t)part->static_data.partition_init;
152 desc.sp_id = part->static_data.partition_id;
Miklos Balintace4c3f2018-07-30 12:31:15 +0200153 res = tfm_core_sfn_request(&desc);
154 if (res == TFM_SUCCESS) {
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100155 tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100156 } else {
Miklos Balintace4c3f2018-07-30 12:31:15 +0200157 tfm_spm_partition_err_handler(part, TFM_INIT_FAILURE, res);
Miklos Balint386b8b52017-11-29 13:12:32 +0000158 fail_cnt++;
159 }
160 }
161 }
162
Miklos Balint6a139ae2018-04-04 19:44:37 +0200163 tfm_secure_api_init_done();
164
Miklos Balint386b8b52017-11-29 13:12:32 +0000165 if (fail_cnt == 0) {
166 return SPM_ERR_OK;
167 } else {
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100168 return SPM_ERR_PARTITION_NOT_AVAILABLE;
Miklos Balint386b8b52017-11-29 13:12:32 +0000169 }
170}
171
172#if TFM_LVL != 1
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100173enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_idx)
Miklos Balint386b8b52017-11-29 13:12:32 +0000174{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200175 struct spm_partition_desc_t *part;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100176 if (!g_spm_partition_db.is_init) {
177 return SPM_ERR_PARTITION_DB_NOT_INIT;
Miklos Balint386b8b52017-11-29 13:12:32 +0000178 }
179
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100180 part = &g_spm_partition_db.partitions[partition_idx];
Miklos Balint386b8b52017-11-29 13:12:32 +0000181
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200182 return tfm_spm_hal_partition_sandbox_config(&(part->memory_data),
183 part->platform_data);
Miklos Balint386b8b52017-11-29 13:12:32 +0000184
Miklos Balint386b8b52017-11-29 13:12:32 +0000185}
186
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100187enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_idx)
Miklos Balint386b8b52017-11-29 13:12:32 +0000188{
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100189 /* This function takes a partition id and disables the
190 * SPM partition for that partition
Miklos Balint386b8b52017-11-29 13:12:32 +0000191 */
192
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200193 struct spm_partition_desc_t *part;
Miklos Balint386b8b52017-11-29 13:12:32 +0000194
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100195 part = &g_spm_partition_db.partitions[partition_idx];
Miklos Balint386b8b52017-11-29 13:12:32 +0000196
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200197 return tfm_spm_hal_partition_sandbox_deconfig(&(part->memory_data),
198 part->platform_data);
Miklos Balint386b8b52017-11-29 13:12:32 +0000199}
200
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100201uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx)
Miklos Balint386b8b52017-11-29 13:12:32 +0000202{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100203 return g_spm_partition_db.partitions[partition_idx].
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200204 memory_data.stack_bottom;
Miklos Balint386b8b52017-11-29 13:12:32 +0000205}
206
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100207uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx)
Miklos Balint386b8b52017-11-29 13:12:32 +0000208{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200209 return g_spm_partition_db.partitions[partition_idx].memory_data.stack_top;
Miklos Balint386b8b52017-11-29 13:12:32 +0000210}
211
Mate Toth-Pal21a74c92018-04-13 14:05:41 +0200212uint32_t tfm_spm_partition_get_zi_start(uint32_t partition_idx)
213{
214 return g_spm_partition_db.partitions[partition_idx].
215 memory_data.zi_start;
216}
217
218uint32_t tfm_spm_partition_get_zi_limit(uint32_t partition_idx)
219{
220 return g_spm_partition_db.partitions[partition_idx].
221 memory_data.zi_limit;
222}
223
224uint32_t tfm_spm_partition_get_rw_start(uint32_t partition_idx)
225{
226 return g_spm_partition_db.partitions[partition_idx].
227 memory_data.rw_start;
228}
229
230uint32_t tfm_spm_partition_get_rw_limit(uint32_t partition_idx)
231{
232 return g_spm_partition_db.partitions[partition_idx].
233 memory_data.rw_limit;
234}
235
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100236void tfm_spm_partition_set_stack(uint32_t partition_idx, uint32_t stack_ptr)
Miklos Balint386b8b52017-11-29 13:12:32 +0000237{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100238 g_spm_partition_db.partitions[partition_idx].
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100239 runtime_data.stack_ptr = stack_ptr;
Miklos Balint386b8b52017-11-29 13:12:32 +0000240}
241#endif
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100242
Miklos Balintace4c3f2018-07-30 12:31:15 +0200243void tfm_spm_partition_store_context(uint32_t partition_idx,
244 uint32_t stack_ptr, uint32_t lr)
245{
246 g_spm_partition_db.partitions[partition_idx].
247 runtime_data.stack_ptr = stack_ptr;
248 g_spm_partition_db.partitions[partition_idx].
249 runtime_data.lr = lr;
250}
251
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100252uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx)
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100253{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100254 return g_spm_partition_db.partitions[partition_idx].static_data.
255 partition_id;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100256}
257
Mate Toth-Pal59398712018-02-28 17:06:40 +0100258uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx)
259{
260 return g_spm_partition_db.partitions[partition_idx].static_data.
261 partition_flags;
262}
263
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100264const struct spm_partition_runtime_data_t *
Mate Toth-Pal59398712018-02-28 17:06:40 +0100265 tfm_spm_partition_get_runtime_data(uint32_t partition_idx)
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100266{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100267 return &(g_spm_partition_db.partitions[partition_idx].runtime_data);
268}
269
270void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state)
271{
272 g_spm_partition_db.partitions[partition_idx].runtime_data.partition_state =
273 state;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100274 if (state == SPM_PARTITION_STATE_RUNNING) {
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100275 g_spm_partition_db.running_partition_idx = partition_idx;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100276 }
277}
278
Miklos Balint6a139ae2018-04-04 19:44:37 +0200279void tfm_spm_partition_set_caller_partition_idx(uint32_t partition_idx,
280 uint32_t caller_partition_idx)
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100281{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100282 g_spm_partition_db.partitions[partition_idx].runtime_data.
283 caller_partition_idx = caller_partition_idx;
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100284}
285
Mate Toth-Pal21a74c92018-04-13 14:05:41 +0200286void tfm_spm_partition_set_caller_client_id(uint32_t partition_idx,
287 int32_t caller_client_id)
288{
289 g_spm_partition_db.partitions[partition_idx].runtime_data.
290 caller_client_id = caller_client_id;
291}
292
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100293enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100294 uint32_t share)
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100295{
296 enum spm_err_t ret = SPM_ERR_OK;
297
298#if TFM_LVL != 1
299 /* Only need to set configuration on levels higher than 1 */
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200300 ret = tfm_spm_hal_set_share_region(share);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100301#endif
302
303 if (ret == SPM_ERR_OK) {
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100304 g_spm_partition_db.partitions[partition_idx].runtime_data.share = share;
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100305 }
306 return ret;
307}
308
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100309uint32_t tfm_spm_partition_get_running_partition_idx(void)
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100310{
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100311 return g_spm_partition_db.running_partition_idx;
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100312}
313
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100314void tfm_spm_partition_cleanup_context(uint32_t partition_idx)
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100315{
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200316 struct spm_partition_desc_t *partition =
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100317 &(g_spm_partition_db.partitions[partition_idx]);
318 partition->runtime_data.caller_partition_idx = SPM_INVALID_PARTITION_IDX;
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100319 partition->runtime_data.share = 0;
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100320}