14a8bfdb9SAchin Gupta /* 2*3b06438dSYann Gautier * Copyright (c) 2022-2025, Arm Limited and Contributors. All rights reserved. 34a8bfdb9SAchin Gupta * 44a8bfdb9SAchin Gupta * SPDX-License-Identifier: BSD-3-Clause 54a8bfdb9SAchin Gupta */ 64a8bfdb9SAchin Gupta 74a8bfdb9SAchin Gupta #include <assert.h> 84a8bfdb9SAchin Gupta #include <inttypes.h> 94a8bfdb9SAchin Gupta #include <stdint.h> 104a8bfdb9SAchin Gupta 114a8bfdb9SAchin Gupta #include <arch_features.h> 124a8bfdb9SAchin Gupta #include <arch_helpers.h> 134a8bfdb9SAchin Gupta #include <bl32/tsp/tsp.h> 144a8bfdb9SAchin Gupta #include <common/bl_common.h> 154a8bfdb9SAchin Gupta #include <common/debug.h> 164a8bfdb9SAchin Gupta #include <lib/spinlock.h> 174a8bfdb9SAchin Gupta #include <plat/common/platform.h> 184a8bfdb9SAchin Gupta #include <platform_tsp.h> 194a8bfdb9SAchin Gupta #include "tsp_private.h" 204a8bfdb9SAchin Gupta 214a8bfdb9SAchin Gupta #include <platform_def.h> 224a8bfdb9SAchin Gupta 234a8bfdb9SAchin Gupta /******************************************************************************* 244a8bfdb9SAchin Gupta * Per cpu data structure to populate parameters for an SMC in C code and use 254a8bfdb9SAchin Gupta * a pointer to this structure in assembler code to populate x0-x7. 264a8bfdb9SAchin Gupta ******************************************************************************/ 274a8bfdb9SAchin Gupta static smc_args_t tsp_smc_args[PLATFORM_CORE_COUNT]; 284a8bfdb9SAchin Gupta 294a8bfdb9SAchin Gupta /******************************************************************************* 304a8bfdb9SAchin Gupta * Per cpu data structure to keep track of TSP activity 314a8bfdb9SAchin Gupta ******************************************************************************/ 324a8bfdb9SAchin Gupta work_statistics_t tsp_stats[PLATFORM_CORE_COUNT]; 334a8bfdb9SAchin Gupta 344a8bfdb9SAchin Gupta smc_args_t *set_smc_args(uint64_t arg0, 354a8bfdb9SAchin Gupta uint64_t arg1, 364a8bfdb9SAchin Gupta uint64_t arg2, 374a8bfdb9SAchin Gupta uint64_t arg3, 384a8bfdb9SAchin Gupta uint64_t arg4, 394a8bfdb9SAchin Gupta uint64_t arg5, 404a8bfdb9SAchin Gupta uint64_t arg6, 414a8bfdb9SAchin Gupta uint64_t arg7) 424a8bfdb9SAchin Gupta { 434a8bfdb9SAchin Gupta uint32_t linear_id; 444a8bfdb9SAchin Gupta smc_args_t *pcpu_smc_args; 454a8bfdb9SAchin Gupta 464a8bfdb9SAchin Gupta /* 474a8bfdb9SAchin Gupta * Return to Secure Monitor by raising an SMC. The results of the 484a8bfdb9SAchin Gupta * service are passed as an arguments to the SMC. 494a8bfdb9SAchin Gupta */ 504a8bfdb9SAchin Gupta linear_id = plat_my_core_pos(); 514a8bfdb9SAchin Gupta pcpu_smc_args = &tsp_smc_args[linear_id]; 524a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG0, arg0); 534a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG1, arg1); 544a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG2, arg2); 554a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG3, arg3); 564a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG4, arg4); 574a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG5, arg5); 584a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG6, arg6); 594a8bfdb9SAchin Gupta write_sp_arg(pcpu_smc_args, SMC_ARG7, arg7); 604a8bfdb9SAchin Gupta 614a8bfdb9SAchin Gupta return pcpu_smc_args; 624a8bfdb9SAchin Gupta } 634a8bfdb9SAchin Gupta 644a8bfdb9SAchin Gupta /******************************************************************************* 654a8bfdb9SAchin Gupta * Setup function for TSP. 664a8bfdb9SAchin Gupta ******************************************************************************/ 674a8bfdb9SAchin Gupta void tsp_setup(void) 684a8bfdb9SAchin Gupta { 69ae770fedSYann Gautier /* Enable early console if EARLY_CONSOLE flag is enabled */ 70ae770fedSYann Gautier plat_setup_early_console(); 71ae770fedSYann Gautier 724a8bfdb9SAchin Gupta /* Perform early platform-specific setup. */ 734a8bfdb9SAchin Gupta tsp_early_platform_setup(); 744a8bfdb9SAchin Gupta 754a8bfdb9SAchin Gupta /* Perform late platform-specific setup. */ 764a8bfdb9SAchin Gupta tsp_plat_arch_setup(); 774a8bfdb9SAchin Gupta 784a8bfdb9SAchin Gupta #if ENABLE_PAUTH 794a8bfdb9SAchin Gupta /* 804a8bfdb9SAchin Gupta * Assert that the ARMv8.3-PAuth registers are present or an access 814a8bfdb9SAchin Gupta * fault will be triggered when they are being saved or restored. 824a8bfdb9SAchin Gupta */ 834a8bfdb9SAchin Gupta assert(is_armv8_3_pauth_present()); 844a8bfdb9SAchin Gupta #endif /* ENABLE_PAUTH */ 854a8bfdb9SAchin Gupta } 864a8bfdb9SAchin Gupta 874a8bfdb9SAchin Gupta /******************************************************************************* 884a8bfdb9SAchin Gupta * This function performs any remaining bookkeeping in the test secure payload 894a8bfdb9SAchin Gupta * before the system is switched off (in response to a psci SYSTEM_OFF request). 904a8bfdb9SAchin Gupta ******************************************************************************/ 914a8bfdb9SAchin Gupta smc_args_t *tsp_system_off_main(uint64_t arg0, 924a8bfdb9SAchin Gupta uint64_t arg1, 934a8bfdb9SAchin Gupta uint64_t arg2, 944a8bfdb9SAchin Gupta uint64_t arg3, 954a8bfdb9SAchin Gupta uint64_t arg4, 964a8bfdb9SAchin Gupta uint64_t arg5, 974a8bfdb9SAchin Gupta uint64_t arg6, 984a8bfdb9SAchin Gupta uint64_t arg7) 994a8bfdb9SAchin Gupta { 1004a8bfdb9SAchin Gupta uint32_t linear_id = plat_my_core_pos(); 1014a8bfdb9SAchin Gupta 1024a8bfdb9SAchin Gupta /* Update this cpu's statistics. */ 1034a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count++; 1044a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count++; 1054a8bfdb9SAchin Gupta 1064a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx SYSTEM_OFF request\n", read_mpidr()); 107*3b06438dSYann Gautier INFO("TSP: cpu 0x%lx: %u smcs, %u erets requests\n", read_mpidr(), 1084a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count, 1094a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count); 1104a8bfdb9SAchin Gupta 1114a8bfdb9SAchin Gupta /* Indicate to the SPD that we have completed this request. */ 1124a8bfdb9SAchin Gupta return set_smc_args(TSP_SYSTEM_OFF_DONE, 0, 0, 0, 0, 0, 0, 0); 1134a8bfdb9SAchin Gupta } 1144a8bfdb9SAchin Gupta 1154a8bfdb9SAchin Gupta /******************************************************************************* 1164a8bfdb9SAchin Gupta * This function performs any remaining bookkeeping in the test secure payload 1174a8bfdb9SAchin Gupta * before the system is reset (in response to a psci SYSTEM_RESET request). 1184a8bfdb9SAchin Gupta ******************************************************************************/ 1194a8bfdb9SAchin Gupta smc_args_t *tsp_system_reset_main(uint64_t arg0, 1204a8bfdb9SAchin Gupta uint64_t arg1, 1214a8bfdb9SAchin Gupta uint64_t arg2, 1224a8bfdb9SAchin Gupta uint64_t arg3, 1234a8bfdb9SAchin Gupta uint64_t arg4, 1244a8bfdb9SAchin Gupta uint64_t arg5, 1254a8bfdb9SAchin Gupta uint64_t arg6, 1264a8bfdb9SAchin Gupta uint64_t arg7) 1274a8bfdb9SAchin Gupta { 1284a8bfdb9SAchin Gupta uint32_t linear_id = plat_my_core_pos(); 1294a8bfdb9SAchin Gupta 1304a8bfdb9SAchin Gupta /* Update this cpu's statistics. */ 1314a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count++; 1324a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count++; 1334a8bfdb9SAchin Gupta 1344a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx SYSTEM_RESET request\n", read_mpidr()); 135*3b06438dSYann Gautier INFO("TSP: cpu 0x%lx: %u smcs, %u erets requests\n", read_mpidr(), 1364a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count, 1374a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count); 1384a8bfdb9SAchin Gupta 1394a8bfdb9SAchin Gupta /* Indicate to the SPD that we have completed this request. */ 1404a8bfdb9SAchin Gupta return set_smc_args(TSP_SYSTEM_RESET_DONE, 0, 0, 0, 0, 0, 0, 0); 1414a8bfdb9SAchin Gupta } 1424a8bfdb9SAchin Gupta 1434a8bfdb9SAchin Gupta /******************************************************************************* 1444a8bfdb9SAchin Gupta * TSP smc abort handler. This function is called when aborting a preempted 1454a8bfdb9SAchin Gupta * yielding SMC request. It should cleanup all resources owned by the SMC 1464a8bfdb9SAchin Gupta * handler such as locks or dynamically allocated memory so following SMC 1474a8bfdb9SAchin Gupta * request are executed in a clean environment. 1484a8bfdb9SAchin Gupta ******************************************************************************/ 1494a8bfdb9SAchin Gupta smc_args_t *tsp_abort_smc_handler(uint64_t func, 1504a8bfdb9SAchin Gupta uint64_t arg1, 1514a8bfdb9SAchin Gupta uint64_t arg2, 1524a8bfdb9SAchin Gupta uint64_t arg3, 1534a8bfdb9SAchin Gupta uint64_t arg4, 1544a8bfdb9SAchin Gupta uint64_t arg5, 1554a8bfdb9SAchin Gupta uint64_t arg6, 1564a8bfdb9SAchin Gupta uint64_t arg7) 1574a8bfdb9SAchin Gupta { 1584a8bfdb9SAchin Gupta return set_smc_args(TSP_ABORT_DONE, 0, 0, 0, 0, 0, 0, 0); 1594a8bfdb9SAchin Gupta } 160