1 /*
2  * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <stdint.h>
9 #include "compiler_ext_defs.h"
10 #include "config_spm.h"
11 #include "runtime_defs.h"
12 #include "svc_num.h"
13 #include "tfm_psa_call_pack.h"
14 #include "utilities.h"
15 #include "psa/client.h"
16 #include "psa/lifecycle.h"
17 #include "psa/service.h"
18 
psa_framework_version_svc(void)19 __naked uint32_t psa_framework_version_svc(void)
20 {
21     __asm volatile("svc     "M2S(TFM_SVC_PSA_FRAMEWORK_VERSION)"\n"
22                    "bx      lr                                  \n");
23 }
24 
psa_version_svc(uint32_t sid)25 __naked uint32_t psa_version_svc(uint32_t sid)
26 {
27     __asm volatile("svc     "M2S(TFM_SVC_PSA_VERSION)"         \n"
28                    "bx      lr                                 \n");
29 }
30 
tfm_psa_call_pack_svc(psa_handle_t handle,uint32_t ctrl_param,const psa_invec * in_vec,psa_outvec * out_vec)31 __naked psa_status_t tfm_psa_call_pack_svc(psa_handle_t handle,
32                                            uint32_t ctrl_param,
33                                            const psa_invec *in_vec,
34                                            psa_outvec *out_vec)
35 {
36     __asm volatile("svc     "M2S(TFM_SVC_PSA_CALL)"            \n"
37                    "bx      lr                                 \n");
38 }
39 
psa_wait_svc(psa_signal_t signal_mask,uint32_t timeout)40 __naked psa_signal_t psa_wait_svc(psa_signal_t signal_mask, uint32_t timeout)
41 {
42     __asm volatile("svc     "M2S(TFM_SVC_PSA_WAIT)"            \n"
43                    "bx      lr                                 \n");
44 }
45 
psa_get_svc(psa_signal_t signal,psa_msg_t * msg)46 __naked psa_status_t psa_get_svc(psa_signal_t signal, psa_msg_t *msg)
47 {
48     __asm volatile("svc     "M2S(TFM_SVC_PSA_GET)"             \n"
49                    "bx      lr                                 \n");
50 }
51 
psa_read_svc(psa_handle_t msg_handle,uint32_t invec_idx,void * buffer,size_t num_bytes)52 __naked size_t psa_read_svc(psa_handle_t msg_handle, uint32_t invec_idx,
53                             void *buffer, size_t num_bytes)
54 {
55     __asm volatile("svc     "M2S(TFM_SVC_PSA_READ)"            \n"
56                    "bx      lr                                 \n");
57 }
58 
psa_skip_svc(psa_handle_t msg_handle,uint32_t invec_idx,size_t num_bytes)59 __naked size_t psa_skip_svc(psa_handle_t msg_handle,
60                             uint32_t invec_idx, size_t num_bytes)
61 {
62     __asm volatile("svc     "M2S(TFM_SVC_PSA_SKIP)"            \n"
63                    "bx      lr                                 \n");
64 }
65 
psa_write_svc(psa_handle_t msg_handle,uint32_t outvec_idx,const void * buffer,size_t num_bytes)66 __naked void psa_write_svc(psa_handle_t msg_handle, uint32_t outvec_idx,
67                            const void *buffer, size_t num_bytes)
68 {
69     __asm volatile("svc     "M2S(TFM_SVC_PSA_WRITE)"           \n"
70                    "bx      lr                                 \n");
71 }
72 
psa_reply_svc(psa_handle_t msg_handle,psa_status_t retval)73 __naked void psa_reply_svc(psa_handle_t msg_handle, psa_status_t retval)
74 {
75     __asm volatile("svc     "M2S(TFM_SVC_PSA_REPLY)"           \n"
76                    "bx      lr                                 \n");
77 }
78 
79 #if CONFIG_TFM_DOORBELL_API == 1
psa_notify_svc(int32_t partition_id)80 __naked void psa_notify_svc(int32_t partition_id)
81 {
82     __asm volatile("svc     "M2S(TFM_SVC_PSA_NOTIFY)"          \n"
83                    "bx      lr                                 \n");
84 }
85 
psa_clear_svc(void)86 __naked void psa_clear_svc(void)
87 {
88     __asm volatile("svc     "M2S(TFM_SVC_PSA_CLEAR)"           \n"
89                    "bx      lr                                 \n");
90 }
91 #endif /* CONFIG_TFM_DOORBELL_API == 1 */
92 
psa_panic_svc(void)93 __naked void psa_panic_svc(void)
94 {
95     __asm volatile("svc     "M2S(TFM_SVC_PSA_PANIC)"           \n"
96                    "bx      lr                                 \n");
97 }
98 
psa_rot_lifecycle_state_svc(void)99 __naked uint32_t psa_rot_lifecycle_state_svc(void)
100 {
101     __asm volatile("svc     "M2S(TFM_SVC_PSA_LIFECYCLE)"       \n"
102                    "bx      lr                                 \n");
103 }
104 
105 /* Following PSA APIs are only needed by connection-based services */
106 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
107 
psa_connect_svc(uint32_t sid,uint32_t version)108 __naked psa_handle_t psa_connect_svc(uint32_t sid, uint32_t version)
109 {
110     __asm volatile("svc     "M2S(TFM_SVC_PSA_CONNECT)"         \n"
111                    "bx      lr                                 \n");
112 }
113 
psa_close_svc(psa_handle_t handle)114 __naked void psa_close_svc(psa_handle_t handle)
115 {
116     __asm volatile("svc     "M2S(TFM_SVC_PSA_CLOSE)"           \n"
117                    "bx      lr                                 \n");
118 }
119 
psa_set_rhandle_svc(psa_handle_t msg_handle,void * rhandle)120 __naked void psa_set_rhandle_svc(psa_handle_t msg_handle, void *rhandle)
121 {
122     __asm volatile("svc     "M2S(TFM_SVC_PSA_SET_RHANDLE)"     \n"
123                    "bx      lr                                 \n");
124 }
125 
126 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
127 
128 #if CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1
129 
psa_irq_enable_svc(psa_signal_t irq_signal)130 __naked void psa_irq_enable_svc(psa_signal_t irq_signal)
131 {
132     __asm volatile("svc     "M2S(TFM_SVC_PSA_IRQ_ENABLE)"      \n"
133                    "bx      lr                                 \n");
134 }
135 
psa_irq_disable_svc(psa_signal_t irq_signal)136 __naked psa_irq_status_t psa_irq_disable_svc(psa_signal_t irq_signal)
137 {
138     __asm volatile("svc     "M2S(TFM_SVC_PSA_IRQ_DISABLE)"     \n"
139                    "bx      lr                                 \n");
140 }
141 
142 /* This API is only used for FLIH. */
143 #if CONFIG_TFM_FLIH_API == 1
psa_reset_signal_svc(psa_signal_t irq_signal)144 __naked void psa_reset_signal_svc(psa_signal_t irq_signal)
145 {
146     __asm volatile("svc     "M2S(TFM_SVC_PSA_RESET_SIGNAL)"    \n"
147                    "bx      lr                                 \n");
148 }
149 #endif
150 
151 /* This API is only used for SLIH. */
152 #if CONFIG_TFM_SLIH_API == 1
psa_eoi_svc(psa_signal_t irq_signal)153 __naked void psa_eoi_svc(psa_signal_t irq_signal)
154 {
155     __asm volatile("svc     "M2S(TFM_SVC_PSA_EOI)"             \n"
156                    "bx      lr                                 \n");
157 }
158 #endif
159 
160 #endif /* CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1 */
161 
162 #ifdef TFM_PARTITION_NS_AGENT_MAILBOX
agent_psa_call_svc(psa_handle_t handle,uint32_t control,const struct client_params_t * params,const void * client_data_stateless)163 __naked psa_status_t agent_psa_call_svc(psa_handle_t handle,
164                                         uint32_t control,
165                                         const struct client_params_t *params,
166                                         const void *client_data_stateless)
167 {
168     __asm volatile("svc     "M2S(TFM_SVC_AGENT_PSA_CALL)"      \n"
169                    "bx      lr                                 \n");
170 }
171 
172 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
agent_psa_connect_svc(uint32_t sid,uint32_t version,int32_t ns_client_id,const void * client_data)173 __naked psa_handle_t agent_psa_connect_svc(uint32_t sid, uint32_t version,
174                                            int32_t ns_client_id,
175                                            const void *client_data)
176 {
177     __asm volatile("svc     "M2S(TFM_SVC_AGENT_PSA_CONNECT)"   \n"
178                    "bx      lr                                 \n");
179 }
180 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1 */
181 #endif /* TFM_PARTITION_NS_AGENT_MAILBOX */
182 
183 const struct psa_api_tbl_t psa_api_svc = {
184                                 tfm_psa_call_pack_svc,
185                                 psa_version_svc,
186                                 psa_framework_version_svc,
187                                 psa_wait_svc,
188                                 psa_get_svc,
189                                 psa_read_svc,
190                                 psa_skip_svc,
191                                 psa_write_svc,
192                                 psa_reply_svc,
193                                 psa_panic_svc,
194                                 psa_rot_lifecycle_state_svc,
195 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
196                                 psa_connect_svc,
197                                 psa_close_svc,
198                                 psa_set_rhandle_svc,
199 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1 */
200 #if CONFIG_TFM_DOORBELL_API == 1
201                                 psa_notify_svc,
202                                 psa_clear_svc,
203 #endif /* CONFIG_TFM_DOORBELL_API == 1 */
204 #if CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1
205                                 psa_irq_enable_svc,
206                                 psa_irq_disable_svc,
207 #if CONFIG_TFM_FLIH_API == 1
208                                 psa_reset_signal_svc,
209 #endif /* CONFIG_TFM_FLIH_API == 1 */
210 #if CONFIG_TFM_SLIH_API == 1
211                                 psa_eoi_svc,
212 #endif /* CONFIG_TFM_SLIH_API == 1 */
213 #endif /* CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1 */
214 #ifdef TFM_PARTITION_NS_AGENT_MAILBOX
215                                 agent_psa_call_svc,
216 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
217                                 agent_psa_connect_svc,
218 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1 */
219 #endif /* TFM_PARTITION_NS_AGENT_MAILBOX */
220                             };
221