blob: 8cd6556a439e17a283bae2d0e187c632901ad8dc [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
49/* Store a set of one or more Secure Partition signals */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020050typedef uint32_t psa_signal_t;
51
Kevin Pengf9a0eb02021-01-05 15:06:05 +080052/* A type used to temporarily store a previous interrupt state. */
53typedef uint32_t psa_irq_status_t;
54
Miklos Balint9ecb24c2018-03-29 15:30:28 +020055/**
Edison Aib3e56962018-09-04 19:12:31 +080056 * Describe a message received by an RoT Service after calling \ref psa_get().
Miklos Balint9ecb24c2018-03-29 15:30:28 +020057 */
58typedef struct psa_msg_t {
Summer Qin4b1d03b2019-07-02 14:56:08 +080059 int32_t type; /* One of the following values:
Edison Aib3e56962018-09-04 19:12:31 +080060 * \ref PSA_IPC_CONNECT
Summer Qin4b1d03b2019-07-02 14:56:08 +080061 * >= 0
Edison Aib3e56962018-09-04 19:12:31 +080062 * \ref PSA_IPC_DISCONNECT
63 */
64 psa_handle_t handle; /* A reference generated by the SPM to the
65 * message returned by psa_get().
66 */
67 int32_t client_id; /* Partition ID of the sender of the message */
68 void *rhandle; /* Be useful for binding a connection to some
69 * application-specific data or function
70 * pointer within the RoT Service
71 * implementation.
72 */
73 size_t in_size[PSA_MAX_IOVEC]; /* Provide the size of each client input
74 * vector in bytes.
75 */
76 size_t out_size[PSA_MAX_IOVEC];/* Provide the size of each client output
77 * vector in bytes.
78 */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020079} psa_msg_t;
80
Edison Aib3e56962018-09-04 19:12:31 +080081/************************* PSA Secure Partition API **************************/
Miklos Balint9ecb24c2018-03-29 15:30:28 +020082
83/**
Edison Aib3e56962018-09-04 19:12:31 +080084 * \brief Return the Secure Partition interrupt signals that have been asserted
85 * from a subset of signals provided by the caller.
Miklos Balint9ecb24c2018-03-29 15:30:28 +020086 *
Edison Aib3e56962018-09-04 19:12:31 +080087 * \param[in] signal_mask A set of signals to query. Signals that are not
88 * in this set will be ignored.
89 * \param[in] timeout Specify either blocking \ref PSA_BLOCK or
90 * polling \ref PSA_POLL operation.
Miklos Balint9ecb24c2018-03-29 15:30:28 +020091 *
Edison Aib3e56962018-09-04 19:12:31 +080092 * \retval >0 At least one signal is asserted.
93 * \retval 0 No signals are asserted. This is only seen when
94 * a polling timeout is used.
Miklos Balint9ecb24c2018-03-29 15:30:28 +020095 */
Edison Aib3e56962018-09-04 19:12:31 +080096psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout);
Miklos Balint9ecb24c2018-03-29 15:30:28 +020097
98/**
Edison Aib3e56962018-09-04 19:12:31 +080099 * \brief Retrieve the message which corresponds to a given RoT Service signal
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200100 * and remove the message from the RoT Service queue.
101 *
Edison Aib3e56962018-09-04 19:12:31 +0800102 * \param[in] signal The signal value for an asserted RoT Service.
103 * \param[out] msg Pointer to \ref psa_msg_t object for receiving
104 * the message.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200105 *
Edison Aib3e56962018-09-04 19:12:31 +0800106 * \retval PSA_SUCCESS Success, *msg will contain the delivered
107 * message.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800108 * \retval PSA_ERROR_DOES_NOT_EXIST Message could not be delivered.
109 * \retval "PROGRAMMER ERROR" The call is invalid because one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800110 * following are true:
111 * \arg signal has more than a single bit set.
112 * \arg signal does not correspond to an RoT Service.
113 * \arg The RoT Service signal is not currently
114 * asserted.
115 * \arg The msg pointer provided is not a valid memory
116 * reference.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200117 */
Edison Aib3e56962018-09-04 19:12:31 +0800118psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200119
120/**
Edison Aib3e56962018-09-04 19:12:31 +0800121 * \brief Associate some RoT Service private data with a client connection.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200122 *
Edison Aib3e56962018-09-04 19:12:31 +0800123 * \param[in] msg_handle Handle for the client's message.
124 * \param[in] rhandle Reverse handle allocated by the RoT Service.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200125 *
Edison Aib3e56962018-09-04 19:12:31 +0800126 * \retval void Success, rhandle will be provided with all
127 * subsequent messages delivered on this
128 * connection.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800129 * \retval "PROGRAMMER ERROR" msg_handle is invalid.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200130 */
131void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle);
132
133/**
Edison Aib3e56962018-09-04 19:12:31 +0800134 * \brief Read a message parameter or part of a message parameter from a client
135 * input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200136 *
Edison Aib3e56962018-09-04 19:12:31 +0800137 * \param[in] msg_handle Handle for the client's message.
138 * \param[in] invec_idx Index of the input vector to read from. Must be
139 * less than \ref PSA_MAX_IOVEC.
140 * \param[out] buffer Buffer in the Secure Partition to copy the
141 * requested data to.
142 * \param[in] num_bytes Maximum number of bytes to be read from the
143 * client input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200144 *
Edison Aib3e56962018-09-04 19:12:31 +0800145 * \retval >0 Number of bytes copied.
146 * \retval 0 There was no remaining data in this input
147 * vector.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800148 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800149 * following are true:
150 * \arg msg_handle is invalid.
151 * \arg msg_handle does not refer to a
152 * \ref PSA_IPC_CALL message.
153 * \arg invec_idx is equal to or greater than
154 * \ref PSA_MAX_IOVEC.
155 * \arg the memory reference for buffer is invalid or
156 * not writable.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200157 */
158size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
Edison Aib3e56962018-09-04 19:12:31 +0800159 void *buffer, size_t num_bytes);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200160
161/**
Edison Aib3e56962018-09-04 19:12:31 +0800162 * \brief Skip over part of a client input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200163 *
Edison Aib3e56962018-09-04 19:12:31 +0800164 * \param[in] msg_handle Handle for the client's message.
165 * \param[in] invec_idx Index of input vector to skip from. Must be
166 * less than \ref PSA_MAX_IOVEC.
167 * \param[in] num_bytes Maximum number of bytes to skip in the client
168 * input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200169 *
Edison Aib3e56962018-09-04 19:12:31 +0800170 * \retval >0 Number of bytes skipped.
171 * \retval 0 There was no remaining data in this input
172 * vector.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800173 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800174 * following are true:
175 * \arg msg_handle is invalid.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800176 * \arg msg_handle does not refer to a request
177 * message.
Edison Aib3e56962018-09-04 19:12:31 +0800178 * \arg invec_idx is equal to or greater than
179 * \ref PSA_MAX_IOVEC.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200180 */
181size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes);
182
183/**
Edison Aib3e56962018-09-04 19:12:31 +0800184 * \brief Write a message response to a client output vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200185 *
Edison Aib3e56962018-09-04 19:12:31 +0800186 * \param[in] msg_handle Handle for the client's message.
187 * \param[out] outvec_idx Index of output vector in message to write to.
188 * Must be less than \ref PSA_MAX_IOVEC.
189 * \param[in] buffer Buffer with the data to write.
190 * \param[in] num_bytes Number of bytes to write to the client output
191 * vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200192 *
Edison Aib3e56962018-09-04 19:12:31 +0800193 * \retval void Success
Summer Qin4b1d03b2019-07-02 14:56:08 +0800194 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800195 * following are true:
196 * \arg msg_handle is invalid.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800197 * \arg msg_handle does not refer to a request
198 * message.
Edison Aib3e56962018-09-04 19:12:31 +0800199 * \arg outvec_idx is equal to or greater than
200 * \ref PSA_MAX_IOVEC.
201 * \arg The memory reference for buffer is invalid.
202 * \arg The call attempts to write data past the end
203 * of the client output vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200204 */
205void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
Edison Aib3e56962018-09-04 19:12:31 +0800206 const void *buffer, size_t num_bytes);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200207
208/**
Edison Aib3e56962018-09-04 19:12:31 +0800209 * \brief Complete handling of a specific message and unblock the client.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200210 *
Edison Aib3e56962018-09-04 19:12:31 +0800211 * \param[in] msg_handle Handle for the client's message.
212 * \param[in] status Message result value to be reported to the
213 * client.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200214 *
Edison Aib3e56962018-09-04 19:12:31 +0800215 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800216 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800217 * following are true:
218 * \arg msg_handle is invalid.
219 * \arg An invalid status code is specified for the
220 * type of message.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200221 */
Edison Aib3e56962018-09-04 19:12:31 +0800222void psa_reply(psa_handle_t msg_handle, psa_status_t status);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200223
224/**
Edison Aib3e56962018-09-04 19:12:31 +0800225 * \brief Send a PSA_DOORBELL signal to a specific Secure Partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200226 *
Edison Aib3e56962018-09-04 19:12:31 +0800227 * \param[in] partition_id Secure Partition ID of the target partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200228 *
Edison Aib3e56962018-09-04 19:12:31 +0800229 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800230 * \retval "PROGRAMMER ERROR" partition_id does not correspond to a Secure
Edison Aib3e56962018-09-04 19:12:31 +0800231 * Partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200232 */
233void psa_notify(int32_t partition_id);
234
235/**
Edison Aib3e56962018-09-04 19:12:31 +0800236 * \brief Clear the PSA_DOORBELL signal.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200237 *
Edison Aib3e56962018-09-04 19:12:31 +0800238 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800239 * \retval "PROGRAMMER ERROR" The Secure Partition's doorbell signal is not
Edison Aib3e56962018-09-04 19:12:31 +0800240 * currently asserted.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200241 */
242void psa_clear(void);
243
244/**
Edison Aib3e56962018-09-04 19:12:31 +0800245 * \brief Inform the SPM that an interrupt has been handled (end of interrupt).
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200246 *
Edison Aib3e56962018-09-04 19:12:31 +0800247 * \param[in] irq_signal The interrupt signal that has been processed.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200248 *
Edison Aib3e56962018-09-04 19:12:31 +0800249 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800250 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800251 * following are true:
252 * \arg irq_signal is not an interrupt signal.
253 * \arg irq_signal indicates more than one signal.
254 * \arg irq_signal is not currently asserted.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200255 */
Edison Aib3e56962018-09-04 19:12:31 +0800256void psa_eoi(psa_signal_t irq_signal);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200257
Summer Qin4b1d03b2019-07-02 14:56:08 +0800258/**
259 * \brief Terminate execution within the calling Secure Partition and will not
260 * return.
261 *
262 * \retval "Does not return"
263 */
264void psa_panic(void);
265
Kevin Pengf9a0eb02021-01-05 15:06:05 +0800266/**
267 * \brief Enable an interrupt.
268 *
269 * \param[in] irq_signal The signal for the interrupt to be enabled.
270 * This must have a single bit set, which must be the
271 * signal value for an interrupt in the calling Secure
272 * Partition.
273 *
274 * \retval void
275 * \retval "PROGRAMMER ERROR" If one or more of the following are true:
276 * \ref irq_signal is not an interrupt signal.
277 * \ref irq_signal indicates more than one signal.
278 */
279void psa_irq_enable(psa_signal_t irq_signal);
280
281/**
282 * \brief Disable an interrupt and return the status of the interrupt prior to
283 * being disabled by this call.
284 *
285 * \param[in] irq_signal The signal for the interrupt to be disabled.
286 * This must have a single bit set, which must be the
287 * signal value for an interrupt in the calling Secure
288 * Partition.
289 *
290 * \retval 0 The interrupt was disabled prior to this call.
291 * 1 The interrupt was enabled prior to this call.
292 * \retval "PROGRAMMER ERROR" If one or more of the following are true:
293 * \ref irq_signal is not an interrupt signal.
294 * \ref irq_signal indicates more than one signal.
295 *
296 * \note The current implementation always return 1. Do not use the return.
297 */
298psa_irq_status_t psa_irq_disable(psa_signal_t irq_signal);
299
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200300#ifdef __cplusplus
301}
302#endif
303
304#endif /* __PSA_SERVICE_H__ */