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