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 <arch_features.h> 12*4a8bfdb9SAchin Gupta #include <arch_helpers.h> 13*4a8bfdb9SAchin Gupta #include <bl32/tsp/tsp.h> 14*4a8bfdb9SAchin Gupta #include <common/bl_common.h> 15*4a8bfdb9SAchin Gupta #include <common/debug.h> 16*4a8bfdb9SAchin Gupta #include <lib/spinlock.h> 17*4a8bfdb9SAchin Gupta #include <plat/common/platform.h> 18*4a8bfdb9SAchin Gupta #include <platform_tsp.h> 19*4a8bfdb9SAchin Gupta #include "tsp_private.h" 20*4a8bfdb9SAchin Gupta 21*4a8bfdb9SAchin Gupta #include <platform_def.h> 22*4a8bfdb9SAchin Gupta 23*4a8bfdb9SAchin Gupta /******************************************************************************* 24*4a8bfdb9SAchin Gupta * Lock to control access to the console 25*4a8bfdb9SAchin Gupta ******************************************************************************/ 26*4a8bfdb9SAchin Gupta spinlock_t console_lock; 27*4a8bfdb9SAchin Gupta 28*4a8bfdb9SAchin Gupta /******************************************************************************* 29*4a8bfdb9SAchin Gupta * Per cpu data structure to populate parameters for an SMC in C code and use 30*4a8bfdb9SAchin Gupta * a pointer to this structure in assembler code to populate x0-x7. 31*4a8bfdb9SAchin Gupta ******************************************************************************/ 32*4a8bfdb9SAchin Gupta static smc_args_t tsp_smc_args[PLATFORM_CORE_COUNT]; 33*4a8bfdb9SAchin Gupta 34*4a8bfdb9SAchin Gupta /******************************************************************************* 35*4a8bfdb9SAchin Gupta * Per cpu data structure to keep track of TSP activity 36*4a8bfdb9SAchin Gupta ******************************************************************************/ 37*4a8bfdb9SAchin Gupta work_statistics_t tsp_stats[PLATFORM_CORE_COUNT]; 38*4a8bfdb9SAchin Gupta 39*4a8bfdb9SAchin Gupta smc_args_t *set_smc_args(uint64_t arg0, 40*4a8bfdb9SAchin Gupta uint64_t arg1, 41*4a8bfdb9SAchin Gupta uint64_t arg2, 42*4a8bfdb9SAchin Gupta uint64_t arg3, 43*4a8bfdb9SAchin Gupta uint64_t arg4, 44*4a8bfdb9SAchin Gupta uint64_t arg5, 45*4a8bfdb9SAchin Gupta uint64_t arg6, 46*4a8bfdb9SAchin Gupta uint64_t arg7) 47*4a8bfdb9SAchin Gupta { 48*4a8bfdb9SAchin Gupta uint32_t linear_id; 49*4a8bfdb9SAchin Gupta smc_args_t *pcpu_smc_args; 50*4a8bfdb9SAchin Gupta 51*4a8bfdb9SAchin Gupta /* 52*4a8bfdb9SAchin Gupta * Return to Secure Monitor by raising an SMC. The results of the 53*4a8bfdb9SAchin Gupta * service are passed as an arguments to the SMC. 54*4a8bfdb9SAchin Gupta */ 55*4a8bfdb9SAchin Gupta linear_id = plat_my_core_pos(); 56*4a8bfdb9SAchin Gupta pcpu_smc_args = &tsp_smc_args[linear_id]; 57*4a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG0, arg0); 58*4a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG1, arg1); 59*4a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG2, arg2); 60*4a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG3, arg3); 61*4a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG4, arg4); 62*4a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG5, arg5); 63*4a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG6, arg6); 64*4a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG7, arg7); 65*4a8bfdb9SAchin Gupta 66*4a8bfdb9SAchin Gupta return pcpu_smc_args; 67*4a8bfdb9SAchin Gupta } 68*4a8bfdb9SAchin Gupta 69*4a8bfdb9SAchin Gupta /******************************************************************************* 70*4a8bfdb9SAchin Gupta * Setup function for TSP. 71*4a8bfdb9SAchin Gupta ******************************************************************************/ 72*4a8bfdb9SAchin Gupta void tsp_setup(void) 73*4a8bfdb9SAchin Gupta { 74*4a8bfdb9SAchin Gupta /* Perform early platform-specific setup. */ 75*4a8bfdb9SAchin Gupta tsp_early_platform_setup(); 76*4a8bfdb9SAchin Gupta 77*4a8bfdb9SAchin Gupta /* Perform late platform-specific setup. */ 78*4a8bfdb9SAchin Gupta tsp_plat_arch_setup(); 79*4a8bfdb9SAchin Gupta 80*4a8bfdb9SAchin Gupta #if ENABLE_PAUTH 81*4a8bfdb9SAchin Gupta /* 82*4a8bfdb9SAchin Gupta * Assert that the ARMv8.3-PAuth registers are present or an access 83*4a8bfdb9SAchin Gupta * fault will be triggered when they are being saved or restored. 84*4a8bfdb9SAchin Gupta */ 85*4a8bfdb9SAchin Gupta assert(is_armv8_3_pauth_present()); 86*4a8bfdb9SAchin Gupta #endif /* ENABLE_PAUTH */ 87*4a8bfdb9SAchin Gupta } 88*4a8bfdb9SAchin Gupta 89*4a8bfdb9SAchin Gupta /******************************************************************************* 90*4a8bfdb9SAchin Gupta * This function performs any remaining bookkeeping in the test secure payload 91*4a8bfdb9SAchin Gupta * before the system is switched off (in response to a psci SYSTEM_OFF request). 92*4a8bfdb9SAchin Gupta ******************************************************************************/ 93*4a8bfdb9SAchin Gupta smc_args_t *tsp_system_off_main(uint64_t arg0, 94*4a8bfdb9SAchin Gupta uint64_t arg1, 95*4a8bfdb9SAchin Gupta uint64_t arg2, 96*4a8bfdb9SAchin Gupta uint64_t arg3, 97*4a8bfdb9SAchin Gupta uint64_t arg4, 98*4a8bfdb9SAchin Gupta uint64_t arg5, 99*4a8bfdb9SAchin Gupta uint64_t arg6, 100*4a8bfdb9SAchin Gupta uint64_t arg7) 101*4a8bfdb9SAchin Gupta { 102*4a8bfdb9SAchin Gupta uint32_t linear_id = plat_my_core_pos(); 103*4a8bfdb9SAchin Gupta 104*4a8bfdb9SAchin Gupta /* Update this cpu's statistics. */ 105*4a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count++; 106*4a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count++; 107*4a8bfdb9SAchin Gupta 108*4a8bfdb9SAchin Gupta #if LOG_LEVEL >= LOG_LEVEL_INFO 109*4a8bfdb9SAchin Gupta spin_lock(&console_lock); 110*4a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx SYSTEM_OFF request\n", read_mpidr()); 111*4a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(), 112*4a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count, 113*4a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count); 114*4a8bfdb9SAchin Gupta spin_unlock(&console_lock); 115*4a8bfdb9SAchin Gupta #endif 116*4a8bfdb9SAchin Gupta 117*4a8bfdb9SAchin Gupta /* Indicate to the SPD that we have completed this request. */ 118*4a8bfdb9SAchin Gupta return set_smc_args(TSP_SYSTEM_OFF_DONE, 0, 0, 0, 0, 0, 0, 0); 119*4a8bfdb9SAchin Gupta } 120*4a8bfdb9SAchin Gupta 121*4a8bfdb9SAchin Gupta /******************************************************************************* 122*4a8bfdb9SAchin Gupta * This function performs any remaining bookkeeping in the test secure payload 123*4a8bfdb9SAchin Gupta * before the system is reset (in response to a psci SYSTEM_RESET request). 124*4a8bfdb9SAchin Gupta ******************************************************************************/ 125*4a8bfdb9SAchin Gupta smc_args_t *tsp_system_reset_main(uint64_t arg0, 126*4a8bfdb9SAchin Gupta uint64_t arg1, 127*4a8bfdb9SAchin Gupta uint64_t arg2, 128*4a8bfdb9SAchin Gupta uint64_t arg3, 129*4a8bfdb9SAchin Gupta uint64_t arg4, 130*4a8bfdb9SAchin Gupta uint64_t arg5, 131*4a8bfdb9SAchin Gupta uint64_t arg6, 132*4a8bfdb9SAchin Gupta uint64_t arg7) 133*4a8bfdb9SAchin Gupta { 134*4a8bfdb9SAchin Gupta uint32_t linear_id = plat_my_core_pos(); 135*4a8bfdb9SAchin Gupta 136*4a8bfdb9SAchin Gupta /* Update this cpu's statistics. */ 137*4a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count++; 138*4a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count++; 139*4a8bfdb9SAchin Gupta 140*4a8bfdb9SAchin Gupta #if LOG_LEVEL >= LOG_LEVEL_INFO 141*4a8bfdb9SAchin Gupta spin_lock(&console_lock); 142*4a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx SYSTEM_RESET request\n", read_mpidr()); 143*4a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(), 144*4a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count, 145*4a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count); 146*4a8bfdb9SAchin Gupta spin_unlock(&console_lock); 147*4a8bfdb9SAchin Gupta #endif 148*4a8bfdb9SAchin Gupta 149*4a8bfdb9SAchin Gupta /* Indicate to the SPD that we have completed this request. */ 150*4a8bfdb9SAchin Gupta return set_smc_args(TSP_SYSTEM_RESET_DONE, 0, 0, 0, 0, 0, 0, 0); 151*4a8bfdb9SAchin Gupta } 152*4a8bfdb9SAchin Gupta 153*4a8bfdb9SAchin Gupta /******************************************************************************* 154*4a8bfdb9SAchin Gupta * TSP smc abort handler. This function is called when aborting a preempted 155*4a8bfdb9SAchin Gupta * yielding SMC request. It should cleanup all resources owned by the SMC 156*4a8bfdb9SAchin Gupta * handler such as locks or dynamically allocated memory so following SMC 157*4a8bfdb9SAchin Gupta * request are executed in a clean environment. 158*4a8bfdb9SAchin Gupta ******************************************************************************/ 159*4a8bfdb9SAchin Gupta smc_args_t *tsp_abort_smc_handler(uint64_t func, 160*4a8bfdb9SAchin Gupta uint64_t arg1, 161*4a8bfdb9SAchin Gupta uint64_t arg2, 162*4a8bfdb9SAchin Gupta uint64_t arg3, 163*4a8bfdb9SAchin Gupta uint64_t arg4, 164*4a8bfdb9SAchin Gupta uint64_t arg5, 165*4a8bfdb9SAchin Gupta uint64_t arg6, 166*4a8bfdb9SAchin Gupta uint64_t arg7) 167*4a8bfdb9SAchin Gupta { 168*4a8bfdb9SAchin Gupta return set_smc_args(TSP_ABORT_DONE, 0, 0, 0, 0, 0, 0, 0); 169*4a8bfdb9SAchin Gupta } 170