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