TF-M Reference Manual  1.2.0
TrustedFirmware-M
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tfm_core_svcalls_ipc.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2020, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <string.h>
9 #include "region.h"
10 #include "spm_ipc.h"
11 #include "tfm_api.h"
12 #include "tfm_arch.h"
13 #include "tfm_core_trustzone.h"
14 #include "tfm_svcalls.h"
15 #include "utilities.h"
16 #include "tfm/tfm_core_svc.h"
17 #include "common/tfm_boot_data.h"
19 
20 /* The section names come from the scatter file */
21 REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Base);
22 REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit);
23 
24 #ifdef PLATFORM_SVC_HANDLERS
25 extern int32_t platform_svc_handlers(tfm_svc_number_t svc_num,
26  uint32_t *ctx, uint32_t lr);
27 #endif
28 
29 static int32_t SVC_Handler_IPC(tfm_svc_number_t svc_num, uint32_t *ctx,
30  uint32_t lr)
31 {
32  bool ns_caller = false;
33  struct partition_t *partition = NULL;
34  uint32_t veneer_base =
35  (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Base);
36  uint32_t veneer_limit =
37  (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit);
38 
39  /*
40  * The caller security attribute detection bases on LR of state context.
41  * However, if SP calls PSA APIs based on its customized SVC, the LR may be
42  * occupied by general purpose value while calling SVC.
43  * Check if caller comes from non-secure: return address (ctx[6]) is belongs
44  * to veneer section, and the bit0 of LR (ctx[5]) is zero.
45  */
46  if (ctx[6] >= veneer_base && ctx[6] < veneer_limit &&
47  !(ctx[5] & TFM_VENEER_LR_BIT0_MASK)) {
48  ns_caller = true;
49  }
50 
51  partition = tfm_spm_get_running_partition();
52  if (!partition) {
54  }
55 
56  tfm_spm_validate_caller(partition, ctx, lr, ns_caller);
57 
58  switch (svc_num) {
59  case TFM_SVC_PSA_FRAMEWORK_VERSION:
61  case TFM_SVC_PSA_VERSION:
62  return tfm_spm_psa_version(ctx, ns_caller);
63  case TFM_SVC_PSA_CONNECT:
64  return tfm_spm_psa_connect(ctx, ns_caller);
65  case TFM_SVC_PSA_CALL:
66  return tfm_spm_psa_call(ctx, ns_caller, lr);
67  case TFM_SVC_PSA_CLOSE:
68  tfm_spm_psa_close(ctx, ns_caller);
69  break;
70  case TFM_SVC_PSA_WAIT:
71  return tfm_spm_psa_wait(ctx);
72  case TFM_SVC_PSA_GET:
73  return tfm_spm_psa_get(ctx);
74  case TFM_SVC_PSA_SET_RHANDLE:
76  break;
77  case TFM_SVC_PSA_READ:
78  return tfm_spm_psa_read(ctx);
79  case TFM_SVC_PSA_SKIP:
80  return tfm_spm_psa_skip(ctx);
81  case TFM_SVC_PSA_WRITE:
82  tfm_spm_psa_write(ctx);
83  break;
84  case TFM_SVC_PSA_REPLY:
85  tfm_spm_psa_reply(ctx);
86  break;
87  case TFM_SVC_PSA_NOTIFY:
88  tfm_spm_psa_notify(ctx);
89  break;
90  case TFM_SVC_PSA_CLEAR:
92  break;
93  case TFM_SVC_PSA_EOI:
94  tfm_spm_psa_eoi(ctx);
95  break;
96  case TFM_SVC_ENABLE_IRQ:
97  tfm_spm_enable_irq(ctx);
98  break;
100  tfm_spm_disable_irq(ctx);
101  break;
102  case TFM_SVC_PSA_PANIC:
104  break;
105  case TFM_SVC_SPM_REQUEST:
106  tfm_spm_request_handler((const struct tfm_state_context_t *)ctx);
107  break;
108  case TFM_SVC_PSA_LIFECYCLE:
110  default:
111 #ifdef PLATFORM_SVC_HANDLERS
112  return (platform_svc_handlers(svc_num, ctx, lr));
113 #else
114  ERROR_MSG("Unknown SVC number requested!");
116 #endif
117  }
118  return PSA_SUCCESS;
119 }
120 
121 uint32_t tfm_core_svc_handler(uint32_t *svc_args, uint32_t exc_return)
122 {
124  /*
125  * Stack contains:
126  * r0, r1, r2, r3, r12, r14 (lr), the return address and xPSR
127  * First argument (r0) is svc_args[0]
128  */
129  if (is_return_secure_stack(exc_return)) {
130  /* SV called directly from secure context. Check instruction for
131  * svc_number
132  */
133  svc_number = ((tfm_svc_number_t *)svc_args[6])[-2];
134  } else {
135  /* Secure SV executing with NS return.
136  * NS cannot directly trigger S SVC so this should not happen. This is
137  * an unrecoverable error.
138  */
139  tfm_core_panic();
140  }
141  switch (svc_number) {
144  exc_return = tfm_spm_init();
145  break;
148  break;
149  default:
150  svc_args[0] = SVC_Handler_IPC(svc_number, svc_args, exc_return);
151  break;
152  }
153 
154  return exc_return;
155 }
156 
157 __attribute__ ((naked)) void tfm_core_handler_mode(void)
158 {
159  __ASM volatile("SVC %0 \n"
160  "BX LR \n"
161  : : "I" (TFM_SVC_HANDLER_MODE));
162 }
163 
165 {
166  while (1) {
167  ;
168  }
169 }
void tfm_spm_psa_eoi(uint32_t *svc_args)
Handle request to record IRQ processed.
Definition: spm_func.c:1118
void tfm_spm_psa_set_rhandle(uint32_t *args)
SVC handler for psa_set_rhandle.
uint32_t tfm_spm_psa_framework_version(void)
SVC handler for psa_framework_version.
#define PSA_SUCCESS
Definition: crypto_values.h:35
void tfm_spm_psa_reply(uint32_t *args)
SVC handler for psa_reply.
uint32_t tfm_core_svc_handler(uint32_t *svc_args, uint32_t exc_return)
The C source of SVCall handlers.
void tfm_core_get_boot_data_handler(uint32_t args[])
Retrieve secure partition related data from shared memory area, which stores shared data between boot...
void tfm_spm_psa_panic(void)
Terminate execution within the calling Secure Partition and will not return.
void tfm_spm_enable_irq(uint32_t *args)
SVC handler of enabling irq_line of the specified irq_signal.
Definition: spm_ipc.c:897
void tfm_spm_validate_caller(struct partition_t *p_cur_sp, uint32_t *p_ctx, uint32_t exc_return, bool ns_caller)
Validate the whether NS caller re-enter.
Definition: spm_ipc.c:953
uint32_t tfm_spm_init(void)
SPM initialization implementation.
Definition: spm_ipc.c:641
uint32_t tfm_spm_get_lifecycle_state(void)
void tfm_core_panic(void)
Definition: utilities.c:11
REGION_DECLARE(Image $$, TFM_UNPRIV_CODE,$$RO $$Base)
#define ERROR_MSG(msg)
Definition: utilities.h:36
void tfm_spm_psa_close(uint32_t *args, bool ns_caller)
SVC handler for psa_close.
#define PSA_ERROR_GENERIC_ERROR
Definition: crypto_values.h:43
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.
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
void tfm_spm_psa_wait(uint32_t *svc_args)
Handle signal wait request.
Definition: spm_func.c:1087
void tfm_access_violation_handler(void)
Should be called in case of access violation.
#define TFM_VENEER_LR_BIT0_MASK
void tfm_spm_request_handler(const struct tfm_state_context_t *svc_ctx)
Handle an SPM request by a secure service.
Definition: spm_func.c:1382
tfm_svc_number_t
Definition: tfm_core_svc.h:13
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.
uint32_t tfm_spm_psa_version(uint32_t *args, bool ns_caller)
SVC handler for psa_version.
void tfm_core_handler_mode(void)
Move to handler mode by a SVC for specific purpose.
__STATIC_INLINE bool is_return_secure_stack(uint32_t lr)
Check whether Secure or Non-secure stack is used to restore stack frame on exception return...
size_t tfm_spm_psa_skip(uint32_t *args)
SVC handler for psa_skip.
void tfm_arch_clear_fp_status(void)
void tfm_spm_disable_irq(uint32_t *args)
SVC handler of disabling irq_line of the specified irq_signal.
Definition: spm_ipc.c:925
psa_status_t tfm_spm_psa_connect(uint32_t *args, bool ns_caller)
SVC handler for psa_connect.