blob: 968f62820e7874e499fc7da3c3acd6db96aef0a6 [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"
Mingyang Sunc3123ec2020-06-11 17:43:58 +080013#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
Summer Qin83214922020-06-22 15:07:08 +080056
57#define EXC_NUM_THREAD_MODE (0)
58#define EXC_NUM_SVCALL (11)
59#define EXC_NUM_PENDSV (14)
60#define EXC_NUM_SYSTICK (15)
61
Miklos Balint386b8b52017-11-29 13:12:32 +000062/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020063 * \brief Holds the iovec parameters that are passed to a service
64 *
65 * \note The size of the structure is (and have to be) multiple of 8 bytes
66 */
67struct iovec_args_t {
68 psa_invec in_vec[PSA_MAX_IOVEC]; /*!< Array of psa_invec objects */
69 size_t in_len; /*!< Number psa_invec objects in in_vec
70 */
71 psa_outvec out_vec[PSA_MAX_IOVEC]; /*!< Array of psa_outvec objects */
72 size_t out_len; /*!< Number psa_outvec objects in out_vec
73 */
74};
Mingyang Sunda01a972019-07-12 17:32:59 +080075
76/* The size of this struct must be multiple of 4 bytes as it is stacked to an
77 * uint32_t[] array
78 */
79struct interrupted_ctx_stack_frame_t {
Mingyang Sunda01a972019-07-12 17:32:59 +080080 uint32_t partition_state;
81};
82
83/* The size of this struct must be multiple of 4 bytes as it is stacked to an
84 * uint32_t[] array
85 */
86struct handler_ctx_stack_frame_t {
87 uint32_t partition_state;
88 uint32_t caller_partition_idx;
89};
Edison Ai66fbdf12019-07-08 16:05:07 +080090#endif /* !define(TFM_PSA_API) */
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020091
92/**
Mate Toth-Pal18b83922018-02-26 17:58:18 +010093 * \brief Runtime context information of a partition
94 */
95struct spm_partition_runtime_data_t {
Edison Ai66fbdf12019-07-08 16:05:07 +080096#ifdef TFM_PSA_API
Edison Ai66fbdf12019-07-08 16:05:07 +080097 uint32_t signals; /* Service signals had been triggered*/
TTornblom83d96372019-11-19 12:53:16 +010098 struct tfm_event_t signal_evnt; /* Event signal */
Edison Ai66fbdf12019-07-08 16:05:07 +080099 struct tfm_list_node_t service_list;/* Service list */
Summer Qin66f1e032020-01-06 15:40:03 +0800100 struct tfm_core_thread_t sp_thrd; /* Thread object */
Shawn Shan9b0e0c72019-10-22 13:43:07 +0800101 uint32_t assigned_signals; /* All assigned signals */
Edison Ai66fbdf12019-07-08 16:05:07 +0800102#else /* TFM_PSA_API */
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100103 uint32_t partition_state;
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100104 uint32_t caller_partition_idx;
Mate Toth-Pal21a74c92018-04-13 14:05:41 +0200105 int32_t caller_client_id;
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100106 uint32_t stack_ptr;
Miklos Balintace4c3f2018-07-30 12:31:15 +0200107 uint32_t lr;
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200108 struct iovec_args_t iovec_args;
109 psa_outvec *orig_outvec;
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200110 uint32_t *ctx_stack_ptr;
Edison Ai66fbdf12019-07-08 16:05:07 +0800111#endif /* TFM_PSA_API */
112 uint32_t signal_mask; /*
113 * Service signal mask passed by
114 * psa_wait()
115 */
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100116};
117
Mingyang Sunda01a972019-07-12 17:32:59 +0800118#ifdef TFM_PSA_API
119
Mingyang Sunda01a972019-07-12 17:32:59 +0800120#define TFM_VERSION_POLICY_RELAXED 0
121#define TFM_VERSION_POLICY_STRICT 1
122
Edison Ai97115822019-08-01 14:22:19 +0800123#define TFM_CONN_HANDLE_MAX_NUM 16
Mingyang Sunda01a972019-07-12 17:32:59 +0800124
125/* RoT connection handle list */
126struct tfm_conn_handle_t {
Edison Ai9cc26242019-08-06 11:28:04 +0800127 void *rhandle; /* Reverse handle value */
Shawn Shancc39fcb2019-11-13 15:38:16 +0800128 uint32_t status; /*
Shawn Shanadb02862019-12-10 11:04:33 +0800129 * Status of handle, three valid
130 * options:
131 * TFM_HANDLE_STATUS_ACTIVE,
132 * TFM_HANDLE_STATUS_IDLE and
133 * TFM_HANDLE_STATUS_CONNECT_ERROR
Shawn Shancc39fcb2019-11-13 15:38:16 +0800134 */
Summer Qin1ce712a2019-10-14 18:04:05 +0800135 int32_t client_id; /*
136 * Partition ID of the sender of the
137 * message:
138 * - secure partition id;
139 * - non secure client endpoint id.
140 */
Edison Ai97115822019-08-01 14:22:19 +0800141 struct tfm_msg_body_t internal_msg; /* Internal message for message queue */
Edison Ai9cc26242019-08-06 11:28:04 +0800142 struct tfm_spm_service_t *service; /* RoT service pointer */
143 struct tfm_list_node_t list; /* list node */
Mingyang Sunda01a972019-07-12 17:32:59 +0800144};
145
146/* Service database defined by manifest */
147struct tfm_spm_service_db_t {
148 char *name; /* Service name */
149 uint32_t partition_id; /* Partition ID which service belong to */
150 psa_signal_t signal; /* Service signal */
151 uint32_t sid; /* Service identifier */
152 bool non_secure_client; /* If can be called by non secure client */
Shawn Shancc39fcb2019-11-13 15:38:16 +0800153 uint32_t version; /* Service version */
154 uint32_t version_policy; /* Service version policy */
Mingyang Sunda01a972019-07-12 17:32:59 +0800155};
156
157/* RoT Service data */
158struct tfm_spm_service_t {
Summer Qine578c5b2019-08-16 16:42:16 +0800159 const struct tfm_spm_service_db_t *service_db;/* Service database pointer */
Mingyang Sunda01a972019-07-12 17:32:59 +0800160 struct spm_partition_desc_t *partition; /*
161 * Point to secure partition
162 * data
163 */
164 struct tfm_list_node_t handle_list; /* Service handle list */
165 struct tfm_msg_queue_t msg_queue; /* Message queue */
166 struct tfm_list_node_t list; /* For list operation */
167};
Summer Qin5fdcf632020-06-22 16:49:24 +0800168
169enum tfm_memory_access_e {
170 TFM_MEMORY_ACCESS_RO = 1,
171 TFM_MEMORY_ACCESS_RW = 2,
172};
Mingyang Sunda01a972019-07-12 17:32:59 +0800173#endif /* ifdef(TFM_PSA_API) */
174
175/*********************** common definitions ***********************/
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100176
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100177/**
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100178 * \brief Returns the index of the partition with the given partition ID.
Miklos Balint386b8b52017-11-29 13:12:32 +0000179 *
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100180 * \param[in] partition_id Partition id
Miklos Balint386b8b52017-11-29 13:12:32 +0000181 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100182 * \return the partition idx if partition_id is valid,
183 * \ref SPM_INVALID_PARTITION_IDX othervise
184 */
185uint32_t get_partition_idx(uint32_t partition_id);
186
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200187/**
Summer Qinb4a854d2019-05-29 15:31:22 +0800188 * \brief Get the id of the partition for its index from the db
189 *
190 * \param[in] partition_idx Partition index
191 *
192 * \return Partition ID for that partition
193 *
194 * \note This function doesn't check if partition_idx is valid.
195 */
196uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx);
197
198/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200199 * \brief Get the flags associated with a partition
200 *
201 * \param[in] partition_idx Partition index
202 *
203 * \return Flags associated with the partition
204 *
205 * \note This function doesn't check if partition_idx is valid.
206 */
207uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx);
208
Mingyang Sunda01a972019-07-12 17:32:59 +0800209/**
210 * \brief Initialize partition database
211 *
212 * \return Error code \ref spm_err_t
213 */
214enum spm_err_t tfm_spm_db_init(void);
215
216/**
217 * \brief Change the privilege mode for partition thread mode.
218 *
219 * \param[in] privileged Privileged mode,
220 * \ref TFM_PARTITION_PRIVILEGED_MODE
221 * and \ref TFM_PARTITION_UNPRIVILEGED_MODE
222 *
223 * \note Barrier instructions are not called by this function, and if
224 * it is called in thread mode, it might be necessary to call
Edison Ai7aff9e82019-07-11 14:56:46 +0800225 * them after this function returns.
Mingyang Sunda01a972019-07-12 17:32:59 +0800226 */
227void tfm_spm_partition_change_privilege(uint32_t privileged);
228
Mate Toth-Pal5e6d0342019-11-22 11:43:20 +0100229/**
230 * \brief Get the current partition mode.
231 *
232 * \param[in] partition_flags Flags of current partition
233 *
234 * \retval TFM_PARTITION_PRIVILEGED_MODE Privileged mode
235 * \retval TFM_PARTITION_UNPRIVILEGED_MODE Unprivileged mode
236 */
237uint32_t tfm_spm_partition_get_privileged_mode(uint32_t partition_flags);
238
Summer Qin830c5542020-02-14 13:44:20 +0800239/**
240 * \brief Handle an SPM request by a secure service
241 * \param[in] svc_ctx The stacked SVC context
242 */
243void tfm_spm_request_handler(const struct tfm_state_context_t *svc_ctx);
244
Mingyang Sunda01a972019-07-12 17:32:59 +0800245/*********************** library definitions ***********************/
246
Summer Qinb4a854d2019-05-29 15:31:22 +0800247#ifndef TFM_PSA_API
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200248/**
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200249 * \brief Save interrupted partition context on ctx stack
250 *
251 * \param[in] partition_idx Partition index
252 *
253 * \note This function doesn't check if partition_idx is valid.
254 * \note This function doesn't whether the ctx stack overflows.
255 */
256void tfm_spm_partition_push_interrupted_ctx(uint32_t partition_idx);
257
258/**
259 * \brief Restores interrupted partition context on ctx stack
260 *
261 * \param[in] partition_idx Partition index
262 *
263 * \note This function doesn't check if partition_idx is valid.
264 * \note This function doesn't whether the ctx stack underflows.
265 */
266void tfm_spm_partition_pop_interrupted_ctx(uint32_t partition_idx);
267
268/**
269 * \brief Save handler partition context on ctx stack
270 *
271 * \param[in] partition_idx Partition index
272 *
273 * \note This function doesn't check if partition_idx is valid.
274 * \note This function doesn't whether the ctx stack overflows.
275 */
276void tfm_spm_partition_push_handler_ctx(uint32_t partition_idx);
277
278/**
279 * \brief Restores handler partition context on ctx stack
280 *
281 * \param[in] partition_idx Partition index
282 *
283 * \note This function doesn't check if partition_idx is valid.
284 * \note This function doesn't whether the ctx stack underflows.
285 */
286void tfm_spm_partition_pop_handler_ctx(uint32_t partition_idx);
287
288/**
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100289 * \brief Get the current runtime data of a partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100290 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100291 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100292 *
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100293 * \return The runtime data of the specified partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100294 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100295 * \note This function doesn't check if partition_idx is valid.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100296 */
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100297const struct spm_partition_runtime_data_t *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100298 tfm_spm_partition_get_runtime_data(uint32_t partition_idx);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100299
300/**
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100301 * \brief Returns the index of the partition that has running state
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100302 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100303 * \return The index of the partition with the running state, if there is any
304 * set. 0 otherwise.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100305 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100306uint32_t tfm_spm_partition_get_running_partition_idx(void);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100307
308/**
Miklos Balintace4c3f2018-07-30 12:31:15 +0200309 * \brief Save stack pointer and link register for partition in database
310 *
311 * \param[in] partition_idx Partition index
312 * \param[in] stack_ptr Stack pointer to be stored
313 * \param[in] lr Link register to be stored
314 *
315 * \note This function doesn't check if partition_idx is valid.
316 */
317void tfm_spm_partition_store_context(uint32_t partition_idx,
318 uint32_t stack_ptr, uint32_t lr);
319
320/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100321 * \brief Set the current state of a partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100322 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100323 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100324 * \param[in] state The state to be set
325 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100326 * \note This function doesn't check if partition_idx is valid.
Gyorgy Szing40a7af02019-02-06 14:19:47 +0100327 * \note The state has to have the value set of \ref spm_part_state_t.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100328 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100329void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100330
331/**
Miklos Balint6a139ae2018-04-04 19:44:37 +0200332 * \brief Set the caller partition index for a given partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100333 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100334 * \param[in] partition_idx Partition index
Miklos Balint6a139ae2018-04-04 19:44:37 +0200335 * \param[in] caller_partition_idx The index of the caller partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100336 *
Miklos Balint6a139ae2018-04-04 19:44:37 +0200337 * \note This function doesn't check if any of the partition_idxs are valid.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100338 */
Miklos Balint6a139ae2018-04-04 19:44:37 +0200339void tfm_spm_partition_set_caller_partition_idx(uint32_t partition_idx,
340 uint32_t caller_partition_idx);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100341
342/**
Mingyang Sunc3123ec2020-06-11 17:43:58 +0800343 * \brief Set the caller client ID for a given partition
344 *
345 * \param[in] partition_idx Partition index
346 * \param[in] caller_client_id The ID of the calling client
347 *
348 * \note This function doesn't check if any of the partition_idxs are valid.
349 */
Mate Toth-Pal21a74c92018-04-13 14:05:41 +0200350void tfm_spm_partition_set_caller_client_id(uint32_t partition_idx,
351 int32_t caller_client_id);
352
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100353
354/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200355 * \brief Set the iovec parameters for the partition
356 *
357 * \param[in] partition_idx Partition index
358 * \param[in] args The arguments of the secure function
359 *
360 * args is expected to be of type int32_t[4] where:
361 * args[0] is in_vec
362 * args[1] is in_len
363 * args[2] is out_vec
364 * args[3] is out_len
365 *
Hugues de Valonf704c802019-02-19 14:51:41 +0000366 * \return Error code \ref spm_err_t
367 *
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200368 * \note This function doesn't check if partition_idx is valid.
369 * \note This function assumes that the iovecs that are passed in args are
370 * valid, and does no sanity check on them at all.
371 */
Hugues de Valonf704c802019-02-19 14:51:41 +0000372enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
373 const int32_t *args);
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200374
375/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100376 * \brief Execute partition init function
Miklos Balint386b8b52017-11-29 13:12:32 +0000377 *
378 * \return Error code \ref spm_err_t
379 */
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100380enum spm_err_t tfm_spm_partition_init(void);
Miklos Balint386b8b52017-11-29 13:12:32 +0000381
382/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100383 * \brief Clears the context info from the database for a partition.
Miklos Balint386b8b52017-11-29 13:12:32 +0000384 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100385 * \param[in] partition_idx Partition index
Miklos Balint386b8b52017-11-29 13:12:32 +0000386 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100387 * \note This function doesn't check if partition_idx is valid.
Miklos Balint386b8b52017-11-29 13:12:32 +0000388 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100389void tfm_spm_partition_cleanup_context(uint32_t partition_idx);
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200390
391/**
392 * \brief Set the signal mask for a given partition
393 *
394 * \param[in] partition_idx Partition index
395 * \param[in] signal_mask The signal mask to be set for the partition
396 *
397 * \note This function doesn't check if any of the partition_idxs are valid.
398 */
399void tfm_spm_partition_set_signal_mask(uint32_t partition_idx,
400 uint32_t signal_mask);
Mingyang Sunabb1aab2020-02-18 13:49:08 +0800401
402/**
403 * \brief Signal that secure partition initialisation is finished
404 */
405void tfm_spm_secure_api_init_done(void);
406
407/**
408 * \brief Called if veneer is running in thread mode
409 */
410uint32_t tfm_spm_partition_request_svc_handler(
411 const uint32_t *svc_args, uint32_t lr);
412
413/**
414 * \brief Called when secure service returns
415 */
416uint32_t tfm_spm_partition_return_handler(uint32_t lr);
417
418/**
Mingyang Sunabb1aab2020-02-18 13:49:08 +0800419 * \brief Stores caller's client id in state context
420 */
421void tfm_spm_get_caller_client_id_handler(uint32_t *svc_args);
422
423/**
424 * \brief Checks if a secure service's access to a memory location is permitted
425 */
426void tfm_spm_memory_permission_check_handler(uint32_t *svc_args);
427
428/**
429 * \brief Check whether a buffer is ok for writing to by the privileged API
430 * function.
431 *
432 * This function checks whether the caller partition owns the buffer, can write
433 * to it, and the buffer has proper alignment.
434 *
435 * \param[in] partition_idx Partition index
436 * \param[in] start_addr The start address of the buffer
437 * \param[in] len The length of the buffer
438 * \param[in] alignment The expected alignment (in bits)
439 *
440 * \return 1 if the check passes, 0 otherwise.
441 *
442 * \note For a 0 long buffer the check fails.
443 */
444int32_t tfm_spm_check_buffer_access(uint32_t partition_idx,
445 void *start_addr,
446 size_t len,
447 uint32_t alignment);
448
449/**
450 * \brief Handle deprivileged request
451 */
452extern uint32_t tfm_spm_depriv_req_handler(uint32_t *svc_args,
453 uint32_t excReturn);
454
455/**
456 * \brief Handle request to return to privileged
457 */
458uint32_t tfm_spm_depriv_return_handler(uint32_t *irq_svc_args, uint32_t lr);
459
460/**
461 * \brief Handle IRQ enable request
462 */
463void tfm_spm_enable_irq_handler(uint32_t *svc_args);
464
465/**
466 * \brief Handle IRQ disable request
467 */
468void tfm_spm_disable_irq_handler(uint32_t *svc_args);
469
470/**
471 * \brief Handle signal wait request
472 */
473void tfm_spm_psa_wait(uint32_t *svc_args);
474
475/**
476 * \brief Handle request to record IRQ processed
477 */
478void tfm_spm_psa_eoi(uint32_t *svc_args);
Summer Qinb4a854d2019-05-29 15:31:22 +0800479#endif /* !defined(TFM_PSA_API) */
480
Mingyang Sunf3d29892019-07-10 17:50:23 +0800481#ifdef TFM_PSA_API
Mingyang Sunda01a972019-07-12 17:32:59 +0800482/*************************** IPC definitions **************************/
Edison Ai7aff9e82019-07-11 14:56:46 +0800483
484/**
Mingyang Sunf3d29892019-07-10 17:50:23 +0800485 * \brief Get the running partition ID.
486 *
487 * \return Returns the partition ID
488 */
489uint32_t tfm_spm_partition_get_running_partition_id(void);
490
Mingyang Sunf3d29892019-07-10 17:50:23 +0800491/******************** Service handle management functions ********************/
492
493/**
494 * \brief Create connection handle for client connect
495 *
496 * \param[in] service Target service context pointer
Summer Qin1ce712a2019-10-14 18:04:05 +0800497 * \param[in] client_id Partition ID of the sender of the message
Mingyang Sunf3d29892019-07-10 17:50:23 +0800498 *
Summer Qin630c76b2020-05-20 10:32:58 +0800499 * \retval NULL Create failed
500 * \retval "Not NULL" Service handle created
Mingyang Sunf3d29892019-07-10 17:50:23 +0800501 */
Summer Qin630c76b2020-05-20 10:32:58 +0800502struct tfm_conn_handle_t *tfm_spm_create_conn_handle(
503 struct tfm_spm_service_t *service,
Summer Qin1ce712a2019-10-14 18:04:05 +0800504 int32_t client_id);
505
506/**
507 * \brief Validate connection handle for client connect
508 *
509 * \param[in] conn_handle Handle to be validated
510 * \param[in] client_id Partition ID of the sender of the message
511 *
512 * \retval IPC_SUCCESS Success
513 * \retval IPC_ERROR_GENERIC Invalid handle
514 */
Summer Qin630c76b2020-05-20 10:32:58 +0800515int32_t tfm_spm_validate_conn_handle(
516 const struct tfm_conn_handle_t *conn_handle,
517 int32_t client_id);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800518
Mingyang Sunf3d29892019-07-10 17:50:23 +0800519/******************** Partition management functions *************************/
520
521/**
522 * \brief Get current running partition context.
523 *
524 * \retval NULL Failed
525 * \retval "Not NULL" Return the parttion context pointer
526 * \ref spm_partition_desc_t structures
527 */
528struct spm_partition_desc_t *tfm_spm_get_running_partition(void);
529
530/**
Mingyang Sunf3d29892019-07-10 17:50:23 +0800531 * \brief Get the service context by service ID.
532 *
533 * \param[in] sid RoT Service identity
534 *
535 * \retval NULL Failed
536 * \retval "Not NULL" Target service context pointer,
537 * \ref tfm_spm_service_t structures
538 */
539struct tfm_spm_service_t *tfm_spm_get_service_by_sid(uint32_t sid);
540
Mingyang Sunf3d29892019-07-10 17:50:23 +0800541/************************ Message functions **********************************/
542
543/**
Edison Ai97115822019-08-01 14:22:19 +0800544 * \brief Get message context by connect handle.
Mingyang Sunf3d29892019-07-10 17:50:23 +0800545 *
Edison Ai97115822019-08-01 14:22:19 +0800546 * \param[in] conn_handle Service connect handle.
547 *
548 * \return The message body context pointer
549 * \ref msg_body_t structures
550 */
551struct tfm_msg_body_t *
Summer Qin630c76b2020-05-20 10:32:58 +0800552 tfm_spm_get_msg_buffer_from_conn_handle(struct tfm_conn_handle_t *conn_handle);
Edison Ai97115822019-08-01 14:22:19 +0800553
554/**
555 * \brief Fill the message for PSA client call.
556 *
557 * \param[in] msg Service Message Queue buffer pointer
Mingyang Sunf3d29892019-07-10 17:50:23 +0800558 * \param[in] service Target service context pointer, which can be
559 * obtained by partition management functions
560 * \prarm[in] handle Connect handle return by psa_connect().
561 * \param[in] type Message type, PSA_IPC_CONNECT, PSA_IPC_CALL or
562 * PSA_IPC_DISCONNECT
Summer Qin1ce712a2019-10-14 18:04:05 +0800563 * \param[in] client_id Partition ID of the sender of the message
Mingyang Sunf3d29892019-07-10 17:50:23 +0800564 * \param[in] invec Array of input \ref psa_invec structures
565 * \param[in] in_len Number of input \ref psa_invec structures
566 * \param[in] outvec Array of output \ref psa_outvec structures
567 * \param[in] out_len Number of output \ref psa_outvec structures
568 * \param[in] caller_outvec Array of caller output \ref psa_outvec structures
Mingyang Sunf3d29892019-07-10 17:50:23 +0800569 */
Edison Ai97115822019-08-01 14:22:19 +0800570void tfm_spm_fill_msg(struct tfm_msg_body_t *msg,
571 struct tfm_spm_service_t *service,
Ken Liu505b1702020-05-29 13:19:58 +0800572 psa_handle_t handle,
Summer Qin1ce712a2019-10-14 18:04:05 +0800573 int32_t type, int32_t client_id,
Edison Ai97115822019-08-01 14:22:19 +0800574 psa_invec *invec, size_t in_len,
575 psa_outvec *outvec, size_t out_len,
576 psa_outvec *caller_outvec);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800577
578/**
579 * \brief Send message and wake up the SP who is waiting on
580 * message queue, block the current thread and
581 * scheduler triggered
582 *
583 * \param[in] service Target service context pointer, which can be
584 * obtained by partition management functions
585 * \param[in] msg message created by tfm_spm_create_msg()
586 * \ref tfm_msg_body_t structures
587 *
588 * \retval IPC_SUCCESS Success
589 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
590 * \retval IPC_ERROR_GENERIC Failed to enqueue message to service message queue
591 */
592int32_t tfm_spm_send_event(struct tfm_spm_service_t *service,
593 struct tfm_msg_body_t *msg);
594
595/**
Jaykumar Pitambarbhai Patel3a986022019-10-08 17:37:15 +0530596 * \brief Check the client version according to
Mingyang Sunf3d29892019-07-10 17:50:23 +0800597 * version policy
598 *
599 * \param[in] service Target service context pointer, which can be get
600 * by partition management functions
Jaykumar Pitambarbhai Patel3a986022019-10-08 17:37:15 +0530601 * \param[in] version Client support version
Mingyang Sunf3d29892019-07-10 17:50:23 +0800602 *
603 * \retval IPC_SUCCESS Success
604 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
605 * \retval IPC_ERROR_VERSION Check failed
606 */
607int32_t tfm_spm_check_client_version(struct tfm_spm_service_t *service,
Jaykumar Pitambarbhai Patel3a986022019-10-08 17:37:15 +0530608 uint32_t version);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800609
610/**
Edison Aie728fbf2019-11-13 09:37:12 +0800611 * \brief Check the client access authorization
612 *
613 * \param[in] sid Target RoT Service identity
614 * \param[in] service Target service context pointer, which can be get
615 * by partition management functions
616 * \param[in] ns_caller Whether from NS caller
617 *
618 * \retval IPC_SUCCESS Success
619 * \retval IPC_ERROR_GENERIC Authorization check failed
620 */
621int32_t tfm_spm_check_authorization(uint32_t sid,
622 struct tfm_spm_service_t *service,
Summer Qin618e8c32019-12-09 10:47:20 +0800623 bool ns_caller);
Edison Aie728fbf2019-11-13 09:37:12 +0800624
625/**
Mingyang Sunf3d29892019-07-10 17:50:23 +0800626 * \brief Check the memory reference is valid.
627 *
628 * \param[in] buffer Pointer of memory reference
629 * \param[in] len Length of memory reference in bytes
630 * \param[in] ns_caller From non-secure caller
631 * \param[in] access Type of access specified by the
632 * \ref tfm_memory_access_e
633 * \param[in] privileged Privileged mode or unprivileged mode:
634 * \ref TFM_PARTITION_UNPRIVILEGED_MODE
635 * \ref TFM_PARTITION_PRIVILEGED_MODE
636 *
637 * \retval IPC_SUCCESS Success
638 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
639 * \retval IPC_ERROR_MEMORY_CHECK Check failed
640 */
Summer Qin43c185d2019-10-10 15:44:42 +0800641int32_t tfm_memory_check(const void *buffer, size_t len, bool ns_caller,
Mingyang Sunf3d29892019-07-10 17:50:23 +0800642 enum tfm_memory_access_e access,
643 uint32_t privileged);
644
Mingyang Sunf3d29892019-07-10 17:50:23 +0800645/*
646 * PendSV specified function.
647 *
648 * Parameters :
Summer Qind2ad7e72020-01-06 18:16:35 +0800649 * p_actx - Architecture context storage pointer
Mingyang Sunf3d29892019-07-10 17:50:23 +0800650 *
651 * Notes:
652 * This is a staging API. Scheduler should be called in SPM finally and
653 * this function will be obsoleted later.
654 */
Summer Qind2ad7e72020-01-06 18:16:35 +0800655void tfm_pendsv_do_schedule(struct tfm_arch_ctx_t *p_actx);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800656
Ken Liu490281d2019-12-30 15:55:26 +0800657/**
658 * \brief SPM initialization implementation
659 *
660 * \details This function must be called under handler mode.
Ken Liuce2692d2020-02-11 12:39:36 +0800661 * \retval This function returns an EXC_RETURN value. Other
662 * faults would panic the execution and never
663 * returned.
Ken Liu490281d2019-12-30 15:55:26 +0800664 */
Ken Liuce2692d2020-02-11 12:39:36 +0800665uint32_t tfm_spm_init(void);
Ken Liu490281d2019-12-30 15:55:26 +0800666
Shawn Shan6e7be072019-11-29 17:56:29 +0800667/*
668 * \brief This function get the current PSA RoT lifecycle state.
669 *
670 * \return state The current security lifecycle state of the PSA
671 * RoT. The PSA state and implementation state are
672 * encoded as follows:
673 * \arg state[15:8] – PSA lifecycle state
674 * \arg state[7:0] – IMPLEMENTATION DEFINED state
675 */
676uint32_t tfm_spm_get_lifecycle_state(void);
677
Mingyang Sund44522a2020-01-16 16:48:37 +0800678/* Svcall for PSA Client APIs */
679
680/**
681 * \brief SVC handler for \ref psa_framework_version.
682 *
683 * \return version The version of the PSA Framework implementation
684 * that is providing the runtime services to the
685 * caller.
686 */
687uint32_t tfm_spm_psa_framework_version(void);
688
689/**
690 * \brief SVC handler for \ref psa_version.
691 *
692 * \param[in] args Include all input arguments: sid.
693 * \param[in] ns_caller If 'true', call from non-secure client.
694 * Or from secure client.
695 *
696 * \retval PSA_VERSION_NONE The RoT Service is not implemented, or the
697 * caller is not permitted to access the service.
698 * \retval > 0 The version of the implemented RoT Service.
699 */
700uint32_t tfm_spm_psa_version(uint32_t *args, bool ns_caller);
701
702/**
703 * \brief SVC handler for \ref psa_connect.
704 *
705 * \param[in] args Include all input arguments:
706 * sid, version.
707 * \param[in] ns_caller If 'true', call from non-secure client.
708 * Or from secure client.
709 *
710 * \retval PSA_SUCCESS Success.
711 * \retval PSA_ERROR_CONNECTION_REFUSED The SPM or RoT Service has refused the
712 * connection.
713 * \retval PSA_ERROR_CONNECTION_BUSY The SPM or RoT Service cannot make the
714 * connection at the moment.
715 * \retval "Does not return" The RoT Service ID and version are not
716 * supported, or the caller is not permitted to
717 * access the service.
718 */
719psa_status_t tfm_spm_psa_connect(uint32_t *args, bool ns_caller);
720
721/**
722 * \brief SVC handler for \ref psa_call.
723 *
724 * \param[in] args Include all input arguments:
725 * handle, in_vec, in_len, out_vec, out_len.
726 * \param[in] ns_caller If 'true', call from non-secure client.
727 * Or from secure client.
728 * \param[in] lr EXC_RETURN value of the SVC.
729 *
730 * \retval >=0 RoT Service-specific status value.
731 * \retval <0 RoT Service-specific error code.
732 * \retval PSA_ERROR_PROGRAMMER_ERROR The connection has been terminated by the
733 * RoT Service. The call is a PROGRAMMER ERROR if
734 * one or more of the following are true:
735 * \arg An invalid handle was passed.
736 * \arg The connection is already handling a request.
737 * \arg type < 0.
738 * \arg An invalid memory reference was provided.
739 * \arg in_len + out_len > PSA_MAX_IOVEC.
740 * \arg The message is unrecognized by the RoT
741 * Service or incorrectly formatted.
742 */
743psa_status_t tfm_spm_psa_call(uint32_t *args, bool ns_caller, uint32_t lr);
744
745/**
746 * \brief SVC handler for \ref psa_close.
747 *
748 * \param[in] args Include all input arguments: handle.
749 * \param[in] ns_caller If 'true', call from non-secure client.
750 * Or from secure client.
751 *
752 * \retval void Success.
753 * \retval "Does not return" The call is invalid, one or more of the
754 * following are true:
755 * \arg An invalid handle was provided that is not
756 * the null handle.
757 * \arg The connection is handling a request.
758 */
759void tfm_spm_psa_close(uint32_t *args, bool ns_caller);
760
761/* Svcall for PSA Service APIs */
762
763/**
764 * \brief SVC handler for \ref psa_wait.
765 *
766 * \param[in] args Include all input arguments:
767 * signal_mask, timeout.
768 *
769 * \retval >0 At least one signal is asserted.
770 * \retval 0 No signals are asserted. This is only seen when
771 * a polling timeout is used.
772 */
773psa_signal_t tfm_spm_psa_wait(uint32_t *args);
774
775/**
776 * \brief SVC handler for \ref psa_get.
777 *
778 * \param[in] args Include all input arguments: signal, msg.
779 *
780 * \retval PSA_SUCCESS Success, *msg will contain the delivered
781 * message.
782 * \retval PSA_ERROR_DOES_NOT_EXIST Message could not be delivered.
783 * \retval "Does not return" The call is invalid because one or more of the
784 * following are true:
785 * \arg signal has more than a single bit set.
786 * \arg signal does not correspond to an RoT Service.
787 * \arg The RoT Service signal is not currently
788 * asserted.
789 * \arg The msg pointer provided is not a valid memory
790 * reference.
791 */
792psa_status_t tfm_spm_psa_get(uint32_t *args);
793
794/**
795 * \brief SVC handler for \ref psa_set_rhandle.
796 *
797 * \param[in] args Include all input arguments:
798 * msg_handle, rhandle.
799 *
800 * \retval void Success, rhandle will be provided with all
801 * subsequent messages delivered on this
802 * connection.
803 * \retval "Does not return" msg_handle is invalid.
804 */
805void tfm_spm_psa_set_rhandle(uint32_t *args);
806
807/**
808 * \brief SVC handler for \ref psa_read.
809 *
810 * \param[in] args Include all input arguments:
811 * msg_handle, invec_idx, buffer, num_bytes.
812 *
813 * \retval >0 Number of bytes copied.
814 * \retval 0 There was no remaining data in this input
815 * vector.
816 * \retval "Does not return" The call is invalid, one or more of the
817 * following are true:
818 * \arg msg_handle is invalid.
819 * \arg msg_handle does not refer to a request
820 * message.
821 * \arg invec_idx is equal to or greater than
822 * \ref PSA_MAX_IOVEC.
823 * \arg the memory reference for buffer is invalid or
824 * not writable.
825 */
826size_t tfm_spm_psa_read(uint32_t *args);
827
828/**
829 * \brief SVC handler for \ref psa_skip.
830 *
831 * \param[in] args Include all input arguments:
832 * msg_handle, invec_idx, num_bytes.
833 *
834 * \retval >0 Number of bytes skipped.
835 * \retval 0 There was no remaining data in this input
836 * vector.
837 * \retval "Does not return" The call is invalid, one or more of the
838 * following are true:
839 * \arg msg_handle is invalid.
840 * \arg msg_handle does not refer to a request
841 * message.
842 * \arg invec_idx is equal to or greater than
843 * \ref PSA_MAX_IOVEC.
844 */
845size_t tfm_spm_psa_skip(uint32_t *args);
846
847/**
848 * \brief SVC handler for \ref psa_write.
849 *
850 * \param[in] args Include all input arguments:
851 * msg_handle, outvec_idx, buffer, num_bytes.
852 *
853 * \retval void Success
854 * \retval "Does not return" The call is invalid, one or more of the
855 * following are true:
856 * \arg msg_handle is invalid.
857 * \arg msg_handle does not refer to a request
858 * message.
859 * \arg outvec_idx is equal to or greater than
860 * \ref PSA_MAX_IOVEC.
861 * \arg The memory reference for buffer is invalid.
862 * \arg The call attempts to write data past the end
863 * of the client output vector.
864 */
865void tfm_spm_psa_write(uint32_t *args);
866
867/**
868 * \brief SVC handler for \ref psa_reply.
869 *
870 * \param[in] args Include all input arguments:
871 * msg_handle, status.
872 *
873 * \retval void Success.
874 * \retval "Does not return" The call is invalid, one or more of the
875 * following are true:
876 * \arg msg_handle is invalid.
877 * \arg An invalid status code is specified for the
878 * type of message.
879 */
880void tfm_spm_psa_reply(uint32_t *args);
881
882/**
883 * \brief SVC handler for \ref psa_notify.
884 *
885 * \param[in] args Include all input arguments: partition_id.
886 *
887 * \retval void Success.
888 * \retval "Does not return" partition_id does not correspond to a Secure
889 * Partition.
890 */
891void tfm_spm_psa_notify(uint32_t *args);
892
893/**
894 * \brief SVC handler for \ref psa_clear.
895 *
896 * \retval void Success.
897 * \retval "Does not return" The Secure Partition's doorbell signal is not
898 * currently asserted.
899 */
900void tfm_spm_psa_clear(void);
901
902/**
903 * \brief SVC handler for \ref psa_eoi.
904 *
905 * \param[in] args Include all input arguments: irq_signal.
906 *
907 * \retval void Success.
908 * \retval "Does not return" The call is invalid, one or more of the
909 * following are true:
910 * \arg irq_signal is not an interrupt signal.
911 * \arg irq_signal indicates more than one signal.
912 * \arg irq_signal is not currently asserted.
913 */
914void tfm_spm_psa_eoi(uint32_t *args);
915
916/**
Mingyang Sunc3123ec2020-06-11 17:43:58 +0800917 * \brief SVC handler of enabling irq_line of the specified irq_signal.
Mingyang Sund44522a2020-01-16 16:48:37 +0800918 *
919 * \param[in] args Include all input arguments: irq_signal.
920 *
921 * \retval void Success.
922 * \retval "Does not return" The call is invalid, one or more of the
923 * following are true:
924 * \arg irq_signal is not an interrupt signal.
925 * \arg irq_signal indicates more than one signal.
926 */
927void tfm_spm_enable_irq(uint32_t *args);
928
929/**
Mingyang Sunc3123ec2020-06-11 17:43:58 +0800930 * \brief SVC handler of disabling irq_line of the specified irq_signal.
Mingyang Sund44522a2020-01-16 16:48:37 +0800931 *
932 * \param[in] args Include all input arguments: irq_signal.
933 *
934 * \retval void Success.
935 * \retval "Does not return" The call is invalid, one or more of the
936 * following are true:
937 * \arg irq_signal is not an interrupt signal.
938 * \arg irq_signal indicates more than one signal.
939 */
940void tfm_spm_disable_irq(uint32_t *args);
941
942/**
943 * \brief Validate the whether NS caller re-enter.
944 *
945 * \param[in] p_cur_sp Pointer to current partition.
946 * \param[in] p_ctx Pointer to current stack context.
947 * \param[in] exc_return EXC_RETURN value.
948 * \param[in] ns_caller If 'true', call from non-secure client.
949 * Or from secure client.
950 *
951 * \retval void Success.
952 */
953void tfm_spm_validate_caller(struct spm_partition_desc_t *p_cur_sp,
954 uint32_t *p_ctx, uint32_t exc_return,
955 bool ns_caller);
956
957/**
958 * \brief Terminate execution within the calling Secure Partition and will not
959 * return.
960 *
961 * \retval "Does not return"
962 */
963void tfm_spm_psa_panic(void);
964
Summer Qin373feb12020-03-27 15:35:33 +0800965/**
Ken Liu505b1702020-05-29 13:19:58 +0800966 * \brief Converts a handle instance into a corresponded user handle.
967 */
968psa_handle_t tfm_spm_to_user_handle(struct tfm_conn_handle_t *handle_instance);
969
970/**
Summer Qin373feb12020-03-27 15:35:33 +0800971 * \brief Converts a user handle into a corresponded handle instance.
972 */
973struct tfm_conn_handle_t *tfm_spm_to_handle_instance(psa_handle_t user_handle);
974
Mingyang Sund44522a2020-01-16 16:48:37 +0800975#endif /* defined(TFM_PSA_API) */
Mingyang Sunf3d29892019-07-10 17:50:23 +0800976
Miklos Balint386b8b52017-11-29 13:12:32 +0000977#endif /*__SPM_API_H__ */