TF-M Reference Manual  1.2.0
TrustedFirmware-M
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
psa_client_service_apis.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <stdint.h>
10 #include "psa/lifecycle.h"
11 #ifdef TFM_PSA_API
12 #include "spm_ipc.h"
13 #else
14 #include "spm_func.h"
15 #endif
16 #include "tfm_core_utils.h"
17 #include "tfm_hal_platform.h"
18 #include "tfm_internal_defines.h"
19 #include "tfm_rpc.h"
20 #include "tfm_spm_hal.h"
21 
22 /*********************** SPM functions for PSA Client APIs *******************/
23 
25 {
26  /*
27  * FixMe: return PSA_LIFECYCLE_UNKNOWN to the caller directly. It will be
28  * implemented in the future.
29  */
30  return PSA_LIFECYCLE_UNKNOWN;
31 }
32 
34 {
36 }
37 
38 uint32_t tfm_spm_psa_version(uint32_t *args, bool ns_caller)
39 {
40  uint32_t sid;
41 
42  TFM_CORE_ASSERT(args != NULL);
43  sid = (uint32_t)args[0];
44 
45  return tfm_spm_client_psa_version(sid, ns_caller);
46 }
47 
48 psa_status_t tfm_spm_psa_connect(uint32_t *args, bool ns_caller)
49 {
50  uint32_t sid;
51  uint32_t version;
52 
53  TFM_CORE_ASSERT(args != NULL);
54  sid = (uint32_t)args[0];
55  version = (uint32_t)args[1];
56 
57  return tfm_spm_client_psa_connect(sid, version, ns_caller);
58 }
59 
60 psa_status_t tfm_spm_psa_call(uint32_t *args, bool ns_caller, uint32_t lr)
61 {
62  psa_handle_t handle;
63  psa_invec *inptr;
64  psa_outvec *outptr;
65  size_t in_num, out_num;
66  struct partition_t *partition = NULL;
67  uint32_t privileged;
68  int32_t type;
69  struct tfm_control_parameter_t ctrl_param;
70 
71  TFM_CORE_ASSERT(args != NULL);
72  handle = (psa_handle_t)args[0];
73 
74  partition = tfm_spm_get_running_partition();
75  if (!partition) {
77  }
79  partition->static_data->partition_flags);
80 
81  /*
82  * Read parameters from the arguments. It is a fatal error if the
83  * memory reference for buffer is invalid or not readable.
84  */
85  if (tfm_memory_check((const void *)args[1],
86  sizeof(struct tfm_control_parameter_t), ns_caller,
87  TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
89  }
90 
91  spm_memcpy(&ctrl_param, (const void *)args[1], sizeof(ctrl_param));
92 
93  type = ctrl_param.type;
94  in_num = ctrl_param.in_len;
95  out_num = ctrl_param.out_len;
96  inptr = (psa_invec *)args[2];
97  outptr = (psa_outvec *)args[3];
98 
99  /* The request type must be zero or positive. */
100  if (type < 0) {
101  tfm_core_panic();
102  }
103 
104  return tfm_spm_client_psa_call(handle, type, inptr, in_num, outptr, out_num,
105  ns_caller, privileged);
106 }
107 
108 void tfm_spm_psa_close(uint32_t *args, bool ns_caller)
109 {
110  psa_handle_t handle;
111 
112  TFM_CORE_ASSERT(args != NULL);
113  handle = args[0];
114 
115  tfm_spm_client_psa_close(handle, ns_caller);
116 }
117 
118 /********************* SPM functions for PSA Service APIs ********************/
119 
121 {
122  psa_signal_t signal_mask;
123  uint32_t timeout;
124  struct partition_t *partition = NULL;
125 
126  TFM_CORE_ASSERT(args != NULL);
127  signal_mask = (psa_signal_t)args[0];
128  timeout = args[1];
129 
130  /*
131  * Timeout[30:0] are reserved for future use.
132  * SPM must ignore the value of RES.
133  */
134  timeout &= PSA_TIMEOUT_MASK;
135 
136  partition = tfm_spm_get_running_partition();
137  if (!partition) {
138  tfm_core_panic();
139  }
140 
141  /*
142  * It is a PROGRAMMER ERROR if the signal_mask does not include any assigned
143  * signals.
144  */
145  if ((partition->signals_allowed & signal_mask) == 0) {
146  tfm_core_panic();
147  }
148 
149  /*
150  * Expected signals are included in signal wait mask, ignored signals
151  * should not be set and affect caller thread state. Save this mask for
152  * further checking while signals are ready to be set.
153  */
154  partition->signals_waiting = signal_mask;
155 
156  /*
157  * tfm_event_wait() blocks the caller thread if no signals are available.
158  * In this case, the return value of this function is temporary set into
159  * runtime context. After new signal(s) are available, the return value
160  * is updated with the available signal(s) and blocked thread gets to run.
161  */
162  if (timeout == PSA_BLOCK &&
163  (partition->signals_asserted & signal_mask) == 0) {
164  tfm_event_wait(&partition->event);
165  }
166 
167  return partition->signals_asserted & signal_mask;
168 }
169 
171 {
172  psa_signal_t signal;
173  psa_msg_t *msg = NULL;
174  struct tfm_msg_body_t *tmp_msg = NULL;
175  struct partition_t *partition = NULL;
176  uint32_t privileged;
177 
178  TFM_CORE_ASSERT(args != NULL);
179  signal = (psa_signal_t)args[0];
180  msg = (psa_msg_t *)args[1];
181 
182  /*
183  * Only one message could be retrieved every time for psa_get(). It is a
184  * fatal error if the input signal has more than a signal bit set.
185  */
186  if (!tfm_is_one_bit_set(signal)) {
187  tfm_core_panic();
188  }
189 
190  partition = tfm_spm_get_running_partition();
191  if (!partition) {
192  tfm_core_panic();
193  }
195  partition->static_data->partition_flags);
196 
197  /*
198  * Write the message to the service buffer. It is a fatal error if the
199  * input msg pointer is not a valid memory reference or not read-write.
200  */
201  if (tfm_memory_check(msg, sizeof(psa_msg_t), false, TFM_MEMORY_ACCESS_RW,
202  privileged) != IPC_SUCCESS) {
203  tfm_core_panic();
204  }
205 
206  /*
207  * It is a fatal error if the caller call psa_get() when no message has
208  * been set. The caller must call this function after an RoT Service signal
209  * is returned by psa_wait().
210  */
211  if (partition->signals_asserted == 0) {
212  tfm_core_panic();
213  }
214 
215  /*
216  * It is a fatal error if the RoT Service signal is not currently asserted.
217  */
218  if ((partition->signals_asserted & signal) == 0) {
219  tfm_core_panic();
220  }
221 
222  /*
223  * Get message by signal from partition. It is a fatal error if getting
224  * failed, which means the input signal is not correspond to an RoT service.
225  */
226  tmp_msg = tfm_spm_get_msg_by_signal(partition, signal);
227  if (!tmp_msg) {
229  }
230 
231  (TFM_GET_CONTAINER_PTR(tmp_msg,
232  struct tfm_conn_handle_t,
233  internal_msg))->status = TFM_HANDLE_STATUS_ACTIVE;
234 
235  spm_memcpy(msg, &tmp_msg->msg, sizeof(psa_msg_t));
236 
237  return PSA_SUCCESS;
238 }
239 
240 void tfm_spm_psa_set_rhandle(uint32_t *args)
241 {
242  psa_handle_t msg_handle;
243  void *rhandle = NULL;
244  struct tfm_msg_body_t *msg = NULL;
245  struct tfm_conn_handle_t *conn_handle;
246 
247  TFM_CORE_ASSERT(args != NULL);
248  msg_handle = (psa_handle_t)args[0];
249  rhandle = (void *)args[1];
250 
251  /* It is a fatal error if message handle is invalid */
252  msg = tfm_spm_get_msg_from_handle(msg_handle);
253  if (!msg) {
254  tfm_core_panic();
255  }
256 
257  msg->msg.rhandle = rhandle;
258  conn_handle = tfm_spm_to_handle_instance(msg_handle);
259 
260  /* Store reverse handle for following client calls. */
261  tfm_spm_set_rhandle(msg->service, conn_handle, rhandle);
262 }
263 
264 size_t tfm_spm_psa_read(uint32_t *args)
265 {
266  psa_handle_t msg_handle;
267  uint32_t invec_idx;
268  void *buffer = NULL;
269  size_t num_bytes;
270  size_t bytes;
271  struct tfm_msg_body_t *msg = NULL;
272  uint32_t privileged;
273  struct partition_t *partition = NULL;
274 
275  TFM_CORE_ASSERT(args != NULL);
276  msg_handle = (psa_handle_t)args[0];
277  invec_idx = args[1];
278  buffer = (void *)args[2];
279  num_bytes = (size_t)args[3];
280 
281  /* It is a fatal error if message handle is invalid */
282  msg = tfm_spm_get_msg_from_handle(msg_handle);
283  if (!msg) {
284  tfm_core_panic();
285  }
286 
287  partition = msg->service->partition;
289  partition->static_data->partition_flags);
290 
291  /*
292  * It is a fatal error if message handle does not refer to a request
293  * message
294  */
295  if (msg->msg.type < PSA_IPC_CALL) {
296  tfm_core_panic();
297  }
298 
299  /*
300  * It is a fatal error if invec_idx is equal to or greater than
301  * PSA_MAX_IOVEC
302  */
303  if (invec_idx >= PSA_MAX_IOVEC) {
304  tfm_core_panic();
305  }
306 
307  /* There was no remaining data in this input vector */
308  if (msg->msg.in_size[invec_idx] == 0) {
309  return 0;
310  }
311 
312  /*
313  * Copy the client data to the service buffer. It is a fatal error
314  * if the memory reference for buffer is invalid or not read-write.
315  */
316  if (tfm_memory_check(buffer, num_bytes, false,
317  TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
318  tfm_core_panic();
319  }
320 
321  bytes = num_bytes > msg->msg.in_size[invec_idx] ?
322  msg->msg.in_size[invec_idx] : num_bytes;
323 
324  spm_memcpy(buffer, msg->invec[invec_idx].base, bytes);
325 
326  /* There maybe some remaining data */
327  msg->invec[invec_idx].base = (char *)msg->invec[invec_idx].base + bytes;
328  msg->msg.in_size[invec_idx] -= bytes;
329 
330  return bytes;
331 }
332 
333 size_t tfm_spm_psa_skip(uint32_t *args)
334 {
335  psa_handle_t msg_handle;
336  uint32_t invec_idx;
337  size_t num_bytes;
338  struct tfm_msg_body_t *msg = NULL;
339 
340  TFM_CORE_ASSERT(args != NULL);
341  msg_handle = (psa_handle_t)args[0];
342  invec_idx = args[1];
343  num_bytes = (size_t)args[2];
344 
345  /* It is a fatal error if message handle is invalid */
346  msg = tfm_spm_get_msg_from_handle(msg_handle);
347  if (!msg) {
348  tfm_core_panic();
349  }
350 
351  /*
352  * It is a fatal error if message handle does not refer to a request
353  * message
354  */
355  if (msg->msg.type < PSA_IPC_CALL) {
356  tfm_core_panic();
357  }
358 
359  /*
360  * It is a fatal error if invec_idx is equal to or greater than
361  * PSA_MAX_IOVEC
362  */
363  if (invec_idx >= PSA_MAX_IOVEC) {
364  tfm_core_panic();
365  }
366 
367  /* There was no remaining data in this input vector */
368  if (msg->msg.in_size[invec_idx] == 0) {
369  return 0;
370  }
371 
372  /*
373  * If num_bytes is greater than the remaining size of the input vector then
374  * the remaining size of the input vector is used.
375  */
376  if (num_bytes > msg->msg.in_size[invec_idx]) {
377  num_bytes = msg->msg.in_size[invec_idx];
378  }
379 
380  /* There maybe some remaining data */
381  msg->invec[invec_idx].base = (char *)msg->invec[invec_idx].base +
382  num_bytes;
383  msg->msg.in_size[invec_idx] -= num_bytes;
384 
385  return num_bytes;
386 }
387 
388 void tfm_spm_psa_write(uint32_t *args)
389 {
390  psa_handle_t msg_handle;
391  uint32_t outvec_idx;
392  void *buffer = NULL;
393  size_t num_bytes;
394  struct tfm_msg_body_t *msg = NULL;
395  uint32_t privileged;
396  struct partition_t *partition = NULL;
397 
398  TFM_CORE_ASSERT(args != NULL);
399  msg_handle = (psa_handle_t)args[0];
400  outvec_idx = args[1];
401  buffer = (void *)args[2];
402  num_bytes = (size_t)args[3];
403 
404  /* It is a fatal error if message handle is invalid */
405  msg = tfm_spm_get_msg_from_handle(msg_handle);
406  if (!msg) {
407  tfm_core_panic();
408  }
409 
410  partition = msg->service->partition;
412  partition->static_data->partition_flags);
413 
414  /*
415  * It is a fatal error if message handle does not refer to a request
416  * message
417  */
418  if (msg->msg.type < PSA_IPC_CALL) {
419  tfm_core_panic();
420  }
421 
422  /*
423  * It is a fatal error if outvec_idx is equal to or greater than
424  * PSA_MAX_IOVEC
425  */
426  if (outvec_idx >= PSA_MAX_IOVEC) {
427  tfm_core_panic();
428  }
429 
430  /*
431  * It is a fatal error if the call attempts to write data past the end of
432  * the client output vector
433  */
434  if (num_bytes > msg->msg.out_size[outvec_idx] -
435  msg->outvec[outvec_idx].len) {
436  tfm_core_panic();
437  }
438 
439  /*
440  * Copy the service buffer to client outvecs. It is a fatal error
441  * if the memory reference for buffer is invalid or not readable.
442  */
443  if (tfm_memory_check(buffer, num_bytes, false,
444  TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
445  tfm_core_panic();
446  }
447 
448  spm_memcpy((char *)msg->outvec[outvec_idx].base +
449  msg->outvec[outvec_idx].len, buffer, num_bytes);
450 
451  /* Update the write number */
452  msg->outvec[outvec_idx].len += num_bytes;
453 }
454 
455 void tfm_spm_psa_reply(uint32_t *args)
456 {
457  psa_handle_t msg_handle;
458  psa_status_t status;
459  struct tfm_spm_service_t *service = NULL;
460  struct tfm_msg_body_t *msg = NULL;
461  int32_t ret = PSA_SUCCESS;
462  struct tfm_conn_handle_t *conn_handle;
463 
464  TFM_CORE_ASSERT(args != NULL);
465  msg_handle = (psa_handle_t)args[0];
466  status = (psa_status_t)args[1];
467 
468  /* It is a fatal error if message handle is invalid */
469  msg = tfm_spm_get_msg_from_handle(msg_handle);
470  if (!msg) {
471  tfm_core_panic();
472  }
473 
474  /*
475  * RoT Service information is needed in this function, stored it in message
476  * body structure. Only two parameters are passed in this function: handle
477  * and status, so it is useful and simply to do like this.
478  */
479  service = msg->service;
480  if (!service) {
481  tfm_core_panic();
482  }
483 
484  /*
485  * Three type of message are passed in this function: CONNECTION, REQUEST,
486  * DISCONNECTION. It needs to process differently for each type.
487  */
488  conn_handle = tfm_spm_to_handle_instance(msg_handle);
489  switch (msg->msg.type) {
490  case PSA_IPC_CONNECT:
491  /*
492  * Reply to PSA_IPC_CONNECT message. Connect handle is returned if the
493  * input status is PSA_SUCCESS. Others return values are based on the
494  * input status.
495  */
496  if (status == PSA_SUCCESS) {
497  ret = msg_handle;
498  } else if (status == PSA_ERROR_CONNECTION_REFUSED) {
499  /* Refuse the client connection, indicating a permanent error. */
500  tfm_spm_free_conn_handle(service, conn_handle);
502  } else if (status == PSA_ERROR_CONNECTION_BUSY) {
503  /* Fail the client connection, indicating a transient error. */
505  } else {
506  tfm_core_panic();
507  }
508  break;
509  case PSA_IPC_DISCONNECT:
510  /* Service handle is not used anymore */
511  tfm_spm_free_conn_handle(service, conn_handle);
512 
513  /*
514  * If the message type is PSA_IPC_DISCONNECT, then the status code is
515  * ignored
516  */
517  break;
518  default:
519  if (msg->msg.type >= PSA_IPC_CALL) {
520  /* Reply to a request message. Return values are based on status */
521  ret = status;
522  /*
523  * The total number of bytes written to a single parameter must be
524  * reported to the client by updating the len member of the
525  * psa_outvec structure for the parameter before returning from
526  * psa_call().
527  */
529  } else {
530  tfm_core_panic();
531  }
532  }
533 
534  if (ret == PSA_ERROR_PROGRAMMER_ERROR) {
535  /*
536  * If the source of the programmer error is a Secure Partition, the SPM
537  * must panic the Secure Partition in response to a PROGRAMMER ERROR.
538  */
539  if (TFM_CLIENT_ID_IS_NS(msg->msg.client_id)) {
541  } else {
542  tfm_core_panic();
543  }
544  } else {
545  conn_handle->status = TFM_HANDLE_STATUS_IDLE;
546  }
547 
548  if (is_tfm_rpc_msg(msg)) {
549  tfm_rpc_client_call_reply(msg, ret);
550  } else {
551  tfm_event_wake(&msg->ack_evnt, ret);
552  }
553 }
554 
555 void tfm_spm_psa_notify(uint32_t *args)
556 {
557  int32_t partition_id;
558 
559  TFM_CORE_ASSERT(args != NULL);
560  partition_id = (int32_t)args[0];
561 
562  notify_with_signal(partition_id, PSA_DOORBELL);
563 }
564 
566 {
567  struct partition_t *partition = NULL;
568 
569  partition = tfm_spm_get_running_partition();
570  if (!partition) {
571  tfm_core_panic();
572  }
573 
574  /*
575  * It is a fatal error if the Secure Partition's doorbell signal is not
576  * currently asserted.
577  */
578  if ((partition->signals_asserted & PSA_DOORBELL) == 0) {
579  tfm_core_panic();
580  }
581  partition->signals_asserted &= ~PSA_DOORBELL;
582 }
583 
584 void tfm_spm_psa_eoi(uint32_t *args)
585 {
586  psa_signal_t irq_signal;
587  IRQn_Type irq_line = (IRQn_Type) 0;
588  int32_t ret;
589  struct partition_t *partition = NULL;
590 
591  TFM_CORE_ASSERT(args != NULL);
592  irq_signal = (psa_signal_t)args[0];
593 
594  /* It is a fatal error if passed signal indicates more than one signals. */
595  if (!tfm_is_one_bit_set(irq_signal)) {
596  tfm_core_panic();
597  }
598 
599  partition = tfm_spm_get_running_partition();
600  if (!partition) {
601  tfm_core_panic();
602  }
603 
605  irq_signal, &irq_line);
606  /* It is a fatal error if passed signal is not an interrupt signal. */
607  if (ret != IPC_SUCCESS) {
608  tfm_core_panic();
609  }
610 
611  /* It is a fatal error if passed signal is not currently asserted */
612  if ((partition->signals_asserted & irq_signal) == 0) {
613  tfm_core_panic();
614  }
615 
616  partition->signals_asserted &= ~irq_signal;
617 
618  tfm_spm_hal_clear_pending_irq(irq_line);
619  tfm_spm_hal_enable_irq(irq_line);
620 }
621 
623 {
624  /*
625  * PSA FF recommends that the SPM causes the system to restart when a secure
626  * partition panics.
627  */
628  tfm_hal_system_reset();
629 }
void tfm_spm_psa_eoi(uint32_t *args)
Handle request to record IRQ processed.
void tfm_spm_psa_set_rhandle(uint32_t *args)
SVC handler for psa_set_rhandle.
#define PSA_ERROR_CONNECTION_BUSY
Definition: error.h:34
uint32_t psa_signal_t
Definition: service.h:50
void * base
Definition: client.h:75
uint32_t tfm_spm_client_psa_framework_version(void)
handler for psa_framework_version.
uint32_t tfm_spm_psa_framework_version(void)
SVC handler for psa_framework_version.
#define TFM_HANDLE_STATUS_CONNECT_ERROR
Definition: spm_ipc.h:25
#define PSA_BLOCK
Definition: service.h:31
int32_t type
Definition: service.h:56
#define PSA_SUCCESS
Definition: crypto_values.h:35
void tfm_event_wake(struct tfm_event_t *pevnt, uint32_t retval)
Definition: tfm_wait.c:20
#define PSA_DOORBELL
Definition: service.h:41
void tfm_spm_psa_reply(uint32_t *args)
SVC handler for psa_reply.
#define TFM_HANDLE_STATUS_ACTIVE
Definition: spm_ipc.h:24
uint32_t tfm_spm_partition_get_privileged_mode(uint32_t partition_flags)
Get the current partition mode.
Definition: spm_func.c:713
struct tfm_spm_service_t service[]
void * rhandle
Definition: spm_ipc.h:149
void tfm_spm_psa_panic(void)
Terminate execution within the calling Secure Partition and will not return.
#define PSA_LIFECYCLE_UNKNOWN
Definition: lifecycle.h:17
psa_outvec outvec[PSA_MAX_IOVEC]
Definition: spm_ipc.h:65
int32_t client_id
Definition: service.h:64
int32_t tfm_spm_set_rhandle(struct tfm_spm_service_t *service, struct tfm_conn_handle_t *conn_handle, void *rhandle)
Set reverse handle value for connection.
Definition: spm_ipc.c:196
#define is_tfm_rpc_msg(x)
Definition: tfm_rpc.h:211
psa_status_t tfm_spm_client_psa_call(psa_handle_t handle, int32_t type, const psa_invec *inptr, size_t in_num, psa_outvec *outptr, size_t out_num, bool ns_caller, uint32_t privileged)
handler for psa_call.
uint32_t tfm_spm_get_lifecycle_state(void)
psa_invec invec[PSA_MAX_IOVEC]
Definition: spm_ipc.h:64
uint32_t partition_flags
Definition: spm_ipc.h:88
void tfm_spm_client_psa_close(psa_handle_t handle, bool ns_caller)
handler for psa_close.
void tfm_core_panic(void)
Definition: utilities.c:11
int32_t tfm_memory_check(const void *buffer, size_t len, bool ns_caller, enum tfm_memory_access_e access, uint32_t privileged)
Check the memory reference is valid.
Definition: spm_ipc.c:596
#define PSA_MAX_IOVEC
Definition: client.h:54
void tfm_spm_psa_close(uint32_t *args, bool ns_caller)
SVC handler for psa_close.
psa_status_t tfm_spm_psa_get(uint32_t *args)
SVC handler for psa_get.
psa_status_t tfm_spm_psa_call(uint32_t *args, bool ns_caller, uint32_t lr)
SVC handler for psa_call.
struct partition_t * partition
Definition: spm_ipc.h:139
void tfm_spm_psa_write(uint32_t *args)
SVC handler for psa_write.
void tfm_spm_psa_clear(void)
SVC handler for psa_clear.
struct partition_t * tfm_spm_get_running_partition(void)
Get current running partition context.
Definition: spm_ipc.c:384
uint32_t signals_waiting
Definition: spm_ipc.h:112
#define PSA_IPC_DISCONNECT
Definition: service.h:47
struct tfm_event_t event
Definition: spm_ipc.h:109
void tfm_event_wait(struct tfm_event_t *pevnt)
Definition: tfm_wait.c:11
psa_signal_t tfm_spm_psa_wait(uint32_t *args)
Handle signal wait request.
psa_msg_t msg
Definition: spm_ipc.h:63
struct tfm_msg_body_t * tfm_spm_get_msg_by_signal(struct partition_t *partition, psa_signal_t signal)
Get the msg context by signal.
Definition: spm_ipc.c:233
uint32_t partition_id
Definition: spm_ipc.h:87
void * spm_memcpy(void *dest, const void *src, size_t n)
Memory copy function for TF-M core.
#define PSA_ERROR_PROGRAMMER_ERROR
Definition: error.h:32
size_t in_size[PSA_MAX_IOVEC]
Definition: service.h:70
struct tfm_spm_service_t * service
Definition: spm_ipc.h:61
#define TFM_CORE_ASSERT(cond)
Definition: utilities.h:21
uint32_t signals_allowed
Definition: spm_ipc.h:111
uint32_t signals_asserted
Definition: spm_ipc.h:113
void tfm_spm_psa_notify(uint32_t *args)
SVC handler for psa_notify.
size_t tfm_spm_psa_read(uint32_t *args)
SVC handler for psa_read.
#define TFM_GET_CONTAINER_PTR(ptr, type, member)
Definition: utilities.h:33
#define PSA_ERROR_CONNECTION_REFUSED
Definition: error.h:33
size_t len
Definition: client.h:76
int32_t psa_handle_t
Definition: client.h:61
uint32_t tfm_spm_psa_version(uint32_t *args, bool ns_caller)
SVC handler for psa_version.
#define IPC_SUCCESS
#define PSA_IPC_CONNECT
Definition: service.h:45
void notify_with_signal(int32_t partition_id, psa_signal_t signal)
notify the partition with the signal.
Definition: spm_ipc.c:831
#define TFM_HANDLE_STATUS_IDLE
Definition: spm_ipc.h:23
const struct partition_static_t * static_data
Definition: spm_ipc.h:104
#define TFM_CLIENT_ID_IS_NS(client_id)
Checks if the provided client ID is a non-secure client ID.
Definition: tfm_api.h:38
psa_status_t tfm_spm_client_psa_connect(uint32_t sid, uint32_t version, bool ns_caller)
handler for psa_connect.
size_t out_size[PSA_MAX_IOVEC]
Definition: service.h:73
size_t tfm_spm_psa_skip(uint32_t *args)
SVC handler for psa_skip.
#define PSA_IPC_CALL
Definition: client.h:59
int32_t get_irq_line_for_signal(int32_t partition_id, psa_signal_t signal, IRQn_Type *irq_line)
Return the IRQ line number associated with a signal.
Definition: spm_ipc.c:881
struct tfm_event_t ack_evnt
Definition: spm_ipc.h:62
void update_caller_outvec_len(struct tfm_msg_body_t *msg)
Definition: spm_ipc.c:807
void * rhandle
Definition: service.h:65
uint32_t tfm_spm_client_psa_version(uint32_t sid, bool ns_caller)
handler for psa_version.
struct tfm_msg_body_t * tfm_spm_get_msg_from_handle(psa_handle_t msg_handle)
Get message context by message handle.
Definition: spm_ipc.c:450
const void * base
Definition: client.h:67
#define PSA_ERROR_DOES_NOT_EXIST
Definition: crypto_values.h:89
#define PSA_TIMEOUT_MASK
Definition: tfm_api.h:41
int32_t tfm_spm_free_conn_handle(struct tfm_spm_service_t *service, struct tfm_conn_handle_t *conn_handle)
Free connection handle which not used anymore.
Definition: spm_ipc.c:179
int32_t psa_status_t
Function return status.
Definition: crypto_types.h:43
struct tfm_conn_handle_t * tfm_spm_to_handle_instance(psa_handle_t user_handle)
Converts a user handle into a corresponded handle instance.
Definition: spm_ipc.c:121
uint32_t status
Definition: spm_ipc.h:150
bool tfm_is_one_bit_set(uint32_t n)
Definition: utilities.c:24
#define tfm_rpc_client_call_reply(owner, ret)
Definition: tfm_rpc.h:215
psa_status_t tfm_spm_psa_connect(uint32_t *args, bool ns_caller)
SVC handler for psa_connect.