blob: 8addb75c67ee49a3d9c7e12d17a7a5e39408d534 [file] [log] [blame]
Miklos Balint9ecb24c2018-03-29 15:30:28 +02001/*
Kevin Penge61e7052022-01-27 14:57:06 +08002 * Copyright (c) 2018-2022, 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"
Shawn Shan038348e2021-09-08 17:11:04 +080017#include "psa/framework_feature.h"
Jamie Fox520fb4d2019-06-13 14:27:21 +010018
Miklos Balint9ecb24c2018-03-29 15:30:28 +020019#ifdef __cplusplus
20extern "C" {
21#endif
22
Edison Aib3e56962018-09-04 19:12:31 +080023/********************** PSA Secure Partition Macros and Types ****************/
24
Summer Qin4b1d03b2019-07-02 14:56:08 +080025/**
26 * A timeout value that requests a polling wait operation.
27 */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020028#define PSA_POLL (0x00000000u)
Summer Qin4b1d03b2019-07-02 14:56:08 +080029
30/**
31 * A timeout value that requests a blocking wait operation.
32 */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020033#define PSA_BLOCK (0x80000000u)
34
Summer Qin4b1d03b2019-07-02 14:56:08 +080035/**
36 * A mask value that includes all Secure Partition signals.
37 */
38#define PSA_WAIT_ANY (0xFFFFFFFFu)
Edison Aib3e56962018-09-04 19:12:31 +080039
Summer Qin4b1d03b2019-07-02 14:56:08 +080040/**
41 * The signal number for the Secure Partition doorbell.
42 */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020043#define PSA_DOORBELL (0x00000008u)
44
45/* PSA message types */
Summer Qin4b1d03b2019-07-02 14:56:08 +080046/* An IPC message type that indicates a new connection. */
47#define PSA_IPC_CONNECT (-1)
48/* An IPC message type that indicates the end of a connection. */
49#define PSA_IPC_DISCONNECT (-2)
Edison Aib3e56962018-09-04 19:12:31 +080050
Kevin Peng9280ae92021-01-13 14:42:10 +080051/* FLIH return types */
52#define PSA_FLIH_NO_SIGNAL ((psa_flih_result_t) 0)
53#define PSA_FLIH_SIGNAL ((psa_flih_result_t) 1)
54
Edison Aib3e56962018-09-04 19:12:31 +080055/* Store a set of one or more Secure Partition signals */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020056typedef uint32_t psa_signal_t;
57
Kevin Pengf9a0eb02021-01-05 15:06:05 +080058/* A type used to temporarily store a previous interrupt state. */
59typedef uint32_t psa_irq_status_t;
60
Kevin Peng9280ae92021-01-13 14:42:10 +080061/* The type of the return value from an FLIH function */
62typedef uint32_t psa_flih_result_t;
63
Miklos Balint9ecb24c2018-03-29 15:30:28 +020064/**
Edison Aib3e56962018-09-04 19:12:31 +080065 * Describe a message received by an RoT Service after calling \ref psa_get().
Miklos Balint9ecb24c2018-03-29 15:30:28 +020066 */
67typedef struct psa_msg_t {
Summer Qin4b1d03b2019-07-02 14:56:08 +080068 int32_t type; /* One of the following values:
Edison Aib3e56962018-09-04 19:12:31 +080069 * \ref PSA_IPC_CONNECT
Summer Qin4b1d03b2019-07-02 14:56:08 +080070 * >= 0
Edison Aib3e56962018-09-04 19:12:31 +080071 * \ref PSA_IPC_DISCONNECT
72 */
73 psa_handle_t handle; /* A reference generated by the SPM to the
74 * message returned by psa_get().
75 */
Kevin Penge61e7052022-01-27 14:57:06 +080076 int32_t client_id; /*
77 * Partition ID of the sender of the
78 * message:
79 * - secure partition id;
80 * - non secure client endpoint id.
81 */
Edison Aib3e56962018-09-04 19:12:31 +080082 void *rhandle; /* Be useful for binding a connection to some
83 * application-specific data or function
84 * pointer within the RoT Service
85 * implementation.
86 */
87 size_t in_size[PSA_MAX_IOVEC]; /* Provide the size of each client input
88 * vector in bytes.
89 */
90 size_t out_size[PSA_MAX_IOVEC];/* Provide the size of each client output
91 * vector in bytes.
92 */
Miklos Balint9ecb24c2018-03-29 15:30:28 +020093} psa_msg_t;
94
Edison Aib3e56962018-09-04 19:12:31 +080095/************************* PSA Secure Partition API **************************/
Miklos Balint9ecb24c2018-03-29 15:30:28 +020096
97/**
Edison Aib3e56962018-09-04 19:12:31 +080098 * \brief Return the Secure Partition interrupt signals that have been asserted
99 * from a subset of signals provided by the caller.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200100 *
Edison Aib3e56962018-09-04 19:12:31 +0800101 * \param[in] signal_mask A set of signals to query. Signals that are not
102 * in this set will be ignored.
103 * \param[in] timeout Specify either blocking \ref PSA_BLOCK or
104 * polling \ref PSA_POLL operation.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200105 *
Edison Aib3e56962018-09-04 19:12:31 +0800106 * \retval >0 At least one signal is asserted.
107 * \retval 0 No signals are asserted. This is only seen when
108 * a polling timeout is used.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200109 */
Edison Aib3e56962018-09-04 19:12:31 +0800110psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200111
112/**
Edison Aib3e56962018-09-04 19:12:31 +0800113 * \brief Retrieve the message which corresponds to a given RoT Service signal
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200114 * and remove the message from the RoT Service queue.
115 *
Edison Aib3e56962018-09-04 19:12:31 +0800116 * \param[in] signal The signal value for an asserted RoT Service.
117 * \param[out] msg Pointer to \ref psa_msg_t object for receiving
118 * the message.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200119 *
Edison Aib3e56962018-09-04 19:12:31 +0800120 * \retval PSA_SUCCESS Success, *msg will contain the delivered
121 * message.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800122 * \retval PSA_ERROR_DOES_NOT_EXIST Message could not be delivered.
123 * \retval "PROGRAMMER ERROR" The call is invalid because one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800124 * following are true:
125 * \arg signal has more than a single bit set.
126 * \arg signal does not correspond to an RoT Service.
127 * \arg The RoT Service signal is not currently
128 * asserted.
129 * \arg The msg pointer provided is not a valid memory
130 * reference.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200131 */
Edison Aib3e56962018-09-04 19:12:31 +0800132psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200133
134/**
Edison Aib3e56962018-09-04 19:12:31 +0800135 * \brief Associate some RoT Service private data with a client connection.
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] rhandle Reverse handle allocated by the RoT Service.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200139 *
Edison Aib3e56962018-09-04 19:12:31 +0800140 * \retval void Success, rhandle will be provided with all
141 * subsequent messages delivered on this
142 * connection.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800143 * \retval "PROGRAMMER ERROR" msg_handle is invalid.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200144 */
145void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle);
146
147/**
Edison Aib3e56962018-09-04 19:12:31 +0800148 * \brief Read a message parameter or part of a message parameter from a client
149 * input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200150 *
Edison Aib3e56962018-09-04 19:12:31 +0800151 * \param[in] msg_handle Handle for the client's message.
152 * \param[in] invec_idx Index of the input vector to read from. Must be
153 * less than \ref PSA_MAX_IOVEC.
154 * \param[out] buffer Buffer in the Secure Partition to copy the
155 * requested data to.
156 * \param[in] num_bytes Maximum number of bytes to be read from the
157 * client input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200158 *
Edison Aib3e56962018-09-04 19:12:31 +0800159 * \retval >0 Number of bytes copied.
160 * \retval 0 There was no remaining data in this input
161 * vector.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800162 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800163 * following are true:
164 * \arg msg_handle is invalid.
165 * \arg msg_handle does not refer to a
166 * \ref PSA_IPC_CALL message.
167 * \arg invec_idx is equal to or greater than
168 * \ref PSA_MAX_IOVEC.
169 * \arg the memory reference for buffer is invalid or
170 * not writable.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200171 */
172size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
Edison Aib3e56962018-09-04 19:12:31 +0800173 void *buffer, size_t num_bytes);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200174
175/**
Edison Aib3e56962018-09-04 19:12:31 +0800176 * \brief Skip over part of a client input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200177 *
Edison Aib3e56962018-09-04 19:12:31 +0800178 * \param[in] msg_handle Handle for the client's message.
179 * \param[in] invec_idx Index of input vector to skip from. Must be
180 * less than \ref PSA_MAX_IOVEC.
181 * \param[in] num_bytes Maximum number of bytes to skip in the client
182 * input vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200183 *
Edison Aib3e56962018-09-04 19:12:31 +0800184 * \retval >0 Number of bytes skipped.
185 * \retval 0 There was no remaining data in this input
186 * vector.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800187 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800188 * following are true:
189 * \arg msg_handle is invalid.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800190 * \arg msg_handle does not refer to a request
191 * message.
Edison Aib3e56962018-09-04 19:12:31 +0800192 * \arg invec_idx is equal to or greater than
193 * \ref PSA_MAX_IOVEC.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200194 */
195size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes);
196
197/**
Edison Aib3e56962018-09-04 19:12:31 +0800198 * \brief Write a message response to a client output vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200199 *
Edison Aib3e56962018-09-04 19:12:31 +0800200 * \param[in] msg_handle Handle for the client's message.
201 * \param[out] outvec_idx Index of output vector in message to write to.
202 * Must be less than \ref PSA_MAX_IOVEC.
203 * \param[in] buffer Buffer with the data to write.
204 * \param[in] num_bytes Number of bytes to write to the client output
205 * vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200206 *
Edison Aib3e56962018-09-04 19:12:31 +0800207 * \retval void Success
Summer Qin4b1d03b2019-07-02 14:56:08 +0800208 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800209 * following are true:
210 * \arg msg_handle is invalid.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800211 * \arg msg_handle does not refer to a request
212 * message.
Edison Aib3e56962018-09-04 19:12:31 +0800213 * \arg outvec_idx is equal to or greater than
214 * \ref PSA_MAX_IOVEC.
215 * \arg The memory reference for buffer is invalid.
216 * \arg The call attempts to write data past the end
217 * of the client output vector.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200218 */
219void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
Edison Aib3e56962018-09-04 19:12:31 +0800220 const void *buffer, size_t num_bytes);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200221
222/**
Edison Aib3e56962018-09-04 19:12:31 +0800223 * \brief Complete handling of a specific message and unblock the client.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200224 *
Edison Aib3e56962018-09-04 19:12:31 +0800225 * \param[in] msg_handle Handle for the client's message.
226 * \param[in] status Message result value to be reported to the
227 * client.
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" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800231 * following are true:
232 * \arg msg_handle is invalid.
233 * \arg An invalid status code is specified for the
234 * type of message.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200235 */
Edison Aib3e56962018-09-04 19:12:31 +0800236void psa_reply(psa_handle_t msg_handle, psa_status_t status);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200237
238/**
Edison Aib3e56962018-09-04 19:12:31 +0800239 * \brief Send a PSA_DOORBELL signal to a specific Secure Partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200240 *
Edison Aib3e56962018-09-04 19:12:31 +0800241 * \param[in] partition_id Secure Partition ID of the target partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200242 *
Edison Aib3e56962018-09-04 19:12:31 +0800243 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800244 * \retval "PROGRAMMER ERROR" partition_id does not correspond to a Secure
Edison Aib3e56962018-09-04 19:12:31 +0800245 * Partition.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200246 */
247void psa_notify(int32_t partition_id);
248
249/**
Edison Aib3e56962018-09-04 19:12:31 +0800250 * \brief Clear the PSA_DOORBELL signal.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200251 *
Edison Aib3e56962018-09-04 19:12:31 +0800252 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800253 * \retval "PROGRAMMER ERROR" The Secure Partition's doorbell signal is not
Edison Aib3e56962018-09-04 19:12:31 +0800254 * currently asserted.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200255 */
256void psa_clear(void);
257
258/**
Edison Aib3e56962018-09-04 19:12:31 +0800259 * \brief Inform the SPM that an interrupt has been handled (end of interrupt).
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200260 *
Edison Aib3e56962018-09-04 19:12:31 +0800261 * \param[in] irq_signal The interrupt signal that has been processed.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200262 *
Edison Aib3e56962018-09-04 19:12:31 +0800263 * \retval void Success.
Summer Qin4b1d03b2019-07-02 14:56:08 +0800264 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
Edison Aib3e56962018-09-04 19:12:31 +0800265 * following are true:
266 * \arg irq_signal is not an interrupt signal.
267 * \arg irq_signal indicates more than one signal.
268 * \arg irq_signal is not currently asserted.
Kevin Peng9280ae92021-01-13 14:42:10 +0800269 * \arg The interrupt is not using SLIH.
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200270 */
Edison Aib3e56962018-09-04 19:12:31 +0800271void psa_eoi(psa_signal_t irq_signal);
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200272
Summer Qin4b1d03b2019-07-02 14:56:08 +0800273/**
274 * \brief Terminate execution within the calling Secure Partition and will not
275 * return.
276 *
277 * \retval "Does not return"
278 */
279void psa_panic(void);
280
Kevin Pengf9a0eb02021-01-05 15:06:05 +0800281/**
282 * \brief Enable an interrupt.
283 *
284 * \param[in] irq_signal The signal for the interrupt to be enabled.
285 * This must have a single bit set, which must be the
286 * signal value for an interrupt in the calling Secure
287 * Partition.
288 *
289 * \retval void
290 * \retval "PROGRAMMER ERROR" If one or more of the following are true:
Kevin Peng9280ae92021-01-13 14:42:10 +0800291 * \arg \a irq_signal is not an interrupt signal.
292 * \arg \a irq_signal indicates more than one signal.
Kevin Pengf9a0eb02021-01-05 15:06:05 +0800293 */
294void psa_irq_enable(psa_signal_t irq_signal);
295
296/**
297 * \brief Disable an interrupt and return the status of the interrupt prior to
298 * being disabled by this call.
299 *
300 * \param[in] irq_signal The signal for the interrupt to be disabled.
301 * This must have a single bit set, which must be the
302 * signal value for an interrupt in the calling Secure
303 * Partition.
304 *
305 * \retval 0 The interrupt was disabled prior to this call.
306 * 1 The interrupt was enabled prior to this call.
307 * \retval "PROGRAMMER ERROR" If one or more of the following are true:
Kevin Peng9280ae92021-01-13 14:42:10 +0800308 * \arg \a irq_signal is not an interrupt signal.
309 * \arg \a irq_signal indicates more than one signal.
Kevin Pengf9a0eb02021-01-05 15:06:05 +0800310 *
311 * \note The current implementation always return 1. Do not use the return.
312 */
313psa_irq_status_t psa_irq_disable(psa_signal_t irq_signal);
314
Kevin Peng9280ae92021-01-13 14:42:10 +0800315/**
316 * \brief Reset the signal for an interrupt that is using FLIH handling.
317 *
318 * \param[in] irq_signal The interrupt signal to be reset.
319 * This must have a single bit set, corresponding to a
320 * currently asserted signal for an interrupt that is
321 * defined to use FLIH handling.
322 *
323 * \retval void
324 * \retval "Programmer Error" if one or more of the following are true:
325 * \arg \a irq_signal is not a signal for an interrupt
326 * that is specified with FLIH handling in the Secure
327 * Partition manifest.
328 * \arg \a irq_signal indicates more than one signal.
329 * \arg \a irq_signal is not currently asserted.
330 */
331void psa_reset_signal(psa_signal_t irq_signal);
332
Shawn Shan038348e2021-09-08 17:11:04 +0800333#if PSA_FRAMEWORK_HAS_MM_IOVEC
334
335/**
336 * \brief Map a client input vector for direct access by a Secure Partition RoT
337 * Service.
338 *
339 * \param[in] msg_handle Handle for the client's message.
340 * \param[in] invec_idx Index of input vector to map. Must be
341 * less than \ref PSA_MAX_IOVEC.
342 *
343 * \retval A pointer to the input vector data.
344 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
345 * following are true:
346 * \arg MM-IOVEC has not been enabled for the RoT
347 * Service that received the message.
348 * \arg msg_handle is invalid.
349 * \arg msg_handle does not refer to a request
350 * message.
351 * \arg invec_idx is equal to or greater than
352 * \ref PSA_MAX_IOVEC.
353 * \arg The input vector has length zero.
354 * \arg The input vector has already been mapped using
355 * psa_map_invec().
356 * \arg The input vector has already been accessed
357 * using psa_read() or psa_skip().
358 */
359const void *psa_map_invec(psa_handle_t msg_handle, uint32_t invec_idx);
360
361/**
362 * \brief Unmap a previously mapped client input vector from a Secure Partition
363 * RoT Service.
364 *
365 * \param[in] msg_handle Handle for the client's message.
366 * \param[in] invec_idx Index of input vector to map. Must be
367 * less than \ref PSA_MAX_IOVEC.
368 *
369 * \retval void
370 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
371 * following are true:
372 * \arg msg_handle is invalid.
373 * \arg msg_handle does not refer to a request
374 * message.
375 * \arg invec_idx is equal to or greater than
376 * \ref PSA_MAX_IOVEC.
377 * \arg The input vector has not been mapped by a call
378 * to psa_map_invec().
379 * \arg The input vector has already been unmapped by
380 * a call to psa_unmap_invec().
381 */
382void psa_unmap_invec(psa_handle_t msg_handle, uint32_t invec_idx);
383
384/**
385 * \brief Map a client output vector for direct access by a Secure Partition RoT
386 * Service.
387 *
388 * \param[in] msg_handle Handle for the client's message.
389 * \param[in] outvec_idx Index of output vector to map. Must be
390 * less than \ref PSA_MAX_IOVEC.
391 *
392 * \retval A pointer to the output vector data.
393 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
394 * following are true:
395 * \arg MM-IOVEC has not been enabled for the RoT
396 * Service that received the message.
397 * \arg msg_handle is invalid.
398 * \arg msg_handle does not refer to a request
399 * message.
400 * \arg outvec_idx is equal to or greater than
401 * \ref PSA_MAX_IOVEC.
402 * \arg The output vector has length zero.
403 * \arg The output vector has already been mapped
404 * using psa_map_outvec().
405 * \arg The output vector has already been accessed
406 * using psa_write().
407 */
408void *psa_map_outvec(psa_handle_t msg_handle, uint32_t outvec_idx);
409
410/**
411 * \brief Unmap a previously mapped client output vector from a Secure Partition
412 * RoT Service.
413 *
414 * \param[in] msg_handle Handle for the client's message.
415 * \param[in] outvec_idx Index of output vector to map. Must be
416 * less than \ref PSA_MAX_IOVEC.
417 * \param[in] len The number of bytes written to the output
418 * vector. This must be less than or equal to the
419 * size of the output vector.
420 *
421 * \retval void
422 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the
423 * following are true:
424 * \arg msg_handle is invalid.
425 * \arg msg_handle does not refer to a request
426 * message.
427 * \arg outvec_idx is equal to or greater than
428 * \ref PSA_MAX_IOVEC.
429 * \arg The output vector has not been mapped by a
430 * call to psa_map_outvec().
431 * \arg The output vector has already been unmapped by
432 * a call to psa_unmap_outvec().
433 */
434void psa_unmap_outvec(psa_handle_t msg_handle, uint32_t outvec_idx, size_t len);
435
436#endif /* PSA_FRAMEWORK_HAS_MM_IOVEC */
437
Miklos Balint9ecb24c2018-03-29 15:30:28 +0200438#ifdef __cplusplus
439}
440#endif
441
442#endif /* __PSA_SERVICE_H__ */