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