blob: 3edd8a8679b3d123ea81868db04b950e6a02241f [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"
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"
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};
Mingyang Sunda01a972019-07-12 17:32:59 +080064
65/* The size of this struct must be multiple of 4 bytes as it is stacked to an
66 * uint32_t[] array
67 */
68struct interrupted_ctx_stack_frame_t {
Mingyang Sunda01a972019-07-12 17:32:59 +080069 uint32_t partition_state;
70};
71
72/* The size of this struct must be multiple of 4 bytes as it is stacked to an
73 * uint32_t[] array
74 */
75struct handler_ctx_stack_frame_t {
76 uint32_t partition_state;
77 uint32_t caller_partition_idx;
78};
Edison Ai66fbdf12019-07-08 16:05:07 +080079#endif /* !define(TFM_PSA_API) */
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020080
81/**
Mate Toth-Pal18b83922018-02-26 17:58:18 +010082 * \brief Runtime context information of a partition
83 */
84struct spm_partition_runtime_data_t {
Edison Ai66fbdf12019-07-08 16:05:07 +080085#ifdef TFM_PSA_API
86 struct tfm_event_t signal_evnt; /* Event signal */
87 uint32_t signals; /* Service signals had been triggered*/
88 struct tfm_list_node_t service_list;/* Service list */
89#else /* TFM_PSA_API */
Mate Toth-Pal18b83922018-02-26 17:58:18 +010090 uint32_t partition_state;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +010091 uint32_t caller_partition_idx;
Mate Toth-Pal21a74c92018-04-13 14:05:41 +020092 int32_t caller_client_id;
Mate Toth-Pal18b83922018-02-26 17:58:18 +010093 uint32_t share;
Mate Toth-Pal18b83922018-02-26 17:58:18 +010094 uint32_t stack_ptr;
Miklos Balintace4c3f2018-07-30 12:31:15 +020095 uint32_t lr;
Mate Toth-Pal2a6f8c22018-12-13 16:37:17 +010096 int32_t iovec_api; /*!< Whether the function in the partition
97 * had been called using the iovec API.
98 * FIXME: Remove the field once this is the
99 * only option
100 */
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200101 struct iovec_args_t iovec_args;
102 psa_outvec *orig_outvec;
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200103 uint32_t *ctx_stack_ptr;
Edison Ai66fbdf12019-07-08 16:05:07 +0800104#endif /* TFM_PSA_API */
105 uint32_t signal_mask; /*
106 * Service signal mask passed by
107 * psa_wait()
108 */
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100109};
110
Mingyang Sunda01a972019-07-12 17:32:59 +0800111#ifdef TFM_PSA_API
112
Mingyang Sunda01a972019-07-12 17:32:59 +0800113#define TFM_VERSION_POLICY_RELAXED 0
114#define TFM_VERSION_POLICY_STRICT 1
115
Edison Ai97115822019-08-01 14:22:19 +0800116#define TFM_CONN_HANDLE_MAX_NUM 16
Mingyang Sunda01a972019-07-12 17:32:59 +0800117
118/* RoT connection handle list */
119struct tfm_conn_handle_t {
Edison Ai9cc26242019-08-06 11:28:04 +0800120 void *rhandle; /* Reverse handle value */
Edison Ai97115822019-08-01 14:22:19 +0800121 struct tfm_msg_body_t internal_msg; /* Internal message for message queue */
Edison Ai9cc26242019-08-06 11:28:04 +0800122 struct tfm_spm_service_t *service; /* RoT service pointer */
123 struct tfm_list_node_t list; /* list node */
Mingyang Sunda01a972019-07-12 17:32:59 +0800124};
125
126/* Service database defined by manifest */
127struct tfm_spm_service_db_t {
128 char *name; /* Service name */
129 uint32_t partition_id; /* Partition ID which service belong to */
130 psa_signal_t signal; /* Service signal */
131 uint32_t sid; /* Service identifier */
132 bool non_secure_client; /* If can be called by non secure client */
133 uint32_t minor_version; /* Minor version */
134 uint32_t minor_policy; /* Minor version policy */
135};
136
137/* RoT Service data */
138struct tfm_spm_service_t {
Summer Qind99509f2019-08-02 17:36:58 +0800139 struct tfm_spm_service_db_t service_db; /* Service database pointer */
Mingyang Sunda01a972019-07-12 17:32:59 +0800140 struct spm_partition_desc_t *partition; /*
141 * Point to secure partition
142 * data
143 */
144 struct tfm_list_node_t handle_list; /* Service handle list */
145 struct tfm_msg_queue_t msg_queue; /* Message queue */
146 struct tfm_list_node_t list; /* For list operation */
147};
148#endif /* ifdef(TFM_PSA_API) */
149
150/*********************** common definitions ***********************/
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100151
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100152/**
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100153 * \brief Returns the index of the partition with the given partition ID.
Miklos Balint386b8b52017-11-29 13:12:32 +0000154 *
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100155 * \param[in] partition_id Partition id
Miklos Balint386b8b52017-11-29 13:12:32 +0000156 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100157 * \return the partition idx if partition_id is valid,
158 * \ref SPM_INVALID_PARTITION_IDX othervise
159 */
160uint32_t get_partition_idx(uint32_t partition_id);
161
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200162/**
Summer Qinb4a854d2019-05-29 15:31:22 +0800163 * \brief Get the id of the partition for its index from the db
164 *
165 * \param[in] partition_idx Partition index
166 *
167 * \return Partition ID for that partition
168 *
169 * \note This function doesn't check if partition_idx is valid.
170 */
171uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx);
172
173/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200174 * \brief Get the flags associated with a partition
175 *
176 * \param[in] partition_idx Partition index
177 *
178 * \return Flags associated with the partition
179 *
180 * \note This function doesn't check if partition_idx is valid.
181 */
182uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx);
183
Mingyang Sunda01a972019-07-12 17:32:59 +0800184/**
185 * \brief Initialize partition database
186 *
187 * \return Error code \ref spm_err_t
188 */
189enum spm_err_t tfm_spm_db_init(void);
190
191/**
192 * \brief Change the privilege mode for partition thread mode.
193 *
194 * \param[in] privileged Privileged mode,
195 * \ref TFM_PARTITION_PRIVILEGED_MODE
196 * and \ref TFM_PARTITION_UNPRIVILEGED_MODE
197 *
198 * \note Barrier instructions are not called by this function, and if
199 * it is called in thread mode, it might be necessary to call
Edison Ai7aff9e82019-07-11 14:56:46 +0800200 * them after this function returns.
Mingyang Sunda01a972019-07-12 17:32:59 +0800201 */
202void tfm_spm_partition_change_privilege(uint32_t privileged);
203
204/*********************** library definitions ***********************/
205
Summer Qinb4a854d2019-05-29 15:31:22 +0800206#ifndef TFM_PSA_API
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200207/**
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200208 * \brief Save interrupted partition context on ctx stack
209 *
210 * \param[in] partition_idx Partition index
211 *
212 * \note This function doesn't check if partition_idx is valid.
213 * \note This function doesn't whether the ctx stack overflows.
214 */
215void tfm_spm_partition_push_interrupted_ctx(uint32_t partition_idx);
216
217/**
218 * \brief Restores interrupted partition context on ctx stack
219 *
220 * \param[in] partition_idx Partition index
221 *
222 * \note This function doesn't check if partition_idx is valid.
223 * \note This function doesn't whether the ctx stack underflows.
224 */
225void tfm_spm_partition_pop_interrupted_ctx(uint32_t partition_idx);
226
227/**
228 * \brief Save handler partition context on ctx stack
229 *
230 * \param[in] partition_idx Partition index
231 *
232 * \note This function doesn't check if partition_idx is valid.
233 * \note This function doesn't whether the ctx stack overflows.
234 */
235void tfm_spm_partition_push_handler_ctx(uint32_t partition_idx);
236
237/**
238 * \brief Restores handler partition context on ctx stack
239 *
240 * \param[in] partition_idx Partition index
241 *
242 * \note This function doesn't check if partition_idx is valid.
243 * \note This function doesn't whether the ctx stack underflows.
244 */
245void tfm_spm_partition_pop_handler_ctx(uint32_t partition_idx);
246
247/**
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100248 * \brief Get the current runtime data of a partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100249 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100250 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100251 *
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100252 * \return The runtime data of the specified partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100253 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100254 * \note This function doesn't check if partition_idx is valid.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100255 */
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100256const struct spm_partition_runtime_data_t *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100257 tfm_spm_partition_get_runtime_data(uint32_t partition_idx);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100258
259/**
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100260 * \brief Returns the index of the partition that has running state
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100261 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100262 * \return The index of the partition with the running state, if there is any
263 * set. 0 otherwise.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100264 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100265uint32_t tfm_spm_partition_get_running_partition_idx(void);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100266
267/**
Miklos Balintace4c3f2018-07-30 12:31:15 +0200268 * \brief Save stack pointer and link register for partition in database
269 *
270 * \param[in] partition_idx Partition index
271 * \param[in] stack_ptr Stack pointer to be stored
272 * \param[in] lr Link register to be stored
273 *
274 * \note This function doesn't check if partition_idx is valid.
275 */
276void tfm_spm_partition_store_context(uint32_t partition_idx,
277 uint32_t stack_ptr, uint32_t lr);
278
279/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100280 * \brief Set the current state of a partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100281 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100282 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100283 * \param[in] state The state to be set
284 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100285 * \note This function doesn't check if partition_idx is valid.
Gyorgy Szing40a7af02019-02-06 14:19:47 +0100286 * \note The state has to have the value set of \ref spm_part_state_t.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100287 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100288void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100289
290/**
Miklos Balint6a139ae2018-04-04 19:44:37 +0200291 * \brief Set the caller partition index for a given partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100292 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100293 * \param[in] partition_idx Partition index
Miklos Balint6a139ae2018-04-04 19:44:37 +0200294 * \param[in] caller_partition_idx The index of the caller partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100295 *
Miklos Balint6a139ae2018-04-04 19:44:37 +0200296 * \note This function doesn't check if any of the partition_idxs are valid.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100297 */
Miklos Balint6a139ae2018-04-04 19:44:37 +0200298void tfm_spm_partition_set_caller_partition_idx(uint32_t partition_idx,
299 uint32_t caller_partition_idx);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100300
301/**
Mate Toth-Pal21a74c92018-04-13 14:05:41 +0200302* \brief Set the caller client ID for a given partition
303*
304* \param[in] partition_idx Partition index
305* \param[in] caller_client_id The ID of the calling client
306*
307* \note This function doesn't check if any of the partition_idxs are valid.
308*/
309void tfm_spm_partition_set_caller_client_id(uint32_t partition_idx,
310 int32_t caller_client_id);
311
312/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100313 * \brief Set the buffer share region of the partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100314 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100315 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100316 * \param[in] share The buffer share region to be set
317 *
318 * \return Error code \ref spm_err_t
319 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100320 * \note This function doesn't check if partition_idx is valid.
Hugues de Valon99578562019-06-18 16:08:51 +0100321 * \note share has to have one of the buffer share values:
322 * - TFM_BUFFER_SHARE_DISABLE
323 * - TFM_BUFFER_SHARE_NS_CODE
324 * - TFM_BUFFER_SHARE_SCRATCH
325 * - TFM_BUFFER_SHARE_PRIV
326 * - TFM_BUFFER_SHARE_DEFAULT
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100327 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100328enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100329 uint32_t share);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100330
331/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200332 * \brief Set the iovec parameters for the partition
333 *
334 * \param[in] partition_idx Partition index
335 * \param[in] args The arguments of the secure function
336 *
337 * args is expected to be of type int32_t[4] where:
338 * args[0] is in_vec
339 * args[1] is in_len
340 * args[2] is out_vec
341 * args[3] is out_len
342 *
Hugues de Valonf704c802019-02-19 14:51:41 +0000343 * \return Error code \ref spm_err_t
344 *
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200345 * \note This function doesn't check if partition_idx is valid.
346 * \note This function assumes that the iovecs that are passed in args are
347 * valid, and does no sanity check on them at all.
348 */
Hugues de Valonf704c802019-02-19 14:51:41 +0000349enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
350 const int32_t *args);
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200351
352/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100353 * \brief Execute partition init function
Miklos Balint386b8b52017-11-29 13:12:32 +0000354 *
355 * \return Error code \ref spm_err_t
356 */
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100357enum spm_err_t tfm_spm_partition_init(void);
Miklos Balint386b8b52017-11-29 13:12:32 +0000358
359/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100360 * \brief Clears the context info from the database for a partition.
Miklos Balint386b8b52017-11-29 13:12:32 +0000361 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100362 * \param[in] partition_idx Partition index
Miklos Balint386b8b52017-11-29 13:12:32 +0000363 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100364 * \note This function doesn't check if partition_idx is valid.
Miklos Balint386b8b52017-11-29 13:12:32 +0000365 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100366void tfm_spm_partition_cleanup_context(uint32_t partition_idx);
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200367
368/**
369 * \brief Set the signal mask for a given partition
370 *
371 * \param[in] partition_idx Partition index
372 * \param[in] signal_mask The signal mask to be set for the partition
373 *
374 * \note This function doesn't check if any of the partition_idxs are valid.
375 */
376void tfm_spm_partition_set_signal_mask(uint32_t partition_idx,
377 uint32_t signal_mask);
Summer Qinb4a854d2019-05-29 15:31:22 +0800378#endif /* !defined(TFM_PSA_API) */
379
Mingyang Sunf3d29892019-07-10 17:50:23 +0800380#ifdef TFM_PSA_API
Mingyang Sunda01a972019-07-12 17:32:59 +0800381/*************************** IPC definitions **************************/
Edison Ai7aff9e82019-07-11 14:56:46 +0800382
383/**
384 * \brief Get bottom of stack region for a partition
385 *
386 * \param[in] partition_idx Partition index
387 *
388 * \return Stack region bottom value
389 *
390 * \note This function doesn't check if partition_idx is valid.
391 */
392uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx);
393
394/**
395 * \brief Get top of stack region for a partition
396 *
397 * \param[in] partition_idx Partition index
398 *
399 * \return Stack region top value
400 *
401 * \note This function doesn't check if partition_idx is valid.
402 */
403uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800404
405/**
406 * \brief Get the running partition ID.
407 *
408 * \return Returns the partition ID
409 */
410uint32_t tfm_spm_partition_get_running_partition_id(void);
411
412/**
413 * \brief Get the current partition mode.
414 *
415 * \param[in] partition_idx Index of current partition
416 *
417 * \retval TFM_PARTITION_PRIVILEGED_MODE Privileged mode
418 * \retval TFM_PARTITION_UNPRIVILEGED_MODE Unprivileged mode
419 */
420uint32_t tfm_spm_partition_get_privileged_mode(uint32_t partition_idx);
421
422/******************** Service handle management functions ********************/
423
424/**
425 * \brief Create connection handle for client connect
426 *
427 * \param[in] service Target service context pointer
428 *
429 * \retval PSA_NULL_HANDLE Create failed \ref PSA_NULL_HANDLE
430 * \retval >0 Service handle created, \ref psa_handle_t
431 */
432psa_handle_t tfm_spm_create_conn_handle(struct tfm_spm_service_t *service);
433
434/**
435 * \brief Free connection handle which not used anymore.
436 *
437 * \param[in] service Target service context pointer
438 * \param[in] conn_handle Connection handle created by
439 * tfm_spm_create_conn_handle(), \ref psa_handle_t
440 *
441 * \retval IPC_SUCCESS Success
442 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
443 * \retval "Does not return" Panic for not find service by handle
444 */
445int32_t tfm_spm_free_conn_handle(struct tfm_spm_service_t *service,
446 psa_handle_t conn_handle);
447
448/**
449 * \brief Set reverse handle value for connection.
450 *
451 * \param[in] service Target service context pointer
452 * \param[in] conn_handle Connection handle created by
453 * tfm_spm_create_conn_handle(), \ref psa_handle_t
454 * \param[in] rhandle rhandle need to save
455 *
456 * \retval IPC_SUCCESS Success
457 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
458 * \retval "Does not return" Panic for not find handle node
459 */
460int32_t tfm_spm_set_rhandle(struct tfm_spm_service_t *service,
461 psa_handle_t conn_handle,
462 void *rhandle);
463
464/**
465 * \brief Get reverse handle value from connection hanlde.
466 *
467 * \param[in] service Target service context pointer
468 * \param[in] conn_handle Connection handle created by
469 * tfm_spm_create_conn_handle(), \ref psa_handle_t
470 *
471 * \retval void * Success
472 * \retval "Does not return" Panic for those:
473 * service pointer are NULL
474 * hanlde is \ref PSA_NULL_HANDLE
475 * handle node does not be found
476 */
477void *tfm_spm_get_rhandle(struct tfm_spm_service_t *service,
478 psa_handle_t conn_handle);
479
480/******************** Partition management functions *************************/
481
482/**
483 * \brief Get current running partition context.
484 *
485 * \retval NULL Failed
486 * \retval "Not NULL" Return the parttion context pointer
487 * \ref spm_partition_desc_t structures
488 */
489struct spm_partition_desc_t *tfm_spm_get_running_partition(void);
490
491/**
492 * \brief Get the service context by signal.
493 *
494 * \param[in] partition Partition context pointer
495 * \ref spm_partition_desc_t structures
496 * \param[in] signal Signal associated with inputs to the Secure
497 * Partition, \ref psa_signal_t
498 *
499 * \retval NULL Failed
500 * \retval "Not NULL" Target service context pointer,
501 * \ref tfm_spm_service_t structures
502 */
503struct tfm_spm_service_t *
504 tfm_spm_get_service_by_signal(struct spm_partition_desc_t *partition,
505 psa_signal_t signal);
506
507/**
508 * \brief Get the service context by service ID.
509 *
510 * \param[in] sid RoT Service identity
511 *
512 * \retval NULL Failed
513 * \retval "Not NULL" Target service context pointer,
514 * \ref tfm_spm_service_t structures
515 */
516struct tfm_spm_service_t *tfm_spm_get_service_by_sid(uint32_t sid);
517
518/**
519 * \brief Get the service context by connection handle.
520 *
521 * \param[in] conn_handle Connection handle created by
522 * tfm_spm_create_conn_handle()
523 *
524 * \retval NULL Failed
525 * \retval "Not NULL" Target service context pointer,
526 * \ref tfm_spm_service_t structures
527 */
528struct tfm_spm_service_t *
529 tfm_spm_get_service_by_handle(psa_handle_t conn_handle);
530
531/**
532 * \brief Get the partition context by partition ID.
533 *
534 * \param[in] partition_id Partition identity
535 *
536 * \retval NULL Failed
537 * \retval "Not NULL" Target partition context pointer,
538 * \ref spm_partition_desc_t structures
539 */
540struct spm_partition_desc_t *
541 tfm_spm_get_partition_by_id(int32_t partition_id);
542
543/************************ Message functions **********************************/
544
545/**
546 * \brief Get message context by message handle.
547 *
548 * \param[in] msg_handle Message handle which is a reference generated
549 * by the SPM to a specific message.
550 *
551 * \return The message body context pointer
552 * \ref tfm_msg_body_t structures
553 */
554struct tfm_msg_body_t *tfm_spm_get_msg_from_handle(psa_handle_t msg_handle);
555
556/**
Edison Ai97115822019-08-01 14:22:19 +0800557 * \brief Get message context by connect handle.
Mingyang Sunf3d29892019-07-10 17:50:23 +0800558 *
Edison Ai97115822019-08-01 14:22:19 +0800559 * \param[in] conn_handle Service connect handle.
560 *
561 * \return The message body context pointer
562 * \ref msg_body_t structures
563 */
564struct tfm_msg_body_t *
565 tfm_spm_get_msg_buffer_from_conn_handle(psa_handle_t conn_handle);
566
567/**
568 * \brief Fill the message for PSA client call.
569 *
570 * \param[in] msg Service Message Queue buffer pointer
Mingyang Sunf3d29892019-07-10 17:50:23 +0800571 * \param[in] service Target service context pointer, which can be
572 * obtained by partition management functions
573 * \prarm[in] handle Connect handle return by psa_connect().
574 * \param[in] type Message type, PSA_IPC_CONNECT, PSA_IPC_CALL or
575 * PSA_IPC_DISCONNECT
576 * \param[in] ns_caller Whether from NS caller
577 * \param[in] invec Array of input \ref psa_invec structures
578 * \param[in] in_len Number of input \ref psa_invec structures
579 * \param[in] outvec Array of output \ref psa_outvec structures
580 * \param[in] out_len Number of output \ref psa_outvec structures
581 * \param[in] caller_outvec Array of caller output \ref psa_outvec structures
Mingyang Sunf3d29892019-07-10 17:50:23 +0800582 */
Edison Ai97115822019-08-01 14:22:19 +0800583void tfm_spm_fill_msg(struct tfm_msg_body_t *msg,
584 struct tfm_spm_service_t *service,
585 psa_handle_t handle,
586 int32_t type, int32_t ns_caller,
587 psa_invec *invec, size_t in_len,
588 psa_outvec *outvec, size_t out_len,
589 psa_outvec *caller_outvec);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800590
591/**
592 * \brief Send message and wake up the SP who is waiting on
593 * message queue, block the current thread and
594 * scheduler triggered
595 *
596 * \param[in] service Target service context pointer, which can be
597 * obtained by partition management functions
598 * \param[in] msg message created by tfm_spm_create_msg()
599 * \ref tfm_msg_body_t structures
600 *
601 * \retval IPC_SUCCESS Success
602 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
603 * \retval IPC_ERROR_GENERIC Failed to enqueue message to service message queue
604 */
605int32_t tfm_spm_send_event(struct tfm_spm_service_t *service,
606 struct tfm_msg_body_t *msg);
607
608/**
609 * \brief Check the client minor version according to
610 * version policy
611 *
612 * \param[in] service Target service context pointer, which can be get
613 * by partition management functions
614 * \param[in] minor_version Client support minor version
615 *
616 * \retval IPC_SUCCESS Success
617 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
618 * \retval IPC_ERROR_VERSION Check failed
619 */
620int32_t tfm_spm_check_client_version(struct tfm_spm_service_t *service,
621 uint32_t minor_version);
622
623/**
624 * \brief Check the memory reference is valid.
625 *
626 * \param[in] buffer Pointer of memory reference
627 * \param[in] len Length of memory reference in bytes
628 * \param[in] ns_caller From non-secure caller
629 * \param[in] access Type of access specified by the
630 * \ref tfm_memory_access_e
631 * \param[in] privileged Privileged mode or unprivileged mode:
632 * \ref TFM_PARTITION_UNPRIVILEGED_MODE
633 * \ref TFM_PARTITION_PRIVILEGED_MODE
634 *
635 * \retval IPC_SUCCESS Success
636 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
637 * \retval IPC_ERROR_MEMORY_CHECK Check failed
638 */
David Hucb05d972019-08-06 18:10:11 +0800639int32_t tfm_memory_check(const void *buffer, size_t len, int32_t ns_caller,
Mingyang Sunf3d29892019-07-10 17:50:23 +0800640 enum tfm_memory_access_e access,
641 uint32_t privileged);
642
643/* This function should be called before schedule function */
644void tfm_spm_init(void);
645
646/*
647 * PendSV specified function.
648 *
649 * Parameters :
650 * ctxb - State context storage pointer
651 *
652 * Notes:
653 * This is a staging API. Scheduler should be called in SPM finally and
654 * this function will be obsoleted later.
655 */
656void tfm_pendsv_do_schedule(struct tfm_state_context_ext *ctxb);
657
658#endif /* ifdef(TFM_PSA_API) */
659
Miklos Balint386b8b52017-11-29 13:12:32 +0000660#endif /*__SPM_API_H__ */