xref: /rk3399_ARM-atf/bl32/tsp/tsp_ffa_main.c (revision 4a8bfdb90956ecec02ba5e189fe5452817a65179)
1*4a8bfdb9SAchin Gupta /*
2*4a8bfdb9SAchin Gupta  * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
3*4a8bfdb9SAchin Gupta  *
4*4a8bfdb9SAchin Gupta  * SPDX-License-Identifier: BSD-3-Clause
5*4a8bfdb9SAchin Gupta  */
6*4a8bfdb9SAchin Gupta 
7*4a8bfdb9SAchin Gupta #include <assert.h>
8*4a8bfdb9SAchin Gupta #include <inttypes.h>
9*4a8bfdb9SAchin Gupta #include <stdint.h>
10*4a8bfdb9SAchin Gupta 
11*4a8bfdb9SAchin Gupta #include "../../services/std_svc/spm/el3_spmc/spmc.h"
12*4a8bfdb9SAchin Gupta #include "../../services/std_svc/spm/el3_spmc/spmc_shared_mem.h"
13*4a8bfdb9SAchin Gupta #include <arch_features.h>
14*4a8bfdb9SAchin Gupta #include <arch_helpers.h>
15*4a8bfdb9SAchin Gupta #include <bl32/tsp/tsp.h>
16*4a8bfdb9SAchin Gupta #include <common/bl_common.h>
17*4a8bfdb9SAchin Gupta #include <common/debug.h>
18*4a8bfdb9SAchin Gupta #include <lib/psci/psci.h>
19*4a8bfdb9SAchin Gupta #include <lib/spinlock.h>
20*4a8bfdb9SAchin Gupta #include <plat/common/platform.h>
21*4a8bfdb9SAchin Gupta #include <platform_tsp.h>
22*4a8bfdb9SAchin Gupta #include <services/ffa_svc.h>
23*4a8bfdb9SAchin Gupta #include "tsp_private.h"
24*4a8bfdb9SAchin Gupta 
25*4a8bfdb9SAchin Gupta #include <platform_def.h>
26*4a8bfdb9SAchin Gupta 
27*4a8bfdb9SAchin Gupta extern void tsp_cpu_on_entry(void);
28*4a8bfdb9SAchin Gupta 
29*4a8bfdb9SAchin Gupta static ffa_endpoint_id16_t tsp_id, spmc_id;
30*4a8bfdb9SAchin Gupta 
31*4a8bfdb9SAchin Gupta static smc_args_t *send_ffa_pm_success(void)
32*4a8bfdb9SAchin Gupta {
33*4a8bfdb9SAchin Gupta 	return set_smc_args(FFA_MSG_SEND_DIRECT_RESP_SMC32,
34*4a8bfdb9SAchin Gupta 			    tsp_id << FFA_DIRECT_MSG_SOURCE_SHIFT |
35*4a8bfdb9SAchin Gupta 			    spmc_id,
36*4a8bfdb9SAchin Gupta 			    FFA_FWK_MSG_BIT |
37*4a8bfdb9SAchin Gupta 			    (FFA_PM_MSG_PM_RESP & FFA_FWK_MSG_MASK),
38*4a8bfdb9SAchin Gupta 			    0, 0, 0, 0, 0);
39*4a8bfdb9SAchin Gupta }
40*4a8bfdb9SAchin Gupta 
41*4a8bfdb9SAchin Gupta /*******************************************************************************
42*4a8bfdb9SAchin Gupta  * This function performs any remaining book keeping in the test secure payload
43*4a8bfdb9SAchin Gupta  * before this cpu is turned off in response to a psci cpu_off request.
44*4a8bfdb9SAchin Gupta  ******************************************************************************/
45*4a8bfdb9SAchin Gupta smc_args_t *tsp_cpu_off_main(uint64_t arg0,
46*4a8bfdb9SAchin Gupta 			     uint64_t arg1,
47*4a8bfdb9SAchin Gupta 			     uint64_t arg2,
48*4a8bfdb9SAchin Gupta 			     uint64_t arg3,
49*4a8bfdb9SAchin Gupta 			     uint64_t arg4,
50*4a8bfdb9SAchin Gupta 			     uint64_t arg5,
51*4a8bfdb9SAchin Gupta 			     uint64_t arg6,
52*4a8bfdb9SAchin Gupta 			     uint64_t arg7)
53*4a8bfdb9SAchin Gupta {
54*4a8bfdb9SAchin Gupta 	uint32_t linear_id = plat_my_core_pos();
55*4a8bfdb9SAchin Gupta 
56*4a8bfdb9SAchin Gupta 	/*
57*4a8bfdb9SAchin Gupta 	 * This cpu is being turned off, so disable the timer to prevent the
58*4a8bfdb9SAchin Gupta 	 * secure timer interrupt from interfering with power down. A pending
59*4a8bfdb9SAchin Gupta 	 * interrupt will be lost but we do not care as we are turning off.
60*4a8bfdb9SAchin Gupta 	 */
61*4a8bfdb9SAchin Gupta 	tsp_generic_timer_stop();
62*4a8bfdb9SAchin Gupta 
63*4a8bfdb9SAchin Gupta 	/* Update this cpu's statistics. */
64*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].smc_count++;
65*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].eret_count++;
66*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].cpu_off_count++;
67*4a8bfdb9SAchin Gupta 
68*4a8bfdb9SAchin Gupta #if LOG_LEVEL >= LOG_LEVEL_INFO
69*4a8bfdb9SAchin Gupta 	spin_lock(&console_lock);
70*4a8bfdb9SAchin Gupta 	INFO("TSP: cpu 0x%lx off request\n", read_mpidr());
71*4a8bfdb9SAchin Gupta 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu off requests\n",
72*4a8bfdb9SAchin Gupta 		read_mpidr(),
73*4a8bfdb9SAchin Gupta 		tsp_stats[linear_id].smc_count,
74*4a8bfdb9SAchin Gupta 		tsp_stats[linear_id].eret_count,
75*4a8bfdb9SAchin Gupta 		tsp_stats[linear_id].cpu_off_count);
76*4a8bfdb9SAchin Gupta 	spin_unlock(&console_lock);
77*4a8bfdb9SAchin Gupta #endif
78*4a8bfdb9SAchin Gupta 
79*4a8bfdb9SAchin Gupta 	return send_ffa_pm_success();
80*4a8bfdb9SAchin Gupta }
81*4a8bfdb9SAchin Gupta 
82*4a8bfdb9SAchin Gupta /*******************************************************************************
83*4a8bfdb9SAchin Gupta  * This function performs any book keeping in the test secure payload before
84*4a8bfdb9SAchin Gupta  * this cpu's architectural state is saved in response to an earlier psci
85*4a8bfdb9SAchin Gupta  * cpu_suspend request.
86*4a8bfdb9SAchin Gupta  ******************************************************************************/
87*4a8bfdb9SAchin Gupta smc_args_t *tsp_cpu_suspend_main(uint64_t arg0,
88*4a8bfdb9SAchin Gupta 				 uint64_t arg1,
89*4a8bfdb9SAchin Gupta 				 uint64_t arg2,
90*4a8bfdb9SAchin Gupta 				 uint64_t arg3,
91*4a8bfdb9SAchin Gupta 				 uint64_t arg4,
92*4a8bfdb9SAchin Gupta 				 uint64_t arg5,
93*4a8bfdb9SAchin Gupta 				 uint64_t arg6,
94*4a8bfdb9SAchin Gupta 				 uint64_t arg7)
95*4a8bfdb9SAchin Gupta {
96*4a8bfdb9SAchin Gupta 	uint32_t linear_id = plat_my_core_pos();
97*4a8bfdb9SAchin Gupta 
98*4a8bfdb9SAchin Gupta 	/*
99*4a8bfdb9SAchin Gupta 	 * Save the time context and disable it to prevent the secure timer
100*4a8bfdb9SAchin Gupta 	 * interrupt from interfering with wakeup from the suspend state.
101*4a8bfdb9SAchin Gupta 	 */
102*4a8bfdb9SAchin Gupta 	tsp_generic_timer_save();
103*4a8bfdb9SAchin Gupta 	tsp_generic_timer_stop();
104*4a8bfdb9SAchin Gupta 
105*4a8bfdb9SAchin Gupta 	/* Update this cpu's statistics. */
106*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].smc_count++;
107*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].eret_count++;
108*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].cpu_suspend_count++;
109*4a8bfdb9SAchin Gupta 
110*4a8bfdb9SAchin Gupta #if LOG_LEVEL >= LOG_LEVEL_INFO
111*4a8bfdb9SAchin Gupta 	spin_lock(&console_lock);
112*4a8bfdb9SAchin Gupta 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n",
113*4a8bfdb9SAchin Gupta 		read_mpidr(),
114*4a8bfdb9SAchin Gupta 		tsp_stats[linear_id].smc_count,
115*4a8bfdb9SAchin Gupta 		tsp_stats[linear_id].eret_count,
116*4a8bfdb9SAchin Gupta 		tsp_stats[linear_id].cpu_suspend_count);
117*4a8bfdb9SAchin Gupta 	spin_unlock(&console_lock);
118*4a8bfdb9SAchin Gupta #endif
119*4a8bfdb9SAchin Gupta 
120*4a8bfdb9SAchin Gupta 	return send_ffa_pm_success();
121*4a8bfdb9SAchin Gupta }
122*4a8bfdb9SAchin Gupta 
123*4a8bfdb9SAchin Gupta /*******************************************************************************
124*4a8bfdb9SAchin Gupta  * This function performs any bookkeeping in the test secure payload after this
125*4a8bfdb9SAchin Gupta  * cpu's architectural state has been restored after wakeup from an earlier psci
126*4a8bfdb9SAchin Gupta  * cpu_suspend request.
127*4a8bfdb9SAchin Gupta  ******************************************************************************/
128*4a8bfdb9SAchin Gupta smc_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl,
129*4a8bfdb9SAchin Gupta 				uint64_t arg1,
130*4a8bfdb9SAchin Gupta 				uint64_t arg2,
131*4a8bfdb9SAchin Gupta 				uint64_t arg3,
132*4a8bfdb9SAchin Gupta 				uint64_t arg4,
133*4a8bfdb9SAchin Gupta 				uint64_t arg5,
134*4a8bfdb9SAchin Gupta 				uint64_t arg6,
135*4a8bfdb9SAchin Gupta 				uint64_t arg7)
136*4a8bfdb9SAchin Gupta {
137*4a8bfdb9SAchin Gupta 	uint32_t linear_id = plat_my_core_pos();
138*4a8bfdb9SAchin Gupta 
139*4a8bfdb9SAchin Gupta 	/* Restore the generic timer context. */
140*4a8bfdb9SAchin Gupta 	tsp_generic_timer_restore();
141*4a8bfdb9SAchin Gupta 
142*4a8bfdb9SAchin Gupta 	/* Update this cpu's statistics. */
143*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].smc_count++;
144*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].eret_count++;
145*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].cpu_resume_count++;
146*4a8bfdb9SAchin Gupta 
147*4a8bfdb9SAchin Gupta #if LOG_LEVEL >= LOG_LEVEL_INFO
148*4a8bfdb9SAchin Gupta 	spin_lock(&console_lock);
149*4a8bfdb9SAchin Gupta 	INFO("TSP: cpu 0x%lx resumed. maximum off power level %" PRId64 "\n",
150*4a8bfdb9SAchin Gupta 	     read_mpidr(), max_off_pwrlvl);
151*4a8bfdb9SAchin Gupta 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu resume requests\n",
152*4a8bfdb9SAchin Gupta 		read_mpidr(),
153*4a8bfdb9SAchin Gupta 		tsp_stats[linear_id].smc_count,
154*4a8bfdb9SAchin Gupta 		tsp_stats[linear_id].eret_count,
155*4a8bfdb9SAchin Gupta 		tsp_stats[linear_id].cpu_resume_count);
156*4a8bfdb9SAchin Gupta 	spin_unlock(&console_lock);
157*4a8bfdb9SAchin Gupta #endif
158*4a8bfdb9SAchin Gupta 
159*4a8bfdb9SAchin Gupta 	return send_ffa_pm_success();
160*4a8bfdb9SAchin Gupta }
161*4a8bfdb9SAchin Gupta 
162*4a8bfdb9SAchin Gupta /*******************************************************************************
163*4a8bfdb9SAchin Gupta  * This function handles framework messages. Currently only PM.
164*4a8bfdb9SAchin Gupta  ******************************************************************************/
165*4a8bfdb9SAchin Gupta static smc_args_t *handle_framework_message(uint64_t arg0,
166*4a8bfdb9SAchin Gupta 					    uint64_t arg1,
167*4a8bfdb9SAchin Gupta 					    uint64_t arg2,
168*4a8bfdb9SAchin Gupta 					    uint64_t arg3,
169*4a8bfdb9SAchin Gupta 					    uint64_t arg4,
170*4a8bfdb9SAchin Gupta 					    uint64_t arg5,
171*4a8bfdb9SAchin Gupta 					    uint64_t arg6,
172*4a8bfdb9SAchin Gupta 					    uint64_t arg7)
173*4a8bfdb9SAchin Gupta {
174*4a8bfdb9SAchin Gupta 	/* Check if it is a power management message from the SPMC. */
175*4a8bfdb9SAchin Gupta 	if (ffa_endpoint_source(arg1) != spmc_id) {
176*4a8bfdb9SAchin Gupta 		goto err;
177*4a8bfdb9SAchin Gupta 	}
178*4a8bfdb9SAchin Gupta 
179*4a8bfdb9SAchin Gupta 	/* Check if it is a PM request message. */
180*4a8bfdb9SAchin Gupta 	if ((arg2 & FFA_FWK_MSG_MASK) == FFA_FWK_MSG_PSCI) {
181*4a8bfdb9SAchin Gupta 		/* Check if it is a PSCI CPU_OFF request. */
182*4a8bfdb9SAchin Gupta 		if (arg3 == PSCI_CPU_OFF) {
183*4a8bfdb9SAchin Gupta 			return tsp_cpu_off_main(arg0, arg1, arg2, arg3,
184*4a8bfdb9SAchin Gupta 						arg4, arg5, arg6, arg7);
185*4a8bfdb9SAchin Gupta 		} else if (arg3 == PSCI_CPU_SUSPEND_AARCH64) {
186*4a8bfdb9SAchin Gupta 			return tsp_cpu_suspend_main(arg0, arg1, arg2, arg3,
187*4a8bfdb9SAchin Gupta 						arg4, arg5, arg6, arg7);
188*4a8bfdb9SAchin Gupta 		}
189*4a8bfdb9SAchin Gupta 	} else if ((arg2 & FFA_FWK_MSG_MASK) == FFA_PM_MSG_WB_REQ) {
190*4a8bfdb9SAchin Gupta 		/* Check it is a PSCI Warm Boot request. */
191*4a8bfdb9SAchin Gupta 		if (arg3 == FFA_WB_TYPE_NOTS2RAM) {
192*4a8bfdb9SAchin Gupta 			return tsp_cpu_resume_main(arg0, arg1, arg2, arg3,
193*4a8bfdb9SAchin Gupta 						arg4, arg5, arg6, arg7);
194*4a8bfdb9SAchin Gupta 		}
195*4a8bfdb9SAchin Gupta 	}
196*4a8bfdb9SAchin Gupta 
197*4a8bfdb9SAchin Gupta err:
198*4a8bfdb9SAchin Gupta 	ERROR("%s: Unknown framework message!\n", __func__);
199*4a8bfdb9SAchin Gupta 	panic();
200*4a8bfdb9SAchin Gupta }
201*4a8bfdb9SAchin Gupta 
202*4a8bfdb9SAchin Gupta /*******************************************************************************
203*4a8bfdb9SAchin Gupta  * This function implements the event loop for handling FF-A ABI invocations.
204*4a8bfdb9SAchin Gupta  ******************************************************************************/
205*4a8bfdb9SAchin Gupta static smc_args_t *tsp_event_loop(uint64_t smc_fid,
206*4a8bfdb9SAchin Gupta 				  uint64_t arg1,
207*4a8bfdb9SAchin Gupta 				  uint64_t arg2,
208*4a8bfdb9SAchin Gupta 				  uint64_t arg3,
209*4a8bfdb9SAchin Gupta 				  uint64_t arg4,
210*4a8bfdb9SAchin Gupta 				  uint64_t arg5,
211*4a8bfdb9SAchin Gupta 				  uint64_t arg6,
212*4a8bfdb9SAchin Gupta 				  uint64_t arg7)
213*4a8bfdb9SAchin Gupta {
214*4a8bfdb9SAchin Gupta 	/* Panic if the SPMC did not forward an FF-A call. */
215*4a8bfdb9SAchin Gupta 	if (!is_ffa_fid(smc_fid)) {
216*4a8bfdb9SAchin Gupta 		ERROR("%s: Unknown SMC FID (0x%lx)\n", __func__, smc_fid);
217*4a8bfdb9SAchin Gupta 		panic();
218*4a8bfdb9SAchin Gupta 	}
219*4a8bfdb9SAchin Gupta 
220*4a8bfdb9SAchin Gupta 	switch (smc_fid) {
221*4a8bfdb9SAchin Gupta 	case FFA_INTERRUPT:
222*4a8bfdb9SAchin Gupta 		/*
223*4a8bfdb9SAchin Gupta 		 * IRQs were enabled upon re-entry into the TSP. The interrupt
224*4a8bfdb9SAchin Gupta 		 * must have been handled by now. Return to the SPMC indicating
225*4a8bfdb9SAchin Gupta 		 * the same.
226*4a8bfdb9SAchin Gupta 		 */
227*4a8bfdb9SAchin Gupta 		return set_smc_args(FFA_MSG_WAIT, 0, 0, 0, 0, 0, 0, 0);
228*4a8bfdb9SAchin Gupta 
229*4a8bfdb9SAchin Gupta 	case FFA_MSG_SEND_DIRECT_REQ_SMC32:
230*4a8bfdb9SAchin Gupta 		/* Check if a framework message, handle accordingly. */
231*4a8bfdb9SAchin Gupta 		if ((arg2 & FFA_FWK_MSG_BIT)) {
232*4a8bfdb9SAchin Gupta 			return handle_framework_message(smc_fid, arg1, arg2, arg3,
233*4a8bfdb9SAchin Gupta 							arg4, arg5, arg6, arg7);
234*4a8bfdb9SAchin Gupta 		}
235*4a8bfdb9SAchin Gupta 	default:
236*4a8bfdb9SAchin Gupta 		break;
237*4a8bfdb9SAchin Gupta 	}
238*4a8bfdb9SAchin Gupta 
239*4a8bfdb9SAchin Gupta 	ERROR("%s: Unsupported FF-A FID (0x%lx)\n", __func__, smc_fid);
240*4a8bfdb9SAchin Gupta 	panic();
241*4a8bfdb9SAchin Gupta }
242*4a8bfdb9SAchin Gupta 
243*4a8bfdb9SAchin Gupta static smc_args_t *tsp_loop(smc_args_t *args)
244*4a8bfdb9SAchin Gupta {
245*4a8bfdb9SAchin Gupta 	smc_args_t ret;
246*4a8bfdb9SAchin Gupta 
247*4a8bfdb9SAchin Gupta 	do {
248*4a8bfdb9SAchin Gupta 		/* --------------------------------------------
249*4a8bfdb9SAchin Gupta 		 * Mask FIQ interrupts to avoid preemption
250*4a8bfdb9SAchin Gupta 		 * in case EL3 SPMC delegates an IRQ next or a
251*4a8bfdb9SAchin Gupta 		 * managed exit. Lastly, unmask IRQs so that
252*4a8bfdb9SAchin Gupta 		 * they can be handled immediately upon re-entry
253*4a8bfdb9SAchin Gupta 		 *  ---------------------------------------------
254*4a8bfdb9SAchin Gupta 		 */
255*4a8bfdb9SAchin Gupta 		write_daifset(DAIF_FIQ_BIT);
256*4a8bfdb9SAchin Gupta 		write_daifclr(DAIF_IRQ_BIT);
257*4a8bfdb9SAchin Gupta 		ret = smc_helper(args->_regs[0], args->_regs[1], args->_regs[2],
258*4a8bfdb9SAchin Gupta 			       args->_regs[3], args->_regs[4], args->_regs[5],
259*4a8bfdb9SAchin Gupta 			       args->_regs[6], args->_regs[7]);
260*4a8bfdb9SAchin Gupta 		args = tsp_event_loop(ret._regs[0], ret._regs[1], ret._regs[2],
261*4a8bfdb9SAchin Gupta 				      ret._regs[3], ret._regs[4], ret._regs[5],
262*4a8bfdb9SAchin Gupta 				      ret._regs[6], ret._regs[7]);
263*4a8bfdb9SAchin Gupta 	} while (1);
264*4a8bfdb9SAchin Gupta 
265*4a8bfdb9SAchin Gupta 	/* Not Reached. */
266*4a8bfdb9SAchin Gupta 	return NULL;
267*4a8bfdb9SAchin Gupta }
268*4a8bfdb9SAchin Gupta 
269*4a8bfdb9SAchin Gupta /*******************************************************************************
270*4a8bfdb9SAchin Gupta  * TSP main entry point where it gets the opportunity to initialize its secure
271*4a8bfdb9SAchin Gupta  * state/applications. Once the state is initialized, it must return to the
272*4a8bfdb9SAchin Gupta  * SPD with a pointer to the 'tsp_vector_table' jump table.
273*4a8bfdb9SAchin Gupta  ******************************************************************************/
274*4a8bfdb9SAchin Gupta uint64_t tsp_main(void)
275*4a8bfdb9SAchin Gupta {
276*4a8bfdb9SAchin Gupta 	smc_args_t smc_args = {0};
277*4a8bfdb9SAchin Gupta 
278*4a8bfdb9SAchin Gupta 	NOTICE("TSP: %s\n", version_string);
279*4a8bfdb9SAchin Gupta 	NOTICE("TSP: %s\n", build_message);
280*4a8bfdb9SAchin Gupta 	INFO("TSP: Total memory base : 0x%lx\n", (unsigned long) BL32_BASE);
281*4a8bfdb9SAchin Gupta 	INFO("TSP: Total memory size : 0x%lx bytes\n", BL32_TOTAL_SIZE);
282*4a8bfdb9SAchin Gupta 	uint32_t linear_id = plat_my_core_pos();
283*4a8bfdb9SAchin Gupta 
284*4a8bfdb9SAchin Gupta 	/* Initialize the platform. */
285*4a8bfdb9SAchin Gupta 	tsp_platform_setup();
286*4a8bfdb9SAchin Gupta 
287*4a8bfdb9SAchin Gupta 	/* Initialize secure/applications state here. */
288*4a8bfdb9SAchin Gupta 	tsp_generic_timer_start();
289*4a8bfdb9SAchin Gupta 
290*4a8bfdb9SAchin Gupta 	/* Register secondary entrypoint with the SPMC. */
291*4a8bfdb9SAchin Gupta 	smc_args = smc_helper(FFA_SECONDARY_EP_REGISTER_SMC64,
292*4a8bfdb9SAchin Gupta 			(uint64_t) tsp_cpu_on_entry,
293*4a8bfdb9SAchin Gupta 			0, 0, 0, 0, 0, 0);
294*4a8bfdb9SAchin Gupta 	if (smc_args._regs[SMC_ARG0] != FFA_SUCCESS_SMC32) {
295*4a8bfdb9SAchin Gupta 		ERROR("TSP could not register secondary ep (0x%lx)\n",
296*4a8bfdb9SAchin Gupta 				smc_args._regs[2]);
297*4a8bfdb9SAchin Gupta 		panic();
298*4a8bfdb9SAchin Gupta 	}
299*4a8bfdb9SAchin Gupta 	/* Get TSP's endpoint id */
300*4a8bfdb9SAchin Gupta 	smc_args = smc_helper(FFA_ID_GET, 0, 0, 0, 0, 0, 0, 0);
301*4a8bfdb9SAchin Gupta 	if (smc_args._regs[SMC_ARG0] != FFA_SUCCESS_SMC32) {
302*4a8bfdb9SAchin Gupta 		ERROR("TSP could not get own ID (0x%lx) on core%d\n",
303*4a8bfdb9SAchin Gupta 				smc_args._regs[2], linear_id);
304*4a8bfdb9SAchin Gupta 		panic();
305*4a8bfdb9SAchin Gupta 	}
306*4a8bfdb9SAchin Gupta 
307*4a8bfdb9SAchin Gupta 	tsp_id = smc_args._regs[2];
308*4a8bfdb9SAchin Gupta 	INFO("TSP FF-A endpoint id = 0x%x\n", tsp_id);
309*4a8bfdb9SAchin Gupta 	/* Get the SPMC ID */
310*4a8bfdb9SAchin Gupta 	smc_args = smc_helper(FFA_SPM_ID_GET, 0, 0, 0, 0, 0, 0, 0);
311*4a8bfdb9SAchin Gupta 	if (smc_args._regs[SMC_ARG0] != FFA_SUCCESS_SMC32) {
312*4a8bfdb9SAchin Gupta 		ERROR("TSP could not get SPMC ID (0x%lx) on core%d\n",
313*4a8bfdb9SAchin Gupta 				smc_args._regs[2], linear_id);
314*4a8bfdb9SAchin Gupta 		panic();
315*4a8bfdb9SAchin Gupta 	}
316*4a8bfdb9SAchin Gupta 
317*4a8bfdb9SAchin Gupta 	spmc_id = smc_args._regs[2];
318*4a8bfdb9SAchin Gupta 
319*4a8bfdb9SAchin Gupta 	/* Update this cpu's statistics */
320*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].smc_count++;
321*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].eret_count++;
322*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].cpu_on_count++;
323*4a8bfdb9SAchin Gupta 
324*4a8bfdb9SAchin Gupta 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
325*4a8bfdb9SAchin Gupta 			read_mpidr(),
326*4a8bfdb9SAchin Gupta 			tsp_stats[linear_id].smc_count,
327*4a8bfdb9SAchin Gupta 			tsp_stats[linear_id].eret_count,
328*4a8bfdb9SAchin Gupta 			tsp_stats[linear_id].cpu_on_count);
329*4a8bfdb9SAchin Gupta 
330*4a8bfdb9SAchin Gupta 	/* Tell SPMD that we are done initialising. */
331*4a8bfdb9SAchin Gupta 	tsp_loop(set_smc_args(FFA_MSG_WAIT, 0, 0, 0, 0, 0, 0, 0));
332*4a8bfdb9SAchin Gupta 
333*4a8bfdb9SAchin Gupta 	/* Not reached. */
334*4a8bfdb9SAchin Gupta 	return 0;
335*4a8bfdb9SAchin Gupta }
336*4a8bfdb9SAchin Gupta 
337*4a8bfdb9SAchin Gupta /*******************************************************************************
338*4a8bfdb9SAchin Gupta  * This function performs any remaining book keeping in the test secure payload
339*4a8bfdb9SAchin Gupta  * after this cpu's architectural state has been setup in response to an earlier
340*4a8bfdb9SAchin Gupta  * psci cpu_on request.
341*4a8bfdb9SAchin Gupta  ******************************************************************************/
342*4a8bfdb9SAchin Gupta smc_args_t *tsp_cpu_on_main(void)
343*4a8bfdb9SAchin Gupta {
344*4a8bfdb9SAchin Gupta 	uint32_t linear_id = plat_my_core_pos();
345*4a8bfdb9SAchin Gupta 
346*4a8bfdb9SAchin Gupta 	/* Initialize secure/applications state here. */
347*4a8bfdb9SAchin Gupta 	tsp_generic_timer_start();
348*4a8bfdb9SAchin Gupta 
349*4a8bfdb9SAchin Gupta 	/* Update this cpu's statistics. */
350*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].smc_count++;
351*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].eret_count++;
352*4a8bfdb9SAchin Gupta 	tsp_stats[linear_id].cpu_on_count++;
353*4a8bfdb9SAchin Gupta #if LOG_LEVEL >= LOG_LEVEL_INFO
354*4a8bfdb9SAchin Gupta 	spin_lock(&console_lock);
355*4a8bfdb9SAchin Gupta 	INFO("TSP: cpu 0x%lx turned on\n", read_mpidr());
356*4a8bfdb9SAchin Gupta 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
357*4a8bfdb9SAchin Gupta 			read_mpidr(),
358*4a8bfdb9SAchin Gupta 			tsp_stats[linear_id].smc_count,
359*4a8bfdb9SAchin Gupta 			tsp_stats[linear_id].eret_count,
360*4a8bfdb9SAchin Gupta 			tsp_stats[linear_id].cpu_on_count);
361*4a8bfdb9SAchin Gupta 	spin_unlock(&console_lock);
362*4a8bfdb9SAchin Gupta #endif
363*4a8bfdb9SAchin Gupta 	/* ---------------------------------------------
364*4a8bfdb9SAchin Gupta 	 * Jump to the main event loop to return to EL3
365*4a8bfdb9SAchin Gupta 	 * and be ready for the next request on this cpu.
366*4a8bfdb9SAchin Gupta 	 * ---------------------------------------------
367*4a8bfdb9SAchin Gupta 	 */
368*4a8bfdb9SAchin Gupta 	return tsp_loop(set_smc_args(FFA_MSG_WAIT, 0, 0, 0, 0, 0, 0, 0));
369*4a8bfdb9SAchin Gupta }
370