blob: 33118b171db73f7f0f652fef43b9e7d1556138b0 [file] [log] [blame]
Miklos Balint386b8b52017-11-29 13:12:32 +00001/*
Mate Toth-Pal5e6d0342019-11-22 11:43:20 +01002 * Copyright (c) 2017-2020, 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"
David Hu49a28eb2019-08-14 18:18:15 +080014#include "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"
Summer Qinb5da9cc2019-08-26 15:19:45 +080021#include "tfm_thread.h"
Edison Ai66fbdf12019-07-08 16:05:07 +080022#endif
Miklos Balint386b8b52017-11-29 13:12:32 +000023
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010024#define SPM_INVALID_PARTITION_IDX (~0U)
25
Summer Qineb537e52019-03-29 09:57:10 +080026/* Privileged definitions for partition thread mode */
27#define TFM_PARTITION_PRIVILEGED_MODE 1
28#define TFM_PARTITION_UNPRIVILEGED_MODE 0
29
Miklos Balint386b8b52017-11-29 13:12:32 +000030enum spm_err_t {
31 SPM_ERR_OK = 0,
Mate Toth-Pal349714a2018-02-23 15:30:24 +010032 SPM_ERR_PARTITION_DB_NOT_INIT,
33 SPM_ERR_PARTITION_ALREADY_ACTIVE,
34 SPM_ERR_PARTITION_NOT_AVAILABLE,
Hugues de Valonf704c802019-02-19 14:51:41 +000035 SPM_ERR_INVALID_PARAMETER,
Miklos Balint386b8b52017-11-29 13:12:32 +000036 SPM_ERR_INVALID_CONFIG,
37};
38
Hugues de Valon99578562019-06-18 16:08:51 +010039#define SPM_PARTITION_STATE_UNINIT 0
40#define SPM_PARTITION_STATE_IDLE 1
41#define SPM_PARTITION_STATE_RUNNING 2
42#define SPM_PARTITION_STATE_HANDLING_IRQ 3
43#define SPM_PARTITION_STATE_SUSPENDED 4
44#define SPM_PARTITION_STATE_BLOCKED 5
45#define SPM_PARTITION_STATE_CLOSED 6
Mate Toth-Pal65291f32018-02-23 14:35:22 +010046
Hugues de Valon99578562019-06-18 16:08:51 +010047#define SPM_PART_FLAG_APP_ROT 0x01
48#define SPM_PART_FLAG_PSA_ROT 0x02
49#define SPM_PART_FLAG_IPC 0x04
Mate Toth-Pal59398712018-02-28 17:06:40 +010050
Shawn Shancc39fcb2019-11-13 15:38:16 +080051#define TFM_HANDLE_STATUS_IDLE 0
52#define TFM_HANDLE_STATUS_ACTIVE 1
Shawn Shanadb02862019-12-10 11:04:33 +080053#define TFM_HANDLE_STATUS_CONNECT_ERROR 2
Shawn Shancc39fcb2019-11-13 15:38:16 +080054
Edison Ai66fbdf12019-07-08 16:05:07 +080055#ifndef TFM_PSA_API
Miklos Balint386b8b52017-11-29 13:12:32 +000056/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020057 * \brief Holds the iovec parameters that are passed to a service
58 *
59 * \note The size of the structure is (and have to be) multiple of 8 bytes
60 */
61struct iovec_args_t {
62 psa_invec in_vec[PSA_MAX_IOVEC]; /*!< Array of psa_invec objects */
63 size_t in_len; /*!< Number psa_invec objects in in_vec
64 */
65 psa_outvec out_vec[PSA_MAX_IOVEC]; /*!< Array of psa_outvec objects */
66 size_t out_len; /*!< Number psa_outvec objects in out_vec
67 */
68};
Mingyang Sunda01a972019-07-12 17:32:59 +080069
70/* The size of this struct must be multiple of 4 bytes as it is stacked to an
71 * uint32_t[] array
72 */
73struct interrupted_ctx_stack_frame_t {
Mingyang Sunda01a972019-07-12 17:32:59 +080074 uint32_t partition_state;
75};
76
77/* The size of this struct must be multiple of 4 bytes as it is stacked to an
78 * uint32_t[] array
79 */
80struct handler_ctx_stack_frame_t {
81 uint32_t partition_state;
82 uint32_t caller_partition_idx;
83};
Edison Ai66fbdf12019-07-08 16:05:07 +080084#endif /* !define(TFM_PSA_API) */
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020085
86/**
Mate Toth-Pal18b83922018-02-26 17:58:18 +010087 * \brief Runtime context information of a partition
88 */
89struct spm_partition_runtime_data_t {
Edison Ai66fbdf12019-07-08 16:05:07 +080090#ifdef TFM_PSA_API
91 struct tfm_event_t signal_evnt; /* Event signal */
92 uint32_t signals; /* Service signals had been triggered*/
93 struct tfm_list_node_t service_list;/* Service list */
Summer Qin66f1e032020-01-06 15:40:03 +080094 struct tfm_core_thread_t sp_thrd; /* Thread object */
Shawn Shan9b0e0c72019-10-22 13:43:07 +080095 uint32_t assigned_signals; /* All assigned signals */
Edison Ai66fbdf12019-07-08 16:05:07 +080096#else /* TFM_PSA_API */
Mate Toth-Pal18b83922018-02-26 17:58:18 +010097 uint32_t partition_state;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010098 uint32_t caller_partition_idx;
Mate Toth-Pal21a74c92018-04-13 14:05:41 +020099 int32_t caller_client_id;
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100100 uint32_t stack_ptr;
Miklos Balintace4c3f2018-07-30 12:31:15 +0200101 uint32_t lr;
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200102 struct iovec_args_t iovec_args;
103 psa_outvec *orig_outvec;
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200104 uint32_t *ctx_stack_ptr;
Edison Ai66fbdf12019-07-08 16:05:07 +0800105#endif /* TFM_PSA_API */
106 uint32_t signal_mask; /*
107 * Service signal mask passed by
108 * psa_wait()
109 */
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100110};
111
Mingyang Sunda01a972019-07-12 17:32:59 +0800112#ifdef TFM_PSA_API
113
Mingyang Sunda01a972019-07-12 17:32:59 +0800114#define TFM_VERSION_POLICY_RELAXED 0
115#define TFM_VERSION_POLICY_STRICT 1
116
Edison Ai97115822019-08-01 14:22:19 +0800117#define TFM_CONN_HANDLE_MAX_NUM 16
Mingyang Sunda01a972019-07-12 17:32:59 +0800118
119/* RoT connection handle list */
120struct tfm_conn_handle_t {
Edison Ai9cc26242019-08-06 11:28:04 +0800121 void *rhandle; /* Reverse handle value */
Shawn Shancc39fcb2019-11-13 15:38:16 +0800122 uint32_t status; /*
Shawn Shanadb02862019-12-10 11:04:33 +0800123 * Status of handle, three valid
124 * options:
125 * TFM_HANDLE_STATUS_ACTIVE,
126 * TFM_HANDLE_STATUS_IDLE and
127 * TFM_HANDLE_STATUS_CONNECT_ERROR
Shawn Shancc39fcb2019-11-13 15:38:16 +0800128 */
Summer Qin1ce712a2019-10-14 18:04:05 +0800129 int32_t client_id; /*
130 * Partition ID of the sender of the
131 * message:
132 * - secure partition id;
133 * - non secure client endpoint id.
134 */
Edison Ai97115822019-08-01 14:22:19 +0800135 struct tfm_msg_body_t internal_msg; /* Internal message for message queue */
Edison Ai9cc26242019-08-06 11:28:04 +0800136 struct tfm_spm_service_t *service; /* RoT service pointer */
137 struct tfm_list_node_t list; /* list node */
Mingyang Sunda01a972019-07-12 17:32:59 +0800138};
139
140/* Service database defined by manifest */
141struct tfm_spm_service_db_t {
142 char *name; /* Service name */
143 uint32_t partition_id; /* Partition ID which service belong to */
144 psa_signal_t signal; /* Service signal */
145 uint32_t sid; /* Service identifier */
146 bool non_secure_client; /* If can be called by non secure client */
Shawn Shancc39fcb2019-11-13 15:38:16 +0800147 uint32_t version; /* Service version */
148 uint32_t version_policy; /* Service version policy */
Mingyang Sunda01a972019-07-12 17:32:59 +0800149};
150
151/* RoT Service data */
152struct tfm_spm_service_t {
Summer Qine578c5b2019-08-16 16:42:16 +0800153 const struct tfm_spm_service_db_t *service_db;/* Service database pointer */
Mingyang Sunda01a972019-07-12 17:32:59 +0800154 struct spm_partition_desc_t *partition; /*
155 * Point to secure partition
156 * data
157 */
158 struct tfm_list_node_t handle_list; /* Service handle list */
159 struct tfm_msg_queue_t msg_queue; /* Message queue */
160 struct tfm_list_node_t list; /* For list operation */
161};
162#endif /* ifdef(TFM_PSA_API) */
163
164/*********************** common definitions ***********************/
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100165
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100166/**
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100167 * \brief Returns the index of the partition with the given partition ID.
Miklos Balint386b8b52017-11-29 13:12:32 +0000168 *
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100169 * \param[in] partition_id Partition id
Miklos Balint386b8b52017-11-29 13:12:32 +0000170 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100171 * \return the partition idx if partition_id is valid,
172 * \ref SPM_INVALID_PARTITION_IDX othervise
173 */
174uint32_t get_partition_idx(uint32_t partition_id);
175
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200176/**
Summer Qinb4a854d2019-05-29 15:31:22 +0800177 * \brief Get the id of the partition for its index from the db
178 *
179 * \param[in] partition_idx Partition index
180 *
181 * \return Partition ID for that partition
182 *
183 * \note This function doesn't check if partition_idx is valid.
184 */
185uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx);
186
187/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200188 * \brief Get the flags associated with a partition
189 *
190 * \param[in] partition_idx Partition index
191 *
192 * \return Flags associated with the partition
193 *
194 * \note This function doesn't check if partition_idx is valid.
195 */
196uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx);
197
Mingyang Sunda01a972019-07-12 17:32:59 +0800198/**
199 * \brief Initialize partition database
200 *
201 * \return Error code \ref spm_err_t
202 */
203enum spm_err_t tfm_spm_db_init(void);
204
205/**
206 * \brief Change the privilege mode for partition thread mode.
207 *
208 * \param[in] privileged Privileged mode,
209 * \ref TFM_PARTITION_PRIVILEGED_MODE
210 * and \ref TFM_PARTITION_UNPRIVILEGED_MODE
211 *
212 * \note Barrier instructions are not called by this function, and if
213 * it is called in thread mode, it might be necessary to call
Edison Ai7aff9e82019-07-11 14:56:46 +0800214 * them after this function returns.
Mingyang Sunda01a972019-07-12 17:32:59 +0800215 */
216void tfm_spm_partition_change_privilege(uint32_t privileged);
217
Mate Toth-Pal5e6d0342019-11-22 11:43:20 +0100218/**
219 * \brief Get the current partition mode.
220 *
221 * \param[in] partition_flags Flags of current partition
222 *
223 * \retval TFM_PARTITION_PRIVILEGED_MODE Privileged mode
224 * \retval TFM_PARTITION_UNPRIVILEGED_MODE Unprivileged mode
225 */
226uint32_t tfm_spm_partition_get_privileged_mode(uint32_t partition_flags);
227
Mingyang Sunda01a972019-07-12 17:32:59 +0800228/*********************** library definitions ***********************/
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
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100336
337/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200338 * \brief Set the iovec parameters for the partition
339 *
340 * \param[in] partition_idx Partition index
341 * \param[in] args The arguments of the secure function
342 *
343 * args is expected to be of type int32_t[4] where:
344 * args[0] is in_vec
345 * args[1] is in_len
346 * args[2] is out_vec
347 * args[3] is out_len
348 *
Hugues de Valonf704c802019-02-19 14:51:41 +0000349 * \return Error code \ref spm_err_t
350 *
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200351 * \note This function doesn't check if partition_idx is valid.
352 * \note This function assumes that the iovecs that are passed in args are
353 * valid, and does no sanity check on them at all.
354 */
Hugues de Valonf704c802019-02-19 14:51:41 +0000355enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
356 const int32_t *args);
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200357
358/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100359 * \brief Execute partition init function
Miklos Balint386b8b52017-11-29 13:12:32 +0000360 *
361 * \return Error code \ref spm_err_t
362 */
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100363enum spm_err_t tfm_spm_partition_init(void);
Miklos Balint386b8b52017-11-29 13:12:32 +0000364
365/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100366 * \brief Clears the context info from the database for a partition.
Miklos Balint386b8b52017-11-29 13:12:32 +0000367 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100368 * \param[in] partition_idx Partition index
Miklos Balint386b8b52017-11-29 13:12:32 +0000369 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100370 * \note This function doesn't check if partition_idx is valid.
Miklos Balint386b8b52017-11-29 13:12:32 +0000371 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100372void tfm_spm_partition_cleanup_context(uint32_t partition_idx);
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200373
374/**
375 * \brief Set the signal mask for a given partition
376 *
377 * \param[in] partition_idx Partition index
378 * \param[in] signal_mask The signal mask to be set for the partition
379 *
380 * \note This function doesn't check if any of the partition_idxs are valid.
381 */
382void tfm_spm_partition_set_signal_mask(uint32_t partition_idx,
383 uint32_t signal_mask);
Summer Qinb4a854d2019-05-29 15:31:22 +0800384#endif /* !defined(TFM_PSA_API) */
385
Mingyang Sunf3d29892019-07-10 17:50:23 +0800386#ifdef TFM_PSA_API
Mingyang Sunda01a972019-07-12 17:32:59 +0800387/*************************** IPC definitions **************************/
Edison Ai7aff9e82019-07-11 14:56:46 +0800388
389/**
390 * \brief Get bottom of stack region for a partition
391 *
392 * \param[in] partition_idx Partition index
393 *
394 * \return Stack region bottom value
395 *
396 * \note This function doesn't check if partition_idx is valid.
397 */
398uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx);
399
400/**
401 * \brief Get top of stack region for a partition
402 *
403 * \param[in] partition_idx Partition index
404 *
405 * \return Stack region top value
406 *
407 * \note This function doesn't check if partition_idx is valid.
408 */
409uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800410
411/**
412 * \brief Get the running partition ID.
413 *
414 * \return Returns the partition ID
415 */
416uint32_t tfm_spm_partition_get_running_partition_id(void);
417
Mingyang Sunf3d29892019-07-10 17:50:23 +0800418/******************** Service handle management functions ********************/
419
420/**
421 * \brief Create connection handle for client connect
422 *
423 * \param[in] service Target service context pointer
Summer Qin1ce712a2019-10-14 18:04:05 +0800424 * \param[in] client_id Partition ID of the sender of the message
Mingyang Sunf3d29892019-07-10 17:50:23 +0800425 *
426 * \retval PSA_NULL_HANDLE Create failed \ref PSA_NULL_HANDLE
427 * \retval >0 Service handle created, \ref psa_handle_t
428 */
Summer Qin1ce712a2019-10-14 18:04:05 +0800429psa_handle_t tfm_spm_create_conn_handle(struct tfm_spm_service_t *service,
430 int32_t client_id);
431
432/**
433 * \brief Validate connection handle for client connect
434 *
435 * \param[in] conn_handle Handle to be validated
436 * \param[in] client_id Partition ID of the sender of the message
437 *
438 * \retval IPC_SUCCESS Success
439 * \retval IPC_ERROR_GENERIC Invalid handle
440 */
441int32_t tfm_spm_validate_conn_handle(psa_handle_t conn_handle,
442 int32_t client_id);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800443
444/**
445 * \brief Free connection handle which not used anymore.
446 *
447 * \param[in] service Target service context pointer
448 * \param[in] conn_handle Connection handle created by
449 * tfm_spm_create_conn_handle(), \ref psa_handle_t
450 *
451 * \retval IPC_SUCCESS Success
452 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
453 * \retval "Does not return" Panic for not find service by handle
454 */
455int32_t tfm_spm_free_conn_handle(struct tfm_spm_service_t *service,
456 psa_handle_t conn_handle);
457
458/**
459 * \brief Set reverse handle value for connection.
460 *
461 * \param[in] service Target service context pointer
462 * \param[in] conn_handle Connection handle created by
463 * tfm_spm_create_conn_handle(), \ref psa_handle_t
464 * \param[in] rhandle rhandle need to save
465 *
466 * \retval IPC_SUCCESS Success
467 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
468 * \retval "Does not return" Panic for not find handle node
469 */
470int32_t tfm_spm_set_rhandle(struct tfm_spm_service_t *service,
471 psa_handle_t conn_handle,
472 void *rhandle);
473
474/**
475 * \brief Get reverse handle value from connection hanlde.
476 *
477 * \param[in] service Target service context pointer
478 * \param[in] conn_handle Connection handle created by
479 * tfm_spm_create_conn_handle(), \ref psa_handle_t
480 *
481 * \retval void * Success
482 * \retval "Does not return" Panic for those:
483 * service pointer are NULL
484 * hanlde is \ref PSA_NULL_HANDLE
485 * handle node does not be found
486 */
487void *tfm_spm_get_rhandle(struct tfm_spm_service_t *service,
488 psa_handle_t conn_handle);
489
490/******************** Partition management functions *************************/
491
492/**
493 * \brief Get current running partition context.
494 *
495 * \retval NULL Failed
496 * \retval "Not NULL" Return the parttion context pointer
497 * \ref spm_partition_desc_t structures
498 */
499struct spm_partition_desc_t *tfm_spm_get_running_partition(void);
500
501/**
502 * \brief Get the service context by signal.
503 *
504 * \param[in] partition Partition context pointer
505 * \ref spm_partition_desc_t structures
506 * \param[in] signal Signal associated with inputs to the Secure
507 * Partition, \ref psa_signal_t
508 *
509 * \retval NULL Failed
510 * \retval "Not NULL" Target service context pointer,
511 * \ref tfm_spm_service_t structures
512 */
513struct tfm_spm_service_t *
514 tfm_spm_get_service_by_signal(struct spm_partition_desc_t *partition,
515 psa_signal_t signal);
516
517/**
518 * \brief Get the service context by service ID.
519 *
520 * \param[in] sid RoT Service identity
521 *
522 * \retval NULL Failed
523 * \retval "Not NULL" Target service context pointer,
524 * \ref tfm_spm_service_t structures
525 */
526struct tfm_spm_service_t *tfm_spm_get_service_by_sid(uint32_t sid);
527
528/**
529 * \brief Get the service context by connection handle.
530 *
531 * \param[in] conn_handle Connection handle created by
532 * tfm_spm_create_conn_handle()
533 *
534 * \retval NULL Failed
535 * \retval "Not NULL" Target service context pointer,
536 * \ref tfm_spm_service_t structures
537 */
538struct tfm_spm_service_t *
539 tfm_spm_get_service_by_handle(psa_handle_t conn_handle);
540
541/**
542 * \brief Get the partition context by partition ID.
543 *
544 * \param[in] partition_id Partition identity
545 *
546 * \retval NULL Failed
547 * \retval "Not NULL" Target partition context pointer,
548 * \ref spm_partition_desc_t structures
549 */
550struct spm_partition_desc_t *
551 tfm_spm_get_partition_by_id(int32_t partition_id);
552
553/************************ Message functions **********************************/
554
555/**
556 * \brief Get message context by message handle.
557 *
558 * \param[in] msg_handle Message handle which is a reference generated
559 * by the SPM to a specific message.
560 *
561 * \return The message body context pointer
562 * \ref tfm_msg_body_t structures
563 */
564struct tfm_msg_body_t *tfm_spm_get_msg_from_handle(psa_handle_t msg_handle);
565
566/**
Edison Ai97115822019-08-01 14:22:19 +0800567 * \brief Get message context by connect handle.
Mingyang Sunf3d29892019-07-10 17:50:23 +0800568 *
Edison Ai97115822019-08-01 14:22:19 +0800569 * \param[in] conn_handle Service connect handle.
570 *
571 * \return The message body context pointer
572 * \ref msg_body_t structures
573 */
574struct tfm_msg_body_t *
575 tfm_spm_get_msg_buffer_from_conn_handle(psa_handle_t conn_handle);
576
577/**
578 * \brief Fill the message for PSA client call.
579 *
580 * \param[in] msg Service Message Queue buffer pointer
Mingyang Sunf3d29892019-07-10 17:50:23 +0800581 * \param[in] service Target service context pointer, which can be
582 * obtained by partition management functions
583 * \prarm[in] handle Connect handle return by psa_connect().
584 * \param[in] type Message type, PSA_IPC_CONNECT, PSA_IPC_CALL or
585 * PSA_IPC_DISCONNECT
Summer Qin1ce712a2019-10-14 18:04:05 +0800586 * \param[in] client_id Partition ID of the sender of the message
Mingyang Sunf3d29892019-07-10 17:50:23 +0800587 * \param[in] invec Array of input \ref psa_invec structures
588 * \param[in] in_len Number of input \ref psa_invec structures
589 * \param[in] outvec Array of output \ref psa_outvec structures
590 * \param[in] out_len Number of output \ref psa_outvec structures
591 * \param[in] caller_outvec Array of caller output \ref psa_outvec structures
Mingyang Sunf3d29892019-07-10 17:50:23 +0800592 */
Edison Ai97115822019-08-01 14:22:19 +0800593void tfm_spm_fill_msg(struct tfm_msg_body_t *msg,
594 struct tfm_spm_service_t *service,
595 psa_handle_t handle,
Summer Qin1ce712a2019-10-14 18:04:05 +0800596 int32_t type, int32_t client_id,
Edison Ai97115822019-08-01 14:22:19 +0800597 psa_invec *invec, size_t in_len,
598 psa_outvec *outvec, size_t out_len,
599 psa_outvec *caller_outvec);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800600
601/**
602 * \brief Send message and wake up the SP who is waiting on
603 * message queue, block the current thread and
604 * scheduler triggered
605 *
606 * \param[in] service Target service context pointer, which can be
607 * obtained by partition management functions
608 * \param[in] msg message created by tfm_spm_create_msg()
609 * \ref tfm_msg_body_t structures
610 *
611 * \retval IPC_SUCCESS Success
612 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
613 * \retval IPC_ERROR_GENERIC Failed to enqueue message to service message queue
614 */
615int32_t tfm_spm_send_event(struct tfm_spm_service_t *service,
616 struct tfm_msg_body_t *msg);
617
618/**
Jaykumar Pitambarbhai Patel3a986022019-10-08 17:37:15 +0530619 * \brief Check the client version according to
Mingyang Sunf3d29892019-07-10 17:50:23 +0800620 * version policy
621 *
622 * \param[in] service Target service context pointer, which can be get
623 * by partition management functions
Jaykumar Pitambarbhai Patel3a986022019-10-08 17:37:15 +0530624 * \param[in] version Client support version
Mingyang Sunf3d29892019-07-10 17:50:23 +0800625 *
626 * \retval IPC_SUCCESS Success
627 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
628 * \retval IPC_ERROR_VERSION Check failed
629 */
630int32_t tfm_spm_check_client_version(struct tfm_spm_service_t *service,
Jaykumar Pitambarbhai Patel3a986022019-10-08 17:37:15 +0530631 uint32_t version);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800632
633/**
Edison Aie728fbf2019-11-13 09:37:12 +0800634 * \brief Check the client access authorization
635 *
636 * \param[in] sid Target RoT Service identity
637 * \param[in] service Target service context pointer, which can be get
638 * by partition management functions
639 * \param[in] ns_caller Whether from NS caller
640 *
641 * \retval IPC_SUCCESS Success
642 * \retval IPC_ERROR_GENERIC Authorization check failed
643 */
644int32_t tfm_spm_check_authorization(uint32_t sid,
645 struct tfm_spm_service_t *service,
Summer Qin618e8c32019-12-09 10:47:20 +0800646 bool ns_caller);
Edison Aie728fbf2019-11-13 09:37:12 +0800647
648/**
Mingyang Sunf3d29892019-07-10 17:50:23 +0800649 * \brief Check the memory reference is valid.
650 *
651 * \param[in] buffer Pointer of memory reference
652 * \param[in] len Length of memory reference in bytes
653 * \param[in] ns_caller From non-secure caller
654 * \param[in] access Type of access specified by the
655 * \ref tfm_memory_access_e
656 * \param[in] privileged Privileged mode or unprivileged mode:
657 * \ref TFM_PARTITION_UNPRIVILEGED_MODE
658 * \ref TFM_PARTITION_PRIVILEGED_MODE
659 *
660 * \retval IPC_SUCCESS Success
661 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
662 * \retval IPC_ERROR_MEMORY_CHECK Check failed
663 */
Summer Qin43c185d2019-10-10 15:44:42 +0800664int32_t tfm_memory_check(const void *buffer, size_t len, bool ns_caller,
Mingyang Sunf3d29892019-07-10 17:50:23 +0800665 enum tfm_memory_access_e access,
666 uint32_t privileged);
667
Mingyang Sunf3d29892019-07-10 17:50:23 +0800668/*
669 * PendSV specified function.
670 *
671 * Parameters :
Summer Qind2ad7e72020-01-06 18:16:35 +0800672 * p_actx - Architecture context storage pointer
Mingyang Sunf3d29892019-07-10 17:50:23 +0800673 *
674 * Notes:
675 * This is a staging API. Scheduler should be called in SPM finally and
676 * this function will be obsoleted later.
677 */
Summer Qind2ad7e72020-01-06 18:16:35 +0800678void tfm_pendsv_do_schedule(struct tfm_arch_ctx_t *p_actx);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800679
Ken Liu490281d2019-12-30 15:55:26 +0800680/**
681 * \brief SPM initialization implementation
682 *
683 * \details This function must be called under handler mode.
Ken Liuce2692d2020-02-11 12:39:36 +0800684 * \retval This function returns an EXC_RETURN value. Other
685 * faults would panic the execution and never
686 * returned.
Ken Liu490281d2019-12-30 15:55:26 +0800687 */
Ken Liuce2692d2020-02-11 12:39:36 +0800688uint32_t tfm_spm_init(void);
Ken Liu490281d2019-12-30 15:55:26 +0800689
Shawn Shan6e7be072019-11-29 17:56:29 +0800690
691/*
692 * \brief This function get the current PSA RoT lifecycle state.
693 *
694 * \return state The current security lifecycle state of the PSA
695 * RoT. The PSA state and implementation state are
696 * encoded as follows:
697 * \arg state[15:8] – PSA lifecycle state
698 * \arg state[7:0] – IMPLEMENTATION DEFINED state
699 */
700uint32_t tfm_spm_get_lifecycle_state(void);
701
Mingyang Sunf3d29892019-07-10 17:50:23 +0800702#endif /* ifdef(TFM_PSA_API) */
703
Miklos Balint386b8b52017-11-29 13:12:32 +0000704#endif /*__SPM_API_H__ */