blob: 12efd2e7384e229a645b1d5b15bd0cc3e1ab16e4 [file] [log] [blame]
Miklos Balint9ecb24c2018-03-29 15:30:28 +02001/*
Kevin Pengf9a0eb02021-01-05 15:06:05 +08002 * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
Miklos Balint9ecb24c2018-03-29 15:30:28 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#ifndef __PSA_SERVICE_H__
9#define __PSA_SERVICE_H__
10
Jamie Fox520fb4d2019-06-13 14:27:21 +010011#include <stddef.h>
12#include <stdint.h>
13
14#include "psa/error.h"
15#include "psa/client.h"
16
Miklos Balint9ecb24c2018-03-29 15:30:28 +020017#ifdef __cplusplus
18extern "C" {
19#endif
20
Edison Aib3e56962018-09-04 19:12:31 +080021/********************** PSA Secure Partition Macros and Types ****************/
22
Summer Qin4b1d03b2019-07-02 14:56:08 +080023/**
24 * A timeout value that requests a polling wait operation.
25 */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020026#define PSA_POLL (0x00000000u)
Summer Qin4b1d03b2019-07-02 14:56:08 +080027
28/**
29 * A timeout value that requests a blocking wait operation.
30 */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020031#define PSA_BLOCK (0x80000000u)
32
Summer Qin4b1d03b2019-07-02 14:56:08 +080033/**
34 * A mask value that includes all Secure Partition signals.
35 */
36#define PSA_WAIT_ANY (0xFFFFFFFFu)
Edison Aib3e56962018-09-04 19:12:31 +080037
Summer Qin4b1d03b2019-07-02 14:56:08 +080038/**
39 * The signal number for the Secure Partition doorbell.
40 */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020041#define PSA_DOORBELL (0x00000008u)
42
43/* PSA message types */
Summer Qin4b1d03b2019-07-02 14:56:08 +080044/* An IPC message type that indicates a new connection. */
45#define PSA_IPC_CONNECT (-1)
46/* An IPC message type that indicates the end of a connection. */
47#define PSA_IPC_DISCONNECT (-2)
Edison Aib3e56962018-09-04 19:12:31 +080048
Kevin Peng9280ae92021-01-13 14:42:10 +080049/* FLIH return types */
50#define PSA_FLIH_NO_SIGNAL ((psa_flih_result_t) 0)
51#define PSA_FLIH_SIGNAL ((psa_flih_result_t) 1)
52
Edison Aib3e56962018-09-04 19:12:31 +080053/* Store a set of one or more Secure Partition signals */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020054typedef uint32_t psa_signal_t;
55
Kevin Pengf9a0eb02021-01-05 15:06:05 +080056/* A type used to temporarily store a previous interrupt state. */
57typedef uint32_t psa_irq_status_t;
58
Kevin Peng9280ae92021-01-13 14:42:10 +080059/* The type of the return value from an FLIH function */
60typedef uint32_t psa_flih_result_t;
61
Miklos Balint9ecb24c2018-03-29 15:30:28 +020062/**
Edison Aib3e56962018-09-04 19:12:31 +080063 * Describe a message received by an RoT Service after calling \ref psa_get().
Miklos Balint9ecb24c2018-03-29 15:30:28 +020064 */
65typedef struct psa_msg_t {
Summer Qin4b1d03b2019-07-02 14:56:08 +080066 int32_t type; /* One of the following values:
Edison Aib3e56962018-09-04 19:12:31 +080067 * \ref PSA_IPC_CONNECT
Summer Qin4b1d03b2019-07-02 14:56:08 +080068 * >= 0
Edison Aib3e56962018-09-04 19:12:31 +080069 * \ref PSA_IPC_DISCONNECT
70 */
71 psa_handle_t handle; /* A reference generated by the SPM to the
72 * message returned by psa_get().
73 */
74 int32_t client_id; /* Partition ID of the sender of the message */
75 void *rhandle; /* Be useful for binding a connection to some
76 * application-specific data or function
77 * pointer within the RoT Service
78 * implementation.
79 */
80 size_t in_size[PSA_MAX_IOVEC]; /* Provide the size of each client input
81 * vector in bytes.
82 */
83 size_t out_size[PSA_MAX_IOVEC];/* Provide the size of each client output
84 * vector in bytes.
85 */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020086} psa_msg_t;
87
Edison Aib3e56962018-09-04 19:12:31 +080088/************************* PSA Secure Partition API **************************/
Miklos Balint9ecb24c2018-03-29 15:30:28 +020089
90/**
Edison Aib3e56962018-09-04 19:12:31 +080091 * \brief Return the Secure Partition interrupt signals that have been asserted
92 * from a subset of signals provided by the caller.
Miklos Balint9ecb24c2018-03-29 15:30:28 +020093 *
Edison Aib3e56962018-09-04 19:12:31 +080094 * \param[in] signal_mask A set of signals to query. Signals that are not
95 * in this set will be ignored.
96 * \param[in] timeout Specify either blocking \ref PSA_BLOCK or
97 * polling \ref PSA_POLL operation.
Miklos Balint9ecb24c2018-03-29 15:30:28 +020098 *
Edison Aib3e56962018-09-04 19:12:31 +080099 * \retval >0 At least one signal is asserted.
100 * \retval 0 No signals are asserted. This is only seen when
101 * a polling timeout is used.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200102 */
Edison Aib3e56962018-09-04 19:12:31 +0800103psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200104
105/**
Edison Aib3e56962018-09-04 19:12:31 +0800106 * \brief Retrieve the message which corresponds to a given RoT Service signal
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200107 * and remove the message from the RoT Service queue.
108 *
Edison Aib3e56962018-09-04 19:12:31 +0800109 * \param[in] signal The signal value for an asserted RoT Service.
110 * \param[out] msg Pointer to \ref psa_msg_t object for receiving
111 * the message.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200112 *
Edison Aib3e56962018-09-04 19:12:31 +0800113 * \retval PSA_SUCCESS Success, *msg will contain the delivered
114 * message.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800115 * \retval PSA_ERROR_DOES_NOT_EXIST Message could not be delivered.
116 * \retval "PROGRAMMER ERROR" The call is invalid because one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800117 * following are true:
118 * \arg signal has more than a single bit set.
119 * \arg signal does not correspond to an RoT Service.
120 * \arg The RoT Service signal is not currently
121 * asserted.
122 * \arg The msg pointer provided is not a valid memory
123 * reference.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200124 */
Edison Aib3e56962018-09-04 19:12:31 +0800125psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200126
127/**
Edison Aib3e56962018-09-04 19:12:31 +0800128 * \brief Associate some RoT Service private data with a client connection.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200129 *
Edison Aib3e56962018-09-04 19:12:31 +0800130 * \param[in] msg_handle Handle for the client's message.
131 * \param[in] rhandle Reverse handle allocated by the RoT Service.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200132 *
Edison Aib3e56962018-09-04 19:12:31 +0800133 * \retval void Success, rhandle will be provided with all
134 * subsequent messages delivered on this
135 * connection.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800136 * \retval "PROGRAMMER ERROR" msg_handle is invalid.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200137 */
138void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle);
139
140/**
Edison Aib3e56962018-09-04 19:12:31 +0800141 * \brief Read a message parameter or part of a message parameter from a client
142 * input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200143 *
Edison Aib3e56962018-09-04 19:12:31 +0800144 * \param[in] msg_handle Handle for the client's message.
145 * \param[in] invec_idx Index of the input vector to read from. Must be
146 * less than \ref PSA_MAX_IOVEC.
147 * \param[out] buffer Buffer in the Secure Partition to copy the
148 * requested data to.
149 * \param[in] num_bytes Maximum number of bytes to be read from the
150 * client input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200151 *
Edison Aib3e56962018-09-04 19:12:31 +0800152 * \retval >0 Number of bytes copied.
153 * \retval 0 There was no remaining data in this input
154 * vector.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800155 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800156 * following are true:
157 * \arg msg_handle is invalid.
158 * \arg msg_handle does not refer to a
159 * \ref PSA_IPC_CALL message.
160 * \arg invec_idx is equal to or greater than
161 * \ref PSA_MAX_IOVEC.
162 * \arg the memory reference for buffer is invalid or
163 * not writable.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200164 */
165size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
Edison Aib3e56962018-09-04 19:12:31 +0800166 void *buffer, size_t num_bytes);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200167
168/**
Edison Aib3e56962018-09-04 19:12:31 +0800169 * \brief Skip over part of a client input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200170 *
Edison Aib3e56962018-09-04 19:12:31 +0800171 * \param[in] msg_handle Handle for the client's message.
172 * \param[in] invec_idx Index of input vector to skip from. Must be
173 * less than \ref PSA_MAX_IOVEC.
174 * \param[in] num_bytes Maximum number of bytes to skip in the client
175 * input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200176 *
Edison Aib3e56962018-09-04 19:12:31 +0800177 * \retval >0 Number of bytes skipped.
178 * \retval 0 There was no remaining data in this input
179 * vector.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800180 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800181 * following are true:
182 * \arg msg_handle is invalid.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800183 * \arg msg_handle does not refer to a request
184 * message.
Edison Aib3e56962018-09-04 19:12:31 +0800185 * \arg invec_idx is equal to or greater than
186 * \ref PSA_MAX_IOVEC.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200187 */
188size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes);
189
190/**
Edison Aib3e56962018-09-04 19:12:31 +0800191 * \brief Write a message response to a client output vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200192 *
Edison Aib3e56962018-09-04 19:12:31 +0800193 * \param[in] msg_handle Handle for the client's message.
194 * \param[out] outvec_idx Index of output vector in message to write to.
195 * Must be less than \ref PSA_MAX_IOVEC.
196 * \param[in] buffer Buffer with the data to write.
197 * \param[in] num_bytes Number of bytes to write to the client output
198 * vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200199 *
Edison Aib3e56962018-09-04 19:12:31 +0800200 * \retval void Success
Summer Qin4b1d03b2019-07-02 14:56:08 +0800201 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800202 * following are true:
203 * \arg msg_handle is invalid.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800204 * \arg msg_handle does not refer to a request
205 * message.
Edison Aib3e56962018-09-04 19:12:31 +0800206 * \arg outvec_idx is equal to or greater than
207 * \ref PSA_MAX_IOVEC.
208 * \arg The memory reference for buffer is invalid.
209 * \arg The call attempts to write data past the end
210 * of the client output vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200211 */
212void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
Edison Aib3e56962018-09-04 19:12:31 +0800213 const void *buffer, size_t num_bytes);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200214
215/**
Edison Aib3e56962018-09-04 19:12:31 +0800216 * \brief Complete handling of a specific message and unblock the client.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200217 *
Edison Aib3e56962018-09-04 19:12:31 +0800218 * \param[in] msg_handle Handle for the client's message.
219 * \param[in] status Message result value to be reported to the
220 * client.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200221 *
Edison Aib3e56962018-09-04 19:12:31 +0800222 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800223 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800224 * following are true:
225 * \arg msg_handle is invalid.
226 * \arg An invalid status code is specified for the
227 * type of message.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200228 */
Edison Aib3e56962018-09-04 19:12:31 +0800229void psa_reply(psa_handle_t msg_handle, psa_status_t status);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200230
231/**
Edison Aib3e56962018-09-04 19:12:31 +0800232 * \brief Send a PSA_DOORBELL signal to a specific Secure Partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200233 *
Edison Aib3e56962018-09-04 19:12:31 +0800234 * \param[in] partition_id Secure Partition ID of the target partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200235 *
Edison Aib3e56962018-09-04 19:12:31 +0800236 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800237 * \retval "PROGRAMMER ERROR" partition_id does not correspond to a Secure
Edison Aib3e56962018-09-04 19:12:31 +0800238 * Partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200239 */
240void psa_notify(int32_t partition_id);
241
242/**
Edison Aib3e56962018-09-04 19:12:31 +0800243 * \brief Clear the PSA_DOORBELL signal.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200244 *
Edison Aib3e56962018-09-04 19:12:31 +0800245 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800246 * \retval "PROGRAMMER ERROR" The Secure Partition's doorbell signal is not
Edison Aib3e56962018-09-04 19:12:31 +0800247 * currently asserted.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200248 */
249void psa_clear(void);
250
251/**
Edison Aib3e56962018-09-04 19:12:31 +0800252 * \brief Inform the SPM that an interrupt has been handled (end of interrupt).
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200253 *
Edison Aib3e56962018-09-04 19:12:31 +0800254 * \param[in] irq_signal The interrupt signal that has been processed.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200255 *
Edison Aib3e56962018-09-04 19:12:31 +0800256 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800257 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800258 * following are true:
259 * \arg irq_signal is not an interrupt signal.
260 * \arg irq_signal indicates more than one signal.
261 * \arg irq_signal is not currently asserted.
Kevin Peng9280ae92021-01-13 14:42:10 +0800262 * \arg The interrupt is not using SLIH.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200263 */
Edison Aib3e56962018-09-04 19:12:31 +0800264void psa_eoi(psa_signal_t irq_signal);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200265
Summer Qin4b1d03b2019-07-02 14:56:08 +0800266/**
267 * \brief Terminate execution within the calling Secure Partition and will not
268 * return.
269 *
270 * \retval "Does not return"
271 */
272void psa_panic(void);
273
Kevin Pengf9a0eb02021-01-05 15:06:05 +0800274/**
275 * \brief Enable an interrupt.
276 *
277 * \param[in] irq_signal The signal for the interrupt to be enabled.
278 * This must have a single bit set, which must be the
279 * signal value for an interrupt in the calling Secure
280 * Partition.
281 *
282 * \retval void
283 * \retval "PROGRAMMER ERROR" If one or more of the following are true:
Kevin Peng9280ae92021-01-13 14:42:10 +0800284 * \arg \a irq_signal is not an interrupt signal.
285 * \arg \a irq_signal indicates more than one signal.
Kevin Pengf9a0eb02021-01-05 15:06:05 +0800286 */
287void psa_irq_enable(psa_signal_t irq_signal);
288
289/**
290 * \brief Disable an interrupt and return the status of the interrupt prior to
291 * being disabled by this call.
292 *
293 * \param[in] irq_signal The signal for the interrupt to be disabled.
294 * This must have a single bit set, which must be the
295 * signal value for an interrupt in the calling Secure
296 * Partition.
297 *
298 * \retval 0 The interrupt was disabled prior to this call.
299 * 1 The interrupt was enabled prior to this call.
300 * \retval "PROGRAMMER ERROR" If one or more of the following are true:
Kevin Peng9280ae92021-01-13 14:42:10 +0800301 * \arg \a irq_signal is not an interrupt signal.
302 * \arg \a irq_signal indicates more than one signal.
Kevin Pengf9a0eb02021-01-05 15:06:05 +0800303 *
304 * \note The current implementation always return 1. Do not use the return.
305 */
306psa_irq_status_t psa_irq_disable(psa_signal_t irq_signal);
307
Kevin Peng9280ae92021-01-13 14:42:10 +0800308/**
309 * \brief Reset the signal for an interrupt that is using FLIH handling.
310 *
311 * \param[in] irq_signal The interrupt signal to be reset.
312 * This must have a single bit set, corresponding to a
313 * currently asserted signal for an interrupt that is
314 * defined to use FLIH handling.
315 *
316 * \retval void
317 * \retval "Programmer Error" if one or more of the following are true:
318 * \arg \a irq_signal is not a signal for an interrupt
319 * that is specified with FLIH handling in the Secure
320 * Partition manifest.
321 * \arg \a irq_signal indicates more than one signal.
322 * \arg \a irq_signal is not currently asserted.
323 */
324void psa_reset_signal(psa_signal_t irq_signal);
325
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200326#ifdef __cplusplus
327}
328#endif
329
330#endif /* __PSA_SERVICE_H__ */