1 /* 2 * Copyright (c) 2013-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 * TSP main entry point where it gets the opportunity to initialize its secure 25 * state/applications. Once the state is initialized, it must return to the 26 * SPD with a pointer to the 'tsp_vector_table' jump table. 27 ******************************************************************************/ 28 uint64_t tsp_main(void) 29 { 30 NOTICE("TSP: %s\n", version_string); 31 NOTICE("TSP: %s\n", build_message); 32 INFO("TSP: Total memory base : 0x%lx\n", (unsigned long) BL32_BASE); 33 INFO("TSP: Total memory size : 0x%lx bytes\n", BL32_TOTAL_SIZE); 34 35 uint32_t linear_id = plat_my_core_pos(); 36 37 /* Initialize the platform */ 38 tsp_platform_setup(); 39 40 /* Initialize secure/applications state here */ 41 tsp_generic_timer_start(); 42 43 /* Update this cpu's statistics */ 44 tsp_stats[linear_id].smc_count++; 45 tsp_stats[linear_id].eret_count++; 46 tsp_stats[linear_id].cpu_on_count++; 47 48 INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n", 49 read_mpidr(), 50 tsp_stats[linear_id].smc_count, 51 tsp_stats[linear_id].eret_count, 52 tsp_stats[linear_id].cpu_on_count); 53 return (uint64_t) &tsp_vector_table; 54 } 55 56 /******************************************************************************* 57 * This function performs any remaining book keeping in the test secure payload 58 * after this cpu's architectural state has been setup in response to an earlier 59 * psci cpu_on request. 60 ******************************************************************************/ 61 smc_args_t *tsp_cpu_on_main(void) 62 { 63 uint32_t linear_id = plat_my_core_pos(); 64 65 /* Initialize secure/applications state here */ 66 tsp_generic_timer_start(); 67 68 /* Update this cpu's statistics */ 69 tsp_stats[linear_id].smc_count++; 70 tsp_stats[linear_id].eret_count++; 71 tsp_stats[linear_id].cpu_on_count++; 72 73 INFO("TSP: cpu 0x%lx turned on\n", read_mpidr()); 74 INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n", 75 read_mpidr(), 76 tsp_stats[linear_id].smc_count, 77 tsp_stats[linear_id].eret_count, 78 tsp_stats[linear_id].cpu_on_count); 79 /* Indicate to the SPD that we have completed turned ourselves on */ 80 return set_smc_args(TSP_ON_DONE, 0, 0, 0, 0, 0, 0, 0); 81 } 82 83 /******************************************************************************* 84 * This function performs any remaining book keeping in the test secure payload 85 * before this cpu is turned off in response to a psci cpu_off request. 86 ******************************************************************************/ 87 smc_args_t *tsp_cpu_off_main(uint64_t arg0, 88 uint64_t arg1, 89 uint64_t arg2, 90 uint64_t arg3, 91 uint64_t arg4, 92 uint64_t arg5, 93 uint64_t arg6, 94 uint64_t arg7) 95 { 96 uint32_t linear_id = plat_my_core_pos(); 97 98 /* 99 * This cpu is being turned off, so disable the timer to prevent the 100 * secure timer interrupt from interfering with power down. A pending 101 * interrupt will be lost but we do not care as we are turning off. 102 */ 103 tsp_generic_timer_stop(); 104 105 /* Update this cpu's statistics */ 106 tsp_stats[linear_id].smc_count++; 107 tsp_stats[linear_id].eret_count++; 108 tsp_stats[linear_id].cpu_off_count++; 109 110 INFO("TSP: cpu 0x%lx off request\n", read_mpidr()); 111 INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu off requests\n", 112 read_mpidr(), 113 tsp_stats[linear_id].smc_count, 114 tsp_stats[linear_id].eret_count, 115 tsp_stats[linear_id].cpu_off_count); 116 117 /* Indicate to the SPD that we have completed this request */ 118 return set_smc_args(TSP_OFF_DONE, 0, 0, 0, 0, 0, 0, 0); 119 } 120 121 /******************************************************************************* 122 * This function performs any book keeping in the test secure payload before 123 * this cpu's architectural state is saved in response to an earlier psci 124 * cpu_suspend request. 125 ******************************************************************************/ 126 smc_args_t *tsp_cpu_suspend_main(uint64_t arg0, 127 uint64_t arg1, 128 uint64_t arg2, 129 uint64_t arg3, 130 uint64_t arg4, 131 uint64_t arg5, 132 uint64_t arg6, 133 uint64_t arg7) 134 { 135 uint32_t linear_id = plat_my_core_pos(); 136 137 /* 138 * Save the time context and disable it to prevent the secure timer 139 * interrupt from interfering with wakeup from the suspend state. 140 */ 141 tsp_generic_timer_save(); 142 tsp_generic_timer_stop(); 143 144 /* Update this cpu's statistics */ 145 tsp_stats[linear_id].smc_count++; 146 tsp_stats[linear_id].eret_count++; 147 tsp_stats[linear_id].cpu_suspend_count++; 148 149 INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n", 150 read_mpidr(), 151 tsp_stats[linear_id].smc_count, 152 tsp_stats[linear_id].eret_count, 153 tsp_stats[linear_id].cpu_suspend_count); 154 155 /* Indicate to the SPD that we have completed this request */ 156 return set_smc_args(TSP_SUSPEND_DONE, 0, 0, 0, 0, 0, 0, 0); 157 } 158 159 /******************************************************************************* 160 * This function performs any book keeping in the test secure payload after this 161 * cpu's architectural state has been restored after wakeup from an earlier psci 162 * cpu_suspend request. 163 ******************************************************************************/ 164 smc_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl, 165 uint64_t arg1, 166 uint64_t arg2, 167 uint64_t arg3, 168 uint64_t arg4, 169 uint64_t arg5, 170 uint64_t arg6, 171 uint64_t arg7) 172 { 173 uint32_t linear_id = plat_my_core_pos(); 174 175 /* Restore the generic timer context */ 176 tsp_generic_timer_restore(); 177 178 /* Update this cpu's statistics */ 179 tsp_stats[linear_id].smc_count++; 180 tsp_stats[linear_id].eret_count++; 181 tsp_stats[linear_id].cpu_resume_count++; 182 183 INFO("TSP: cpu 0x%lx resumed. maximum off power level %" PRId64 "\n", 184 read_mpidr(), max_off_pwrlvl); 185 INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu resume requests\n", 186 read_mpidr(), 187 tsp_stats[linear_id].smc_count, 188 tsp_stats[linear_id].eret_count, 189 tsp_stats[linear_id].cpu_resume_count); 190 /* Indicate to the SPD that we have completed this request */ 191 return set_smc_args(TSP_RESUME_DONE, 0, 0, 0, 0, 0, 0, 0); 192 } 193 194 /******************************************************************************* 195 * TSP fast smc handler. The secure monitor jumps to this function by 196 * doing the ERET after populating X0-X7 registers. The arguments are received 197 * in the function arguments in order. Once the service is rendered, this 198 * function returns to Secure Monitor by raising SMC. 199 ******************************************************************************/ 200 smc_args_t *tsp_smc_handler(uint64_t func, 201 uint64_t arg1, 202 uint64_t arg2, 203 uint64_t arg3, 204 uint64_t arg4, 205 uint64_t arg5, 206 uint64_t arg6, 207 uint64_t arg7) 208 { 209 uint128_t service_args; 210 uint64_t service_arg0; 211 uint64_t service_arg1; 212 uint64_t results[2]; 213 uint32_t linear_id = plat_my_core_pos(); 214 u_register_t dit; 215 216 /* Update this cpu's statistics */ 217 tsp_stats[linear_id].smc_count++; 218 tsp_stats[linear_id].eret_count++; 219 220 INFO("TSP: cpu 0x%lx received %s smc 0x%" PRIx64 "\n", read_mpidr(), 221 ((func >> 31) & 1) == 1 ? "fast" : "yielding", 222 func); 223 INFO("TSP: cpu 0x%lx: %d smcs, %d erets\n", read_mpidr(), 224 tsp_stats[linear_id].smc_count, 225 tsp_stats[linear_id].eret_count); 226 227 /* Render secure services and obtain results here */ 228 results[0] = arg1; 229 results[1] = arg2; 230 231 /* 232 * Request a service back from dispatcher/secure monitor. 233 * This call returns and thereafter resumes execution. 234 */ 235 service_args = tsp_get_magic(); 236 service_arg0 = (uint64_t)service_args; 237 service_arg1 = (uint64_t)(service_args >> 64U); 238 239 #if CTX_INCLUDE_MTE_REGS 240 /* 241 * Write a dummy value to an MTE register, to simulate usage in the 242 * secure world 243 */ 244 write_gcr_el1(0x99); 245 #endif 246 247 /* Determine the function to perform based on the function ID */ 248 switch (TSP_BARE_FID(func)) { 249 case TSP_ADD: 250 results[0] += service_arg0; 251 results[1] += service_arg1; 252 break; 253 case TSP_SUB: 254 results[0] -= service_arg0; 255 results[1] -= service_arg1; 256 break; 257 case TSP_MUL: 258 results[0] *= service_arg0; 259 results[1] *= service_arg1; 260 break; 261 case TSP_DIV: 262 results[0] /= service_arg0 ? service_arg0 : 1; 263 results[1] /= service_arg1 ? service_arg1 : 1; 264 break; 265 case TSP_CHECK_DIT: 266 if (!is_feat_dit_supported()) { 267 ERROR("DIT not supported\n"); 268 results[0] = 0; 269 results[1] = 0xffff; 270 break; 271 } 272 dit = read_dit(); 273 results[0] = dit == service_arg0; 274 results[1] = dit; 275 /* Toggle the dit bit */ 276 write_dit(service_arg0 != 0U ? 0 : DIT_BIT); 277 break; 278 default: 279 break; 280 } 281 282 return set_smc_args(func, 0, 283 results[0], 284 results[1], 285 0, 0, 0, 0); 286 } 287