blob: 6b8164be042db353cf0ebb9eb159a8ed93a93347 [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"
Mingyang Sunf3d29892019-07-10 17:50:23 +080015#include <stdbool.h>
Edison Ai66fbdf12019-07-08 16:05:07 +080016#ifdef TFM_PSA_API
17#include "tfm_list.h"
18#include "tfm_wait.h"
Mingyang Sunf3d29892019-07-10 17:50:23 +080019#include "tfm_message_queue.h"
20#include "tfm_secure_api.h"
Edison Ai66fbdf12019-07-08 16:05:07 +080021#endif
Miklos Balint386b8b52017-11-29 13:12:32 +000022
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010023#define SPM_INVALID_PARTITION_IDX (~0U)
24
Summer Qineb537e52019-03-29 09:57:10 +080025/* Privileged definitions for partition thread mode */
26#define TFM_PARTITION_PRIVILEGED_MODE 1
27#define TFM_PARTITION_UNPRIVILEGED_MODE 0
28
Miklos Balint386b8b52017-11-29 13:12:32 +000029enum spm_err_t {
30 SPM_ERR_OK = 0,
Mate Toth-Pal349714a2018-02-23 15:30:24 +010031 SPM_ERR_PARTITION_DB_NOT_INIT,
32 SPM_ERR_PARTITION_ALREADY_ACTIVE,
33 SPM_ERR_PARTITION_NOT_AVAILABLE,
Hugues de Valonf704c802019-02-19 14:51:41 +000034 SPM_ERR_INVALID_PARAMETER,
Miklos Balint386b8b52017-11-29 13:12:32 +000035 SPM_ERR_INVALID_CONFIG,
36};
37
Hugues de Valon99578562019-06-18 16:08:51 +010038#define SPM_PARTITION_STATE_UNINIT 0
39#define SPM_PARTITION_STATE_IDLE 1
40#define SPM_PARTITION_STATE_RUNNING 2
41#define SPM_PARTITION_STATE_HANDLING_IRQ 3
42#define SPM_PARTITION_STATE_SUSPENDED 4
43#define SPM_PARTITION_STATE_BLOCKED 5
44#define SPM_PARTITION_STATE_CLOSED 6
Mate Toth-Pal65291f32018-02-23 14:35:22 +010045
Hugues de Valon99578562019-06-18 16:08:51 +010046#define SPM_PART_FLAG_APP_ROT 0x01
47#define SPM_PART_FLAG_PSA_ROT 0x02
48#define SPM_PART_FLAG_IPC 0x04
Mate Toth-Pal59398712018-02-28 17:06:40 +010049
Edison Ai66fbdf12019-07-08 16:05:07 +080050#ifndef TFM_PSA_API
Miklos Balint386b8b52017-11-29 13:12:32 +000051/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020052 * \brief Holds the iovec parameters that are passed to a service
53 *
54 * \note The size of the structure is (and have to be) multiple of 8 bytes
55 */
56struct iovec_args_t {
57 psa_invec in_vec[PSA_MAX_IOVEC]; /*!< Array of psa_invec objects */
58 size_t in_len; /*!< Number psa_invec objects in in_vec
59 */
60 psa_outvec out_vec[PSA_MAX_IOVEC]; /*!< Array of psa_outvec objects */
61 size_t out_len; /*!< Number psa_outvec objects in out_vec
62 */
63};
Edison Ai66fbdf12019-07-08 16:05:07 +080064#endif /* !define(TFM_PSA_API) */
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020065
66/**
Mate Toth-Pal18b83922018-02-26 17:58:18 +010067 * \brief Runtime context information of a partition
68 */
69struct spm_partition_runtime_data_t {
Edison Ai66fbdf12019-07-08 16:05:07 +080070#ifdef TFM_PSA_API
71 struct tfm_event_t signal_evnt; /* Event signal */
72 uint32_t signals; /* Service signals had been triggered*/
73 struct tfm_list_node_t service_list;/* Service list */
74#else /* TFM_PSA_API */
Mate Toth-Pal18b83922018-02-26 17:58:18 +010075 uint32_t partition_state;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010076 uint32_t caller_partition_idx;
Mate Toth-Pal21a74c92018-04-13 14:05:41 +020077 int32_t caller_client_id;
Mate Toth-Pal18b83922018-02-26 17:58:18 +010078 uint32_t share;
Mate Toth-Pal18b83922018-02-26 17:58:18 +010079 uint32_t stack_ptr;
Miklos Balintace4c3f2018-07-30 12:31:15 +020080 uint32_t lr;
Mate Toth-Pal2a6f8c22018-12-13 16:37:17 +010081 int32_t iovec_api; /*!< Whether the function in the partition
82 * had been called using the iovec API.
83 * FIXME: Remove the field once this is the
84 * only option
85 */
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020086 struct iovec_args_t iovec_args;
87 psa_outvec *orig_outvec;
Mate Toth-Pal4341de02018-10-02 12:55:47 +020088 uint32_t *ctx_stack_ptr;
Edison Ai66fbdf12019-07-08 16:05:07 +080089#endif /* TFM_PSA_API */
90 uint32_t signal_mask; /*
91 * Service signal mask passed by
92 * psa_wait()
93 */
Mate Toth-Pal18b83922018-02-26 17:58:18 +010094};
95
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010096
Mate Toth-Pal18b83922018-02-26 17:58:18 +010097/**
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010098 * \brief Returns the index of the partition with the given partition ID.
Miklos Balint386b8b52017-11-29 13:12:32 +000099 *
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100100 * \param[in] partition_id Partition id
Miklos Balint386b8b52017-11-29 13:12:32 +0000101 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100102 * \return the partition idx if partition_id is valid,
103 * \ref SPM_INVALID_PARTITION_IDX othervise
104 */
105uint32_t get_partition_idx(uint32_t partition_id);
106
Miklos Balintdd02bb32019-05-26 21:13:12 +0200107#if (TFM_LVL != 1) || defined(TFM_PSA_API)
Summer Qind00e4db2019-05-09 18:03:52 +0800108/**
109 * \brief Get bottom of stack region for a partition
110 *
111 * \param[in] partition_idx Partition index
112 *
113 * \return Stack region bottom value
114 *
115 * \note This function doesn't check if partition_idx is valid.
116 */
117uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx);
118
119/**
120 * \brief Get top of stack region for a partition
121 *
122 * \param[in] partition_idx Partition index
123 *
124 * \return Stack region top value
125 *
126 * \note This function doesn't check if partition_idx is valid.
127 */
128uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx);
Miklos Balintdd02bb32019-05-26 21:13:12 +0200129#endif
Summer Qind00e4db2019-05-09 18:03:52 +0800130
Miklos Balintdd02bb32019-05-26 21:13:12 +0200131#if (TFM_LVL != 1) && !defined(TFM_PSA_API)
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100132/**
133 * \brief Configure isolated sandbox for a partition
134 *
135 * \param[in] partition_idx Partition index
136 *
Miklos Balint386b8b52017-11-29 13:12:32 +0000137 * \return Error code \ref spm_err_t
138 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100139 * \note This function doesn't check if partition_idx is valid.
Miklos Balint386b8b52017-11-29 13:12:32 +0000140 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100141enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_idx);
Miklos Balint386b8b52017-11-29 13:12:32 +0000142
143/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100144 * \brief Deconfigure sandbox for a partition
Miklos Balint386b8b52017-11-29 13:12:32 +0000145 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100146 * \param[in] partition_idx Partition index
Miklos Balint386b8b52017-11-29 13:12:32 +0000147 *
148 * \return Error code \ref spm_err_t
149 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100150 * \note This function doesn't check if partition_idx is valid.
Miklos Balint386b8b52017-11-29 13:12:32 +0000151 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100152enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_idx);
Miklos Balint386b8b52017-11-29 13:12:32 +0000153
154/**
Mate Toth-Pal21a74c92018-04-13 14:05:41 +0200155 * \brief Get the start of the zero-initialised region for a partition
156 *
157 * \param[in] partition_idx Partition idx
158 *
159 * \return Start of the zero-initialised region
160 *
161 * \note This function doesn't check if partition_idx is valid.
162 */
163uint32_t tfm_spm_partition_get_zi_start(uint32_t partition_idx);
164
165/**
166 * \brief Get the limit of the zero-initialised region for a partition
167 *
168 * \param[in] partition_idx Partition idx
169 *
170 * \return Limit of the zero-initialised region
171 *
172 * \note This function doesn't check if partition_idx is valid.
173 * \note The address returned is not part of the region.
174 */
175uint32_t tfm_spm_partition_get_zi_limit(uint32_t partition_idx);
176
177/**
178 * \brief Get the start of the read-write region for a partition
179 *
180 * \param[in] partition_idx Partition idx
181 *
182 * \return Start of the read-write region
183 *
184 * \note This function doesn't check if partition_idx is valid.
185 */
186uint32_t tfm_spm_partition_get_rw_start(uint32_t partition_idx);
187
188/**
189 * \brief Get the limit of the read-write region for a partition
190 *
191 * \param[in] partition_idx Partition idx
192 *
193 * \return Limit of the read-write region
194 *
195 * \note This function doesn't check if partition_idx is valid.
196 * \note The address returned is not part of the region.
197 */
198uint32_t tfm_spm_partition_get_rw_limit(uint32_t partition_idx);
199
200/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200201 * \brief Save stack pointer for partition in database
202 *
203 * \param[in] partition_idx Partition index
204 * \param[in] stack_ptr Stack pointer to be stored
205 *
206 * \note This function doesn't check if partition_idx is valid.
207 */
Gyorgy Szing40a7af02019-02-06 14:19:47 +0100208void tfm_spm_partition_set_stack(uint32_t partition_idx, uint32_t stack_ptr);
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200209#endif
210
211/**
Summer Qinb4a854d2019-05-29 15:31:22 +0800212 * \brief Get the id of the partition for its index from the db
213 *
214 * \param[in] partition_idx Partition index
215 *
216 * \return Partition ID for that partition
217 *
218 * \note This function doesn't check if partition_idx is valid.
219 */
220uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx);
221
222/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200223 * \brief Get the flags associated with a partition
224 *
225 * \param[in] partition_idx Partition index
226 *
227 * \return Flags associated with the partition
228 *
229 * \note This function doesn't check if partition_idx is valid.
230 */
231uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx);
232
Summer Qinb4a854d2019-05-29 15:31:22 +0800233#ifndef TFM_PSA_API
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200234/**
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200235 * \brief Save 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 overflows.
241 */
242void tfm_spm_partition_push_interrupted_ctx(uint32_t partition_idx);
243
244/**
245 * \brief Restores interrupted 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 underflows.
251 */
252void tfm_spm_partition_pop_interrupted_ctx(uint32_t partition_idx);
253
254/**
255 * \brief Save 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 overflows.
261 */
262void tfm_spm_partition_push_handler_ctx(uint32_t partition_idx);
263
264/**
265 * \brief Restores handler partition context on ctx stack
266 *
267 * \param[in] partition_idx Partition index
268 *
269 * \note This function doesn't check if partition_idx is valid.
270 * \note This function doesn't whether the ctx stack underflows.
271 */
272void tfm_spm_partition_pop_handler_ctx(uint32_t partition_idx);
273
274/**
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100275 * \brief Get the current runtime data of a partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100276 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100277 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100278 *
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100279 * \return The runtime data of the specified partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100280 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100281 * \note This function doesn't check if partition_idx is valid.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100282 */
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100283const struct spm_partition_runtime_data_t *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100284 tfm_spm_partition_get_runtime_data(uint32_t partition_idx);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100285
286/**
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100287 * \brief Returns the index of the partition that has running state
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100288 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100289 * \return The index of the partition with the running state, if there is any
290 * set. 0 otherwise.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100291 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100292uint32_t tfm_spm_partition_get_running_partition_idx(void);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100293
294/**
Miklos Balintace4c3f2018-07-30 12:31:15 +0200295 * \brief Save stack pointer and link register for partition in database
296 *
297 * \param[in] partition_idx Partition index
298 * \param[in] stack_ptr Stack pointer to be stored
299 * \param[in] lr Link register to be stored
300 *
301 * \note This function doesn't check if partition_idx is valid.
302 */
303void tfm_spm_partition_store_context(uint32_t partition_idx,
304 uint32_t stack_ptr, uint32_t lr);
305
306/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100307 * \brief Set the current state of a partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100308 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100309 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100310 * \param[in] state The state to be set
311 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100312 * \note This function doesn't check if partition_idx is valid.
Gyorgy Szing40a7af02019-02-06 14:19:47 +0100313 * \note The state has to have the value set of \ref spm_part_state_t.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100314 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100315void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100316
317/**
Miklos Balint6a139ae2018-04-04 19:44:37 +0200318 * \brief Set the caller partition index for a given partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100319 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100320 * \param[in] partition_idx Partition index
Miklos Balint6a139ae2018-04-04 19:44:37 +0200321 * \param[in] caller_partition_idx The index of the caller partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100322 *
Miklos Balint6a139ae2018-04-04 19:44:37 +0200323 * \note This function doesn't check if any of the partition_idxs are valid.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100324 */
Miklos Balint6a139ae2018-04-04 19:44:37 +0200325void tfm_spm_partition_set_caller_partition_idx(uint32_t partition_idx,
326 uint32_t caller_partition_idx);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100327
328/**
Mate Toth-Pal21a74c92018-04-13 14:05:41 +0200329* \brief Set the caller client ID for a given partition
330*
331* \param[in] partition_idx Partition index
332* \param[in] caller_client_id The ID of the calling client
333*
334* \note This function doesn't check if any of the partition_idxs are valid.
335*/
336void tfm_spm_partition_set_caller_client_id(uint32_t partition_idx,
337 int32_t caller_client_id);
338
339/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100340 * \brief Set the buffer share region of the partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100341 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100342 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100343 * \param[in] share The buffer share region to be set
344 *
345 * \return Error code \ref spm_err_t
346 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100347 * \note This function doesn't check if partition_idx is valid.
Hugues de Valon99578562019-06-18 16:08:51 +0100348 * \note share has to have one of the buffer share values:
349 * - TFM_BUFFER_SHARE_DISABLE
350 * - TFM_BUFFER_SHARE_NS_CODE
351 * - TFM_BUFFER_SHARE_SCRATCH
352 * - TFM_BUFFER_SHARE_PRIV
353 * - TFM_BUFFER_SHARE_DEFAULT
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100354 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100355enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100356 uint32_t share);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100357
358/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200359 * \brief Set the iovec parameters for the partition
360 *
361 * \param[in] partition_idx Partition index
362 * \param[in] args The arguments of the secure function
363 *
364 * args is expected to be of type int32_t[4] where:
365 * args[0] is in_vec
366 * args[1] is in_len
367 * args[2] is out_vec
368 * args[3] is out_len
369 *
Hugues de Valonf704c802019-02-19 14:51:41 +0000370 * \return Error code \ref spm_err_t
371 *
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200372 * \note This function doesn't check if partition_idx is valid.
373 * \note This function assumes that the iovecs that are passed in args are
374 * valid, and does no sanity check on them at all.
375 */
Hugues de Valonf704c802019-02-19 14:51:41 +0000376enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
377 const int32_t *args);
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200378
379/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100380 * \brief Execute partition init function
Miklos Balint386b8b52017-11-29 13:12:32 +0000381 *
382 * \return Error code \ref spm_err_t
383 */
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100384enum spm_err_t tfm_spm_partition_init(void);
Miklos Balint386b8b52017-11-29 13:12:32 +0000385
386/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100387 * \brief Clears the context info from the database for a partition.
Miklos Balint386b8b52017-11-29 13:12:32 +0000388 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100389 * \param[in] partition_idx Partition index
Miklos Balint386b8b52017-11-29 13:12:32 +0000390 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100391 * \note This function doesn't check if partition_idx is valid.
Miklos Balint386b8b52017-11-29 13:12:32 +0000392 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100393void tfm_spm_partition_cleanup_context(uint32_t partition_idx);
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200394
395/**
396 * \brief Set the signal mask for a given partition
397 *
398 * \param[in] partition_idx Partition index
399 * \param[in] signal_mask The signal mask to be set for the partition
400 *
401 * \note This function doesn't check if any of the partition_idxs are valid.
402 */
403void tfm_spm_partition_set_signal_mask(uint32_t partition_idx,
404 uint32_t signal_mask);
Summer Qinb4a854d2019-05-29 15:31:22 +0800405#endif /* !defined(TFM_PSA_API) */
406
407/**
408 * \brief Initialize partition database
409 *
410 * \return Error code \ref spm_err_t
411 */
412enum spm_err_t tfm_spm_db_init(void);
Miklos Balint386b8b52017-11-29 13:12:32 +0000413
Edison Aib5571352019-03-22 10:49:52 +0800414/**
415 * \brief Change the privilege mode for partition thread mode.
416 *
417 * \param[in] privileged Privileged mode,
418 * \ref TFM_PARTITION_PRIVILEGED_MODE
419 * and \ref TFM_PARTITION_UNPRIVILEGED_MODE
420 *
421 * \note Barrier instructions are not called by this function, and if
422 * it is called in thread mode, it might be necessary to call
423 * them after this function returns (just like it is done in
424 * jump_to_ns_code()).
425 */
426void tfm_spm_partition_change_privilege(uint32_t privileged);
427
Mingyang Sunf3d29892019-07-10 17:50:23 +0800428#ifdef TFM_PSA_API
429
430#define TFM_SPM_MAX_ROT_SERV_NUM 48
431#define TFM_VERSION_POLICY_RELAXED 0
432#define TFM_VERSION_POLICY_STRICT 1
433
434#define TFM_CONN_HANDLE_MAX_NUM 32
435
436/* RoT connection handle list */
437struct tfm_conn_handle_t {
438 psa_handle_t handle; /* Handle value */
439 void *rhandle; /* Reverse handle value */
440 struct tfm_list_node_t list; /* list node */
441};
442
443/* Service database defined by manifest */
444struct tfm_spm_service_db_t {
445 char *name; /* Service name */
446 uint32_t partition_id; /* Partition ID which service belong to */
447 psa_signal_t signal; /* Service signal */
448 uint32_t sid; /* Service identifier */
449 bool non_secure_client; /* If can be called by non secure client */
450 uint32_t minor_version; /* Minor version */
451 uint32_t minor_policy; /* Minor version policy */
452};
453
454/* RoT Service data */
455struct tfm_spm_service_t {
456 struct tfm_spm_service_db_t *service_db; /* Service database pointer */
457 struct spm_partition_desc_t *partition; /*
458 * Point to secure partition
459 * data
460 */
461 struct tfm_list_node_t handle_list; /* Service handle list */
462 struct tfm_msg_queue_t msg_queue; /* Message queue */
463 struct tfm_list_node_t list; /* For list operation */
464};
465
466/*************************** Extended SPM functions **************************/
467
468/**
469 * \brief Get the running partition ID.
470 *
471 * \return Returns the partition ID
472 */
473uint32_t tfm_spm_partition_get_running_partition_id(void);
474
475/**
476 * \brief Get the current partition mode.
477 *
478 * \param[in] partition_idx Index of current partition
479 *
480 * \retval TFM_PARTITION_PRIVILEGED_MODE Privileged mode
481 * \retval TFM_PARTITION_UNPRIVILEGED_MODE Unprivileged mode
482 */
483uint32_t tfm_spm_partition_get_privileged_mode(uint32_t partition_idx);
484
485/******************** Service handle management functions ********************/
486
487/**
488 * \brief Create connection handle for client connect
489 *
490 * \param[in] service Target service context pointer
491 *
492 * \retval PSA_NULL_HANDLE Create failed \ref PSA_NULL_HANDLE
493 * \retval >0 Service handle created, \ref psa_handle_t
494 */
495psa_handle_t tfm_spm_create_conn_handle(struct tfm_spm_service_t *service);
496
497/**
498 * \brief Free connection handle which not used anymore.
499 *
500 * \param[in] service Target service context pointer
501 * \param[in] conn_handle Connection handle created by
502 * tfm_spm_create_conn_handle(), \ref psa_handle_t
503 *
504 * \retval IPC_SUCCESS Success
505 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
506 * \retval "Does not return" Panic for not find service by handle
507 */
508int32_t tfm_spm_free_conn_handle(struct tfm_spm_service_t *service,
509 psa_handle_t conn_handle);
510
511/**
512 * \brief Set reverse handle value for connection.
513 *
514 * \param[in] service Target service context pointer
515 * \param[in] conn_handle Connection handle created by
516 * tfm_spm_create_conn_handle(), \ref psa_handle_t
517 * \param[in] rhandle rhandle need to save
518 *
519 * \retval IPC_SUCCESS Success
520 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
521 * \retval "Does not return" Panic for not find handle node
522 */
523int32_t tfm_spm_set_rhandle(struct tfm_spm_service_t *service,
524 psa_handle_t conn_handle,
525 void *rhandle);
526
527/**
528 * \brief Get reverse handle value from connection hanlde.
529 *
530 * \param[in] service Target service context pointer
531 * \param[in] conn_handle Connection handle created by
532 * tfm_spm_create_conn_handle(), \ref psa_handle_t
533 *
534 * \retval void * Success
535 * \retval "Does not return" Panic for those:
536 * service pointer are NULL
537 * hanlde is \ref PSA_NULL_HANDLE
538 * handle node does not be found
539 */
540void *tfm_spm_get_rhandle(struct tfm_spm_service_t *service,
541 psa_handle_t conn_handle);
542
543/******************** Partition management functions *************************/
544
545/**
546 * \brief Get current running partition context.
547 *
548 * \retval NULL Failed
549 * \retval "Not NULL" Return the parttion context pointer
550 * \ref spm_partition_desc_t structures
551 */
552struct spm_partition_desc_t *tfm_spm_get_running_partition(void);
553
554/**
555 * \brief Get the service context by signal.
556 *
557 * \param[in] partition Partition context pointer
558 * \ref spm_partition_desc_t structures
559 * \param[in] signal Signal associated with inputs to the Secure
560 * Partition, \ref psa_signal_t
561 *
562 * \retval NULL Failed
563 * \retval "Not NULL" Target service context pointer,
564 * \ref tfm_spm_service_t structures
565 */
566struct tfm_spm_service_t *
567 tfm_spm_get_service_by_signal(struct spm_partition_desc_t *partition,
568 psa_signal_t signal);
569
570/**
571 * \brief Get the service context by service ID.
572 *
573 * \param[in] sid RoT Service identity
574 *
575 * \retval NULL Failed
576 * \retval "Not NULL" Target service context pointer,
577 * \ref tfm_spm_service_t structures
578 */
579struct tfm_spm_service_t *tfm_spm_get_service_by_sid(uint32_t sid);
580
581/**
582 * \brief Get the service context by connection handle.
583 *
584 * \param[in] conn_handle Connection handle created by
585 * tfm_spm_create_conn_handle()
586 *
587 * \retval NULL Failed
588 * \retval "Not NULL" Target service context pointer,
589 * \ref tfm_spm_service_t structures
590 */
591struct tfm_spm_service_t *
592 tfm_spm_get_service_by_handle(psa_handle_t conn_handle);
593
594/**
595 * \brief Get the partition context by partition ID.
596 *
597 * \param[in] partition_id Partition identity
598 *
599 * \retval NULL Failed
600 * \retval "Not NULL" Target partition context pointer,
601 * \ref spm_partition_desc_t structures
602 */
603struct spm_partition_desc_t *
604 tfm_spm_get_partition_by_id(int32_t partition_id);
605
606/************************ Message functions **********************************/
607
608/**
609 * \brief Get message context by message handle.
610 *
611 * \param[in] msg_handle Message handle which is a reference generated
612 * by the SPM to a specific message.
613 *
614 * \return The message body context pointer
615 * \ref tfm_msg_body_t structures
616 */
617struct tfm_msg_body_t *tfm_spm_get_msg_from_handle(psa_handle_t msg_handle);
618
619/**
620 * \brief Create a message for PSA client call.
621 *
622 * \param[in] service Target service context pointer, which can be
623 * obtained by partition management functions
624 * \prarm[in] handle Connect handle return by psa_connect().
625 * \param[in] type Message type, PSA_IPC_CONNECT, PSA_IPC_CALL or
626 * PSA_IPC_DISCONNECT
627 * \param[in] ns_caller Whether from NS caller
628 * \param[in] invec Array of input \ref psa_invec structures
629 * \param[in] in_len Number of input \ref psa_invec structures
630 * \param[in] outvec Array of output \ref psa_outvec structures
631 * \param[in] out_len Number of output \ref psa_outvec structures
632 * \param[in] caller_outvec Array of caller output \ref psa_outvec structures
633 *
634 * \retval NULL Failed
635 * \retval "Not NULL" New message body pointer \ref tfm_msg_body_t
636 * structures
637 */
638struct tfm_msg_body_t *tfm_spm_create_msg(struct tfm_spm_service_t *service,
639 psa_handle_t handle,
640 int32_t type, int32_t ns_caller,
641 psa_invec *invec, size_t in_len,
642 psa_outvec *outvec, size_t out_len,
643 psa_outvec *caller_outvec);
644
645/**
646 * \brief Free message which unused anymore
647 *
648 * \param[in] msg Message pointer which want to free
649 * \ref tfm_msg_body_t structures
650 *
651 * \retval void Success
652 * \retval "Does not return" Failed
653 */
654void tfm_spm_free_msg(struct tfm_msg_body_t *msg);
655
656/**
657 * \brief Send message and wake up the SP who is waiting on
658 * message queue, block the current thread and
659 * scheduler triggered
660 *
661 * \param[in] service Target service context pointer, which can be
662 * obtained by partition management functions
663 * \param[in] msg message created by tfm_spm_create_msg()
664 * \ref tfm_msg_body_t structures
665 *
666 * \retval IPC_SUCCESS Success
667 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
668 * \retval IPC_ERROR_GENERIC Failed to enqueue message to service message queue
669 */
670int32_t tfm_spm_send_event(struct tfm_spm_service_t *service,
671 struct tfm_msg_body_t *msg);
672
673/**
674 * \brief Check the client minor version according to
675 * version policy
676 *
677 * \param[in] service Target service context pointer, which can be get
678 * by partition management functions
679 * \param[in] minor_version Client support minor version
680 *
681 * \retval IPC_SUCCESS Success
682 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
683 * \retval IPC_ERROR_VERSION Check failed
684 */
685int32_t tfm_spm_check_client_version(struct tfm_spm_service_t *service,
686 uint32_t minor_version);
687
688/**
689 * \brief Check the memory reference is valid.
690 *
691 * \param[in] buffer Pointer of memory reference
692 * \param[in] len Length of memory reference in bytes
693 * \param[in] ns_caller From non-secure caller
694 * \param[in] access Type of access specified by the
695 * \ref tfm_memory_access_e
696 * \param[in] privileged Privileged mode or unprivileged mode:
697 * \ref TFM_PARTITION_UNPRIVILEGED_MODE
698 * \ref TFM_PARTITION_PRIVILEGED_MODE
699 *
700 * \retval IPC_SUCCESS Success
701 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
702 * \retval IPC_ERROR_MEMORY_CHECK Check failed
703 */
704int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller,
705 enum tfm_memory_access_e access,
706 uint32_t privileged);
707
708/* This function should be called before schedule function */
709void tfm_spm_init(void);
710
711/*
712 * PendSV specified function.
713 *
714 * Parameters :
715 * ctxb - State context storage pointer
716 *
717 * Notes:
718 * This is a staging API. Scheduler should be called in SPM finally and
719 * this function will be obsoleted later.
720 */
721void tfm_pendsv_do_schedule(struct tfm_state_context_ext *ctxb);
722
723#endif /* ifdef(TFM_PSA_API) */
724
Miklos Balint386b8b52017-11-29 13:12:32 +0000725#endif /*__SPM_API_H__ */