blob: 94eb08230cef2a69aefd31eca0959516245eb04c [file] [log] [blame]
Miklos Balint9ecb24c2018-03-29 15:30:28 +02001/*
Edison Aib3e56962018-09-04 19:12:31 +08002 * Copyright (c) 2018-2019, 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
52/**
Edison Aib3e56962018-09-04 19:12:31 +080053 * Describe a message received by an RoT Service after calling \ref psa_get().
Miklos Balint9ecb24c2018-03-29 15:30:28 +020054 */
55typedef struct psa_msg_t {
Summer Qin4b1d03b2019-07-02 14:56:08 +080056 int32_t type; /* One of the following values:
Edison Aib3e56962018-09-04 19:12:31 +080057 * \ref PSA_IPC_CONNECT
Summer Qin4b1d03b2019-07-02 14:56:08 +080058 * >= 0
Edison Aib3e56962018-09-04 19:12:31 +080059 * \ref PSA_IPC_DISCONNECT
60 */
61 psa_handle_t handle; /* A reference generated by the SPM to the
62 * message returned by psa_get().
63 */
64 int32_t client_id; /* Partition ID of the sender of the message */
65 void *rhandle; /* Be useful for binding a connection to some
66 * application-specific data or function
67 * pointer within the RoT Service
68 * implementation.
69 */
70 size_t in_size[PSA_MAX_IOVEC]; /* Provide the size of each client input
71 * vector in bytes.
72 */
73 size_t out_size[PSA_MAX_IOVEC];/* Provide the size of each client output
74 * vector in bytes.
75 */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020076} psa_msg_t;
77
Edison Aib3e56962018-09-04 19:12:31 +080078/************************* PSA Secure Partition API **************************/
Miklos Balint9ecb24c2018-03-29 15:30:28 +020079
80/**
Edison Aib3e56962018-09-04 19:12:31 +080081 * \brief Return the Secure Partition interrupt signals that have been asserted
82 * from a subset of signals provided by the caller.
Miklos Balint9ecb24c2018-03-29 15:30:28 +020083 *
Edison Aib3e56962018-09-04 19:12:31 +080084 * \param[in] signal_mask A set of signals to query. Signals that are not
85 * in this set will be ignored.
86 * \param[in] timeout Specify either blocking \ref PSA_BLOCK or
87 * polling \ref PSA_POLL operation.
Miklos Balint9ecb24c2018-03-29 15:30:28 +020088 *
Edison Aib3e56962018-09-04 19:12:31 +080089 * \retval >0 At least one signal is asserted.
90 * \retval 0 No signals are asserted. This is only seen when
91 * a polling timeout is used.
Miklos Balint9ecb24c2018-03-29 15:30:28 +020092 */
Edison Aib3e56962018-09-04 19:12:31 +080093psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout);
Miklos Balint9ecb24c2018-03-29 15:30:28 +020094
95/**
Edison Aib3e56962018-09-04 19:12:31 +080096 * \brief Retrieve the message which corresponds to a given RoT Service signal
Miklos Balint9ecb24c2018-03-29 15:30:28 +020097 * and remove the message from the RoT Service queue.
98 *
Edison Aib3e56962018-09-04 19:12:31 +080099 * \param[in] signal The signal value for an asserted RoT Service.
100 * \param[out] msg Pointer to \ref psa_msg_t object for receiving
101 * the message.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200102 *
Edison Aib3e56962018-09-04 19:12:31 +0800103 * \retval PSA_SUCCESS Success, *msg will contain the delivered
104 * message.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800105 * \retval PSA_ERROR_DOES_NOT_EXIST Message could not be delivered.
106 * \retval "PROGRAMMER ERROR" The call is invalid because one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800107 * following are true:
108 * \arg signal has more than a single bit set.
109 * \arg signal does not correspond to an RoT Service.
110 * \arg The RoT Service signal is not currently
111 * asserted.
112 * \arg The msg pointer provided is not a valid memory
113 * reference.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200114 */
Edison Aib3e56962018-09-04 19:12:31 +0800115psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200116
117/**
Edison Aib3e56962018-09-04 19:12:31 +0800118 * \brief Associate some RoT Service private data with a client connection.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200119 *
Edison Aib3e56962018-09-04 19:12:31 +0800120 * \param[in] msg_handle Handle for the client's message.
121 * \param[in] rhandle Reverse handle allocated by the RoT Service.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200122 *
Edison Aib3e56962018-09-04 19:12:31 +0800123 * \retval void Success, rhandle will be provided with all
124 * subsequent messages delivered on this
125 * connection.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800126 * \retval "PROGRAMMER ERROR" msg_handle is invalid.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200127 */
128void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle);
129
130/**
Edison Aib3e56962018-09-04 19:12:31 +0800131 * \brief Read a message parameter or part of a message parameter from a client
132 * input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200133 *
Edison Aib3e56962018-09-04 19:12:31 +0800134 * \param[in] msg_handle Handle for the client's message.
135 * \param[in] invec_idx Index of the input vector to read from. Must be
136 * less than \ref PSA_MAX_IOVEC.
137 * \param[out] buffer Buffer in the Secure Partition to copy the
138 * requested data to.
139 * \param[in] num_bytes Maximum number of bytes to be read from the
140 * client input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200141 *
Edison Aib3e56962018-09-04 19:12:31 +0800142 * \retval >0 Number of bytes copied.
143 * \retval 0 There was no remaining data in this input
144 * vector.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800145 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800146 * following are true:
147 * \arg msg_handle is invalid.
148 * \arg msg_handle does not refer to a
149 * \ref PSA_IPC_CALL message.
150 * \arg invec_idx is equal to or greater than
151 * \ref PSA_MAX_IOVEC.
152 * \arg the memory reference for buffer is invalid or
153 * not writable.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200154 */
155size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
Edison Aib3e56962018-09-04 19:12:31 +0800156 void *buffer, size_t num_bytes);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200157
158/**
Edison Aib3e56962018-09-04 19:12:31 +0800159 * \brief Skip over part of a client input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200160 *
Edison Aib3e56962018-09-04 19:12:31 +0800161 * \param[in] msg_handle Handle for the client's message.
162 * \param[in] invec_idx Index of input vector to skip from. Must be
163 * less than \ref PSA_MAX_IOVEC.
164 * \param[in] num_bytes Maximum number of bytes to skip in the client
165 * input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200166 *
Edison Aib3e56962018-09-04 19:12:31 +0800167 * \retval >0 Number of bytes skipped.
168 * \retval 0 There was no remaining data in this input
169 * vector.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800170 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800171 * following are true:
172 * \arg msg_handle is invalid.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800173 * \arg msg_handle does not refer to a request
174 * message.
Edison Aib3e56962018-09-04 19:12:31 +0800175 * \arg invec_idx is equal to or greater than
176 * \ref PSA_MAX_IOVEC.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200177 */
178size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes);
179
180/**
Edison Aib3e56962018-09-04 19:12:31 +0800181 * \brief Write a message response to a client output vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200182 *
Edison Aib3e56962018-09-04 19:12:31 +0800183 * \param[in] msg_handle Handle for the client's message.
184 * \param[out] outvec_idx Index of output vector in message to write to.
185 * Must be less than \ref PSA_MAX_IOVEC.
186 * \param[in] buffer Buffer with the data to write.
187 * \param[in] num_bytes Number of bytes to write to the client output
188 * vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200189 *
Edison Aib3e56962018-09-04 19:12:31 +0800190 * \retval void Success
Summer Qin4b1d03b2019-07-02 14:56:08 +0800191 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800192 * following are true:
193 * \arg msg_handle is invalid.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800194 * \arg msg_handle does not refer to a request
195 * message.
Edison Aib3e56962018-09-04 19:12:31 +0800196 * \arg outvec_idx is equal to or greater than
197 * \ref PSA_MAX_IOVEC.
198 * \arg The memory reference for buffer is invalid.
199 * \arg The call attempts to write data past the end
200 * of the client output vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200201 */
202void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
Edison Aib3e56962018-09-04 19:12:31 +0800203 const void *buffer, size_t num_bytes);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200204
205/**
Edison Aib3e56962018-09-04 19:12:31 +0800206 * \brief Complete handling of a specific message and unblock the client.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200207 *
Edison Aib3e56962018-09-04 19:12:31 +0800208 * \param[in] msg_handle Handle for the client's message.
209 * \param[in] status Message result value to be reported to the
210 * client.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200211 *
Edison Aib3e56962018-09-04 19:12:31 +0800212 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800213 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800214 * following are true:
215 * \arg msg_handle is invalid.
216 * \arg An invalid status code is specified for the
217 * type of message.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200218 */
Edison Aib3e56962018-09-04 19:12:31 +0800219void psa_reply(psa_handle_t msg_handle, psa_status_t status);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200220
221/**
Edison Aib3e56962018-09-04 19:12:31 +0800222 * \brief Send a PSA_DOORBELL signal to a specific Secure Partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200223 *
Edison Aib3e56962018-09-04 19:12:31 +0800224 * \param[in] partition_id Secure Partition ID of the target partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200225 *
Edison Aib3e56962018-09-04 19:12:31 +0800226 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800227 * \retval "PROGRAMMER ERROR" partition_id does not correspond to a Secure
Edison Aib3e56962018-09-04 19:12:31 +0800228 * Partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200229 */
230void psa_notify(int32_t partition_id);
231
232/**
Edison Aib3e56962018-09-04 19:12:31 +0800233 * \brief Clear the PSA_DOORBELL signal.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200234 *
Edison Aib3e56962018-09-04 19:12:31 +0800235 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800236 * \retval "PROGRAMMER ERROR" The Secure Partition's doorbell signal is not
Edison Aib3e56962018-09-04 19:12:31 +0800237 * currently asserted.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200238 */
239void psa_clear(void);
240
241/**
Edison Aib3e56962018-09-04 19:12:31 +0800242 * \brief Inform the SPM that an interrupt has been handled (end of interrupt).
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200243 *
Edison Aib3e56962018-09-04 19:12:31 +0800244 * \param[in] irq_signal The interrupt signal that has been processed.
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 call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800248 * following are true:
249 * \arg irq_signal is not an interrupt signal.
250 * \arg irq_signal indicates more than one signal.
251 * \arg irq_signal is not currently asserted.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200252 */
Edison Aib3e56962018-09-04 19:12:31 +0800253void psa_eoi(psa_signal_t irq_signal);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200254
Summer Qin4b1d03b2019-07-02 14:56:08 +0800255/**
256 * \brief Terminate execution within the calling Secure Partition and will not
257 * return.
258 *
259 * \retval "Does not return"
260 */
261void psa_panic(void);
262
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200263#ifdef __cplusplus
264}
265#endif
266
267#endif /* __PSA_SERVICE_H__ */