1 /*
2 * Copyright (c) 2014-2026, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <assert.h>
8 #include <stdint.h>
9
10 #include <arch_features.h>
11 #include <common/debug.h>
12 #include <common/runtime_svc.h>
13 #include <lib/el3_runtime/cpu_data.h>
14 #include <lib/pmf/pmf.h>
15 #include <lib/psci/psci.h>
16 #include <lib/runtime_instr.h>
17 #include <services/drtm_svc.h>
18 #include <services/errata_abi_svc.h>
19 #include <services/firme_svc.h>
20 #include <services/lfa_svc.h>
21 #include <services/pci_svc.h>
22 #include <services/rmmd_svc.h>
23 #include <services/sdei.h>
24 #include <services/spm_mm_svc.h>
25 #include <services/spmc_svc.h>
26 #include <services/spmd_svc.h>
27 #include <services/std_svc.h>
28 #include <services/trng_svc.h>
29 #include <smccc_helpers.h>
30 #include <tools_share/uuid.h>
31
32 /* Standard Service UUID */
33 static uuid_t arm_svc_uid = {
34 {0x5b, 0x90, 0x8d, 0x10},
35 {0x63, 0xf8},
36 {0xe8, 0x47},
37 0xae, 0x2d,
38 {0xc0, 0xfb, 0x56, 0x41, 0xf6, 0xe2}
39 };
40
41 /* Setup Standard Services */
std_svc_setup(void)42 static int32_t std_svc_setup(void)
43 {
44 uintptr_t svc_arg;
45 int ret = 0;
46
47 svc_arg = get_arm_std_svc_args(PSCI_FID_MASK);
48 assert(svc_arg);
49
50 /*
51 * PSCI is one of the specifications implemented as a Standard Service.
52 * The `psci_setup()` also does EL3 architectural setup.
53 */
54 if (psci_setup((const psci_lib_args_t *)svc_arg) != PSCI_E_SUCCESS) {
55 ret = 1;
56 }
57
58 #if SPM_MM
59 if (spm_mm_setup() != 0) {
60 ret = 1;
61 }
62 #endif
63
64 #if defined(SPD_spmd)
65 if (spmd_setup() != 0) {
66 ret = 1;
67 }
68 #endif
69
70 #if ENABLE_RMM
71 if (is_feat_rme_supported() && (rmmd_setup() != 0)) {
72 WARN("RMMD setup failed. Continuing boot.\n");
73 }
74 #endif
75
76 #if SDEI_SUPPORT
77 /* SDEI initialisation */
78 sdei_init();
79 #endif
80
81 #if TRNG_SUPPORT
82 /* TRNG initialisation */
83 trng_setup();
84 #endif /* TRNG_SUPPORT */
85
86 #if DRTM_SUPPORT
87 if (drtm_setup() != 0) {
88 ret = 1;
89 }
90 #endif /* DRTM_SUPPORT */
91
92 #if LFA_SUPPORT
93 /*
94 * Setup/Initialize resources useful during LFA
95 */
96 if (lfa_setup() != 0) {
97 ret = 1;
98 }
99 #endif /* LFA_SUPPORT */
100
101 return ret;
102 }
103
104 /*
105 * Top-level Standard Service SMC handler. This handler will in turn dispatch
106 * calls to PSCI SMC handler
107 */
std_svc_smc_handler(uint32_t smc_fid,u_register_t x1_arg,u_register_t x2_arg,u_register_t x3_arg,u_register_t x4_arg,void * cookie,void * handle,u_register_t flags)108 static uintptr_t std_svc_smc_handler(uint32_t smc_fid,
109 u_register_t x1_arg,
110 u_register_t x2_arg,
111 u_register_t x3_arg,
112 u_register_t x4_arg,
113 void *cookie,
114 void *handle,
115 u_register_t flags)
116 {
117 u_register_t x1 = x1_arg;
118 u_register_t x2 = x2_arg;
119 u_register_t x3 = x3_arg;
120 u_register_t x4 = x4_arg;
121
122 if (((smc_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_32) {
123 /* 32-bit SMC function, clear top parameter bits */
124
125 x1 &= UINT32_MAX;
126 x2 &= UINT32_MAX;
127 x3 &= UINT32_MAX;
128 x4 &= UINT32_MAX;
129 }
130
131 /*
132 * Dispatch PSCI calls to PSCI SMC handler and return its return
133 * value
134 */
135 if (is_psci_fid(smc_fid)) {
136 uint64_t ret;
137
138 #if ENABLE_RUNTIME_INSTRUMENTATION
139
140 /*
141 * Flush cache line so that even if CPU power down happens
142 * the timestamp update is reflected in memory.
143 */
144 PMF_WRITE_TIMESTAMP(rt_instr_svc,
145 RT_INSTR_ENTER_PSCI,
146 PMF_CACHE_MAINT,
147 get_cpu_data(cpu_data_pmf_ts[CPU_DATA_PMF_TS0_IDX]));
148 #endif
149
150 ret = psci_smc_handler(smc_fid, x1, x2, x3, x4,
151 cookie, handle, flags);
152
153 #if ENABLE_RUNTIME_INSTRUMENTATION
154 PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
155 RT_INSTR_EXIT_PSCI,
156 PMF_NO_CACHE_MAINT);
157 #endif
158
159 SMC_RET1(handle, ret);
160 }
161
162 #if SPM_MM
163 /*
164 * Dispatch SPM calls to SPM SMC handler and return its return
165 * value
166 */
167 if (is_spm_mm_fid(smc_fid)) {
168 return spm_mm_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
169 handle, flags);
170 }
171 #endif
172
173 #if defined(SPD_spmd)
174 /*
175 * Dispatch FFA calls to the FFA SMC handler implemented by the SPM
176 * dispatcher and return its return value
177 */
178 if (is_ffa_fid(smc_fid)) {
179 return spmd_ffa_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
180 handle, flags);
181 }
182 #endif
183
184 #if SDEI_SUPPORT
185 if (is_sdei_fid(smc_fid)) {
186 return sdei_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
187 flags);
188 }
189 #endif
190
191 #if TRNG_SUPPORT
192 if (is_trng_fid(smc_fid)) {
193 return trng_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
194 flags);
195 }
196 #endif /* TRNG_SUPPORT */
197
198 #if ERRATA_ABI_SUPPORT
199 if (is_errata_fid(smc_fid)) {
200 return errata_abi_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
201 handle, flags);
202 }
203 #endif /* ERRATA_ABI_SUPPORT */
204
205 #if ENABLE_RMM
206
207 if (is_rmmd_el3_fid(smc_fid)) {
208 return rmmd_rmm_el3_handler(smc_fid, x1, x2, x3, x4, cookie,
209 handle, flags);
210 }
211
212 if (is_rmi_fid(smc_fid)) {
213 return rmmd_rmi_handler(smc_fid, x1, x2, x3, x4, cookie,
214 handle, flags);
215 }
216 #endif
217
218 #if FIRME_SUPPORT
219 if (is_firme_fid(smc_fid)) {
220 return firme_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
221 flags);
222 }
223 #endif
224
225 #if SMC_PCI_SUPPORT
226 if (is_pci_fid(smc_fid)) {
227 return pci_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
228 flags);
229 }
230 #endif
231
232 #if DRTM_SUPPORT
233 if (is_drtm_fid(smc_fid)) {
234 return drtm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
235 flags);
236 }
237 #endif /* DRTM_SUPPORT */
238
239 #if LFA_SUPPORT
240 if (is_lfa_fid(smc_fid)) {
241 return lfa_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
242 }
243 #endif /* LFA_SUPPORT */
244
245
246 switch (smc_fid) {
247 case ARM_STD_SVC_CALL_COUNT:
248 /*
249 * Return the number of Standard Service Calls. PSCI is the only
250 * standard service implemented; so return number of PSCI calls
251 */
252 SMC_RET1(handle, PSCI_NUM_CALLS);
253
254 case ARM_STD_SVC_UID:
255 /* Return UID to the caller */
256 SMC_UUID_RET(handle, arm_svc_uid);
257
258 case ARM_STD_SVC_VERSION:
259 /* Return the version of current implementation */
260 SMC_RET2(handle, STD_SVC_VERSION_MAJOR, STD_SVC_VERSION_MINOR);
261
262 default:
263 VERBOSE("Unimplemented Standard Service Call: 0x%x \n", smc_fid);
264 SMC_RET1(handle, SMC_UNK);
265 }
266 }
267
268 /* Register Standard Service Calls as runtime service */
269 DECLARE_RT_SVC(
270 std_svc,
271
272 OEN_STD_START,
273 OEN_STD_END,
274 SMC_TYPE_FAST,
275 std_svc_setup,
276 std_svc_smc_handler
277 );
278