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