xref: /aosp_15_r20/external/arm-trusted-firmware/bl32/tsp/tsp_main.c (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park  * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
3*54fd6939SJiyong Park  *
4*54fd6939SJiyong Park  * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park  */
6*54fd6939SJiyong Park 
7*54fd6939SJiyong Park #include <assert.h>
8*54fd6939SJiyong Park #include <inttypes.h>
9*54fd6939SJiyong Park #include <stdint.h>
10*54fd6939SJiyong Park 
11*54fd6939SJiyong Park #include <arch_features.h>
12*54fd6939SJiyong Park #include <arch_helpers.h>
13*54fd6939SJiyong Park #include <bl32/tsp/tsp.h>
14*54fd6939SJiyong Park #include <common/bl_common.h>
15*54fd6939SJiyong Park #include <common/debug.h>
16*54fd6939SJiyong Park #include <lib/spinlock.h>
17*54fd6939SJiyong Park #include <plat/common/platform.h>
18*54fd6939SJiyong Park #include <platform_def.h>
19*54fd6939SJiyong Park #include <platform_tsp.h>
20*54fd6939SJiyong Park 
21*54fd6939SJiyong Park #include "tsp_private.h"
22*54fd6939SJiyong Park 
23*54fd6939SJiyong Park 
24*54fd6939SJiyong Park /*******************************************************************************
25*54fd6939SJiyong Park  * Lock to control access to the console
26*54fd6939SJiyong Park  ******************************************************************************/
27*54fd6939SJiyong Park spinlock_t console_lock;
28*54fd6939SJiyong Park 
29*54fd6939SJiyong Park /*******************************************************************************
30*54fd6939SJiyong Park  * Per cpu data structure to populate parameters for an SMC in C code and use
31*54fd6939SJiyong Park  * a pointer to this structure in assembler code to populate x0-x7
32*54fd6939SJiyong Park  ******************************************************************************/
33*54fd6939SJiyong Park static tsp_args_t tsp_smc_args[PLATFORM_CORE_COUNT];
34*54fd6939SJiyong Park 
35*54fd6939SJiyong Park /*******************************************************************************
36*54fd6939SJiyong Park  * Per cpu data structure to keep track of TSP activity
37*54fd6939SJiyong Park  ******************************************************************************/
38*54fd6939SJiyong Park work_statistics_t tsp_stats[PLATFORM_CORE_COUNT];
39*54fd6939SJiyong Park 
40*54fd6939SJiyong Park /*******************************************************************************
41*54fd6939SJiyong Park  * The TSP memory footprint starts at address BL32_BASE and ends with the
42*54fd6939SJiyong Park  * linker symbol __BL32_END__. Use these addresses to compute the TSP image
43*54fd6939SJiyong Park  * size.
44*54fd6939SJiyong Park  ******************************************************************************/
45*54fd6939SJiyong Park #define BL32_TOTAL_LIMIT BL32_END
46*54fd6939SJiyong Park #define BL32_TOTAL_SIZE (BL32_TOTAL_LIMIT - (unsigned long) BL32_BASE)
47*54fd6939SJiyong Park 
set_smc_args(uint64_t arg0,uint64_t arg1,uint64_t arg2,uint64_t arg3,uint64_t arg4,uint64_t arg5,uint64_t arg6,uint64_t arg7)48*54fd6939SJiyong Park static tsp_args_t *set_smc_args(uint64_t arg0,
49*54fd6939SJiyong Park 			     uint64_t arg1,
50*54fd6939SJiyong Park 			     uint64_t arg2,
51*54fd6939SJiyong Park 			     uint64_t arg3,
52*54fd6939SJiyong Park 			     uint64_t arg4,
53*54fd6939SJiyong Park 			     uint64_t arg5,
54*54fd6939SJiyong Park 			     uint64_t arg6,
55*54fd6939SJiyong Park 			     uint64_t arg7)
56*54fd6939SJiyong Park {
57*54fd6939SJiyong Park 	uint32_t linear_id;
58*54fd6939SJiyong Park 	tsp_args_t *pcpu_smc_args;
59*54fd6939SJiyong Park 
60*54fd6939SJiyong Park 	/*
61*54fd6939SJiyong Park 	 * Return to Secure Monitor by raising an SMC. The results of the
62*54fd6939SJiyong Park 	 * service are passed as an arguments to the SMC
63*54fd6939SJiyong Park 	 */
64*54fd6939SJiyong Park 	linear_id = plat_my_core_pos();
65*54fd6939SJiyong Park 	pcpu_smc_args = &tsp_smc_args[linear_id];
66*54fd6939SJiyong Park 	write_sp_arg(pcpu_smc_args, TSP_ARG0, arg0);
67*54fd6939SJiyong Park 	write_sp_arg(pcpu_smc_args, TSP_ARG1, arg1);
68*54fd6939SJiyong Park 	write_sp_arg(pcpu_smc_args, TSP_ARG2, arg2);
69*54fd6939SJiyong Park 	write_sp_arg(pcpu_smc_args, TSP_ARG3, arg3);
70*54fd6939SJiyong Park 	write_sp_arg(pcpu_smc_args, TSP_ARG4, arg4);
71*54fd6939SJiyong Park 	write_sp_arg(pcpu_smc_args, TSP_ARG5, arg5);
72*54fd6939SJiyong Park 	write_sp_arg(pcpu_smc_args, TSP_ARG6, arg6);
73*54fd6939SJiyong Park 	write_sp_arg(pcpu_smc_args, TSP_ARG7, arg7);
74*54fd6939SJiyong Park 
75*54fd6939SJiyong Park 	return pcpu_smc_args;
76*54fd6939SJiyong Park }
77*54fd6939SJiyong Park 
78*54fd6939SJiyong Park /*******************************************************************************
79*54fd6939SJiyong Park  * Setup function for TSP.
80*54fd6939SJiyong Park  ******************************************************************************/
tsp_setup(void)81*54fd6939SJiyong Park void tsp_setup(void)
82*54fd6939SJiyong Park {
83*54fd6939SJiyong Park 	/* Perform early platform-specific setup */
84*54fd6939SJiyong Park 	tsp_early_platform_setup();
85*54fd6939SJiyong Park 
86*54fd6939SJiyong Park 	/* Perform late platform-specific setup */
87*54fd6939SJiyong Park 	tsp_plat_arch_setup();
88*54fd6939SJiyong Park 
89*54fd6939SJiyong Park #if ENABLE_PAUTH
90*54fd6939SJiyong Park 	/*
91*54fd6939SJiyong Park 	 * Assert that the ARMv8.3-PAuth registers are present or an access
92*54fd6939SJiyong Park 	 * fault will be triggered when they are being saved or restored.
93*54fd6939SJiyong Park 	 */
94*54fd6939SJiyong Park 	assert(is_armv8_3_pauth_present());
95*54fd6939SJiyong Park #endif /* ENABLE_PAUTH */
96*54fd6939SJiyong Park }
97*54fd6939SJiyong Park 
98*54fd6939SJiyong Park /*******************************************************************************
99*54fd6939SJiyong Park  * TSP main entry point where it gets the opportunity to initialize its secure
100*54fd6939SJiyong Park  * state/applications. Once the state is initialized, it must return to the
101*54fd6939SJiyong Park  * SPD with a pointer to the 'tsp_vector_table' jump table.
102*54fd6939SJiyong Park  ******************************************************************************/
tsp_main(void)103*54fd6939SJiyong Park uint64_t tsp_main(void)
104*54fd6939SJiyong Park {
105*54fd6939SJiyong Park 	NOTICE("TSP: %s\n", version_string);
106*54fd6939SJiyong Park 	NOTICE("TSP: %s\n", build_message);
107*54fd6939SJiyong Park 	INFO("TSP: Total memory base : 0x%lx\n", (unsigned long) BL32_BASE);
108*54fd6939SJiyong Park 	INFO("TSP: Total memory size : 0x%lx bytes\n", BL32_TOTAL_SIZE);
109*54fd6939SJiyong Park 
110*54fd6939SJiyong Park 	uint32_t linear_id = plat_my_core_pos();
111*54fd6939SJiyong Park 
112*54fd6939SJiyong Park 	/* Initialize the platform */
113*54fd6939SJiyong Park 	tsp_platform_setup();
114*54fd6939SJiyong Park 
115*54fd6939SJiyong Park 	/* Initialize secure/applications state here */
116*54fd6939SJiyong Park 	tsp_generic_timer_start();
117*54fd6939SJiyong Park 
118*54fd6939SJiyong Park 	/* Update this cpu's statistics */
119*54fd6939SJiyong Park 	tsp_stats[linear_id].smc_count++;
120*54fd6939SJiyong Park 	tsp_stats[linear_id].eret_count++;
121*54fd6939SJiyong Park 	tsp_stats[linear_id].cpu_on_count++;
122*54fd6939SJiyong Park 
123*54fd6939SJiyong Park #if LOG_LEVEL >= LOG_LEVEL_INFO
124*54fd6939SJiyong Park 	spin_lock(&console_lock);
125*54fd6939SJiyong Park 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
126*54fd6939SJiyong Park 	     read_mpidr(),
127*54fd6939SJiyong Park 	     tsp_stats[linear_id].smc_count,
128*54fd6939SJiyong Park 	     tsp_stats[linear_id].eret_count,
129*54fd6939SJiyong Park 	     tsp_stats[linear_id].cpu_on_count);
130*54fd6939SJiyong Park 	spin_unlock(&console_lock);
131*54fd6939SJiyong Park #endif
132*54fd6939SJiyong Park 	return (uint64_t) &tsp_vector_table;
133*54fd6939SJiyong Park }
134*54fd6939SJiyong Park 
135*54fd6939SJiyong Park /*******************************************************************************
136*54fd6939SJiyong Park  * This function performs any remaining book keeping in the test secure payload
137*54fd6939SJiyong Park  * after this cpu's architectural state has been setup in response to an earlier
138*54fd6939SJiyong Park  * psci cpu_on request.
139*54fd6939SJiyong Park  ******************************************************************************/
tsp_cpu_on_main(void)140*54fd6939SJiyong Park tsp_args_t *tsp_cpu_on_main(void)
141*54fd6939SJiyong Park {
142*54fd6939SJiyong Park 	uint32_t linear_id = plat_my_core_pos();
143*54fd6939SJiyong Park 
144*54fd6939SJiyong Park 	/* Initialize secure/applications state here */
145*54fd6939SJiyong Park 	tsp_generic_timer_start();
146*54fd6939SJiyong Park 
147*54fd6939SJiyong Park 	/* Update this cpu's statistics */
148*54fd6939SJiyong Park 	tsp_stats[linear_id].smc_count++;
149*54fd6939SJiyong Park 	tsp_stats[linear_id].eret_count++;
150*54fd6939SJiyong Park 	tsp_stats[linear_id].cpu_on_count++;
151*54fd6939SJiyong Park 
152*54fd6939SJiyong Park #if LOG_LEVEL >= LOG_LEVEL_INFO
153*54fd6939SJiyong Park 	spin_lock(&console_lock);
154*54fd6939SJiyong Park 	INFO("TSP: cpu 0x%lx turned on\n", read_mpidr());
155*54fd6939SJiyong Park 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
156*54fd6939SJiyong Park 		read_mpidr(),
157*54fd6939SJiyong Park 		tsp_stats[linear_id].smc_count,
158*54fd6939SJiyong Park 		tsp_stats[linear_id].eret_count,
159*54fd6939SJiyong Park 		tsp_stats[linear_id].cpu_on_count);
160*54fd6939SJiyong Park 	spin_unlock(&console_lock);
161*54fd6939SJiyong Park #endif
162*54fd6939SJiyong Park 	/* Indicate to the SPD that we have completed turned ourselves on */
163*54fd6939SJiyong Park 	return set_smc_args(TSP_ON_DONE, 0, 0, 0, 0, 0, 0, 0);
164*54fd6939SJiyong Park }
165*54fd6939SJiyong Park 
166*54fd6939SJiyong Park /*******************************************************************************
167*54fd6939SJiyong Park  * This function performs any remaining book keeping in the test secure payload
168*54fd6939SJiyong Park  * before this cpu is turned off in response to a psci cpu_off request.
169*54fd6939SJiyong Park  ******************************************************************************/
tsp_cpu_off_main(uint64_t arg0,uint64_t arg1,uint64_t arg2,uint64_t arg3,uint64_t arg4,uint64_t arg5,uint64_t arg6,uint64_t arg7)170*54fd6939SJiyong Park tsp_args_t *tsp_cpu_off_main(uint64_t arg0,
171*54fd6939SJiyong Park 			   uint64_t arg1,
172*54fd6939SJiyong Park 			   uint64_t arg2,
173*54fd6939SJiyong Park 			   uint64_t arg3,
174*54fd6939SJiyong Park 			   uint64_t arg4,
175*54fd6939SJiyong Park 			   uint64_t arg5,
176*54fd6939SJiyong Park 			   uint64_t arg6,
177*54fd6939SJiyong Park 			   uint64_t arg7)
178*54fd6939SJiyong Park {
179*54fd6939SJiyong Park 	uint32_t linear_id = plat_my_core_pos();
180*54fd6939SJiyong Park 
181*54fd6939SJiyong Park 	/*
182*54fd6939SJiyong Park 	 * This cpu is being turned off, so disable the timer to prevent the
183*54fd6939SJiyong Park 	 * secure timer interrupt from interfering with power down. A pending
184*54fd6939SJiyong Park 	 * interrupt will be lost but we do not care as we are turning off.
185*54fd6939SJiyong Park 	 */
186*54fd6939SJiyong Park 	tsp_generic_timer_stop();
187*54fd6939SJiyong Park 
188*54fd6939SJiyong Park 	/* Update this cpu's statistics */
189*54fd6939SJiyong Park 	tsp_stats[linear_id].smc_count++;
190*54fd6939SJiyong Park 	tsp_stats[linear_id].eret_count++;
191*54fd6939SJiyong Park 	tsp_stats[linear_id].cpu_off_count++;
192*54fd6939SJiyong Park 
193*54fd6939SJiyong Park #if LOG_LEVEL >= LOG_LEVEL_INFO
194*54fd6939SJiyong Park 	spin_lock(&console_lock);
195*54fd6939SJiyong Park 	INFO("TSP: cpu 0x%lx off request\n", read_mpidr());
196*54fd6939SJiyong Park 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu off requests\n",
197*54fd6939SJiyong Park 		read_mpidr(),
198*54fd6939SJiyong Park 		tsp_stats[linear_id].smc_count,
199*54fd6939SJiyong Park 		tsp_stats[linear_id].eret_count,
200*54fd6939SJiyong Park 		tsp_stats[linear_id].cpu_off_count);
201*54fd6939SJiyong Park 	spin_unlock(&console_lock);
202*54fd6939SJiyong Park #endif
203*54fd6939SJiyong Park 
204*54fd6939SJiyong Park 	/* Indicate to the SPD that we have completed this request */
205*54fd6939SJiyong Park 	return set_smc_args(TSP_OFF_DONE, 0, 0, 0, 0, 0, 0, 0);
206*54fd6939SJiyong Park }
207*54fd6939SJiyong Park 
208*54fd6939SJiyong Park /*******************************************************************************
209*54fd6939SJiyong Park  * This function performs any book keeping in the test secure payload before
210*54fd6939SJiyong Park  * this cpu's architectural state is saved in response to an earlier psci
211*54fd6939SJiyong Park  * cpu_suspend request.
212*54fd6939SJiyong Park  ******************************************************************************/
tsp_cpu_suspend_main(uint64_t arg0,uint64_t arg1,uint64_t arg2,uint64_t arg3,uint64_t arg4,uint64_t arg5,uint64_t arg6,uint64_t arg7)213*54fd6939SJiyong Park tsp_args_t *tsp_cpu_suspend_main(uint64_t arg0,
214*54fd6939SJiyong Park 			       uint64_t arg1,
215*54fd6939SJiyong Park 			       uint64_t arg2,
216*54fd6939SJiyong Park 			       uint64_t arg3,
217*54fd6939SJiyong Park 			       uint64_t arg4,
218*54fd6939SJiyong Park 			       uint64_t arg5,
219*54fd6939SJiyong Park 			       uint64_t arg6,
220*54fd6939SJiyong Park 			       uint64_t arg7)
221*54fd6939SJiyong Park {
222*54fd6939SJiyong Park 	uint32_t linear_id = plat_my_core_pos();
223*54fd6939SJiyong Park 
224*54fd6939SJiyong Park 	/*
225*54fd6939SJiyong Park 	 * Save the time context and disable it to prevent the secure timer
226*54fd6939SJiyong Park 	 * interrupt from interfering with wakeup from the suspend state.
227*54fd6939SJiyong Park 	 */
228*54fd6939SJiyong Park 	tsp_generic_timer_save();
229*54fd6939SJiyong Park 	tsp_generic_timer_stop();
230*54fd6939SJiyong Park 
231*54fd6939SJiyong Park 	/* Update this cpu's statistics */
232*54fd6939SJiyong Park 	tsp_stats[linear_id].smc_count++;
233*54fd6939SJiyong Park 	tsp_stats[linear_id].eret_count++;
234*54fd6939SJiyong Park 	tsp_stats[linear_id].cpu_suspend_count++;
235*54fd6939SJiyong Park 
236*54fd6939SJiyong Park #if LOG_LEVEL >= LOG_LEVEL_INFO
237*54fd6939SJiyong Park 	spin_lock(&console_lock);
238*54fd6939SJiyong Park 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n",
239*54fd6939SJiyong Park 		read_mpidr(),
240*54fd6939SJiyong Park 		tsp_stats[linear_id].smc_count,
241*54fd6939SJiyong Park 		tsp_stats[linear_id].eret_count,
242*54fd6939SJiyong Park 		tsp_stats[linear_id].cpu_suspend_count);
243*54fd6939SJiyong Park 	spin_unlock(&console_lock);
244*54fd6939SJiyong Park #endif
245*54fd6939SJiyong Park 
246*54fd6939SJiyong Park 	/* Indicate to the SPD that we have completed this request */
247*54fd6939SJiyong Park 	return set_smc_args(TSP_SUSPEND_DONE, 0, 0, 0, 0, 0, 0, 0);
248*54fd6939SJiyong Park }
249*54fd6939SJiyong Park 
250*54fd6939SJiyong Park /*******************************************************************************
251*54fd6939SJiyong Park  * This function performs any book keeping in the test secure payload after this
252*54fd6939SJiyong Park  * cpu's architectural state has been restored after wakeup from an earlier psci
253*54fd6939SJiyong Park  * cpu_suspend request.
254*54fd6939SJiyong Park  ******************************************************************************/
tsp_cpu_resume_main(uint64_t max_off_pwrlvl,uint64_t arg1,uint64_t arg2,uint64_t arg3,uint64_t arg4,uint64_t arg5,uint64_t arg6,uint64_t arg7)255*54fd6939SJiyong Park tsp_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl,
256*54fd6939SJiyong Park 			      uint64_t arg1,
257*54fd6939SJiyong Park 			      uint64_t arg2,
258*54fd6939SJiyong Park 			      uint64_t arg3,
259*54fd6939SJiyong Park 			      uint64_t arg4,
260*54fd6939SJiyong Park 			      uint64_t arg5,
261*54fd6939SJiyong Park 			      uint64_t arg6,
262*54fd6939SJiyong Park 			      uint64_t arg7)
263*54fd6939SJiyong Park {
264*54fd6939SJiyong Park 	uint32_t linear_id = plat_my_core_pos();
265*54fd6939SJiyong Park 
266*54fd6939SJiyong Park 	/* Restore the generic timer context */
267*54fd6939SJiyong Park 	tsp_generic_timer_restore();
268*54fd6939SJiyong Park 
269*54fd6939SJiyong Park 	/* Update this cpu's statistics */
270*54fd6939SJiyong Park 	tsp_stats[linear_id].smc_count++;
271*54fd6939SJiyong Park 	tsp_stats[linear_id].eret_count++;
272*54fd6939SJiyong Park 	tsp_stats[linear_id].cpu_resume_count++;
273*54fd6939SJiyong Park 
274*54fd6939SJiyong Park #if LOG_LEVEL >= LOG_LEVEL_INFO
275*54fd6939SJiyong Park 	spin_lock(&console_lock);
276*54fd6939SJiyong Park 	INFO("TSP: cpu 0x%lx resumed. maximum off power level %" PRId64 "\n",
277*54fd6939SJiyong Park 	     read_mpidr(), max_off_pwrlvl);
278*54fd6939SJiyong Park 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu resume requests\n",
279*54fd6939SJiyong Park 		read_mpidr(),
280*54fd6939SJiyong Park 		tsp_stats[linear_id].smc_count,
281*54fd6939SJiyong Park 		tsp_stats[linear_id].eret_count,
282*54fd6939SJiyong Park 		tsp_stats[linear_id].cpu_resume_count);
283*54fd6939SJiyong Park 	spin_unlock(&console_lock);
284*54fd6939SJiyong Park #endif
285*54fd6939SJiyong Park 	/* Indicate to the SPD that we have completed this request */
286*54fd6939SJiyong Park 	return set_smc_args(TSP_RESUME_DONE, 0, 0, 0, 0, 0, 0, 0);
287*54fd6939SJiyong Park }
288*54fd6939SJiyong Park 
289*54fd6939SJiyong Park /*******************************************************************************
290*54fd6939SJiyong Park  * This function performs any remaining bookkeeping in the test secure payload
291*54fd6939SJiyong Park  * before the system is switched off (in response to a psci SYSTEM_OFF request)
292*54fd6939SJiyong Park  ******************************************************************************/
tsp_system_off_main(uint64_t arg0,uint64_t arg1,uint64_t arg2,uint64_t arg3,uint64_t arg4,uint64_t arg5,uint64_t arg6,uint64_t arg7)293*54fd6939SJiyong Park tsp_args_t *tsp_system_off_main(uint64_t arg0,
294*54fd6939SJiyong Park 				uint64_t arg1,
295*54fd6939SJiyong Park 				uint64_t arg2,
296*54fd6939SJiyong Park 				uint64_t arg3,
297*54fd6939SJiyong Park 				uint64_t arg4,
298*54fd6939SJiyong Park 				uint64_t arg5,
299*54fd6939SJiyong Park 				uint64_t arg6,
300*54fd6939SJiyong Park 				uint64_t arg7)
301*54fd6939SJiyong Park {
302*54fd6939SJiyong Park 	uint32_t linear_id = plat_my_core_pos();
303*54fd6939SJiyong Park 
304*54fd6939SJiyong Park 	/* Update this cpu's statistics */
305*54fd6939SJiyong Park 	tsp_stats[linear_id].smc_count++;
306*54fd6939SJiyong Park 	tsp_stats[linear_id].eret_count++;
307*54fd6939SJiyong Park 
308*54fd6939SJiyong Park #if LOG_LEVEL >= LOG_LEVEL_INFO
309*54fd6939SJiyong Park 	spin_lock(&console_lock);
310*54fd6939SJiyong Park 	INFO("TSP: cpu 0x%lx SYSTEM_OFF request\n", read_mpidr());
311*54fd6939SJiyong Park 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(),
312*54fd6939SJiyong Park 	     tsp_stats[linear_id].smc_count,
313*54fd6939SJiyong Park 	     tsp_stats[linear_id].eret_count);
314*54fd6939SJiyong Park 	spin_unlock(&console_lock);
315*54fd6939SJiyong Park #endif
316*54fd6939SJiyong Park 
317*54fd6939SJiyong Park 	/* Indicate to the SPD that we have completed this request */
318*54fd6939SJiyong Park 	return set_smc_args(TSP_SYSTEM_OFF_DONE, 0, 0, 0, 0, 0, 0, 0);
319*54fd6939SJiyong Park }
320*54fd6939SJiyong Park 
321*54fd6939SJiyong Park /*******************************************************************************
322*54fd6939SJiyong Park  * This function performs any remaining bookkeeping in the test secure payload
323*54fd6939SJiyong Park  * before the system is reset (in response to a psci SYSTEM_RESET request)
324*54fd6939SJiyong Park  ******************************************************************************/
tsp_system_reset_main(uint64_t arg0,uint64_t arg1,uint64_t arg2,uint64_t arg3,uint64_t arg4,uint64_t arg5,uint64_t arg6,uint64_t arg7)325*54fd6939SJiyong Park tsp_args_t *tsp_system_reset_main(uint64_t arg0,
326*54fd6939SJiyong Park 				uint64_t arg1,
327*54fd6939SJiyong Park 				uint64_t arg2,
328*54fd6939SJiyong Park 				uint64_t arg3,
329*54fd6939SJiyong Park 				uint64_t arg4,
330*54fd6939SJiyong Park 				uint64_t arg5,
331*54fd6939SJiyong Park 				uint64_t arg6,
332*54fd6939SJiyong Park 				uint64_t arg7)
333*54fd6939SJiyong Park {
334*54fd6939SJiyong Park 	uint32_t linear_id = plat_my_core_pos();
335*54fd6939SJiyong Park 
336*54fd6939SJiyong Park 	/* Update this cpu's statistics */
337*54fd6939SJiyong Park 	tsp_stats[linear_id].smc_count++;
338*54fd6939SJiyong Park 	tsp_stats[linear_id].eret_count++;
339*54fd6939SJiyong Park 
340*54fd6939SJiyong Park #if LOG_LEVEL >= LOG_LEVEL_INFO
341*54fd6939SJiyong Park 	spin_lock(&console_lock);
342*54fd6939SJiyong Park 	INFO("TSP: cpu 0x%lx SYSTEM_RESET request\n", read_mpidr());
343*54fd6939SJiyong Park 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(),
344*54fd6939SJiyong Park 	     tsp_stats[linear_id].smc_count,
345*54fd6939SJiyong Park 	     tsp_stats[linear_id].eret_count);
346*54fd6939SJiyong Park 	spin_unlock(&console_lock);
347*54fd6939SJiyong Park #endif
348*54fd6939SJiyong Park 
349*54fd6939SJiyong Park 	/* Indicate to the SPD that we have completed this request */
350*54fd6939SJiyong Park 	return set_smc_args(TSP_SYSTEM_RESET_DONE, 0, 0, 0, 0, 0, 0, 0);
351*54fd6939SJiyong Park }
352*54fd6939SJiyong Park 
353*54fd6939SJiyong Park /*******************************************************************************
354*54fd6939SJiyong Park  * TSP fast smc handler. The secure monitor jumps to this function by
355*54fd6939SJiyong Park  * doing the ERET after populating X0-X7 registers. The arguments are received
356*54fd6939SJiyong Park  * in the function arguments in order. Once the service is rendered, this
357*54fd6939SJiyong Park  * function returns to Secure Monitor by raising SMC.
358*54fd6939SJiyong Park  ******************************************************************************/
tsp_smc_handler(uint64_t func,uint64_t arg1,uint64_t arg2,uint64_t arg3,uint64_t arg4,uint64_t arg5,uint64_t arg6,uint64_t arg7)359*54fd6939SJiyong Park tsp_args_t *tsp_smc_handler(uint64_t func,
360*54fd6939SJiyong Park 			       uint64_t arg1,
361*54fd6939SJiyong Park 			       uint64_t arg2,
362*54fd6939SJiyong Park 			       uint64_t arg3,
363*54fd6939SJiyong Park 			       uint64_t arg4,
364*54fd6939SJiyong Park 			       uint64_t arg5,
365*54fd6939SJiyong Park 			       uint64_t arg6,
366*54fd6939SJiyong Park 			       uint64_t arg7)
367*54fd6939SJiyong Park {
368*54fd6939SJiyong Park 	uint128_t service_args;
369*54fd6939SJiyong Park 	uint64_t service_arg0;
370*54fd6939SJiyong Park 	uint64_t service_arg1;
371*54fd6939SJiyong Park 	uint64_t results[2];
372*54fd6939SJiyong Park 	uint32_t linear_id = plat_my_core_pos();
373*54fd6939SJiyong Park 
374*54fd6939SJiyong Park 	/* Update this cpu's statistics */
375*54fd6939SJiyong Park 	tsp_stats[linear_id].smc_count++;
376*54fd6939SJiyong Park 	tsp_stats[linear_id].eret_count++;
377*54fd6939SJiyong Park 
378*54fd6939SJiyong Park #if LOG_LEVEL >= LOG_LEVEL_INFO
379*54fd6939SJiyong Park 	spin_lock(&console_lock);
380*54fd6939SJiyong Park 	INFO("TSP: cpu 0x%lx received %s smc 0x%" PRIx64 "\n", read_mpidr(),
381*54fd6939SJiyong Park 		((func >> 31) & 1) == 1 ? "fast" : "yielding",
382*54fd6939SJiyong Park 		func);
383*54fd6939SJiyong Park 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets\n", read_mpidr(),
384*54fd6939SJiyong Park 		tsp_stats[linear_id].smc_count,
385*54fd6939SJiyong Park 		tsp_stats[linear_id].eret_count);
386*54fd6939SJiyong Park 	spin_unlock(&console_lock);
387*54fd6939SJiyong Park #endif
388*54fd6939SJiyong Park 
389*54fd6939SJiyong Park 	/* Render secure services and obtain results here */
390*54fd6939SJiyong Park 	results[0] = arg1;
391*54fd6939SJiyong Park 	results[1] = arg2;
392*54fd6939SJiyong Park 
393*54fd6939SJiyong Park 	/*
394*54fd6939SJiyong Park 	 * Request a service back from dispatcher/secure monitor.
395*54fd6939SJiyong Park 	 * This call returns and thereafter resumes execution.
396*54fd6939SJiyong Park 	 */
397*54fd6939SJiyong Park 	service_args = tsp_get_magic();
398*54fd6939SJiyong Park 	service_arg0 = (uint64_t)service_args;
399*54fd6939SJiyong Park 	service_arg1 = (uint64_t)(service_args >> 64U);
400*54fd6939SJiyong Park 
401*54fd6939SJiyong Park #if CTX_INCLUDE_MTE_REGS
402*54fd6939SJiyong Park 	/*
403*54fd6939SJiyong Park 	 * Write a dummy value to an MTE register, to simulate usage in the
404*54fd6939SJiyong Park 	 * secure world
405*54fd6939SJiyong Park 	 */
406*54fd6939SJiyong Park 	write_gcr_el1(0x99);
407*54fd6939SJiyong Park #endif
408*54fd6939SJiyong Park 
409*54fd6939SJiyong Park 	/* Determine the function to perform based on the function ID */
410*54fd6939SJiyong Park 	switch (TSP_BARE_FID(func)) {
411*54fd6939SJiyong Park 	case TSP_ADD:
412*54fd6939SJiyong Park 		results[0] += service_arg0;
413*54fd6939SJiyong Park 		results[1] += service_arg1;
414*54fd6939SJiyong Park 		break;
415*54fd6939SJiyong Park 	case TSP_SUB:
416*54fd6939SJiyong Park 		results[0] -= service_arg0;
417*54fd6939SJiyong Park 		results[1] -= service_arg1;
418*54fd6939SJiyong Park 		break;
419*54fd6939SJiyong Park 	case TSP_MUL:
420*54fd6939SJiyong Park 		results[0] *= service_arg0;
421*54fd6939SJiyong Park 		results[1] *= service_arg1;
422*54fd6939SJiyong Park 		break;
423*54fd6939SJiyong Park 	case TSP_DIV:
424*54fd6939SJiyong Park 		results[0] /= service_arg0 ? service_arg0 : 1;
425*54fd6939SJiyong Park 		results[1] /= service_arg1 ? service_arg1 : 1;
426*54fd6939SJiyong Park 		break;
427*54fd6939SJiyong Park 	default:
428*54fd6939SJiyong Park 		break;
429*54fd6939SJiyong Park 	}
430*54fd6939SJiyong Park 
431*54fd6939SJiyong Park 	return set_smc_args(func, 0,
432*54fd6939SJiyong Park 			    results[0],
433*54fd6939SJiyong Park 			    results[1],
434*54fd6939SJiyong Park 			    0, 0, 0, 0);
435*54fd6939SJiyong Park }
436*54fd6939SJiyong Park 
437*54fd6939SJiyong Park /*******************************************************************************
438*54fd6939SJiyong Park  * TSP smc abort handler. This function is called when aborting a preempted
439*54fd6939SJiyong Park  * yielding SMC request. It should cleanup all resources owned by the SMC
440*54fd6939SJiyong Park  * handler such as locks or dynamically allocated memory so following SMC
441*54fd6939SJiyong Park  * request are executed in a clean environment.
442*54fd6939SJiyong Park  ******************************************************************************/
tsp_abort_smc_handler(uint64_t func,uint64_t arg1,uint64_t arg2,uint64_t arg3,uint64_t arg4,uint64_t arg5,uint64_t arg6,uint64_t arg7)443*54fd6939SJiyong Park tsp_args_t *tsp_abort_smc_handler(uint64_t func,
444*54fd6939SJiyong Park 				  uint64_t arg1,
445*54fd6939SJiyong Park 				  uint64_t arg2,
446*54fd6939SJiyong Park 				  uint64_t arg3,
447*54fd6939SJiyong Park 				  uint64_t arg4,
448*54fd6939SJiyong Park 				  uint64_t arg5,
449*54fd6939SJiyong Park 				  uint64_t arg6,
450*54fd6939SJiyong Park 				  uint64_t arg7)
451*54fd6939SJiyong Park {
452*54fd6939SJiyong Park 	return set_smc_args(TSP_ABORT_DONE, 0, 0, 0, 0, 0, 0, 0);
453*54fd6939SJiyong Park }
454