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