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 
163 const struct psa_api_tbl_t psa_api_svc = {
164                                 tfm_psa_call_pack_svc,
165                                 psa_version_svc,
166                                 psa_framework_version_svc,
167                                 psa_wait_svc,
168                                 psa_get_svc,
169                                 psa_read_svc,
170                                 psa_skip_svc,
171                                 psa_write_svc,
172                                 psa_reply_svc,
173                                 psa_panic_svc,
174                                 psa_rot_lifecycle_state_svc,
175 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
176                                 psa_connect_svc,
177                                 psa_close_svc,
178                                 psa_set_rhandle_svc,
179 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1 */
180 #if CONFIG_TFM_DOORBELL_API == 1
181                                 psa_notify_svc,
182                                 psa_clear_svc,
183 #endif /* CONFIG_TFM_DOORBELL_API == 1 */
184 #if CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1
185                                 psa_irq_enable_svc,
186                                 psa_irq_disable_svc,
187 #if CONFIG_TFM_FLIH_API == 1
188                                 psa_reset_signal_svc,
189 #endif /* CONFIG_TFM_FLIH_API == 1 */
190 #if CONFIG_TFM_SLIH_API == 1
191                                 psa_eoi_svc,
192 #endif /* CONFIG_TFM_SLIH_API == 1 */
193 #endif /* CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1 */
194                             };
195