blob: 51e4f9efc78603319e26687a8288b3acd2059016 [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-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/**
Mingyang Sunda01a972019-07-12 17:32:59 +0800188 * \brief Initialize partition database
189 *
190 * \return Error code \ref spm_err_t
191 */
192enum spm_err_t tfm_spm_db_init(void);
193
194/**
Mate Toth-Pal5e6d0342019-11-22 11:43:20 +0100195 * \brief Get the current partition mode.
196 *
197 * \param[in] partition_flags Flags of current partition
198 *
199 * \retval TFM_PARTITION_PRIVILEGED_MODE Privileged mode
200 * \retval TFM_PARTITION_UNPRIVILEGED_MODE Unprivileged mode
201 */
202uint32_t tfm_spm_partition_get_privileged_mode(uint32_t partition_flags);
203
Summer Qin830c5542020-02-14 13:44:20 +0800204/**
205 * \brief Handle an SPM request by a secure service
206 * \param[in] svc_ctx The stacked SVC context
207 */
208void tfm_spm_request_handler(const struct tfm_state_context_t *svc_ctx);
209
Mingyang Sunda01a972019-07-12 17:32:59 +0800210/*********************** library definitions ***********************/
211
Summer Qinb4a854d2019-05-29 15:31:22 +0800212#ifndef TFM_PSA_API
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200213/**
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200214 * \brief Save interrupted partition context on ctx stack
215 *
216 * \param[in] partition_idx Partition index
217 *
218 * \note This function doesn't check if partition_idx is valid.
219 * \note This function doesn't whether the ctx stack overflows.
220 */
221void tfm_spm_partition_push_interrupted_ctx(uint32_t partition_idx);
222
223/**
224 * \brief Restores interrupted partition context on ctx stack
225 *
226 * \param[in] partition_idx Partition index
227 *
228 * \note This function doesn't check if partition_idx is valid.
229 * \note This function doesn't whether the ctx stack underflows.
230 */
231void tfm_spm_partition_pop_interrupted_ctx(uint32_t partition_idx);
232
233/**
234 * \brief Save handler partition context on ctx stack
235 *
236 * \param[in] partition_idx Partition index
237 *
238 * \note This function doesn't check if partition_idx is valid.
239 * \note This function doesn't whether the ctx stack overflows.
240 */
241void tfm_spm_partition_push_handler_ctx(uint32_t partition_idx);
242
243/**
244 * \brief Restores handler partition context on ctx stack
245 *
246 * \param[in] partition_idx Partition index
247 *
248 * \note This function doesn't check if partition_idx is valid.
249 * \note This function doesn't whether the ctx stack underflows.
250 */
251void tfm_spm_partition_pop_handler_ctx(uint32_t partition_idx);
252
253/**
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100254 * \brief Get the current runtime data of a partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100255 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100256 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100257 *
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100258 * \return The runtime data of the specified partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100259 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100260 * \note This function doesn't check if partition_idx is valid.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100261 */
Mate Toth-Pal18b83922018-02-26 17:58:18 +0100262const struct spm_partition_runtime_data_t *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100263 tfm_spm_partition_get_runtime_data(uint32_t partition_idx);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100264
265/**
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100266 * \brief Returns the index of the partition that has running state
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100267 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100268 * \return The index of the partition with the running state, if there is any
269 * set. 0 otherwise.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100270 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100271uint32_t tfm_spm_partition_get_running_partition_idx(void);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100272
273/**
Miklos Balintace4c3f2018-07-30 12:31:15 +0200274 * \brief Save stack pointer and link register for partition in database
275 *
276 * \param[in] partition_idx Partition index
277 * \param[in] stack_ptr Stack pointer to be stored
278 * \param[in] lr Link register to be stored
279 *
280 * \note This function doesn't check if partition_idx is valid.
281 */
282void tfm_spm_partition_store_context(uint32_t partition_idx,
283 uint32_t stack_ptr, uint32_t lr);
284
285/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100286 * \brief Set the current state of a partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100287 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100288 * \param[in] partition_idx Partition index
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100289 * \param[in] state The state to be set
290 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100291 * \note This function doesn't check if partition_idx is valid.
Gyorgy Szing40a7af02019-02-06 14:19:47 +0100292 * \note The state has to have the value set of \ref spm_part_state_t.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100293 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100294void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100295
296/**
Miklos Balint6a139ae2018-04-04 19:44:37 +0200297 * \brief Set the caller partition index for a given partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100298 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100299 * \param[in] partition_idx Partition index
Miklos Balint6a139ae2018-04-04 19:44:37 +0200300 * \param[in] caller_partition_idx The index of the caller partition
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100301 *
Miklos Balint6a139ae2018-04-04 19:44:37 +0200302 * \note This function doesn't check if any of the partition_idxs are valid.
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100303 */
Miklos Balint6a139ae2018-04-04 19:44:37 +0200304void tfm_spm_partition_set_caller_partition_idx(uint32_t partition_idx,
305 uint32_t caller_partition_idx);
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100306
307/**
Mingyang Sunc3123ec2020-06-11 17:43:58 +0800308 * \brief Set the caller client ID for a given partition
309 *
310 * \param[in] partition_idx Partition index
311 * \param[in] caller_client_id The ID of the calling client
312 *
313 * \note This function doesn't check if any of the partition_idxs are valid.
314 */
Mate Toth-Pal21a74c92018-04-13 14:05:41 +0200315void tfm_spm_partition_set_caller_client_id(uint32_t partition_idx,
316 int32_t caller_client_id);
317
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100318
319/**
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200320 * \brief Set the iovec parameters for the partition
321 *
322 * \param[in] partition_idx Partition index
323 * \param[in] args The arguments of the secure function
324 *
325 * args is expected to be of type int32_t[4] where:
326 * args[0] is in_vec
327 * args[1] is in_len
328 * args[2] is out_vec
329 * args[3] is out_len
330 *
Hugues de Valonf704c802019-02-19 14:51:41 +0000331 * \return Error code \ref spm_err_t
332 *
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200333 * \note This function doesn't check if partition_idx is valid.
334 * \note This function assumes that the iovecs that are passed in args are
335 * valid, and does no sanity check on them at all.
336 */
Hugues de Valonf704c802019-02-19 14:51:41 +0000337enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
338 const int32_t *args);
Mate Toth-Pal3db437a2018-06-22 16:15:13 +0200339
340/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100341 * \brief Execute partition init function
Miklos Balint386b8b52017-11-29 13:12:32 +0000342 *
343 * \return Error code \ref spm_err_t
344 */
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100345enum spm_err_t tfm_spm_partition_init(void);
Miklos Balint386b8b52017-11-29 13:12:32 +0000346
347/**
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100348 * \brief Clears the context info from the database for a partition.
Miklos Balint386b8b52017-11-29 13:12:32 +0000349 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100350 * \param[in] partition_idx Partition index
Miklos Balint386b8b52017-11-29 13:12:32 +0000351 *
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100352 * \note This function doesn't check if partition_idx is valid.
Miklos Balint386b8b52017-11-29 13:12:32 +0000353 */
Mate Toth-Pal52674ab2018-02-26 09:47:56 +0100354void tfm_spm_partition_cleanup_context(uint32_t partition_idx);
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200355
356/**
357 * \brief Set the signal mask for a given partition
358 *
359 * \param[in] partition_idx Partition index
360 * \param[in] signal_mask The signal mask to be set for the partition
361 *
362 * \note This function doesn't check if any of the partition_idxs are valid.
363 */
364void tfm_spm_partition_set_signal_mask(uint32_t partition_idx,
365 uint32_t signal_mask);
Mingyang Sunabb1aab2020-02-18 13:49:08 +0800366
367/**
368 * \brief Signal that secure partition initialisation is finished
369 */
370void tfm_spm_secure_api_init_done(void);
371
372/**
373 * \brief Called if veneer is running in thread mode
374 */
375uint32_t tfm_spm_partition_request_svc_handler(
376 const uint32_t *svc_args, uint32_t lr);
377
378/**
379 * \brief Called when secure service returns
380 */
381uint32_t tfm_spm_partition_return_handler(uint32_t lr);
382
383/**
Mingyang Sunabb1aab2020-02-18 13:49:08 +0800384 * \brief Stores caller's client id in state context
385 */
386void tfm_spm_get_caller_client_id_handler(uint32_t *svc_args);
387
388/**
389 * \brief Checks if a secure service's access to a memory location is permitted
390 */
391void tfm_spm_memory_permission_check_handler(uint32_t *svc_args);
392
393/**
394 * \brief Check whether a buffer is ok for writing to by the privileged API
395 * function.
396 *
397 * This function checks whether the caller partition owns the buffer, can write
398 * to it, and the buffer has proper alignment.
399 *
400 * \param[in] partition_idx Partition index
401 * \param[in] start_addr The start address of the buffer
402 * \param[in] len The length of the buffer
403 * \param[in] alignment The expected alignment (in bits)
404 *
405 * \return 1 if the check passes, 0 otherwise.
406 *
407 * \note For a 0 long buffer the check fails.
408 */
409int32_t tfm_spm_check_buffer_access(uint32_t partition_idx,
410 void *start_addr,
411 size_t len,
412 uint32_t alignment);
413
414/**
415 * \brief Handle deprivileged request
416 */
417extern uint32_t tfm_spm_depriv_req_handler(uint32_t *svc_args,
418 uint32_t excReturn);
419
420/**
421 * \brief Handle request to return to privileged
422 */
423uint32_t tfm_spm_depriv_return_handler(uint32_t *irq_svc_args, uint32_t lr);
424
425/**
426 * \brief Handle IRQ enable request
427 */
428void tfm_spm_enable_irq_handler(uint32_t *svc_args);
429
430/**
431 * \brief Handle IRQ disable request
432 */
433void tfm_spm_disable_irq_handler(uint32_t *svc_args);
434
435/**
436 * \brief Handle signal wait request
437 */
438void tfm_spm_psa_wait(uint32_t *svc_args);
439
440/**
441 * \brief Handle request to record IRQ processed
442 */
443void tfm_spm_psa_eoi(uint32_t *svc_args);
Summer Qinb4a854d2019-05-29 15:31:22 +0800444#endif /* !defined(TFM_PSA_API) */
445
Mingyang Sunf3d29892019-07-10 17:50:23 +0800446#ifdef TFM_PSA_API
Mingyang Sunda01a972019-07-12 17:32:59 +0800447/*************************** IPC definitions **************************/
Edison Ai7aff9e82019-07-11 14:56:46 +0800448
449/**
Mingyang Sunf3d29892019-07-10 17:50:23 +0800450 * \brief Get the running partition ID.
451 *
452 * \return Returns the partition ID
453 */
454uint32_t tfm_spm_partition_get_running_partition_id(void);
455
Mingyang Sunf3d29892019-07-10 17:50:23 +0800456/******************** Service handle management functions ********************/
457
458/**
459 * \brief Create connection handle for client connect
460 *
461 * \param[in] service Target service context pointer
Summer Qin1ce712a2019-10-14 18:04:05 +0800462 * \param[in] client_id Partition ID of the sender of the message
Mingyang Sunf3d29892019-07-10 17:50:23 +0800463 *
Summer Qin630c76b2020-05-20 10:32:58 +0800464 * \retval NULL Create failed
465 * \retval "Not NULL" Service handle created
Mingyang Sunf3d29892019-07-10 17:50:23 +0800466 */
Summer Qin630c76b2020-05-20 10:32:58 +0800467struct tfm_conn_handle_t *tfm_spm_create_conn_handle(
468 struct tfm_spm_service_t *service,
Summer Qin1ce712a2019-10-14 18:04:05 +0800469 int32_t client_id);
470
471/**
472 * \brief Validate connection handle for client connect
473 *
474 * \param[in] conn_handle Handle to be validated
475 * \param[in] client_id Partition ID of the sender of the message
476 *
477 * \retval IPC_SUCCESS Success
478 * \retval IPC_ERROR_GENERIC Invalid handle
479 */
Summer Qin630c76b2020-05-20 10:32:58 +0800480int32_t tfm_spm_validate_conn_handle(
481 const struct tfm_conn_handle_t *conn_handle,
482 int32_t client_id);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800483
Mingyang Sunf3d29892019-07-10 17:50:23 +0800484/******************** Partition management functions *************************/
485
486/**
487 * \brief Get current running partition context.
488 *
489 * \retval NULL Failed
490 * \retval "Not NULL" Return the parttion context pointer
491 * \ref spm_partition_desc_t structures
492 */
493struct spm_partition_desc_t *tfm_spm_get_running_partition(void);
494
495/**
Mingyang Sunf3d29892019-07-10 17:50:23 +0800496 * \brief Get the service context by service ID.
497 *
498 * \param[in] sid RoT Service identity
499 *
500 * \retval NULL Failed
501 * \retval "Not NULL" Target service context pointer,
502 * \ref tfm_spm_service_t structures
503 */
504struct tfm_spm_service_t *tfm_spm_get_service_by_sid(uint32_t sid);
505
Mingyang Sunf3d29892019-07-10 17:50:23 +0800506/************************ Message functions **********************************/
507
508/**
Edison Ai97115822019-08-01 14:22:19 +0800509 * \brief Get message context by connect handle.
Mingyang Sunf3d29892019-07-10 17:50:23 +0800510 *
Edison Ai97115822019-08-01 14:22:19 +0800511 * \param[in] conn_handle Service connect handle.
512 *
513 * \return The message body context pointer
514 * \ref msg_body_t structures
515 */
516struct tfm_msg_body_t *
Summer Qin630c76b2020-05-20 10:32:58 +0800517 tfm_spm_get_msg_buffer_from_conn_handle(struct tfm_conn_handle_t *conn_handle);
Edison Ai97115822019-08-01 14:22:19 +0800518
519/**
520 * \brief Fill the message for PSA client call.
521 *
522 * \param[in] msg Service Message Queue buffer pointer
Mingyang Sunf3d29892019-07-10 17:50:23 +0800523 * \param[in] service Target service context pointer, which can be
524 * obtained by partition management functions
525 * \prarm[in] handle Connect handle return by psa_connect().
526 * \param[in] type Message type, PSA_IPC_CONNECT, PSA_IPC_CALL or
527 * PSA_IPC_DISCONNECT
Summer Qin1ce712a2019-10-14 18:04:05 +0800528 * \param[in] client_id Partition ID of the sender of the message
Mingyang Sunf3d29892019-07-10 17:50:23 +0800529 * \param[in] invec Array of input \ref psa_invec structures
530 * \param[in] in_len Number of input \ref psa_invec structures
531 * \param[in] outvec Array of output \ref psa_outvec structures
532 * \param[in] out_len Number of output \ref psa_outvec structures
533 * \param[in] caller_outvec Array of caller output \ref psa_outvec structures
Mingyang Sunf3d29892019-07-10 17:50:23 +0800534 */
Edison Ai97115822019-08-01 14:22:19 +0800535void tfm_spm_fill_msg(struct tfm_msg_body_t *msg,
536 struct tfm_spm_service_t *service,
Ken Liu505b1702020-05-29 13:19:58 +0800537 psa_handle_t handle,
Summer Qin1ce712a2019-10-14 18:04:05 +0800538 int32_t type, int32_t client_id,
Edison Ai97115822019-08-01 14:22:19 +0800539 psa_invec *invec, size_t in_len,
540 psa_outvec *outvec, size_t out_len,
541 psa_outvec *caller_outvec);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800542
543/**
544 * \brief Send message and wake up the SP who is waiting on
545 * message queue, block the current thread and
546 * scheduler triggered
547 *
548 * \param[in] service Target service context pointer, which can be
549 * obtained by partition management functions
550 * \param[in] msg message created by tfm_spm_create_msg()
551 * \ref tfm_msg_body_t structures
552 *
553 * \retval IPC_SUCCESS Success
554 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
555 * \retval IPC_ERROR_GENERIC Failed to enqueue message to service message queue
556 */
557int32_t tfm_spm_send_event(struct tfm_spm_service_t *service,
558 struct tfm_msg_body_t *msg);
559
560/**
Jaykumar Pitambarbhai Patel3a986022019-10-08 17:37:15 +0530561 * \brief Check the client version according to
Mingyang Sunf3d29892019-07-10 17:50:23 +0800562 * version policy
563 *
564 * \param[in] service Target service context pointer, which can be get
565 * by partition management functions
Jaykumar Pitambarbhai Patel3a986022019-10-08 17:37:15 +0530566 * \param[in] version Client support version
Mingyang Sunf3d29892019-07-10 17:50:23 +0800567 *
568 * \retval IPC_SUCCESS Success
569 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
570 * \retval IPC_ERROR_VERSION Check failed
571 */
572int32_t tfm_spm_check_client_version(struct tfm_spm_service_t *service,
Jaykumar Pitambarbhai Patel3a986022019-10-08 17:37:15 +0530573 uint32_t version);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800574
575/**
Edison Aie728fbf2019-11-13 09:37:12 +0800576 * \brief Check the client access authorization
577 *
578 * \param[in] sid Target RoT Service identity
579 * \param[in] service Target service context pointer, which can be get
580 * by partition management functions
581 * \param[in] ns_caller Whether from NS caller
582 *
583 * \retval IPC_SUCCESS Success
584 * \retval IPC_ERROR_GENERIC Authorization check failed
585 */
586int32_t tfm_spm_check_authorization(uint32_t sid,
587 struct tfm_spm_service_t *service,
Summer Qin618e8c32019-12-09 10:47:20 +0800588 bool ns_caller);
Edison Aie728fbf2019-11-13 09:37:12 +0800589
590/**
Mingyang Sunf3d29892019-07-10 17:50:23 +0800591 * \brief Check the memory reference is valid.
592 *
593 * \param[in] buffer Pointer of memory reference
594 * \param[in] len Length of memory reference in bytes
595 * \param[in] ns_caller From non-secure caller
596 * \param[in] access Type of access specified by the
597 * \ref tfm_memory_access_e
598 * \param[in] privileged Privileged mode or unprivileged mode:
599 * \ref TFM_PARTITION_UNPRIVILEGED_MODE
600 * \ref TFM_PARTITION_PRIVILEGED_MODE
601 *
602 * \retval IPC_SUCCESS Success
603 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
604 * \retval IPC_ERROR_MEMORY_CHECK Check failed
605 */
Summer Qin43c185d2019-10-10 15:44:42 +0800606int32_t tfm_memory_check(const void *buffer, size_t len, bool ns_caller,
Mingyang Sunf3d29892019-07-10 17:50:23 +0800607 enum tfm_memory_access_e access,
608 uint32_t privileged);
609
Mingyang Sunf3d29892019-07-10 17:50:23 +0800610/*
611 * PendSV specified function.
612 *
613 * Parameters :
Summer Qind2ad7e72020-01-06 18:16:35 +0800614 * p_actx - Architecture context storage pointer
Mingyang Sunf3d29892019-07-10 17:50:23 +0800615 *
616 * Notes:
617 * This is a staging API. Scheduler should be called in SPM finally and
618 * this function will be obsoleted later.
619 */
Summer Qind2ad7e72020-01-06 18:16:35 +0800620void tfm_pendsv_do_schedule(struct tfm_arch_ctx_t *p_actx);
Mingyang Sunf3d29892019-07-10 17:50:23 +0800621
Ken Liu490281d2019-12-30 15:55:26 +0800622/**
623 * \brief SPM initialization implementation
624 *
625 * \details This function must be called under handler mode.
Ken Liuce2692d2020-02-11 12:39:36 +0800626 * \retval This function returns an EXC_RETURN value. Other
627 * faults would panic the execution and never
628 * returned.
Ken Liu490281d2019-12-30 15:55:26 +0800629 */
Ken Liuce2692d2020-02-11 12:39:36 +0800630uint32_t tfm_spm_init(void);
Ken Liu490281d2019-12-30 15:55:26 +0800631
Shawn Shan6e7be072019-11-29 17:56:29 +0800632/*
633 * \brief This function get the current PSA RoT lifecycle state.
634 *
635 * \return state The current security lifecycle state of the PSA
636 * RoT. The PSA state and implementation state are
637 * encoded as follows:
638 * \arg state[15:8] – PSA lifecycle state
639 * \arg state[7:0] – IMPLEMENTATION DEFINED state
640 */
641uint32_t tfm_spm_get_lifecycle_state(void);
642
Mingyang Sund44522a2020-01-16 16:48:37 +0800643/* Svcall for PSA Client APIs */
644
645/**
646 * \brief SVC handler for \ref psa_framework_version.
647 *
648 * \return version The version of the PSA Framework implementation
649 * that is providing the runtime services to the
650 * caller.
651 */
652uint32_t tfm_spm_psa_framework_version(void);
653
654/**
655 * \brief SVC handler for \ref psa_version.
656 *
657 * \param[in] args Include all input arguments: sid.
658 * \param[in] ns_caller If 'true', call from non-secure client.
659 * Or from secure client.
660 *
661 * \retval PSA_VERSION_NONE The RoT Service is not implemented, or the
662 * caller is not permitted to access the service.
663 * \retval > 0 The version of the implemented RoT Service.
664 */
665uint32_t tfm_spm_psa_version(uint32_t *args, bool ns_caller);
666
667/**
668 * \brief SVC handler for \ref psa_connect.
669 *
670 * \param[in] args Include all input arguments:
671 * sid, version.
672 * \param[in] ns_caller If 'true', call from non-secure client.
673 * Or from secure client.
674 *
675 * \retval PSA_SUCCESS Success.
676 * \retval PSA_ERROR_CONNECTION_REFUSED The SPM or RoT Service has refused the
677 * connection.
678 * \retval PSA_ERROR_CONNECTION_BUSY The SPM or RoT Service cannot make the
679 * connection at the moment.
680 * \retval "Does not return" The RoT Service ID and version are not
681 * supported, or the caller is not permitted to
682 * access the service.
683 */
684psa_status_t tfm_spm_psa_connect(uint32_t *args, bool ns_caller);
685
686/**
687 * \brief SVC handler for \ref psa_call.
688 *
689 * \param[in] args Include all input arguments:
690 * handle, in_vec, in_len, out_vec, out_len.
691 * \param[in] ns_caller If 'true', call from non-secure client.
692 * Or from secure client.
693 * \param[in] lr EXC_RETURN value of the SVC.
694 *
695 * \retval >=0 RoT Service-specific status value.
696 * \retval <0 RoT Service-specific error code.
697 * \retval PSA_ERROR_PROGRAMMER_ERROR The connection has been terminated by the
698 * RoT Service. The call is a PROGRAMMER ERROR if
699 * one or more of the following are true:
700 * \arg An invalid handle was passed.
701 * \arg The connection is already handling a request.
702 * \arg type < 0.
703 * \arg An invalid memory reference was provided.
704 * \arg in_len + out_len > PSA_MAX_IOVEC.
705 * \arg The message is unrecognized by the RoT
706 * Service or incorrectly formatted.
707 */
708psa_status_t tfm_spm_psa_call(uint32_t *args, bool ns_caller, uint32_t lr);
709
710/**
711 * \brief SVC handler for \ref psa_close.
712 *
713 * \param[in] args Include all input arguments: handle.
714 * \param[in] ns_caller If 'true', call from non-secure client.
715 * Or from secure client.
716 *
717 * \retval void Success.
718 * \retval "Does not return" The call is invalid, one or more of the
719 * following are true:
720 * \arg An invalid handle was provided that is not
721 * the null handle.
722 * \arg The connection is handling a request.
723 */
724void tfm_spm_psa_close(uint32_t *args, bool ns_caller);
725
726/* Svcall for PSA Service APIs */
727
728/**
729 * \brief SVC handler for \ref psa_wait.
730 *
731 * \param[in] args Include all input arguments:
732 * signal_mask, timeout.
733 *
734 * \retval >0 At least one signal is asserted.
735 * \retval 0 No signals are asserted. This is only seen when
736 * a polling timeout is used.
737 */
738psa_signal_t tfm_spm_psa_wait(uint32_t *args);
739
740/**
741 * \brief SVC handler for \ref psa_get.
742 *
743 * \param[in] args Include all input arguments: signal, msg.
744 *
745 * \retval PSA_SUCCESS Success, *msg will contain the delivered
746 * message.
747 * \retval PSA_ERROR_DOES_NOT_EXIST Message could not be delivered.
748 * \retval "Does not return" The call is invalid because one or more of the
749 * following are true:
750 * \arg signal has more than a single bit set.
751 * \arg signal does not correspond to an RoT Service.
752 * \arg The RoT Service signal is not currently
753 * asserted.
754 * \arg The msg pointer provided is not a valid memory
755 * reference.
756 */
757psa_status_t tfm_spm_psa_get(uint32_t *args);
758
759/**
760 * \brief SVC handler for \ref psa_set_rhandle.
761 *
762 * \param[in] args Include all input arguments:
763 * msg_handle, rhandle.
764 *
765 * \retval void Success, rhandle will be provided with all
766 * subsequent messages delivered on this
767 * connection.
768 * \retval "Does not return" msg_handle is invalid.
769 */
770void tfm_spm_psa_set_rhandle(uint32_t *args);
771
772/**
773 * \brief SVC handler for \ref psa_read.
774 *
775 * \param[in] args Include all input arguments:
776 * msg_handle, invec_idx, buffer, num_bytes.
777 *
778 * \retval >0 Number of bytes copied.
779 * \retval 0 There was no remaining data in this input
780 * vector.
781 * \retval "Does not return" The call is invalid, one or more of the
782 * following are true:
783 * \arg msg_handle is invalid.
784 * \arg msg_handle does not refer to a request
785 * message.
786 * \arg invec_idx is equal to or greater than
787 * \ref PSA_MAX_IOVEC.
788 * \arg the memory reference for buffer is invalid or
789 * not writable.
790 */
791size_t tfm_spm_psa_read(uint32_t *args);
792
793/**
794 * \brief SVC handler for \ref psa_skip.
795 *
796 * \param[in] args Include all input arguments:
797 * msg_handle, invec_idx, num_bytes.
798 *
799 * \retval >0 Number of bytes skipped.
800 * \retval 0 There was no remaining data in this input
801 * vector.
802 * \retval "Does not return" The call is invalid, one or more of the
803 * following are true:
804 * \arg msg_handle is invalid.
805 * \arg msg_handle does not refer to a request
806 * message.
807 * \arg invec_idx is equal to or greater than
808 * \ref PSA_MAX_IOVEC.
809 */
810size_t tfm_spm_psa_skip(uint32_t *args);
811
812/**
813 * \brief SVC handler for \ref psa_write.
814 *
815 * \param[in] args Include all input arguments:
816 * msg_handle, outvec_idx, buffer, num_bytes.
817 *
818 * \retval void Success
819 * \retval "Does not return" The call is invalid, one or more of the
820 * following are true:
821 * \arg msg_handle is invalid.
822 * \arg msg_handle does not refer to a request
823 * message.
824 * \arg outvec_idx is equal to or greater than
825 * \ref PSA_MAX_IOVEC.
826 * \arg The memory reference for buffer is invalid.
827 * \arg The call attempts to write data past the end
828 * of the client output vector.
829 */
830void tfm_spm_psa_write(uint32_t *args);
831
832/**
833 * \brief SVC handler for \ref psa_reply.
834 *
835 * \param[in] args Include all input arguments:
836 * msg_handle, status.
837 *
838 * \retval void Success.
839 * \retval "Does not return" The call is invalid, one or more of the
840 * following are true:
841 * \arg msg_handle is invalid.
842 * \arg An invalid status code is specified for the
843 * type of message.
844 */
845void tfm_spm_psa_reply(uint32_t *args);
846
847/**
848 * \brief SVC handler for \ref psa_notify.
849 *
850 * \param[in] args Include all input arguments: partition_id.
851 *
852 * \retval void Success.
853 * \retval "Does not return" partition_id does not correspond to a Secure
854 * Partition.
855 */
856void tfm_spm_psa_notify(uint32_t *args);
857
858/**
859 * \brief SVC handler for \ref psa_clear.
860 *
861 * \retval void Success.
862 * \retval "Does not return" The Secure Partition's doorbell signal is not
863 * currently asserted.
864 */
865void tfm_spm_psa_clear(void);
866
867/**
868 * \brief SVC handler for \ref psa_eoi.
869 *
870 * \param[in] args Include all input arguments: irq_signal.
871 *
872 * \retval void Success.
873 * \retval "Does not return" The call is invalid, one or more of the
874 * following are true:
875 * \arg irq_signal is not an interrupt signal.
876 * \arg irq_signal indicates more than one signal.
877 * \arg irq_signal is not currently asserted.
878 */
879void tfm_spm_psa_eoi(uint32_t *args);
880
881/**
Mingyang Sunc3123ec2020-06-11 17:43:58 +0800882 * \brief SVC handler of enabling irq_line of the specified irq_signal.
Mingyang Sund44522a2020-01-16 16:48:37 +0800883 *
884 * \param[in] args Include all input arguments: irq_signal.
885 *
886 * \retval void Success.
887 * \retval "Does not return" The call is invalid, one or more of the
888 * following are true:
889 * \arg irq_signal is not an interrupt signal.
890 * \arg irq_signal indicates more than one signal.
891 */
892void tfm_spm_enable_irq(uint32_t *args);
893
894/**
Mingyang Sunc3123ec2020-06-11 17:43:58 +0800895 * \brief SVC handler of disabling irq_line of the specified irq_signal.
Mingyang Sund44522a2020-01-16 16:48:37 +0800896 *
897 * \param[in] args Include all input arguments: irq_signal.
898 *
899 * \retval void Success.
900 * \retval "Does not return" The call is invalid, one or more of the
901 * following are true:
902 * \arg irq_signal is not an interrupt signal.
903 * \arg irq_signal indicates more than one signal.
904 */
905void tfm_spm_disable_irq(uint32_t *args);
906
907/**
908 * \brief Validate the whether NS caller re-enter.
909 *
910 * \param[in] p_cur_sp Pointer to current partition.
911 * \param[in] p_ctx Pointer to current stack context.
912 * \param[in] exc_return EXC_RETURN value.
913 * \param[in] ns_caller If 'true', call from non-secure client.
914 * Or from secure client.
915 *
916 * \retval void Success.
917 */
918void tfm_spm_validate_caller(struct spm_partition_desc_t *p_cur_sp,
919 uint32_t *p_ctx, uint32_t exc_return,
920 bool ns_caller);
921
922/**
923 * \brief Terminate execution within the calling Secure Partition and will not
924 * return.
925 *
926 * \retval "Does not return"
927 */
928void tfm_spm_psa_panic(void);
929
Summer Qin373feb12020-03-27 15:35:33 +0800930/**
Ken Liu505b1702020-05-29 13:19:58 +0800931 * \brief Converts a handle instance into a corresponded user handle.
932 */
933psa_handle_t tfm_spm_to_user_handle(struct tfm_conn_handle_t *handle_instance);
934
935/**
Summer Qin373feb12020-03-27 15:35:33 +0800936 * \brief Converts a user handle into a corresponded handle instance.
937 */
938struct tfm_conn_handle_t *tfm_spm_to_handle_instance(psa_handle_t user_handle);
939
Mingyang Sund44522a2020-01-16 16:48:37 +0800940#endif /* defined(TFM_PSA_API) */
Mingyang Sunf3d29892019-07-10 17:50:23 +0800941
Miklos Balint386b8b52017-11-29 13:12:32 +0000942#endif /*__SPM_API_H__ */