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