14a8bfdb9SAchin Gupta /* 2*15ca1ee3SMarc Bonnici * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved. 34a8bfdb9SAchin Gupta * 44a8bfdb9SAchin Gupta * SPDX-License-Identifier: BSD-3-Clause 54a8bfdb9SAchin Gupta */ 64a8bfdb9SAchin Gupta 74a8bfdb9SAchin Gupta #include <assert.h> 84a8bfdb9SAchin Gupta #include <inttypes.h> 94a8bfdb9SAchin Gupta #include <stdint.h> 104a8bfdb9SAchin Gupta 114a8bfdb9SAchin Gupta #include "../../services/std_svc/spm/el3_spmc/spmc.h" 124a8bfdb9SAchin Gupta #include "../../services/std_svc/spm/el3_spmc/spmc_shared_mem.h" 134a8bfdb9SAchin Gupta #include <arch_features.h> 144a8bfdb9SAchin Gupta #include <arch_helpers.h> 154a8bfdb9SAchin Gupta #include <bl32/tsp/tsp.h> 164a8bfdb9SAchin Gupta #include <common/bl_common.h> 174a8bfdb9SAchin Gupta #include <common/debug.h> 18*15ca1ee3SMarc Bonnici #include "ffa_helpers.h" 194a8bfdb9SAchin Gupta #include <lib/psci/psci.h> 204a8bfdb9SAchin Gupta #include <lib/spinlock.h> 21*15ca1ee3SMarc Bonnici #include <lib/xlat_tables/xlat_tables_defs.h> 22*15ca1ee3SMarc Bonnici #include <lib/xlat_tables/xlat_tables_v2.h> 234a8bfdb9SAchin Gupta #include <plat/common/platform.h> 244a8bfdb9SAchin Gupta #include <platform_tsp.h> 254a8bfdb9SAchin Gupta #include <services/ffa_svc.h> 264a8bfdb9SAchin Gupta #include "tsp_private.h" 274a8bfdb9SAchin Gupta 284a8bfdb9SAchin Gupta #include <platform_def.h> 294a8bfdb9SAchin Gupta 304a8bfdb9SAchin Gupta static ffa_endpoint_id16_t tsp_id, spmc_id; 31*15ca1ee3SMarc Bonnici uint8_t mem_region_buffer[4096 * 2] __aligned(PAGE_SIZE); 32*15ca1ee3SMarc Bonnici 33*15ca1ee3SMarc Bonnici /* Partition Mailbox. */ 34*15ca1ee3SMarc Bonnici static uint8_t send_page[PAGE_SIZE] __aligned(PAGE_SIZE); 35*15ca1ee3SMarc Bonnici static uint8_t recv_page[PAGE_SIZE] __aligned(PAGE_SIZE); 36*15ca1ee3SMarc Bonnici 37*15ca1ee3SMarc Bonnici /* 38*15ca1ee3SMarc Bonnici * Declare a global mailbox for use within the TSP. 39*15ca1ee3SMarc Bonnici * This will be initialized appropriately when the buffers 40*15ca1ee3SMarc Bonnici * are mapped with the SPMC. 41*15ca1ee3SMarc Bonnici */ 42*15ca1ee3SMarc Bonnici static struct mailbox mailbox; 43*15ca1ee3SMarc Bonnici 44*15ca1ee3SMarc Bonnici /******************************************************************************* 45*15ca1ee3SMarc Bonnici * This enum is used to handle test cases driven from the FF-A Test Driver. 46*15ca1ee3SMarc Bonnici ******************************************************************************/ 47*15ca1ee3SMarc Bonnici /* Keep in Sync with FF-A Test Driver. */ 48*15ca1ee3SMarc Bonnici enum message_t { 49*15ca1ee3SMarc Bonnici /* Partition Only Messages. */ 50*15ca1ee3SMarc Bonnici FF_A_RELAY_MESSAGE = 0, 51*15ca1ee3SMarc Bonnici 52*15ca1ee3SMarc Bonnici /* Basic Functionality. */ 53*15ca1ee3SMarc Bonnici FF_A_ECHO_MESSAGE, 54*15ca1ee3SMarc Bonnici FF_A_RELAY_MESSAGE_EL3, 55*15ca1ee3SMarc Bonnici 56*15ca1ee3SMarc Bonnici /* Memory Sharing. */ 57*15ca1ee3SMarc Bonnici FF_A_MEMORY_SHARE, 58*15ca1ee3SMarc Bonnici FF_A_MEMORY_SHARE_FRAGMENTED, 59*15ca1ee3SMarc Bonnici FF_A_MEMORY_LEND, 60*15ca1ee3SMarc Bonnici FF_A_MEMORY_LEND_FRAGMENTED, 61*15ca1ee3SMarc Bonnici 62*15ca1ee3SMarc Bonnici FF_A_MEMORY_SHARE_MULTI_ENDPOINT, 63*15ca1ee3SMarc Bonnici FF_A_MEMORY_LEND_MULTI_ENDPOINT, 64*15ca1ee3SMarc Bonnici 65*15ca1ee3SMarc Bonnici LAST, 66*15ca1ee3SMarc Bonnici FF_A_RUN_ALL = 255, 67*15ca1ee3SMarc Bonnici FF_A_OP_MAX = 256 68*15ca1ee3SMarc Bonnici }; 69*15ca1ee3SMarc Bonnici 70*15ca1ee3SMarc Bonnici #if SPMC_AT_EL3 71*15ca1ee3SMarc Bonnici extern void tsp_cpu_on_entry(void); 72*15ca1ee3SMarc Bonnici #endif 73*15ca1ee3SMarc Bonnici 74*15ca1ee3SMarc Bonnici /******************************************************************************* 75*15ca1ee3SMarc Bonnici * Test Functions. 76*15ca1ee3SMarc Bonnici ******************************************************************************/ 77*15ca1ee3SMarc Bonnici 78*15ca1ee3SMarc Bonnici /******************************************************************************* 79*15ca1ee3SMarc Bonnici * Enable the TSP to forward the received message to another partition and ask 80*15ca1ee3SMarc Bonnici * it to echo the value back in order to validate direct messages functionality. 81*15ca1ee3SMarc Bonnici ******************************************************************************/ 82*15ca1ee3SMarc Bonnici static int ffa_test_relay(uint64_t arg0, 83*15ca1ee3SMarc Bonnici uint64_t arg1, 84*15ca1ee3SMarc Bonnici uint64_t arg2, 85*15ca1ee3SMarc Bonnici uint64_t arg3, 86*15ca1ee3SMarc Bonnici uint64_t arg4, 87*15ca1ee3SMarc Bonnici uint64_t arg5, 88*15ca1ee3SMarc Bonnici uint64_t arg6, 89*15ca1ee3SMarc Bonnici uint64_t arg7) 90*15ca1ee3SMarc Bonnici { 91*15ca1ee3SMarc Bonnici smc_args_t ffa_forward_result; 92*15ca1ee3SMarc Bonnici ffa_endpoint_id16_t receiver = arg5; 93*15ca1ee3SMarc Bonnici 94*15ca1ee3SMarc Bonnici ffa_forward_result = ffa_msg_send_direct_req(ffa_endpoint_source(arg1), 95*15ca1ee3SMarc Bonnici receiver, 96*15ca1ee3SMarc Bonnici FF_A_ECHO_MESSAGE, arg4, 97*15ca1ee3SMarc Bonnici 0, 0, 0); 98*15ca1ee3SMarc Bonnici return ffa_forward_result._regs[3]; 99*15ca1ee3SMarc Bonnici } 100*15ca1ee3SMarc Bonnici 101*15ca1ee3SMarc Bonnici /******************************************************************************* 102*15ca1ee3SMarc Bonnici * This function handles memory management tests, currently share and lend. 103*15ca1ee3SMarc Bonnici * This test supports the use of FRAG_RX to use memory descriptors that do not 104*15ca1ee3SMarc Bonnici * fit in a single 4KB buffer. 105*15ca1ee3SMarc Bonnici ******************************************************************************/ 106*15ca1ee3SMarc Bonnici static int test_memory_send(ffa_endpoint_id16_t sender, uint64_t handle, 107*15ca1ee3SMarc Bonnici ffa_mtd_flag32_t flags, bool multi_endpoint) 108*15ca1ee3SMarc Bonnici { 109*15ca1ee3SMarc Bonnici struct ffa_mtd *m; 110*15ca1ee3SMarc Bonnici struct ffa_emad_v1_0 *receivers; 111*15ca1ee3SMarc Bonnici struct ffa_comp_mrd *composite; 112*15ca1ee3SMarc Bonnici int ret, status = 0; 113*15ca1ee3SMarc Bonnici unsigned int mem_attrs; 114*15ca1ee3SMarc Bonnici char *ptr; 115*15ca1ee3SMarc Bonnici ffa_endpoint_id16_t source = sender; 116*15ca1ee3SMarc Bonnici uint32_t total_length, recv_length = 0; 117*15ca1ee3SMarc Bonnici 118*15ca1ee3SMarc Bonnici /* 119*15ca1ee3SMarc Bonnici * In the case that we're testing multiple endpoints choose a partition 120*15ca1ee3SMarc Bonnici * ID that resides in the normal world so the SPMC won't detect it as 121*15ca1ee3SMarc Bonnici * invalid. 122*15ca1ee3SMarc Bonnici * TODO: Should get endpoint receiver id and flag as input from NWd. 123*15ca1ee3SMarc Bonnici */ 124*15ca1ee3SMarc Bonnici uint32_t receiver_count = multi_endpoint ? 2 : 1; 125*15ca1ee3SMarc Bonnici ffa_endpoint_id16_t test_receivers[2] = { tsp_id, 0x10 }; 126*15ca1ee3SMarc Bonnici 127*15ca1ee3SMarc Bonnici /* Ensure that the sender ID resides in the normal world. */ 128*15ca1ee3SMarc Bonnici if (ffa_is_secure_world_id(sender)) { 129*15ca1ee3SMarc Bonnici ERROR("Invalid sender ID 0x%x.\n", sender); 130*15ca1ee3SMarc Bonnici return FFA_ERROR_DENIED; 131*15ca1ee3SMarc Bonnici } 132*15ca1ee3SMarc Bonnici 133*15ca1ee3SMarc Bonnici if (!memory_retrieve(&mailbox, &m, handle, source, test_receivers, 134*15ca1ee3SMarc Bonnici receiver_count, flags, &recv_length, 135*15ca1ee3SMarc Bonnici &total_length)) { 136*15ca1ee3SMarc Bonnici return FFA_ERROR_INVALID_PARAMETER; 137*15ca1ee3SMarc Bonnici } 138*15ca1ee3SMarc Bonnici 139*15ca1ee3SMarc Bonnici receivers = (struct ffa_emad_v1_0 *) 140*15ca1ee3SMarc Bonnici ((uint8_t *) m + m->emad_offset); 141*15ca1ee3SMarc Bonnici while (total_length != recv_length) { 142*15ca1ee3SMarc Bonnici smc_args_t ffa_return; 143*15ca1ee3SMarc Bonnici uint32_t frag_length; 144*15ca1ee3SMarc Bonnici 145*15ca1ee3SMarc Bonnici ffa_return = ffa_mem_frag_rx(handle, recv_length); 146*15ca1ee3SMarc Bonnici 147*15ca1ee3SMarc Bonnici if (ffa_return._regs[0] == FFA_ERROR) { 148*15ca1ee3SMarc Bonnici WARN("TSP: failed to resume mem with handle %lx\n", 149*15ca1ee3SMarc Bonnici handle); 150*15ca1ee3SMarc Bonnici return ffa_return._regs[2]; 151*15ca1ee3SMarc Bonnici } 152*15ca1ee3SMarc Bonnici frag_length = ffa_return._regs[3]; 153*15ca1ee3SMarc Bonnici 154*15ca1ee3SMarc Bonnici /* Validate frag_length is less than total_length and mailbox size. */ 155*15ca1ee3SMarc Bonnici if (frag_length > total_length || 156*15ca1ee3SMarc Bonnici frag_length > (mailbox.rxtx_page_count * PAGE_SIZE)) { 157*15ca1ee3SMarc Bonnici ERROR("Invalid parameters!\n"); 158*15ca1ee3SMarc Bonnici return FFA_ERROR_INVALID_PARAMETER; 159*15ca1ee3SMarc Bonnici } 160*15ca1ee3SMarc Bonnici 161*15ca1ee3SMarc Bonnici /* Validate frag_length is less than remaining mem_region_buffer size. */ 162*15ca1ee3SMarc Bonnici if (frag_length + recv_length >= REGION_BUF_SIZE) { 163*15ca1ee3SMarc Bonnici ERROR("Out of memory!\n"); 164*15ca1ee3SMarc Bonnici return FFA_ERROR_INVALID_PARAMETER; 165*15ca1ee3SMarc Bonnici } 166*15ca1ee3SMarc Bonnici 167*15ca1ee3SMarc Bonnici memcpy(&mem_region_buffer[recv_length], mailbox.rx_buffer, 168*15ca1ee3SMarc Bonnici frag_length); 169*15ca1ee3SMarc Bonnici 170*15ca1ee3SMarc Bonnici if (ffa_rx_release()) { 171*15ca1ee3SMarc Bonnici ERROR("Failed to release buffer!\n"); 172*15ca1ee3SMarc Bonnici return FFA_ERROR_DENIED; 173*15ca1ee3SMarc Bonnici } 174*15ca1ee3SMarc Bonnici 175*15ca1ee3SMarc Bonnici recv_length += frag_length; 176*15ca1ee3SMarc Bonnici 177*15ca1ee3SMarc Bonnici assert(recv_length <= total_length); 178*15ca1ee3SMarc Bonnici } 179*15ca1ee3SMarc Bonnici 180*15ca1ee3SMarc Bonnici composite = ffa_memory_region_get_composite(m, 0); 181*15ca1ee3SMarc Bonnici if (composite == NULL) { 182*15ca1ee3SMarc Bonnici WARN("Failed to get composite descriptor!\n"); 183*15ca1ee3SMarc Bonnici return FFA_ERROR_INVALID_PARAMETER; 184*15ca1ee3SMarc Bonnici } 185*15ca1ee3SMarc Bonnici 186*15ca1ee3SMarc Bonnici VERBOSE("Address: %p; page_count: %x %lx\n", 187*15ca1ee3SMarc Bonnici (void *)composite->address_range_array[0].address, 188*15ca1ee3SMarc Bonnici composite->address_range_array[0].page_count, PAGE_SIZE); 189*15ca1ee3SMarc Bonnici 190*15ca1ee3SMarc Bonnici /* This test is only concerned with RW permissions. */ 191*15ca1ee3SMarc Bonnici if (ffa_get_data_access_attr( 192*15ca1ee3SMarc Bonnici receivers[0].mapd.memory_access_permissions) != FFA_MEM_PERM_RW) { 193*15ca1ee3SMarc Bonnici ERROR("Data permission in retrieve response %x does not match share/lend %x!\n", 194*15ca1ee3SMarc Bonnici ffa_get_data_access_attr(receivers[0].mapd.memory_access_permissions), 195*15ca1ee3SMarc Bonnici FFA_MEM_PERM_RW); 196*15ca1ee3SMarc Bonnici return FFA_ERROR_INVALID_PARAMETER; 197*15ca1ee3SMarc Bonnici } 198*15ca1ee3SMarc Bonnici 199*15ca1ee3SMarc Bonnici mem_attrs = MT_RW_DATA | MT_EXECUTE_NEVER; 200*15ca1ee3SMarc Bonnici 201*15ca1ee3SMarc Bonnici /* Only expecting to be sent memory from NWd so map accordingly. */ 202*15ca1ee3SMarc Bonnici mem_attrs |= MT_NS; 203*15ca1ee3SMarc Bonnici 204*15ca1ee3SMarc Bonnici for (uint32_t i = 0U; i < composite->address_range_count; i++) { 205*15ca1ee3SMarc Bonnici size_t size = composite->address_range_array[i].page_count * PAGE_SIZE; 206*15ca1ee3SMarc Bonnici 207*15ca1ee3SMarc Bonnici ptr = (char *) composite->address_range_array[i].address; 208*15ca1ee3SMarc Bonnici ret = mmap_add_dynamic_region( 209*15ca1ee3SMarc Bonnici (uint64_t)ptr, 210*15ca1ee3SMarc Bonnici (uint64_t)ptr, 211*15ca1ee3SMarc Bonnici size, mem_attrs); 212*15ca1ee3SMarc Bonnici 213*15ca1ee3SMarc Bonnici if (ret != 0) { 214*15ca1ee3SMarc Bonnici ERROR("Failed [%u] mmap_add_dynamic_region %u (%lx) (%lx) (%x)!\n", 215*15ca1ee3SMarc Bonnici i, ret, 216*15ca1ee3SMarc Bonnici (uint64_t)composite->address_range_array[i].address, 217*15ca1ee3SMarc Bonnici size, mem_attrs); 218*15ca1ee3SMarc Bonnici 219*15ca1ee3SMarc Bonnici /* Remove mappings created in this transaction. */ 220*15ca1ee3SMarc Bonnici for (i--; i >= 0U; i--) { 221*15ca1ee3SMarc Bonnici ret = mmap_remove_dynamic_region( 222*15ca1ee3SMarc Bonnici (uint64_t)ptr, 223*15ca1ee3SMarc Bonnici composite->address_range_array[i].page_count * PAGE_SIZE); 224*15ca1ee3SMarc Bonnici 225*15ca1ee3SMarc Bonnici if (ret != 0) { 226*15ca1ee3SMarc Bonnici ERROR("Failed [%d] mmap_remove_dynamic_region!\n", i); 227*15ca1ee3SMarc Bonnici panic(); 228*15ca1ee3SMarc Bonnici } 229*15ca1ee3SMarc Bonnici } 230*15ca1ee3SMarc Bonnici return FFA_ERROR_NO_MEMORY; 231*15ca1ee3SMarc Bonnici } 232*15ca1ee3SMarc Bonnici 233*15ca1ee3SMarc Bonnici /* Increment memory region for validation purposes. */ 234*15ca1ee3SMarc Bonnici ++(*ptr); 235*15ca1ee3SMarc Bonnici 236*15ca1ee3SMarc Bonnici /* 237*15ca1ee3SMarc Bonnici * Read initial magic number from memory region for 238*15ca1ee3SMarc Bonnici * validation purposes. 239*15ca1ee3SMarc Bonnici */ 240*15ca1ee3SMarc Bonnici if (!i) { 241*15ca1ee3SMarc Bonnici status = *ptr; 242*15ca1ee3SMarc Bonnici } 243*15ca1ee3SMarc Bonnici } 244*15ca1ee3SMarc Bonnici 245*15ca1ee3SMarc Bonnici for (uint32_t i = 0U; i < composite->address_range_count; i++) { 246*15ca1ee3SMarc Bonnici ret = mmap_remove_dynamic_region( 247*15ca1ee3SMarc Bonnici (uint64_t)composite->address_range_array[i].address, 248*15ca1ee3SMarc Bonnici composite->address_range_array[i].page_count * PAGE_SIZE); 249*15ca1ee3SMarc Bonnici 250*15ca1ee3SMarc Bonnici if (ret != 0) { 251*15ca1ee3SMarc Bonnici ERROR("Failed [%d] mmap_remove_dynamic_region!\n", i); 252*15ca1ee3SMarc Bonnici return FFA_ERROR_NO_MEMORY; 253*15ca1ee3SMarc Bonnici } 254*15ca1ee3SMarc Bonnici } 255*15ca1ee3SMarc Bonnici 256*15ca1ee3SMarc Bonnici if (!memory_relinquish((struct ffa_mem_relinquish_descriptor *)mailbox.tx_buffer, 257*15ca1ee3SMarc Bonnici m->handle, tsp_id)) { 258*15ca1ee3SMarc Bonnici ERROR("Failed to relinquish memory region!\n"); 259*15ca1ee3SMarc Bonnici return FFA_ERROR_INVALID_PARAMETER; 260*15ca1ee3SMarc Bonnici } 261*15ca1ee3SMarc Bonnici return status; 262*15ca1ee3SMarc Bonnici } 2634a8bfdb9SAchin Gupta 2644a8bfdb9SAchin Gupta static smc_args_t *send_ffa_pm_success(void) 2654a8bfdb9SAchin Gupta { 2664a8bfdb9SAchin Gupta return set_smc_args(FFA_MSG_SEND_DIRECT_RESP_SMC32, 267*15ca1ee3SMarc Bonnici ((tsp_id & FFA_DIRECT_MSG_ENDPOINT_ID_MASK) 268*15ca1ee3SMarc Bonnici << FFA_DIRECT_MSG_SOURCE_SHIFT) | spmc_id, 2694a8bfdb9SAchin Gupta FFA_FWK_MSG_BIT | 2704a8bfdb9SAchin Gupta (FFA_PM_MSG_PM_RESP & FFA_FWK_MSG_MASK), 2714a8bfdb9SAchin Gupta 0, 0, 0, 0, 0); 2724a8bfdb9SAchin Gupta } 2734a8bfdb9SAchin Gupta 2744a8bfdb9SAchin Gupta /******************************************************************************* 2754a8bfdb9SAchin Gupta * This function performs any remaining book keeping in the test secure payload 2764a8bfdb9SAchin Gupta * before this cpu is turned off in response to a psci cpu_off request. 2774a8bfdb9SAchin Gupta ******************************************************************************/ 2784a8bfdb9SAchin Gupta smc_args_t *tsp_cpu_off_main(uint64_t arg0, 2794a8bfdb9SAchin Gupta uint64_t arg1, 2804a8bfdb9SAchin Gupta uint64_t arg2, 2814a8bfdb9SAchin Gupta uint64_t arg3, 2824a8bfdb9SAchin Gupta uint64_t arg4, 2834a8bfdb9SAchin Gupta uint64_t arg5, 2844a8bfdb9SAchin Gupta uint64_t arg6, 2854a8bfdb9SAchin Gupta uint64_t arg7) 2864a8bfdb9SAchin Gupta { 2874a8bfdb9SAchin Gupta uint32_t linear_id = plat_my_core_pos(); 2884a8bfdb9SAchin Gupta 2894a8bfdb9SAchin Gupta /* 2904a8bfdb9SAchin Gupta * This cpu is being turned off, so disable the timer to prevent the 2914a8bfdb9SAchin Gupta * secure timer interrupt from interfering with power down. A pending 2924a8bfdb9SAchin Gupta * interrupt will be lost but we do not care as we are turning off. 2934a8bfdb9SAchin Gupta */ 2944a8bfdb9SAchin Gupta tsp_generic_timer_stop(); 2954a8bfdb9SAchin Gupta 2964a8bfdb9SAchin Gupta /* Update this cpu's statistics. */ 2974a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count++; 2984a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count++; 2994a8bfdb9SAchin Gupta tsp_stats[linear_id].cpu_off_count++; 3004a8bfdb9SAchin Gupta 3014a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx off request\n", read_mpidr()); 3024a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu off requests\n", 3034a8bfdb9SAchin Gupta read_mpidr(), 3044a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count, 3054a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count, 3064a8bfdb9SAchin Gupta tsp_stats[linear_id].cpu_off_count); 3074a8bfdb9SAchin Gupta 3084a8bfdb9SAchin Gupta return send_ffa_pm_success(); 3094a8bfdb9SAchin Gupta } 3104a8bfdb9SAchin Gupta 3114a8bfdb9SAchin Gupta /******************************************************************************* 3124a8bfdb9SAchin Gupta * This function performs any book keeping in the test secure payload before 3134a8bfdb9SAchin Gupta * this cpu's architectural state is saved in response to an earlier psci 3144a8bfdb9SAchin Gupta * cpu_suspend request. 3154a8bfdb9SAchin Gupta ******************************************************************************/ 3164a8bfdb9SAchin Gupta smc_args_t *tsp_cpu_suspend_main(uint64_t arg0, 3174a8bfdb9SAchin Gupta uint64_t arg1, 3184a8bfdb9SAchin Gupta uint64_t arg2, 3194a8bfdb9SAchin Gupta uint64_t arg3, 3204a8bfdb9SAchin Gupta uint64_t arg4, 3214a8bfdb9SAchin Gupta uint64_t arg5, 3224a8bfdb9SAchin Gupta uint64_t arg6, 3234a8bfdb9SAchin Gupta uint64_t arg7) 3244a8bfdb9SAchin Gupta { 3254a8bfdb9SAchin Gupta uint32_t linear_id = plat_my_core_pos(); 3264a8bfdb9SAchin Gupta 3274a8bfdb9SAchin Gupta /* 3284a8bfdb9SAchin Gupta * Save the time context and disable it to prevent the secure timer 3294a8bfdb9SAchin Gupta * interrupt from interfering with wakeup from the suspend state. 3304a8bfdb9SAchin Gupta */ 3314a8bfdb9SAchin Gupta tsp_generic_timer_save(); 3324a8bfdb9SAchin Gupta tsp_generic_timer_stop(); 3334a8bfdb9SAchin Gupta 3344a8bfdb9SAchin Gupta /* Update this cpu's statistics. */ 3354a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count++; 3364a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count++; 3374a8bfdb9SAchin Gupta tsp_stats[linear_id].cpu_suspend_count++; 3384a8bfdb9SAchin Gupta 3394a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n", 3404a8bfdb9SAchin Gupta read_mpidr(), 3414a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count, 3424a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count, 3434a8bfdb9SAchin Gupta tsp_stats[linear_id].cpu_suspend_count); 3444a8bfdb9SAchin Gupta 3454a8bfdb9SAchin Gupta return send_ffa_pm_success(); 3464a8bfdb9SAchin Gupta } 3474a8bfdb9SAchin Gupta 3484a8bfdb9SAchin Gupta /******************************************************************************* 3494a8bfdb9SAchin Gupta * This function performs any bookkeeping in the test secure payload after this 3504a8bfdb9SAchin Gupta * cpu's architectural state has been restored after wakeup from an earlier psci 3514a8bfdb9SAchin Gupta * cpu_suspend request. 3524a8bfdb9SAchin Gupta ******************************************************************************/ 3534a8bfdb9SAchin Gupta smc_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl, 3544a8bfdb9SAchin Gupta uint64_t arg1, 3554a8bfdb9SAchin Gupta uint64_t arg2, 3564a8bfdb9SAchin Gupta uint64_t arg3, 3574a8bfdb9SAchin Gupta uint64_t arg4, 3584a8bfdb9SAchin Gupta uint64_t arg5, 3594a8bfdb9SAchin Gupta uint64_t arg6, 3604a8bfdb9SAchin Gupta uint64_t arg7) 3614a8bfdb9SAchin Gupta { 3624a8bfdb9SAchin Gupta uint32_t linear_id = plat_my_core_pos(); 3634a8bfdb9SAchin Gupta 3644a8bfdb9SAchin Gupta /* Restore the generic timer context. */ 3654a8bfdb9SAchin Gupta tsp_generic_timer_restore(); 3664a8bfdb9SAchin Gupta 3674a8bfdb9SAchin Gupta /* Update this cpu's statistics. */ 3684a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count++; 3694a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count++; 3704a8bfdb9SAchin Gupta tsp_stats[linear_id].cpu_resume_count++; 3714a8bfdb9SAchin Gupta 3724a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx resumed. maximum off power level %" PRId64 "\n", 3734a8bfdb9SAchin Gupta read_mpidr(), max_off_pwrlvl); 3744a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu resume requests\n", 3754a8bfdb9SAchin Gupta read_mpidr(), 3764a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count, 3774a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count, 3784a8bfdb9SAchin Gupta tsp_stats[linear_id].cpu_resume_count); 3794a8bfdb9SAchin Gupta 3804a8bfdb9SAchin Gupta return send_ffa_pm_success(); 3814a8bfdb9SAchin Gupta } 3824a8bfdb9SAchin Gupta 3834a8bfdb9SAchin Gupta /******************************************************************************* 3844a8bfdb9SAchin Gupta * This function handles framework messages. Currently only PM. 3854a8bfdb9SAchin Gupta ******************************************************************************/ 3864a8bfdb9SAchin Gupta static smc_args_t *handle_framework_message(uint64_t arg0, 3874a8bfdb9SAchin Gupta uint64_t arg1, 3884a8bfdb9SAchin Gupta uint64_t arg2, 3894a8bfdb9SAchin Gupta uint64_t arg3, 3904a8bfdb9SAchin Gupta uint64_t arg4, 3914a8bfdb9SAchin Gupta uint64_t arg5, 3924a8bfdb9SAchin Gupta uint64_t arg6, 3934a8bfdb9SAchin Gupta uint64_t arg7) 3944a8bfdb9SAchin Gupta { 3954a8bfdb9SAchin Gupta /* Check if it is a power management message from the SPMC. */ 3964a8bfdb9SAchin Gupta if (ffa_endpoint_source(arg1) != spmc_id) { 3974a8bfdb9SAchin Gupta goto err; 3984a8bfdb9SAchin Gupta } 3994a8bfdb9SAchin Gupta 4004a8bfdb9SAchin Gupta /* Check if it is a PM request message. */ 4014a8bfdb9SAchin Gupta if ((arg2 & FFA_FWK_MSG_MASK) == FFA_FWK_MSG_PSCI) { 4024a8bfdb9SAchin Gupta /* Check if it is a PSCI CPU_OFF request. */ 4034a8bfdb9SAchin Gupta if (arg3 == PSCI_CPU_OFF) { 4044a8bfdb9SAchin Gupta return tsp_cpu_off_main(arg0, arg1, arg2, arg3, 4054a8bfdb9SAchin Gupta arg4, arg5, arg6, arg7); 4064a8bfdb9SAchin Gupta } else if (arg3 == PSCI_CPU_SUSPEND_AARCH64) { 4074a8bfdb9SAchin Gupta return tsp_cpu_suspend_main(arg0, arg1, arg2, arg3, 4084a8bfdb9SAchin Gupta arg4, arg5, arg6, arg7); 4094a8bfdb9SAchin Gupta } 4104a8bfdb9SAchin Gupta } else if ((arg2 & FFA_FWK_MSG_MASK) == FFA_PM_MSG_WB_REQ) { 4114a8bfdb9SAchin Gupta /* Check it is a PSCI Warm Boot request. */ 4124a8bfdb9SAchin Gupta if (arg3 == FFA_WB_TYPE_NOTS2RAM) { 4134a8bfdb9SAchin Gupta return tsp_cpu_resume_main(arg0, arg1, arg2, arg3, 4144a8bfdb9SAchin Gupta arg4, arg5, arg6, arg7); 4154a8bfdb9SAchin Gupta } 4164a8bfdb9SAchin Gupta } 4174a8bfdb9SAchin Gupta 4184a8bfdb9SAchin Gupta err: 4194a8bfdb9SAchin Gupta ERROR("%s: Unknown framework message!\n", __func__); 4204a8bfdb9SAchin Gupta panic(); 4214a8bfdb9SAchin Gupta } 4224a8bfdb9SAchin Gupta 4234a8bfdb9SAchin Gupta /******************************************************************************* 424*15ca1ee3SMarc Bonnici * Handles partition messages. Exercised from the FF-A Test Driver. 425*15ca1ee3SMarc Bonnici ******************************************************************************/ 426*15ca1ee3SMarc Bonnici static smc_args_t *handle_partition_message(uint64_t arg0, 427*15ca1ee3SMarc Bonnici uint64_t arg1, 428*15ca1ee3SMarc Bonnici uint64_t arg2, 429*15ca1ee3SMarc Bonnici uint64_t arg3, 430*15ca1ee3SMarc Bonnici uint64_t arg4, 431*15ca1ee3SMarc Bonnici uint64_t arg5, 432*15ca1ee3SMarc Bonnici uint64_t arg6, 433*15ca1ee3SMarc Bonnici uint64_t arg7) 434*15ca1ee3SMarc Bonnici { 435*15ca1ee3SMarc Bonnici uint16_t sender = ffa_endpoint_source(arg1); 436*15ca1ee3SMarc Bonnici uint16_t receiver = ffa_endpoint_destination(arg1); 437*15ca1ee3SMarc Bonnici int status = -1; 438*15ca1ee3SMarc Bonnici const bool multi_endpoint = true; 439*15ca1ee3SMarc Bonnici 440*15ca1ee3SMarc Bonnici switch (arg3) { 441*15ca1ee3SMarc Bonnici case FF_A_MEMORY_SHARE: 442*15ca1ee3SMarc Bonnici INFO("TSP Tests: Memory Share Request--\n"); 443*15ca1ee3SMarc Bonnici status = test_memory_send(sender, arg4, FFA_FLAG_SHARE_MEMORY, !multi_endpoint); 444*15ca1ee3SMarc Bonnici break; 445*15ca1ee3SMarc Bonnici 446*15ca1ee3SMarc Bonnici case FF_A_MEMORY_LEND: 447*15ca1ee3SMarc Bonnici INFO("TSP Tests: Memory Lend Request--\n"); 448*15ca1ee3SMarc Bonnici status = test_memory_send(sender, arg4, FFA_FLAG_LEND_MEMORY, !multi_endpoint); 449*15ca1ee3SMarc Bonnici break; 450*15ca1ee3SMarc Bonnici 451*15ca1ee3SMarc Bonnici case FF_A_MEMORY_SHARE_MULTI_ENDPOINT: 452*15ca1ee3SMarc Bonnici INFO("TSP Tests: Multi Endpoint Memory Share Request--\n"); 453*15ca1ee3SMarc Bonnici status = test_memory_send(sender, arg4, FFA_FLAG_SHARE_MEMORY, multi_endpoint); 454*15ca1ee3SMarc Bonnici break; 455*15ca1ee3SMarc Bonnici 456*15ca1ee3SMarc Bonnici case FF_A_MEMORY_LEND_MULTI_ENDPOINT: 457*15ca1ee3SMarc Bonnici INFO("TSP Tests: Multi Endpoint Memory Lend Request--\n"); 458*15ca1ee3SMarc Bonnici status = test_memory_send(sender, arg4, FFA_FLAG_LEND_MEMORY, multi_endpoint); 459*15ca1ee3SMarc Bonnici break; 460*15ca1ee3SMarc Bonnici case FF_A_RELAY_MESSAGE: 461*15ca1ee3SMarc Bonnici INFO("TSP Tests: Relaying message--\n"); 462*15ca1ee3SMarc Bonnici status = ffa_test_relay(arg0, arg1, arg2, arg3, arg4, 463*15ca1ee3SMarc Bonnici arg5, arg6, arg7); 464*15ca1ee3SMarc Bonnici break; 465*15ca1ee3SMarc Bonnici 466*15ca1ee3SMarc Bonnici case FF_A_ECHO_MESSAGE: 467*15ca1ee3SMarc Bonnici INFO("TSP Tests: echo message--\n"); 468*15ca1ee3SMarc Bonnici status = arg4; 469*15ca1ee3SMarc Bonnici break; 470*15ca1ee3SMarc Bonnici 471*15ca1ee3SMarc Bonnici default: 472*15ca1ee3SMarc Bonnici INFO("TSP Tests: Unknown request ID %d--\n", (int) arg3); 473*15ca1ee3SMarc Bonnici } 474*15ca1ee3SMarc Bonnici 475*15ca1ee3SMarc Bonnici /* Swap the sender and receiver in the response. */ 476*15ca1ee3SMarc Bonnici return ffa_msg_send_direct_resp(receiver, sender, status, 0, 0, 0, 0); 477*15ca1ee3SMarc Bonnici } 478*15ca1ee3SMarc Bonnici 479*15ca1ee3SMarc Bonnici /******************************************************************************* 4804a8bfdb9SAchin Gupta * This function implements the event loop for handling FF-A ABI invocations. 4814a8bfdb9SAchin Gupta ******************************************************************************/ 4824a8bfdb9SAchin Gupta static smc_args_t *tsp_event_loop(uint64_t smc_fid, 4834a8bfdb9SAchin Gupta uint64_t arg1, 4844a8bfdb9SAchin Gupta uint64_t arg2, 4854a8bfdb9SAchin Gupta uint64_t arg3, 4864a8bfdb9SAchin Gupta uint64_t arg4, 4874a8bfdb9SAchin Gupta uint64_t arg5, 4884a8bfdb9SAchin Gupta uint64_t arg6, 4894a8bfdb9SAchin Gupta uint64_t arg7) 4904a8bfdb9SAchin Gupta { 4914a8bfdb9SAchin Gupta /* Panic if the SPMC did not forward an FF-A call. */ 4924a8bfdb9SAchin Gupta if (!is_ffa_fid(smc_fid)) { 4934a8bfdb9SAchin Gupta ERROR("%s: Unknown SMC FID (0x%lx)\n", __func__, smc_fid); 4944a8bfdb9SAchin Gupta panic(); 4954a8bfdb9SAchin Gupta } 4964a8bfdb9SAchin Gupta 4974a8bfdb9SAchin Gupta switch (smc_fid) { 4984a8bfdb9SAchin Gupta case FFA_INTERRUPT: 4994a8bfdb9SAchin Gupta /* 5004a8bfdb9SAchin Gupta * IRQs were enabled upon re-entry into the TSP. The interrupt 5014a8bfdb9SAchin Gupta * must have been handled by now. Return to the SPMC indicating 5024a8bfdb9SAchin Gupta * the same. 5034a8bfdb9SAchin Gupta */ 5044a8bfdb9SAchin Gupta return set_smc_args(FFA_MSG_WAIT, 0, 0, 0, 0, 0, 0, 0); 5054a8bfdb9SAchin Gupta 506*15ca1ee3SMarc Bonnici case FFA_MSG_SEND_DIRECT_REQ_SMC64: 5074a8bfdb9SAchin Gupta case FFA_MSG_SEND_DIRECT_REQ_SMC32: 5084a8bfdb9SAchin Gupta /* Check if a framework message, handle accordingly. */ 5094a8bfdb9SAchin Gupta if ((arg2 & FFA_FWK_MSG_BIT)) { 5104a8bfdb9SAchin Gupta return handle_framework_message(smc_fid, arg1, arg2, arg3, 5114a8bfdb9SAchin Gupta arg4, arg5, arg6, arg7); 5124a8bfdb9SAchin Gupta } 513*15ca1ee3SMarc Bonnici return handle_partition_message(smc_fid, arg1, arg2, arg3, 514*15ca1ee3SMarc Bonnici arg4, arg5, arg6, arg7); 5154a8bfdb9SAchin Gupta } 5164a8bfdb9SAchin Gupta 5174a8bfdb9SAchin Gupta ERROR("%s: Unsupported FF-A FID (0x%lx)\n", __func__, smc_fid); 5184a8bfdb9SAchin Gupta panic(); 5194a8bfdb9SAchin Gupta } 5204a8bfdb9SAchin Gupta 5214a8bfdb9SAchin Gupta static smc_args_t *tsp_loop(smc_args_t *args) 5224a8bfdb9SAchin Gupta { 5234a8bfdb9SAchin Gupta smc_args_t ret; 5244a8bfdb9SAchin Gupta 5254a8bfdb9SAchin Gupta do { 5264a8bfdb9SAchin Gupta /* -------------------------------------------- 5274a8bfdb9SAchin Gupta * Mask FIQ interrupts to avoid preemption 5284a8bfdb9SAchin Gupta * in case EL3 SPMC delegates an IRQ next or a 5294a8bfdb9SAchin Gupta * managed exit. Lastly, unmask IRQs so that 530*15ca1ee3SMarc Bonnici * they can be handled immediately upon re-entry. 5314a8bfdb9SAchin Gupta * --------------------------------------------- 5324a8bfdb9SAchin Gupta */ 5334a8bfdb9SAchin Gupta write_daifset(DAIF_FIQ_BIT); 5344a8bfdb9SAchin Gupta write_daifclr(DAIF_IRQ_BIT); 5354a8bfdb9SAchin Gupta ret = smc_helper(args->_regs[0], args->_regs[1], args->_regs[2], 5364a8bfdb9SAchin Gupta args->_regs[3], args->_regs[4], args->_regs[5], 5374a8bfdb9SAchin Gupta args->_regs[6], args->_regs[7]); 5384a8bfdb9SAchin Gupta args = tsp_event_loop(ret._regs[0], ret._regs[1], ret._regs[2], 5394a8bfdb9SAchin Gupta ret._regs[3], ret._regs[4], ret._regs[5], 5404a8bfdb9SAchin Gupta ret._regs[6], ret._regs[7]); 5414a8bfdb9SAchin Gupta } while (1); 5424a8bfdb9SAchin Gupta 5434a8bfdb9SAchin Gupta /* Not Reached. */ 5444a8bfdb9SAchin Gupta return NULL; 5454a8bfdb9SAchin Gupta } 5464a8bfdb9SAchin Gupta 5474a8bfdb9SAchin Gupta /******************************************************************************* 5484a8bfdb9SAchin Gupta * TSP main entry point where it gets the opportunity to initialize its secure 5494a8bfdb9SAchin Gupta * state/applications. Once the state is initialized, it must return to the 5504a8bfdb9SAchin Gupta * SPD with a pointer to the 'tsp_vector_table' jump table. 5514a8bfdb9SAchin Gupta ******************************************************************************/ 5524a8bfdb9SAchin Gupta uint64_t tsp_main(void) 5534a8bfdb9SAchin Gupta { 5544a8bfdb9SAchin Gupta smc_args_t smc_args = {0}; 5554a8bfdb9SAchin Gupta 5564a8bfdb9SAchin Gupta NOTICE("TSP: %s\n", version_string); 5574a8bfdb9SAchin Gupta NOTICE("TSP: %s\n", build_message); 5584a8bfdb9SAchin Gupta INFO("TSP: Total memory base : 0x%lx\n", (unsigned long) BL32_BASE); 5594a8bfdb9SAchin Gupta INFO("TSP: Total memory size : 0x%lx bytes\n", BL32_TOTAL_SIZE); 5604a8bfdb9SAchin Gupta uint32_t linear_id = plat_my_core_pos(); 5614a8bfdb9SAchin Gupta 5624a8bfdb9SAchin Gupta /* Initialize the platform. */ 5634a8bfdb9SAchin Gupta tsp_platform_setup(); 5644a8bfdb9SAchin Gupta 5654a8bfdb9SAchin Gupta /* Initialize secure/applications state here. */ 5664a8bfdb9SAchin Gupta tsp_generic_timer_start(); 5674a8bfdb9SAchin Gupta 5684a8bfdb9SAchin Gupta /* Register secondary entrypoint with the SPMC. */ 5694a8bfdb9SAchin Gupta smc_args = smc_helper(FFA_SECONDARY_EP_REGISTER_SMC64, 5704a8bfdb9SAchin Gupta (uint64_t) tsp_cpu_on_entry, 5714a8bfdb9SAchin Gupta 0, 0, 0, 0, 0, 0); 5724a8bfdb9SAchin Gupta if (smc_args._regs[SMC_ARG0] != FFA_SUCCESS_SMC32) { 5734a8bfdb9SAchin Gupta ERROR("TSP could not register secondary ep (0x%lx)\n", 5744a8bfdb9SAchin Gupta smc_args._regs[2]); 5754a8bfdb9SAchin Gupta panic(); 5764a8bfdb9SAchin Gupta } 577*15ca1ee3SMarc Bonnici /* Get TSP's endpoint id. */ 5784a8bfdb9SAchin Gupta smc_args = smc_helper(FFA_ID_GET, 0, 0, 0, 0, 0, 0, 0); 5794a8bfdb9SAchin Gupta if (smc_args._regs[SMC_ARG0] != FFA_SUCCESS_SMC32) { 5804a8bfdb9SAchin Gupta ERROR("TSP could not get own ID (0x%lx) on core%d\n", 5814a8bfdb9SAchin Gupta smc_args._regs[2], linear_id); 5824a8bfdb9SAchin Gupta panic(); 5834a8bfdb9SAchin Gupta } 5844a8bfdb9SAchin Gupta 5854a8bfdb9SAchin Gupta tsp_id = smc_args._regs[2]; 5864a8bfdb9SAchin Gupta INFO("TSP FF-A endpoint id = 0x%x\n", tsp_id); 587*15ca1ee3SMarc Bonnici 588*15ca1ee3SMarc Bonnici /* Get the SPMC ID. */ 5894a8bfdb9SAchin Gupta smc_args = smc_helper(FFA_SPM_ID_GET, 0, 0, 0, 0, 0, 0, 0); 5904a8bfdb9SAchin Gupta if (smc_args._regs[SMC_ARG0] != FFA_SUCCESS_SMC32) { 5914a8bfdb9SAchin Gupta ERROR("TSP could not get SPMC ID (0x%lx) on core%d\n", 5924a8bfdb9SAchin Gupta smc_args._regs[2], linear_id); 5934a8bfdb9SAchin Gupta panic(); 5944a8bfdb9SAchin Gupta } 5954a8bfdb9SAchin Gupta 5964a8bfdb9SAchin Gupta spmc_id = smc_args._regs[2]; 5974a8bfdb9SAchin Gupta 598*15ca1ee3SMarc Bonnici /* Call RXTX_MAP to map a 4k RX and TX buffer. */ 599*15ca1ee3SMarc Bonnici if (ffa_rxtx_map((uintptr_t) send_page, 600*15ca1ee3SMarc Bonnici (uintptr_t) recv_page, 1)) { 601*15ca1ee3SMarc Bonnici ERROR("TSP could not map it's RX/TX Buffers\n"); 602*15ca1ee3SMarc Bonnici panic(); 603*15ca1ee3SMarc Bonnici } 604*15ca1ee3SMarc Bonnici 605*15ca1ee3SMarc Bonnici mailbox.tx_buffer = send_page; 606*15ca1ee3SMarc Bonnici mailbox.rx_buffer = recv_page; 607*15ca1ee3SMarc Bonnici mailbox.rxtx_page_count = 1; 608*15ca1ee3SMarc Bonnici 609*15ca1ee3SMarc Bonnici /* Update this cpu's statistics. */ 6104a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count++; 6114a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count++; 6124a8bfdb9SAchin Gupta tsp_stats[linear_id].cpu_on_count++; 6134a8bfdb9SAchin Gupta 6144a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n", 6154a8bfdb9SAchin Gupta read_mpidr(), 6164a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count, 6174a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count, 6184a8bfdb9SAchin Gupta tsp_stats[linear_id].cpu_on_count); 6194a8bfdb9SAchin Gupta 6204a8bfdb9SAchin Gupta /* Tell SPMD that we are done initialising. */ 6214a8bfdb9SAchin Gupta tsp_loop(set_smc_args(FFA_MSG_WAIT, 0, 0, 0, 0, 0, 0, 0)); 6224a8bfdb9SAchin Gupta 6234a8bfdb9SAchin Gupta /* Not reached. */ 6244a8bfdb9SAchin Gupta return 0; 6254a8bfdb9SAchin Gupta } 6264a8bfdb9SAchin Gupta 6274a8bfdb9SAchin Gupta /******************************************************************************* 6284a8bfdb9SAchin Gupta * This function performs any remaining book keeping in the test secure payload 6294a8bfdb9SAchin Gupta * after this cpu's architectural state has been setup in response to an earlier 6304a8bfdb9SAchin Gupta * psci cpu_on request. 6314a8bfdb9SAchin Gupta ******************************************************************************/ 6324a8bfdb9SAchin Gupta smc_args_t *tsp_cpu_on_main(void) 6334a8bfdb9SAchin Gupta { 6344a8bfdb9SAchin Gupta uint32_t linear_id = plat_my_core_pos(); 6354a8bfdb9SAchin Gupta 6364a8bfdb9SAchin Gupta /* Initialize secure/applications state here. */ 6374a8bfdb9SAchin Gupta tsp_generic_timer_start(); 6384a8bfdb9SAchin Gupta 6394a8bfdb9SAchin Gupta /* Update this cpu's statistics. */ 6404a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count++; 6414a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count++; 6424a8bfdb9SAchin Gupta tsp_stats[linear_id].cpu_on_count++; 6434a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx turned on\n", read_mpidr()); 6444a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n", 6454a8bfdb9SAchin Gupta read_mpidr(), 6464a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count, 6474a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count, 6484a8bfdb9SAchin Gupta tsp_stats[linear_id].cpu_on_count); 6494a8bfdb9SAchin Gupta /* --------------------------------------------- 6504a8bfdb9SAchin Gupta * Jump to the main event loop to return to EL3 6514a8bfdb9SAchin Gupta * and be ready for the next request on this cpu. 6524a8bfdb9SAchin Gupta * --------------------------------------------- 6534a8bfdb9SAchin Gupta */ 6544a8bfdb9SAchin Gupta return tsp_loop(set_smc_args(FFA_MSG_WAIT, 0, 0, 0, 0, 0, 0, 0)); 6554a8bfdb9SAchin Gupta } 656