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