blob: 565e70840e9ce04578ea6a2bf9b4a59ddeb9e6ae [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"
15
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010016#define SPM_INVALID_PARTITION_IDX (~0U)
17
Summer Qineb537e52019-03-29 09:57:10 +080018/* Privileged definitions for partition thread mode */
19#define TFM_PARTITION_PRIVILEGED_MODE 1
20#define TFM_PARTITION_UNPRIVILEGED_MODE 0
21
Miklos Balint386b8b52017-11-29 13:12:32 +000022enum spm_err_t {
23 SPM_ERR_OK = 0,
Mate Toth-Pal349714a2018-02-23 15:30:24 +010024 SPM_ERR_PARTITION_DB_NOT_INIT,
25 SPM_ERR_PARTITION_ALREADY_ACTIVE,
26 SPM_ERR_PARTITION_NOT_AVAILABLE,
Hugues de Valonf704c802019-02-19 14:51:41 +000027 SPM_ERR_INVALID_PARAMETER,
Miklos Balint386b8b52017-11-29 13:12:32 +000028 SPM_ERR_INVALID_CONFIG,
29};
30
Hugues de Valon99578562019-06-18 16:08:51 +010031#define SPM_PARTITION_STATE_UNINIT 0
32#define SPM_PARTITION_STATE_IDLE 1
33#define SPM_PARTITION_STATE_RUNNING 2
34#define SPM_PARTITION_STATE_HANDLING_IRQ 3
35#define SPM_PARTITION_STATE_SUSPENDED 4
36#define SPM_PARTITION_STATE_BLOCKED 5
37#define SPM_PARTITION_STATE_CLOSED 6
Mate Toth-Pal65291f32018-02-23 14:35:22 +010038
Hugues de Valon99578562019-06-18 16:08:51 +010039#define SPM_PART_FLAG_APP_ROT 0x01
40#define SPM_PART_FLAG_PSA_ROT 0x02
41#define SPM_PART_FLAG_IPC 0x04
Mate Toth-Pal59398712018-02-28 17:06:40 +010042
Miklos Balint386b8b52017-11-29 13:12:32 +000043/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020044 * \brief Holds the iovec parameters that are passed to a service
45 *
46 * \note The size of the structure is (and have to be) multiple of 8 bytes
47 */
48struct iovec_args_t {
49 psa_invec in_vec[PSA_MAX_IOVEC]; /*!< Array of psa_invec objects */
50 size_t in_len; /*!< Number psa_invec objects in in_vec
51 */
52 psa_outvec out_vec[PSA_MAX_IOVEC]; /*!< Array of psa_outvec objects */
53 size_t out_len; /*!< Number psa_outvec objects in out_vec
54 */
55};
56
57/**
Mate Toth-Pal18b83922018-02-26 17:58:18 +010058 * \brief Runtime context information of a partition
59 */
60struct spm_partition_runtime_data_t {
61 uint32_t partition_state;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010062 uint32_t caller_partition_idx;
Mate Toth-Pal21a74c92018-04-13 14:05:41 +020063 int32_t caller_client_id;
Mate Toth-Pal18b83922018-02-26 17:58:18 +010064 uint32_t share;
Mate Toth-Pal18b83922018-02-26 17:58:18 +010065 uint32_t stack_ptr;
Miklos Balintace4c3f2018-07-30 12:31:15 +020066 uint32_t lr;
Mate Toth-Pal2a6f8c22018-12-13 16:37:17 +010067 int32_t iovec_api; /*!< Whether the function in the partition
68 * had been called using the iovec API.
69 * FIXME: Remove the field once this is the
70 * only option
71 */
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020072 struct iovec_args_t iovec_args;
73 psa_outvec *orig_outvec;
Mate Toth-Pal4341de02018-10-02 12:55:47 +020074 uint32_t *ctx_stack_ptr;
75 /*
76 * FIXME: There is a 'signal_mask' defined in the structure
77 * 'tfm_spm_ipc_partition_t'. It should be eliminated, and the IPC
78 * implementation should use the 'signal_mask' define in this structure.
79 * However currently the content of 'spm_partition_runtime_data_t' structure
80 * is not maintained by the IPC implementation. This is to be fixed with the
81 * effort of restructuring common code among library and IPC model.
82 */
83 uint32_t signal_mask;
Mate Toth-Pal18b83922018-02-26 17:58:18 +010084};
85
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010086
Mate Toth-Pal18b83922018-02-26 17:58:18 +010087/**
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010088 * \brief Returns the index of the partition with the given partition ID.
Miklos Balint386b8b52017-11-29 13:12:32 +000089 *
Mate Toth-Pal349714a2018-02-23 15:30:24 +010090 * \param[in] partition_id Partition id
Miklos Balint386b8b52017-11-29 13:12:32 +000091 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010092 * \return the partition idx if partition_id is valid,
93 * \ref SPM_INVALID_PARTITION_IDX othervise
94 */
95uint32_t get_partition_idx(uint32_t partition_id);
96
Miklos Balintdd02bb32019-05-26 21:13:12 +020097#if (TFM_LVL != 1) || defined(TFM_PSA_API)
Summer Qind00e4db2019-05-09 18:03:52 +080098/**
99 * \brief Get bottom of stack region for a partition
100 *
101 * \param[in] partition_idx Partition index
102 *
103 * \return Stack region bottom value
104 *
105 * \note This function doesn't check if partition_idx is valid.
106 */
107uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx);
108
109/**
110 * \brief Get top of stack region for a partition
111 *
112 * \param[in] partition_idx Partition index
113 *
114 * \return Stack region top value
115 *
116 * \note This function doesn't check if partition_idx is valid.
117 */
118uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx);
Miklos Balintdd02bb32019-05-26 21:13:12 +0200119#endif
Summer Qind00e4db2019-05-09 18:03:52 +0800120
Miklos Balintdd02bb32019-05-26 21:13:12 +0200121#if (TFM_LVL != 1) && !defined(TFM_PSA_API)
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100122/**
123 * \brief Configure isolated sandbox for a partition
124 *
125 * \param[in] partition_idx Partition index
126 *
Miklos Balint386b8b52017-11-29 13:12:32 +0000127 * \return Error code \ref spm_err_t
128 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100129 * \note This function doesn't check if partition_idx is valid.
Miklos Balint386b8b52017-11-29 13:12:32 +0000130 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100131enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_idx);
Miklos Balint386b8b52017-11-29 13:12:32 +0000132
133/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100134 * \brief Deconfigure sandbox for a partition
Miklos Balint386b8b52017-11-29 13:12:32 +0000135 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100136 * \param[in] partition_idx Partition index
Miklos Balint386b8b52017-11-29 13:12:32 +0000137 *
138 * \return Error code \ref spm_err_t
139 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100140 * \note This function doesn't check if partition_idx is valid.
Miklos Balint386b8b52017-11-29 13:12:32 +0000141 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100142enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_idx);
Miklos Balint386b8b52017-11-29 13:12:32 +0000143
144/**
Mate Toth-Pal21a74c92018-04-13 14:05:41 +0200145 * \brief Get the start of the zero-initialised region for a partition
146 *
147 * \param[in] partition_idx Partition idx
148 *
149 * \return Start of the zero-initialised region
150 *
151 * \note This function doesn't check if partition_idx is valid.
152 */
153uint32_t tfm_spm_partition_get_zi_start(uint32_t partition_idx);
154
155/**
156 * \brief Get the limit of the zero-initialised region for a partition
157 *
158 * \param[in] partition_idx Partition idx
159 *
160 * \return Limit of the zero-initialised region
161 *
162 * \note This function doesn't check if partition_idx is valid.
163 * \note The address returned is not part of the region.
164 */
165uint32_t tfm_spm_partition_get_zi_limit(uint32_t partition_idx);
166
167/**
168 * \brief Get the start of the read-write region for a partition
169 *
170 * \param[in] partition_idx Partition idx
171 *
172 * \return Start of the read-write region
173 *
174 * \note This function doesn't check if partition_idx is valid.
175 */
176uint32_t tfm_spm_partition_get_rw_start(uint32_t partition_idx);
177
178/**
179 * \brief Get the limit of the read-write region for a partition
180 *
181 * \param[in] partition_idx Partition idx
182 *
183 * \return Limit of the read-write region
184 *
185 * \note This function doesn't check if partition_idx is valid.
186 * \note The address returned is not part of the region.
187 */
188uint32_t tfm_spm_partition_get_rw_limit(uint32_t partition_idx);
189
190/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200191 * \brief Save stack pointer for partition in database
192 *
193 * \param[in] partition_idx Partition index
194 * \param[in] stack_ptr Stack pointer to be stored
195 *
196 * \note This function doesn't check if partition_idx is valid.
197 */
Gyorgy Szing40a7af02019-02-06 14:19:47 +0100198void tfm_spm_partition_set_stack(uint32_t partition_idx, uint32_t stack_ptr);
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200199#endif
200
201/**
Summer Qinb4a854d2019-05-29 15:31:22 +0800202 * \brief Get the id of the partition for its index from the db
203 *
204 * \param[in] partition_idx Partition index
205 *
206 * \return Partition ID for that partition
207 *
208 * \note This function doesn't check if partition_idx is valid.
209 */
210uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx);
211
212/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200213 * \brief Get the flags associated with a partition
214 *
215 * \param[in] partition_idx Partition index
216 *
217 * \return Flags associated with the partition
218 *
219 * \note This function doesn't check if partition_idx is valid.
220 */
221uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx);
222
Summer Qinb4a854d2019-05-29 15:31:22 +0800223#ifndef TFM_PSA_API
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200224/**
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200225 * \brief Save interrupted partition context on ctx stack
226 *
227 * \param[in] partition_idx Partition index
228 *
229 * \note This function doesn't check if partition_idx is valid.
230 * \note This function doesn't whether the ctx stack overflows.
231 */
232void tfm_spm_partition_push_interrupted_ctx(uint32_t partition_idx);
233
234/**
235 * \brief Restores interrupted partition context on ctx stack
236 *
237 * \param[in] partition_idx Partition index
238 *
239 * \note This function doesn't check if partition_idx is valid.
240 * \note This function doesn't whether the ctx stack underflows.
241 */
242void tfm_spm_partition_pop_interrupted_ctx(uint32_t partition_idx);
243
244/**
245 * \brief Save handler partition context on ctx stack
246 *
247 * \param[in] partition_idx Partition index
248 *
249 * \note This function doesn't check if partition_idx is valid.
250 * \note This function doesn't whether the ctx stack overflows.
251 */
252void tfm_spm_partition_push_handler_ctx(uint32_t partition_idx);
253
254/**
255 * \brief Restores handler partition context on ctx stack
256 *
257 * \param[in] partition_idx Partition index
258 *
259 * \note This function doesn't check if partition_idx is valid.
260 * \note This function doesn't whether the ctx stack underflows.
261 */
262void tfm_spm_partition_pop_handler_ctx(uint32_t partition_idx);
263
264/**
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100265 * \brief Get the current runtime data of a partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100266 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100267 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100268 *
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100269 * \return The runtime data of the specified partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100270 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100271 * \note This function doesn't check if partition_idx is valid.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100272 */
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100273const struct spm_partition_runtime_data_t *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100274 tfm_spm_partition_get_runtime_data(uint32_t partition_idx);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100275
276/**
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100277 * \brief Returns the index of the partition that has running state
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100278 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100279 * \return The index of the partition with the running state, if there is any
280 * set. 0 otherwise.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100281 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100282uint32_t tfm_spm_partition_get_running_partition_idx(void);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100283
284/**
Miklos Balintace4c3f2018-07-30 12:31:15 +0200285 * \brief Save stack pointer and link register for partition in database
286 *
287 * \param[in] partition_idx Partition index
288 * \param[in] stack_ptr Stack pointer to be stored
289 * \param[in] lr Link register to be stored
290 *
291 * \note This function doesn't check if partition_idx is valid.
292 */
293void tfm_spm_partition_store_context(uint32_t partition_idx,
294 uint32_t stack_ptr, uint32_t lr);
295
296/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100297 * \brief Set the current state of a partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100298 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100299 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100300 * \param[in] state The state to be set
301 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100302 * \note This function doesn't check if partition_idx is valid.
Gyorgy Szing40a7af02019-02-06 14:19:47 +0100303 * \note The state has to have the value set of \ref spm_part_state_t.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100304 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100305void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100306
307/**
Miklos Balint6a139ae2018-04-04 19:44:37 +0200308 * \brief Set the caller partition index for a given partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100309 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100310 * \param[in] partition_idx Partition index
Miklos Balint6a139ae2018-04-04 19:44:37 +0200311 * \param[in] caller_partition_idx The index of the caller partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100312 *
Miklos Balint6a139ae2018-04-04 19:44:37 +0200313 * \note This function doesn't check if any of the partition_idxs are valid.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100314 */
Miklos Balint6a139ae2018-04-04 19:44:37 +0200315void tfm_spm_partition_set_caller_partition_idx(uint32_t partition_idx,
316 uint32_t caller_partition_idx);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100317
318/**
Mate Toth-Pal21a74c92018-04-13 14:05:41 +0200319* \brief Set the caller client ID for a given partition
320*
321* \param[in] partition_idx Partition index
322* \param[in] caller_client_id The ID of the calling client
323*
324* \note This function doesn't check if any of the partition_idxs are valid.
325*/
326void tfm_spm_partition_set_caller_client_id(uint32_t partition_idx,
327 int32_t caller_client_id);
328
329/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100330 * \brief Set the buffer share region of the partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100331 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100332 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100333 * \param[in] share The buffer share region to be set
334 *
335 * \return Error code \ref spm_err_t
336 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100337 * \note This function doesn't check if partition_idx is valid.
Hugues de Valon99578562019-06-18 16:08:51 +0100338 * \note share has to have one of the buffer share values:
339 * - TFM_BUFFER_SHARE_DISABLE
340 * - TFM_BUFFER_SHARE_NS_CODE
341 * - TFM_BUFFER_SHARE_SCRATCH
342 * - TFM_BUFFER_SHARE_PRIV
343 * - TFM_BUFFER_SHARE_DEFAULT
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100344 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100345enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100346 uint32_t share);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100347
348/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200349 * \brief Set the iovec parameters for the partition
350 *
351 * \param[in] partition_idx Partition index
352 * \param[in] args The arguments of the secure function
353 *
354 * args is expected to be of type int32_t[4] where:
355 * args[0] is in_vec
356 * args[1] is in_len
357 * args[2] is out_vec
358 * args[3] is out_len
359 *
Hugues de Valonf704c802019-02-19 14:51:41 +0000360 * \return Error code \ref spm_err_t
361 *
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200362 * \note This function doesn't check if partition_idx is valid.
363 * \note This function assumes that the iovecs that are passed in args are
364 * valid, and does no sanity check on them at all.
365 */
Hugues de Valonf704c802019-02-19 14:51:41 +0000366enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
367 const int32_t *args);
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200368
369/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100370 * \brief Execute partition init function
Miklos Balint386b8b52017-11-29 13:12:32 +0000371 *
372 * \return Error code \ref spm_err_t
373 */
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100374enum spm_err_t tfm_spm_partition_init(void);
Miklos Balint386b8b52017-11-29 13:12:32 +0000375
376/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100377 * \brief Clears the context info from the database for a partition.
Miklos Balint386b8b52017-11-29 13:12:32 +0000378 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100379 * \param[in] partition_idx Partition index
Miklos Balint386b8b52017-11-29 13:12:32 +0000380 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100381 * \note This function doesn't check if partition_idx is valid.
Miklos Balint386b8b52017-11-29 13:12:32 +0000382 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100383void tfm_spm_partition_cleanup_context(uint32_t partition_idx);
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200384
385/**
386 * \brief Set the signal mask for a given partition
387 *
388 * \param[in] partition_idx Partition index
389 * \param[in] signal_mask The signal mask to be set for the partition
390 *
391 * \note This function doesn't check if any of the partition_idxs are valid.
392 */
393void tfm_spm_partition_set_signal_mask(uint32_t partition_idx,
394 uint32_t signal_mask);
Summer Qinb4a854d2019-05-29 15:31:22 +0800395#endif /* !defined(TFM_PSA_API) */
396
397/**
398 * \brief Initialize partition database
399 *
400 * \return Error code \ref spm_err_t
401 */
402enum spm_err_t tfm_spm_db_init(void);
Miklos Balint386b8b52017-11-29 13:12:32 +0000403
Edison Aib5571352019-03-22 10:49:52 +0800404/**
405 * \brief Change the privilege mode for partition thread mode.
406 *
407 * \param[in] privileged Privileged mode,
408 * \ref TFM_PARTITION_PRIVILEGED_MODE
409 * and \ref TFM_PARTITION_UNPRIVILEGED_MODE
410 *
411 * \note Barrier instructions are not called by this function, and if
412 * it is called in thread mode, it might be necessary to call
413 * them after this function returns (just like it is done in
414 * jump_to_ns_code()).
415 */
416void tfm_spm_partition_change_privilege(uint32_t privileged);
417
Miklos Balint386b8b52017-11-29 13:12:32 +0000418#endif /*__SPM_API_H__ */