blob: adc57f2ca534f1381388b8e0cbbac29b459df196 [file] [log] [blame]
Miklos Balint386b8b52017-11-29 13:12:32 +00001/*
Gyorgy Szing40a7af02019-02-06 14:19:47 +01002 * Copyright (c) 2017-2019, Arm Limited. All rights reserved.
Miklos Balint386b8b52017-11-29 13:12:32 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#ifndef __SPM_API_H__
9#define __SPM_API_H__
10
11/* This file contains the apis exported by the SPM to tfm core */
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020012#include "tfm_api.h"
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010013#include "spm_partition_defs.h"
Miklos Balint386b8b52017-11-29 13:12:32 +000014#include "secure_fw/core/tfm_secure_api.h"
Edison Ai66fbdf12019-07-08 16:05:07 +080015#ifdef TFM_PSA_API
16#include "tfm_list.h"
17#include "tfm_wait.h"
18#endif
Miklos Balint386b8b52017-11-29 13:12:32 +000019
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010020#define SPM_INVALID_PARTITION_IDX (~0U)
21
Summer Qineb537e52019-03-29 09:57:10 +080022/* Privileged definitions for partition thread mode */
23#define TFM_PARTITION_PRIVILEGED_MODE 1
24#define TFM_PARTITION_UNPRIVILEGED_MODE 0
25
Miklos Balint386b8b52017-11-29 13:12:32 +000026enum spm_err_t {
27 SPM_ERR_OK = 0,
Mate Toth-Pal349714a2018-02-23 15:30:24 +010028 SPM_ERR_PARTITION_DB_NOT_INIT,
29 SPM_ERR_PARTITION_ALREADY_ACTIVE,
30 SPM_ERR_PARTITION_NOT_AVAILABLE,
Hugues de Valonf704c802019-02-19 14:51:41 +000031 SPM_ERR_INVALID_PARAMETER,
Miklos Balint386b8b52017-11-29 13:12:32 +000032 SPM_ERR_INVALID_CONFIG,
33};
34
Hugues de Valon99578562019-06-18 16:08:51 +010035#define SPM_PARTITION_STATE_UNINIT 0
36#define SPM_PARTITION_STATE_IDLE 1
37#define SPM_PARTITION_STATE_RUNNING 2
38#define SPM_PARTITION_STATE_HANDLING_IRQ 3
39#define SPM_PARTITION_STATE_SUSPENDED 4
40#define SPM_PARTITION_STATE_BLOCKED 5
41#define SPM_PARTITION_STATE_CLOSED 6
Mate Toth-Pal65291f32018-02-23 14:35:22 +010042
Hugues de Valon99578562019-06-18 16:08:51 +010043#define SPM_PART_FLAG_APP_ROT 0x01
44#define SPM_PART_FLAG_PSA_ROT 0x02
45#define SPM_PART_FLAG_IPC 0x04
Mate Toth-Pal59398712018-02-28 17:06:40 +010046
Edison Ai66fbdf12019-07-08 16:05:07 +080047#ifndef TFM_PSA_API
Miklos Balint386b8b52017-11-29 13:12:32 +000048/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020049 * \brief Holds the iovec parameters that are passed to a service
50 *
51 * \note The size of the structure is (and have to be) multiple of 8 bytes
52 */
53struct iovec_args_t {
54 psa_invec in_vec[PSA_MAX_IOVEC]; /*!< Array of psa_invec objects */
55 size_t in_len; /*!< Number psa_invec objects in in_vec
56 */
57 psa_outvec out_vec[PSA_MAX_IOVEC]; /*!< Array of psa_outvec objects */
58 size_t out_len; /*!< Number psa_outvec objects in out_vec
59 */
60};
Edison Ai66fbdf12019-07-08 16:05:07 +080061#endif /* !define(TFM_PSA_API) */
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020062
63/**
Mate Toth-Pal18b83922018-02-26 17:58:18 +010064 * \brief Runtime context information of a partition
65 */
66struct spm_partition_runtime_data_t {
Edison Ai66fbdf12019-07-08 16:05:07 +080067#ifdef TFM_PSA_API
68 struct tfm_event_t signal_evnt; /* Event signal */
69 uint32_t signals; /* Service signals had been triggered*/
70 struct tfm_list_node_t service_list;/* Service list */
71#else /* TFM_PSA_API */
Mate Toth-Pal18b83922018-02-26 17:58:18 +010072 uint32_t partition_state;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010073 uint32_t caller_partition_idx;
Mate Toth-Pal21a74c92018-04-13 14:05:41 +020074 int32_t caller_client_id;
Mate Toth-Pal18b83922018-02-26 17:58:18 +010075 uint32_t share;
Mate Toth-Pal18b83922018-02-26 17:58:18 +010076 uint32_t stack_ptr;
Miklos Balintace4c3f2018-07-30 12:31:15 +020077 uint32_t lr;
Mate Toth-Pal2a6f8c22018-12-13 16:37:17 +010078 int32_t iovec_api; /*!< Whether the function in the partition
79 * had been called using the iovec API.
80 * FIXME: Remove the field once this is the
81 * only option
82 */
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020083 struct iovec_args_t iovec_args;
84 psa_outvec *orig_outvec;
Mate Toth-Pal4341de02018-10-02 12:55:47 +020085 uint32_t *ctx_stack_ptr;
Edison Ai66fbdf12019-07-08 16:05:07 +080086#endif /* TFM_PSA_API */
87 uint32_t signal_mask; /*
88 * Service signal mask passed by
89 * psa_wait()
90 */
Mate Toth-Pal18b83922018-02-26 17:58:18 +010091};
92
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010093
Mate Toth-Pal18b83922018-02-26 17:58:18 +010094/**
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010095 * \brief Returns the index of the partition with the given partition ID.
Miklos Balint386b8b52017-11-29 13:12:32 +000096 *
Mate Toth-Pal349714a2018-02-23 15:30:24 +010097 * \param[in] partition_id Partition id
Miklos Balint386b8b52017-11-29 13:12:32 +000098 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010099 * \return the partition idx if partition_id is valid,
100 * \ref SPM_INVALID_PARTITION_IDX othervise
101 */
102uint32_t get_partition_idx(uint32_t partition_id);
103
Miklos Balintdd02bb32019-05-26 21:13:12 +0200104#if (TFM_LVL != 1) || defined(TFM_PSA_API)
Summer Qind00e4db2019-05-09 18:03:52 +0800105/**
106 * \brief Get bottom of stack region for a partition
107 *
108 * \param[in] partition_idx Partition index
109 *
110 * \return Stack region bottom value
111 *
112 * \note This function doesn't check if partition_idx is valid.
113 */
114uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx);
115
116/**
117 * \brief Get top of stack region for a partition
118 *
119 * \param[in] partition_idx Partition index
120 *
121 * \return Stack region top value
122 *
123 * \note This function doesn't check if partition_idx is valid.
124 */
125uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx);
Miklos Balintdd02bb32019-05-26 21:13:12 +0200126#endif
Summer Qind00e4db2019-05-09 18:03:52 +0800127
Miklos Balintdd02bb32019-05-26 21:13:12 +0200128#if (TFM_LVL != 1) && !defined(TFM_PSA_API)
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100129/**
130 * \brief Configure isolated sandbox for a partition
131 *
132 * \param[in] partition_idx Partition index
133 *
Miklos Balint386b8b52017-11-29 13:12:32 +0000134 * \return Error code \ref spm_err_t
135 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100136 * \note This function doesn't check if partition_idx is valid.
Miklos Balint386b8b52017-11-29 13:12:32 +0000137 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100138enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_idx);
Miklos Balint386b8b52017-11-29 13:12:32 +0000139
140/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100141 * \brief Deconfigure sandbox for a partition
Miklos Balint386b8b52017-11-29 13:12:32 +0000142 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100143 * \param[in] partition_idx Partition index
Miklos Balint386b8b52017-11-29 13:12:32 +0000144 *
145 * \return Error code \ref spm_err_t
146 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100147 * \note This function doesn't check if partition_idx is valid.
Miklos Balint386b8b52017-11-29 13:12:32 +0000148 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100149enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_idx);
Miklos Balint386b8b52017-11-29 13:12:32 +0000150
151/**
Mate Toth-Pal21a74c92018-04-13 14:05:41 +0200152 * \brief Get the start of the zero-initialised region for a partition
153 *
154 * \param[in] partition_idx Partition idx
155 *
156 * \return Start of the zero-initialised region
157 *
158 * \note This function doesn't check if partition_idx is valid.
159 */
160uint32_t tfm_spm_partition_get_zi_start(uint32_t partition_idx);
161
162/**
163 * \brief Get the limit of the zero-initialised region for a partition
164 *
165 * \param[in] partition_idx Partition idx
166 *
167 * \return Limit of the zero-initialised region
168 *
169 * \note This function doesn't check if partition_idx is valid.
170 * \note The address returned is not part of the region.
171 */
172uint32_t tfm_spm_partition_get_zi_limit(uint32_t partition_idx);
173
174/**
175 * \brief Get the start of the read-write region for a partition
176 *
177 * \param[in] partition_idx Partition idx
178 *
179 * \return Start of the read-write region
180 *
181 * \note This function doesn't check if partition_idx is valid.
182 */
183uint32_t tfm_spm_partition_get_rw_start(uint32_t partition_idx);
184
185/**
186 * \brief Get the limit of the read-write region for a partition
187 *
188 * \param[in] partition_idx Partition idx
189 *
190 * \return Limit of the read-write region
191 *
192 * \note This function doesn't check if partition_idx is valid.
193 * \note The address returned is not part of the region.
194 */
195uint32_t tfm_spm_partition_get_rw_limit(uint32_t partition_idx);
196
197/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200198 * \brief Save stack pointer for partition in database
199 *
200 * \param[in] partition_idx Partition index
201 * \param[in] stack_ptr Stack pointer to be stored
202 *
203 * \note This function doesn't check if partition_idx is valid.
204 */
Gyorgy Szing40a7af02019-02-06 14:19:47 +0100205void tfm_spm_partition_set_stack(uint32_t partition_idx, uint32_t stack_ptr);
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200206#endif
207
208/**
Summer Qinb4a854d2019-05-29 15:31:22 +0800209 * \brief Get the id of the partition for its index from the db
210 *
211 * \param[in] partition_idx Partition index
212 *
213 * \return Partition ID for that partition
214 *
215 * \note This function doesn't check if partition_idx is valid.
216 */
217uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx);
218
219/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200220 * \brief Get the flags associated with a partition
221 *
222 * \param[in] partition_idx Partition index
223 *
224 * \return Flags associated with the partition
225 *
226 * \note This function doesn't check if partition_idx is valid.
227 */
228uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx);
229
Summer Qinb4a854d2019-05-29 15:31:22 +0800230#ifndef TFM_PSA_API
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200231/**
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200232 * \brief Save interrupted partition context on ctx stack
233 *
234 * \param[in] partition_idx Partition index
235 *
236 * \note This function doesn't check if partition_idx is valid.
237 * \note This function doesn't whether the ctx stack overflows.
238 */
239void tfm_spm_partition_push_interrupted_ctx(uint32_t partition_idx);
240
241/**
242 * \brief Restores interrupted partition context on ctx stack
243 *
244 * \param[in] partition_idx Partition index
245 *
246 * \note This function doesn't check if partition_idx is valid.
247 * \note This function doesn't whether the ctx stack underflows.
248 */
249void tfm_spm_partition_pop_interrupted_ctx(uint32_t partition_idx);
250
251/**
252 * \brief Save handler partition context on ctx stack
253 *
254 * \param[in] partition_idx Partition index
255 *
256 * \note This function doesn't check if partition_idx is valid.
257 * \note This function doesn't whether the ctx stack overflows.
258 */
259void tfm_spm_partition_push_handler_ctx(uint32_t partition_idx);
260
261/**
262 * \brief Restores handler partition context on ctx stack
263 *
264 * \param[in] partition_idx Partition index
265 *
266 * \note This function doesn't check if partition_idx is valid.
267 * \note This function doesn't whether the ctx stack underflows.
268 */
269void tfm_spm_partition_pop_handler_ctx(uint32_t partition_idx);
270
271/**
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100272 * \brief Get the current runtime data of a partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100273 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100274 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100275 *
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100276 * \return The runtime data of the specified partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100277 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100278 * \note This function doesn't check if partition_idx is valid.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100279 */
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100280const struct spm_partition_runtime_data_t *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100281 tfm_spm_partition_get_runtime_data(uint32_t partition_idx);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100282
283/**
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100284 * \brief Returns the index of the partition that has running state
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100285 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100286 * \return The index of the partition with the running state, if there is any
287 * set. 0 otherwise.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100288 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100289uint32_t tfm_spm_partition_get_running_partition_idx(void);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100290
291/**
Miklos Balintace4c3f2018-07-30 12:31:15 +0200292 * \brief Save stack pointer and link register for partition in database
293 *
294 * \param[in] partition_idx Partition index
295 * \param[in] stack_ptr Stack pointer to be stored
296 * \param[in] lr Link register to be stored
297 *
298 * \note This function doesn't check if partition_idx is valid.
299 */
300void tfm_spm_partition_store_context(uint32_t partition_idx,
301 uint32_t stack_ptr, uint32_t lr);
302
303/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100304 * \brief Set the current state of a partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100305 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100306 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100307 * \param[in] state The state to be set
308 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100309 * \note This function doesn't check if partition_idx is valid.
Gyorgy Szing40a7af02019-02-06 14:19:47 +0100310 * \note The state has to have the value set of \ref spm_part_state_t.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100311 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100312void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100313
314/**
Miklos Balint6a139ae2018-04-04 19:44:37 +0200315 * \brief Set the caller partition index for a given partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100316 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100317 * \param[in] partition_idx Partition index
Miklos Balint6a139ae2018-04-04 19:44:37 +0200318 * \param[in] caller_partition_idx The index of the caller partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100319 *
Miklos Balint6a139ae2018-04-04 19:44:37 +0200320 * \note This function doesn't check if any of the partition_idxs are valid.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100321 */
Miklos Balint6a139ae2018-04-04 19:44:37 +0200322void tfm_spm_partition_set_caller_partition_idx(uint32_t partition_idx,
323 uint32_t caller_partition_idx);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100324
325/**
Mate Toth-Pal21a74c92018-04-13 14:05:41 +0200326* \brief Set the caller client ID for a given partition
327*
328* \param[in] partition_idx Partition index
329* \param[in] caller_client_id The ID of the calling client
330*
331* \note This function doesn't check if any of the partition_idxs are valid.
332*/
333void tfm_spm_partition_set_caller_client_id(uint32_t partition_idx,
334 int32_t caller_client_id);
335
336/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100337 * \brief Set the buffer share region of the partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100338 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100339 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100340 * \param[in] share The buffer share region to be set
341 *
342 * \return Error code \ref spm_err_t
343 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100344 * \note This function doesn't check if partition_idx is valid.
Hugues de Valon99578562019-06-18 16:08:51 +0100345 * \note share has to have one of the buffer share values:
346 * - TFM_BUFFER_SHARE_DISABLE
347 * - TFM_BUFFER_SHARE_NS_CODE
348 * - TFM_BUFFER_SHARE_SCRATCH
349 * - TFM_BUFFER_SHARE_PRIV
350 * - TFM_BUFFER_SHARE_DEFAULT
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100351 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100352enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100353 uint32_t share);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100354
355/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200356 * \brief Set the iovec parameters for the partition
357 *
358 * \param[in] partition_idx Partition index
359 * \param[in] args The arguments of the secure function
360 *
361 * args is expected to be of type int32_t[4] where:
362 * args[0] is in_vec
363 * args[1] is in_len
364 * args[2] is out_vec
365 * args[3] is out_len
366 *
Hugues de Valonf704c802019-02-19 14:51:41 +0000367 * \return Error code \ref spm_err_t
368 *
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200369 * \note This function doesn't check if partition_idx is valid.
370 * \note This function assumes that the iovecs that are passed in args are
371 * valid, and does no sanity check on them at all.
372 */
Hugues de Valonf704c802019-02-19 14:51:41 +0000373enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
374 const int32_t *args);
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200375
376/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100377 * \brief Execute partition init function
Miklos Balint386b8b52017-11-29 13:12:32 +0000378 *
379 * \return Error code \ref spm_err_t
380 */
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100381enum spm_err_t tfm_spm_partition_init(void);
Miklos Balint386b8b52017-11-29 13:12:32 +0000382
383/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100384 * \brief Clears the context info from the database for a partition.
Miklos Balint386b8b52017-11-29 13:12:32 +0000385 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100386 * \param[in] partition_idx Partition index
Miklos Balint386b8b52017-11-29 13:12:32 +0000387 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100388 * \note This function doesn't check if partition_idx is valid.
Miklos Balint386b8b52017-11-29 13:12:32 +0000389 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100390void tfm_spm_partition_cleanup_context(uint32_t partition_idx);
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200391
392/**
393 * \brief Set the signal mask for a given partition
394 *
395 * \param[in] partition_idx Partition index
396 * \param[in] signal_mask The signal mask to be set for the partition
397 *
398 * \note This function doesn't check if any of the partition_idxs are valid.
399 */
400void tfm_spm_partition_set_signal_mask(uint32_t partition_idx,
401 uint32_t signal_mask);
Summer Qinb4a854d2019-05-29 15:31:22 +0800402#endif /* !defined(TFM_PSA_API) */
403
404/**
405 * \brief Initialize partition database
406 *
407 * \return Error code \ref spm_err_t
408 */
409enum spm_err_t tfm_spm_db_init(void);
Miklos Balint386b8b52017-11-29 13:12:32 +0000410
Edison Aib5571352019-03-22 10:49:52 +0800411/**
412 * \brief Change the privilege mode for partition thread mode.
413 *
414 * \param[in] privileged Privileged mode,
415 * \ref TFM_PARTITION_PRIVILEGED_MODE
416 * and \ref TFM_PARTITION_UNPRIVILEGED_MODE
417 *
418 * \note Barrier instructions are not called by this function, and if
419 * it is called in thread mode, it might be necessary to call
420 * them after this function returns (just like it is done in
421 * jump_to_ns_code()).
422 */
423void tfm_spm_partition_change_privilege(uint32_t privileged);
424
Miklos Balint386b8b52017-11-29 13:12:32 +0000425#endif /*__SPM_API_H__ */