xref: /rk3399_ARM-atf/services/std_svc/std_svc_setup.c (revision 430f246e58d146949d399d72294f56403672bee0)
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