xref: /rk3399_ARM-atf/bl32/tsp/tsp_common.c (revision ac2605e69a7477dfb72d688fa96bfb154b2e8f8a)
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  * Lock to control access to the console
25  ******************************************************************************/
26 spinlock_t console_lock;
27 
28 /*******************************************************************************
29  * Per cpu data structure to populate parameters for an SMC in C code and use
30  * a pointer to this structure in assembler code to populate x0-x7.
31  ******************************************************************************/
32 static smc_args_t tsp_smc_args[PLATFORM_CORE_COUNT];
33 
34 /*******************************************************************************
35  * Per cpu data structure to keep track of TSP activity
36  ******************************************************************************/
37 work_statistics_t tsp_stats[PLATFORM_CORE_COUNT];
38 
39 smc_args_t *set_smc_args(uint64_t arg0,
40 			 uint64_t arg1,
41 			 uint64_t arg2,
42 			 uint64_t arg3,
43 			 uint64_t arg4,
44 			 uint64_t arg5,
45 			 uint64_t arg6,
46 			 uint64_t arg7)
47 {
48 	uint32_t linear_id;
49 	smc_args_t *pcpu_smc_args;
50 
51 	/*
52 	 * Return to Secure Monitor by raising an SMC. The results of the
53 	 * service are passed as an arguments to the SMC.
54 	 */
55 	linear_id = plat_my_core_pos();
56 	pcpu_smc_args = &tsp_smc_args[linear_id];
57 	write_sp_arg(pcpu_smc_args, SMC_ARG0, arg0);
58 	write_sp_arg(pcpu_smc_args, SMC_ARG1, arg1);
59 	write_sp_arg(pcpu_smc_args, SMC_ARG2, arg2);
60 	write_sp_arg(pcpu_smc_args, SMC_ARG3, arg3);
61 	write_sp_arg(pcpu_smc_args, SMC_ARG4, arg4);
62 	write_sp_arg(pcpu_smc_args, SMC_ARG5, arg5);
63 	write_sp_arg(pcpu_smc_args, SMC_ARG6, arg6);
64 	write_sp_arg(pcpu_smc_args, SMC_ARG7, arg7);
65 
66 	return pcpu_smc_args;
67 }
68 
69 /*******************************************************************************
70  * Setup function for TSP.
71  ******************************************************************************/
72 void tsp_setup(void)
73 {
74 	/* Perform early platform-specific setup. */
75 	tsp_early_platform_setup();
76 
77 	/* Perform late platform-specific setup. */
78 	tsp_plat_arch_setup();
79 
80 #if ENABLE_PAUTH
81 	/*
82 	 * Assert that the ARMv8.3-PAuth registers are present or an access
83 	 * fault will be triggered when they are being saved or restored.
84 	 */
85 	assert(is_armv8_3_pauth_present());
86 #endif /* ENABLE_PAUTH */
87 }
88 
89 /*******************************************************************************
90  * This function performs any remaining bookkeeping in the test secure payload
91  * before the system is switched off (in response to a psci SYSTEM_OFF request).
92  ******************************************************************************/
93 smc_args_t *tsp_system_off_main(uint64_t arg0,
94 				uint64_t arg1,
95 				uint64_t arg2,
96 				uint64_t arg3,
97 				uint64_t arg4,
98 				uint64_t arg5,
99 				uint64_t arg6,
100 				uint64_t arg7)
101 {
102 	uint32_t linear_id = plat_my_core_pos();
103 
104 	/* Update this cpu's statistics. */
105 	tsp_stats[linear_id].smc_count++;
106 	tsp_stats[linear_id].eret_count++;
107 
108 #if LOG_LEVEL >= LOG_LEVEL_INFO
109 	spin_lock(&console_lock);
110 	INFO("TSP: cpu 0x%lx SYSTEM_OFF request\n", read_mpidr());
111 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(),
112 	     tsp_stats[linear_id].smc_count,
113 	     tsp_stats[linear_id].eret_count);
114 	spin_unlock(&console_lock);
115 #endif
116 
117 	/* Indicate to the SPD that we have completed this request. */
118 	return set_smc_args(TSP_SYSTEM_OFF_DONE, 0, 0, 0, 0, 0, 0, 0);
119 }
120 
121 /*******************************************************************************
122  * This function performs any remaining bookkeeping in the test secure payload
123  * before the system is reset (in response to a psci SYSTEM_RESET request).
124  ******************************************************************************/
125 smc_args_t *tsp_system_reset_main(uint64_t arg0,
126 				  uint64_t arg1,
127 				  uint64_t arg2,
128 				  uint64_t arg3,
129 				  uint64_t arg4,
130 				  uint64_t arg5,
131 				  uint64_t arg6,
132 				  uint64_t arg7)
133 {
134 	uint32_t linear_id = plat_my_core_pos();
135 
136 	/* Update this cpu's statistics. */
137 	tsp_stats[linear_id].smc_count++;
138 	tsp_stats[linear_id].eret_count++;
139 
140 #if LOG_LEVEL >= LOG_LEVEL_INFO
141 	spin_lock(&console_lock);
142 	INFO("TSP: cpu 0x%lx SYSTEM_RESET request\n", read_mpidr());
143 	INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(),
144 	     tsp_stats[linear_id].smc_count,
145 	     tsp_stats[linear_id].eret_count);
146 	spin_unlock(&console_lock);
147 #endif
148 
149 	/* Indicate to the SPD that we have completed this request. */
150 	return set_smc_args(TSP_SYSTEM_RESET_DONE, 0, 0, 0, 0, 0, 0, 0);
151 }
152 
153 /*******************************************************************************
154  * TSP smc abort handler. This function is called when aborting a preempted
155  * yielding SMC request. It should cleanup all resources owned by the SMC
156  * handler such as locks or dynamically allocated memory so following SMC
157  * request are executed in a clean environment.
158  ******************************************************************************/
159 smc_args_t *tsp_abort_smc_handler(uint64_t func,
160 				  uint64_t arg1,
161 				  uint64_t arg2,
162 				  uint64_t arg3,
163 				  uint64_t arg4,
164 				  uint64_t arg5,
165 				  uint64_t arg6,
166 				  uint64_t arg7)
167 {
168 	return set_smc_args(TSP_ABORT_DONE, 0, 0, 0, 0, 0, 0, 0);
169 }
170