14a8bfdb9SAchin Gupta /*
23b06438dSYann 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
set_smc_args(uint64_t arg0,uint64_t arg1,uint64_t arg2,uint64_t arg3,uint64_t arg4,uint64_t arg5,uint64_t arg6,uint64_t arg7)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 ******************************************************************************/
tsp_setup(u_register_t arg0,u_register_t arg1,u_register_t arg2,u_register_t arg3)67*32d9e8ecSHarrison Mutai void tsp_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
68*32d9e8ecSHarrison Mutai u_register_t arg3)
694a8bfdb9SAchin Gupta {
70ae770fedSYann Gautier /* Enable early console if EARLY_CONSOLE flag is enabled */
71ae770fedSYann Gautier plat_setup_early_console();
72ae770fedSYann Gautier
734a8bfdb9SAchin Gupta /* Perform early platform-specific setup. */
74*32d9e8ecSHarrison Mutai tsp_early_platform_setup(arg0, arg1, arg2, arg3);
754a8bfdb9SAchin Gupta
764a8bfdb9SAchin Gupta /* Perform late platform-specific setup. */
774a8bfdb9SAchin Gupta tsp_plat_arch_setup();
784a8bfdb9SAchin Gupta }
794a8bfdb9SAchin Gupta
804a8bfdb9SAchin Gupta /*******************************************************************************
814a8bfdb9SAchin Gupta * This function performs any remaining bookkeeping in the test secure payload
824a8bfdb9SAchin Gupta * before the system is switched off (in response to a psci SYSTEM_OFF request).
834a8bfdb9SAchin Gupta ******************************************************************************/
tsp_system_off_main(uint64_t arg0,uint64_t arg1,uint64_t arg2,uint64_t arg3,uint64_t arg4,uint64_t arg5,uint64_t arg6,uint64_t arg7)844a8bfdb9SAchin Gupta smc_args_t *tsp_system_off_main(uint64_t arg0,
854a8bfdb9SAchin Gupta uint64_t arg1,
864a8bfdb9SAchin Gupta uint64_t arg2,
874a8bfdb9SAchin Gupta uint64_t arg3,
884a8bfdb9SAchin Gupta uint64_t arg4,
894a8bfdb9SAchin Gupta uint64_t arg5,
904a8bfdb9SAchin Gupta uint64_t arg6,
914a8bfdb9SAchin Gupta uint64_t arg7)
924a8bfdb9SAchin Gupta {
934a8bfdb9SAchin Gupta uint32_t linear_id = plat_my_core_pos();
944a8bfdb9SAchin Gupta
954a8bfdb9SAchin Gupta /* Update this cpu's statistics. */
964a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count++;
974a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count++;
984a8bfdb9SAchin Gupta
994a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx SYSTEM_OFF request\n", read_mpidr());
1003b06438dSYann Gautier INFO("TSP: cpu 0x%lx: %u smcs, %u erets requests\n", read_mpidr(),
1014a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count,
1024a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count);
1034a8bfdb9SAchin Gupta
1044a8bfdb9SAchin Gupta /* Indicate to the SPD that we have completed this request. */
1054a8bfdb9SAchin Gupta return set_smc_args(TSP_SYSTEM_OFF_DONE, 0, 0, 0, 0, 0, 0, 0);
1064a8bfdb9SAchin Gupta }
1074a8bfdb9SAchin Gupta
1084a8bfdb9SAchin Gupta /*******************************************************************************
1094a8bfdb9SAchin Gupta * This function performs any remaining bookkeeping in the test secure payload
1104a8bfdb9SAchin Gupta * before the system is reset (in response to a psci SYSTEM_RESET request).
1114a8bfdb9SAchin Gupta ******************************************************************************/
tsp_system_reset_main(uint64_t arg0,uint64_t arg1,uint64_t arg2,uint64_t arg3,uint64_t arg4,uint64_t arg5,uint64_t arg6,uint64_t arg7)1124a8bfdb9SAchin Gupta smc_args_t *tsp_system_reset_main(uint64_t arg0,
1134a8bfdb9SAchin Gupta uint64_t arg1,
1144a8bfdb9SAchin Gupta uint64_t arg2,
1154a8bfdb9SAchin Gupta uint64_t arg3,
1164a8bfdb9SAchin Gupta uint64_t arg4,
1174a8bfdb9SAchin Gupta uint64_t arg5,
1184a8bfdb9SAchin Gupta uint64_t arg6,
1194a8bfdb9SAchin Gupta uint64_t arg7)
1204a8bfdb9SAchin Gupta {
1214a8bfdb9SAchin Gupta uint32_t linear_id = plat_my_core_pos();
1224a8bfdb9SAchin Gupta
1234a8bfdb9SAchin Gupta /* Update this cpu's statistics. */
1244a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count++;
1254a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count++;
1264a8bfdb9SAchin Gupta
1274a8bfdb9SAchin Gupta INFO("TSP: cpu 0x%lx SYSTEM_RESET request\n", read_mpidr());
1283b06438dSYann Gautier INFO("TSP: cpu 0x%lx: %u smcs, %u erets requests\n", read_mpidr(),
1294a8bfdb9SAchin Gupta tsp_stats[linear_id].smc_count,
1304a8bfdb9SAchin Gupta tsp_stats[linear_id].eret_count);
1314a8bfdb9SAchin Gupta
1324a8bfdb9SAchin Gupta /* Indicate to the SPD that we have completed this request. */
1334a8bfdb9SAchin Gupta return set_smc_args(TSP_SYSTEM_RESET_DONE, 0, 0, 0, 0, 0, 0, 0);
1344a8bfdb9SAchin Gupta }
1354a8bfdb9SAchin Gupta
1364a8bfdb9SAchin Gupta /*******************************************************************************
1374a8bfdb9SAchin Gupta * TSP smc abort handler. This function is called when aborting a preempted
1384a8bfdb9SAchin Gupta * yielding SMC request. It should cleanup all resources owned by the SMC
1394a8bfdb9SAchin Gupta * handler such as locks or dynamically allocated memory so following SMC
1404a8bfdb9SAchin Gupta * request are executed in a clean environment.
1414a8bfdb9SAchin Gupta ******************************************************************************/
tsp_abort_smc_handler(uint64_t func,uint64_t arg1,uint64_t arg2,uint64_t arg3,uint64_t arg4,uint64_t arg5,uint64_t arg6,uint64_t arg7)1424a8bfdb9SAchin Gupta smc_args_t *tsp_abort_smc_handler(uint64_t func,
1434a8bfdb9SAchin Gupta uint64_t arg1,
1444a8bfdb9SAchin Gupta uint64_t arg2,
1454a8bfdb9SAchin Gupta uint64_t arg3,
1464a8bfdb9SAchin Gupta uint64_t arg4,
1474a8bfdb9SAchin Gupta uint64_t arg5,
1484a8bfdb9SAchin Gupta uint64_t arg6,
1494a8bfdb9SAchin Gupta uint64_t arg7)
1504a8bfdb9SAchin Gupta {
1514a8bfdb9SAchin Gupta return set_smc_args(TSP_ABORT_DONE, 0, 0, 0, 0, 0, 0, 0);
1524a8bfdb9SAchin Gupta }
153