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(void) 68 { 69 /* Enable early console if EARLY_CONSOLE flag is enabled */ 70 plat_setup_early_console(); 71 72 /* Perform early platform-specific setup. */ 73 tsp_early_platform_setup(); 74 75 /* Perform late platform-specific setup. */ 76 tsp_plat_arch_setup(); 77 } 78 79 /******************************************************************************* 80 * This function performs any remaining bookkeeping in the test secure payload 81 * before the system is switched off (in response to a psci SYSTEM_OFF request). 82 ******************************************************************************/ 83 smc_args_t *tsp_system_off_main(uint64_t arg0, 84 uint64_t arg1, 85 uint64_t arg2, 86 uint64_t arg3, 87 uint64_t arg4, 88 uint64_t arg5, 89 uint64_t arg6, 90 uint64_t arg7) 91 { 92 uint32_t linear_id = plat_my_core_pos(); 93 94 /* Update this cpu's statistics. */ 95 tsp_stats[linear_id].smc_count++; 96 tsp_stats[linear_id].eret_count++; 97 98 INFO("TSP: cpu 0x%lx SYSTEM_OFF request\n", read_mpidr()); 99 INFO("TSP: cpu 0x%lx: %u smcs, %u erets requests\n", read_mpidr(), 100 tsp_stats[linear_id].smc_count, 101 tsp_stats[linear_id].eret_count); 102 103 /* Indicate to the SPD that we have completed this request. */ 104 return set_smc_args(TSP_SYSTEM_OFF_DONE, 0, 0, 0, 0, 0, 0, 0); 105 } 106 107 /******************************************************************************* 108 * This function performs any remaining bookkeeping in the test secure payload 109 * before the system is reset (in response to a psci SYSTEM_RESET request). 110 ******************************************************************************/ 111 smc_args_t *tsp_system_reset_main(uint64_t arg0, 112 uint64_t arg1, 113 uint64_t arg2, 114 uint64_t arg3, 115 uint64_t arg4, 116 uint64_t arg5, 117 uint64_t arg6, 118 uint64_t arg7) 119 { 120 uint32_t linear_id = plat_my_core_pos(); 121 122 /* Update this cpu's statistics. */ 123 tsp_stats[linear_id].smc_count++; 124 tsp_stats[linear_id].eret_count++; 125 126 INFO("TSP: cpu 0x%lx SYSTEM_RESET request\n", read_mpidr()); 127 INFO("TSP: cpu 0x%lx: %u smcs, %u erets requests\n", read_mpidr(), 128 tsp_stats[linear_id].smc_count, 129 tsp_stats[linear_id].eret_count); 130 131 /* Indicate to the SPD that we have completed this request. */ 132 return set_smc_args(TSP_SYSTEM_RESET_DONE, 0, 0, 0, 0, 0, 0, 0); 133 } 134 135 /******************************************************************************* 136 * TSP smc abort handler. This function is called when aborting a preempted 137 * yielding SMC request. It should cleanup all resources owned by the SMC 138 * handler such as locks or dynamically allocated memory so following SMC 139 * request are executed in a clean environment. 140 ******************************************************************************/ 141 smc_args_t *tsp_abort_smc_handler(uint64_t func, 142 uint64_t arg1, 143 uint64_t arg2, 144 uint64_t arg3, 145 uint64_t arg4, 146 uint64_t arg5, 147 uint64_t arg6, 148 uint64_t arg7) 149 { 150 return set_smc_args(TSP_ABORT_DONE, 0, 0, 0, 0, 0, 0, 0); 151 } 152