blob: 2c94f4c7ff9420dba3fa672ceca28b6412bcbbee [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
Jamie Fox520fb4d2019-06-13 14:27:21 +010014#include "psa/client.h"
Ken Liu82e3eac2021-10-14 16:19:13 +080015#include "psa_config.h"
16#include "psa/error.h"
Jamie Fox520fb4d2019-06-13 14:27:21 +010017
Miklos Balint9ecb24c2018-03-29 15:30:28 +020018#ifdef __cplusplus
19extern "C" {
20#endif
21
Edison Aib3e56962018-09-04 19:12:31 +080022/********************** PSA Secure Partition Macros and Types ****************/
23
Summer Qin4b1d03b2019-07-02 14:56:08 +080024/**
25 * A timeout value that requests a polling wait operation.
26 */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020027#define PSA_POLL (0x00000000u)
Summer Qin4b1d03b2019-07-02 14:56:08 +080028
29/**
30 * A timeout value that requests a blocking wait operation.
31 */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020032#define PSA_BLOCK (0x80000000u)
33
Summer Qin4b1d03b2019-07-02 14:56:08 +080034/**
35 * A mask value that includes all Secure Partition signals.
36 */
37#define PSA_WAIT_ANY (0xFFFFFFFFu)
Edison Aib3e56962018-09-04 19:12:31 +080038
Summer Qin4b1d03b2019-07-02 14:56:08 +080039/**
40 * The signal number for the Secure Partition doorbell.
41 */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020042#define PSA_DOORBELL (0x00000008u)
43
44/* PSA message types */
Summer Qin4b1d03b2019-07-02 14:56:08 +080045/* An IPC message type that indicates a new connection. */
46#define PSA_IPC_CONNECT (-1)
47/* An IPC message type that indicates the end of a connection. */
48#define PSA_IPC_DISCONNECT (-2)
Edison Aib3e56962018-09-04 19:12:31 +080049
Kevin Peng9280ae92021-01-13 14:42:10 +080050/* FLIH return types */
51#define PSA_FLIH_NO_SIGNAL ((psa_flih_result_t) 0)
52#define PSA_FLIH_SIGNAL ((psa_flih_result_t) 1)
53
Edison Aib3e56962018-09-04 19:12:31 +080054/* Store a set of one or more Secure Partition signals */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020055typedef uint32_t psa_signal_t;
56
Kevin Pengf9a0eb02021-01-05 15:06:05 +080057/* A type used to temporarily store a previous interrupt state. */
58typedef uint32_t psa_irq_status_t;
59
Kevin Peng9280ae92021-01-13 14:42:10 +080060/* The type of the return value from an FLIH function */
61typedef uint32_t psa_flih_result_t;
62
Miklos Balint9ecb24c2018-03-29 15:30:28 +020063/**
Edison Aib3e56962018-09-04 19:12:31 +080064 * Describe a message received by an RoT Service after calling \ref psa_get().
Miklos Balint9ecb24c2018-03-29 15:30:28 +020065 */
66typedef struct psa_msg_t {
Summer Qin4b1d03b2019-07-02 14:56:08 +080067 int32_t type; /* One of the following values:
Edison Aib3e56962018-09-04 19:12:31 +080068 * \ref PSA_IPC_CONNECT
Summer Qin4b1d03b2019-07-02 14:56:08 +080069 * >= 0
Edison Aib3e56962018-09-04 19:12:31 +080070 * \ref PSA_IPC_DISCONNECT
71 */
72 psa_handle_t handle; /* A reference generated by the SPM to the
73 * message returned by psa_get().
74 */
75 int32_t client_id; /* Partition ID of the sender of the message */
76 void *rhandle; /* Be useful for binding a connection to some
77 * application-specific data or function
78 * pointer within the RoT Service
79 * implementation.
80 */
81 size_t in_size[PSA_MAX_IOVEC]; /* Provide the size of each client input
82 * vector in bytes.
83 */
84 size_t out_size[PSA_MAX_IOVEC];/* Provide the size of each client output
85 * vector in bytes.
86 */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020087} psa_msg_t;
88
Edison Aib3e56962018-09-04 19:12:31 +080089/************************* PSA Secure Partition API **************************/
Miklos Balint9ecb24c2018-03-29 15:30:28 +020090
91/**
Edison Aib3e56962018-09-04 19:12:31 +080092 * \brief Return the Secure Partition interrupt signals that have been asserted
93 * from a subset of signals provided by the caller.
Miklos Balint9ecb24c2018-03-29 15:30:28 +020094 *
Edison Aib3e56962018-09-04 19:12:31 +080095 * \param[in] signal_mask A set of signals to query. Signals that are not
96 * in this set will be ignored.
97 * \param[in] timeout Specify either blocking \ref PSA_BLOCK or
98 * polling \ref PSA_POLL operation.
Miklos Balint9ecb24c2018-03-29 15:30:28 +020099 *
Edison Aib3e56962018-09-04 19:12:31 +0800100 * \retval >0 At least one signal is asserted.
101 * \retval 0 No signals are asserted. This is only seen when
102 * a polling timeout is used.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200103 */
Edison Aib3e56962018-09-04 19:12:31 +0800104psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200105
106/**
Edison Aib3e56962018-09-04 19:12:31 +0800107 * \brief Retrieve the message which corresponds to a given RoT Service signal
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200108 * and remove the message from the RoT Service queue.
109 *
Edison Aib3e56962018-09-04 19:12:31 +0800110 * \param[in] signal The signal value for an asserted RoT Service.
111 * \param[out] msg Pointer to \ref psa_msg_t object for receiving
112 * the message.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200113 *
Edison Aib3e56962018-09-04 19:12:31 +0800114 * \retval PSA_SUCCESS Success, *msg will contain the delivered
115 * message.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800116 * \retval PSA_ERROR_DOES_NOT_EXIST Message could not be delivered.
117 * \retval "PROGRAMMER ERROR" The call is invalid because one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800118 * following are true:
119 * \arg signal has more than a single bit set.
120 * \arg signal does not correspond to an RoT Service.
121 * \arg The RoT Service signal is not currently
122 * asserted.
123 * \arg The msg pointer provided is not a valid memory
124 * reference.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200125 */
Edison Aib3e56962018-09-04 19:12:31 +0800126psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200127
128/**
Edison Aib3e56962018-09-04 19:12:31 +0800129 * \brief Associate some RoT Service private data with a client connection.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200130 *
Edison Aib3e56962018-09-04 19:12:31 +0800131 * \param[in] msg_handle Handle for the client's message.
132 * \param[in] rhandle Reverse handle allocated by the RoT Service.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200133 *
Edison Aib3e56962018-09-04 19:12:31 +0800134 * \retval void Success, rhandle will be provided with all
135 * subsequent messages delivered on this
136 * connection.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800137 * \retval "PROGRAMMER ERROR" msg_handle is invalid.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200138 */
139void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle);
140
141/**
Edison Aib3e56962018-09-04 19:12:31 +0800142 * \brief Read a message parameter or part of a message parameter from a client
143 * input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200144 *
Edison Aib3e56962018-09-04 19:12:31 +0800145 * \param[in] msg_handle Handle for the client's message.
146 * \param[in] invec_idx Index of the input vector to read from. Must be
147 * less than \ref PSA_MAX_IOVEC.
148 * \param[out] buffer Buffer in the Secure Partition to copy the
149 * requested data to.
150 * \param[in] num_bytes Maximum number of bytes to be read from the
151 * client input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200152 *
Edison Aib3e56962018-09-04 19:12:31 +0800153 * \retval >0 Number of bytes copied.
154 * \retval 0 There was no remaining data in this input
155 * vector.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800156 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800157 * following are true:
158 * \arg msg_handle is invalid.
159 * \arg msg_handle does not refer to a
160 * \ref PSA_IPC_CALL message.
161 * \arg invec_idx is equal to or greater than
162 * \ref PSA_MAX_IOVEC.
163 * \arg the memory reference for buffer is invalid or
164 * not writable.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200165 */
166size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
Edison Aib3e56962018-09-04 19:12:31 +0800167 void *buffer, size_t num_bytes);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200168
169/**
Edison Aib3e56962018-09-04 19:12:31 +0800170 * \brief Skip over part of a client input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200171 *
Edison Aib3e56962018-09-04 19:12:31 +0800172 * \param[in] msg_handle Handle for the client's message.
173 * \param[in] invec_idx Index of input vector to skip from. Must be
174 * less than \ref PSA_MAX_IOVEC.
175 * \param[in] num_bytes Maximum number of bytes to skip in the client
176 * input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200177 *
Edison Aib3e56962018-09-04 19:12:31 +0800178 * \retval >0 Number of bytes skipped.
179 * \retval 0 There was no remaining data in this input
180 * vector.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800181 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800182 * following are true:
183 * \arg msg_handle is invalid.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800184 * \arg msg_handle does not refer to a request
185 * message.
Edison Aib3e56962018-09-04 19:12:31 +0800186 * \arg invec_idx is equal to or greater than
187 * \ref PSA_MAX_IOVEC.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200188 */
189size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes);
190
191/**
Edison Aib3e56962018-09-04 19:12:31 +0800192 * \brief Write a message response to a client output vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200193 *
Edison Aib3e56962018-09-04 19:12:31 +0800194 * \param[in] msg_handle Handle for the client's message.
195 * \param[out] outvec_idx Index of output vector in message to write to.
196 * Must be less than \ref PSA_MAX_IOVEC.
197 * \param[in] buffer Buffer with the data to write.
198 * \param[in] num_bytes Number of bytes to write to the client output
199 * vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200200 *
Edison Aib3e56962018-09-04 19:12:31 +0800201 * \retval void Success
Summer Qin4b1d03b2019-07-02 14:56:08 +0800202 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800203 * following are true:
204 * \arg msg_handle is invalid.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800205 * \arg msg_handle does not refer to a request
206 * message.
Edison Aib3e56962018-09-04 19:12:31 +0800207 * \arg outvec_idx is equal to or greater than
208 * \ref PSA_MAX_IOVEC.
209 * \arg The memory reference for buffer is invalid.
210 * \arg The call attempts to write data past the end
211 * of the client output vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200212 */
213void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
Edison Aib3e56962018-09-04 19:12:31 +0800214 const void *buffer, size_t num_bytes);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200215
216/**
Edison Aib3e56962018-09-04 19:12:31 +0800217 * \brief Complete handling of a specific message and unblock the client.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200218 *
Edison Aib3e56962018-09-04 19:12:31 +0800219 * \param[in] msg_handle Handle for the client's message.
220 * \param[in] status Message result value to be reported to the
221 * client.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200222 *
Edison Aib3e56962018-09-04 19:12:31 +0800223 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800224 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800225 * following are true:
226 * \arg msg_handle is invalid.
227 * \arg An invalid status code is specified for the
228 * type of message.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200229 */
Edison Aib3e56962018-09-04 19:12:31 +0800230void psa_reply(psa_handle_t msg_handle, psa_status_t status);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200231
232/**
Edison Aib3e56962018-09-04 19:12:31 +0800233 * \brief Send a PSA_DOORBELL signal to a specific Secure Partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200234 *
Edison Aib3e56962018-09-04 19:12:31 +0800235 * \param[in] partition_id Secure Partition ID of the target partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200236 *
Edison Aib3e56962018-09-04 19:12:31 +0800237 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800238 * \retval "PROGRAMMER ERROR" partition_id does not correspond to a Secure
Edison Aib3e56962018-09-04 19:12:31 +0800239 * Partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200240 */
241void psa_notify(int32_t partition_id);
242
243/**
Edison Aib3e56962018-09-04 19:12:31 +0800244 * \brief Clear the PSA_DOORBELL signal.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200245 *
Edison Aib3e56962018-09-04 19:12:31 +0800246 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800247 * \retval "PROGRAMMER ERROR" The Secure Partition's doorbell signal is not
Edison Aib3e56962018-09-04 19:12:31 +0800248 * currently asserted.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200249 */
250void psa_clear(void);
251
252/**
Edison Aib3e56962018-09-04 19:12:31 +0800253 * \brief Inform the SPM that an interrupt has been handled (end of interrupt).
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200254 *
Edison Aib3e56962018-09-04 19:12:31 +0800255 * \param[in] irq_signal The interrupt signal that has been processed.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200256 *
Edison Aib3e56962018-09-04 19:12:31 +0800257 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800258 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800259 * following are true:
260 * \arg irq_signal is not an interrupt signal.
261 * \arg irq_signal indicates more than one signal.
262 * \arg irq_signal is not currently asserted.
Kevin Peng9280ae92021-01-13 14:42:10 +0800263 * \arg The interrupt is not using SLIH.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200264 */
Edison Aib3e56962018-09-04 19:12:31 +0800265void psa_eoi(psa_signal_t irq_signal);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200266
Summer Qin4b1d03b2019-07-02 14:56:08 +0800267/**
268 * \brief Terminate execution within the calling Secure Partition and will not
269 * return.
270 *
271 * \retval "Does not return"
272 */
273void psa_panic(void);
274
Kevin Pengf9a0eb02021-01-05 15:06:05 +0800275/**
276 * \brief Enable an interrupt.
277 *
278 * \param[in] irq_signal The signal for the interrupt to be enabled.
279 * This must have a single bit set, which must be the
280 * signal value for an interrupt in the calling Secure
281 * Partition.
282 *
283 * \retval void
284 * \retval "PROGRAMMER ERROR" If one or more of the following are true:
Kevin Peng9280ae92021-01-13 14:42:10 +0800285 * \arg \a irq_signal is not an interrupt signal.
286 * \arg \a irq_signal indicates more than one signal.
Kevin Pengf9a0eb02021-01-05 15:06:05 +0800287 */
288void psa_irq_enable(psa_signal_t irq_signal);
289
290/**
291 * \brief Disable an interrupt and return the status of the interrupt prior to
292 * being disabled by this call.
293 *
294 * \param[in] irq_signal The signal for the interrupt to be disabled.
295 * This must have a single bit set, which must be the
296 * signal value for an interrupt in the calling Secure
297 * Partition.
298 *
299 * \retval 0 The interrupt was disabled prior to this call.
300 * 1 The interrupt was enabled prior to this call.
301 * \retval "PROGRAMMER ERROR" If one or more of the following are true:
Kevin Peng9280ae92021-01-13 14:42:10 +0800302 * \arg \a irq_signal is not an interrupt signal.
303 * \arg \a irq_signal indicates more than one signal.
Kevin Pengf9a0eb02021-01-05 15:06:05 +0800304 *
305 * \note The current implementation always return 1. Do not use the return.
306 */
307psa_irq_status_t psa_irq_disable(psa_signal_t irq_signal);
308
Kevin Peng9280ae92021-01-13 14:42:10 +0800309/**
310 * \brief Reset the signal for an interrupt that is using FLIH handling.
311 *
312 * \param[in] irq_signal The interrupt signal to be reset.
313 * This must have a single bit set, corresponding to a
314 * currently asserted signal for an interrupt that is
315 * defined to use FLIH handling.
316 *
317 * \retval void
318 * \retval "Programmer Error" if one or more of the following are true:
319 * \arg \a irq_signal is not a signal for an interrupt
320 * that is specified with FLIH handling in the Secure
321 * Partition manifest.
322 * \arg \a irq_signal indicates more than one signal.
323 * \arg \a irq_signal is not currently asserted.
324 */
325void psa_reset_signal(psa_signal_t irq_signal);
326
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200327#ifdef __cplusplus
328}
329#endif
330
331#endif /* __PSA_SERVICE_H__ */