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 * 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
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)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 ******************************************************************************/
tsp_setup(void)67 void tsp_setup(void)
68 {
69 /* Perform early platform-specific setup. */
70 tsp_early_platform_setup();
71
72 /* Perform late platform-specific setup. */
73 tsp_plat_arch_setup();
74
75 #if ENABLE_PAUTH
76 /*
77 * Assert that the ARMv8.3-PAuth registers are present or an access
78 * fault will be triggered when they are being saved or restored.
79 */
80 assert(is_armv8_3_pauth_present());
81 #endif /* ENABLE_PAUTH */
82 }
83
84 /*******************************************************************************
85 * This function performs any remaining bookkeeping in the test secure payload
86 * before the system is switched off (in response to a psci SYSTEM_OFF request).
87 ******************************************************************************/
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)88 smc_args_t *tsp_system_off_main(uint64_t arg0,
89 uint64_t arg1,
90 uint64_t arg2,
91 uint64_t arg3,
92 uint64_t arg4,
93 uint64_t arg5,
94 uint64_t arg6,
95 uint64_t arg7)
96 {
97 uint32_t linear_id = plat_my_core_pos();
98
99 /* Update this cpu's statistics. */
100 tsp_stats[linear_id].smc_count++;
101 tsp_stats[linear_id].eret_count++;
102
103 INFO("TSP: cpu 0x%lx SYSTEM_OFF request\n", read_mpidr());
104 INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(),
105 tsp_stats[linear_id].smc_count,
106 tsp_stats[linear_id].eret_count);
107
108 /* Indicate to the SPD that we have completed this request. */
109 return set_smc_args(TSP_SYSTEM_OFF_DONE, 0, 0, 0, 0, 0, 0, 0);
110 }
111
112 /*******************************************************************************
113 * This function performs any remaining bookkeeping in the test secure payload
114 * before the system is reset (in response to a psci SYSTEM_RESET request).
115 ******************************************************************************/
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)116 smc_args_t *tsp_system_reset_main(uint64_t arg0,
117 uint64_t arg1,
118 uint64_t arg2,
119 uint64_t arg3,
120 uint64_t arg4,
121 uint64_t arg5,
122 uint64_t arg6,
123 uint64_t arg7)
124 {
125 uint32_t linear_id = plat_my_core_pos();
126
127 /* Update this cpu's statistics. */
128 tsp_stats[linear_id].smc_count++;
129 tsp_stats[linear_id].eret_count++;
130
131 INFO("TSP: cpu 0x%lx SYSTEM_RESET request\n", read_mpidr());
132 INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(),
133 tsp_stats[linear_id].smc_count,
134 tsp_stats[linear_id].eret_count);
135
136 /* Indicate to the SPD that we have completed this request. */
137 return set_smc_args(TSP_SYSTEM_RESET_DONE, 0, 0, 0, 0, 0, 0, 0);
138 }
139
140 /*******************************************************************************
141 * TSP smc abort handler. This function is called when aborting a preempted
142 * yielding SMC request. It should cleanup all resources owned by the SMC
143 * handler such as locks or dynamically allocated memory so following SMC
144 * request are executed in a clean environment.
145 ******************************************************************************/
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)146 smc_args_t *tsp_abort_smc_handler(uint64_t func,
147 uint64_t arg1,
148 uint64_t arg2,
149 uint64_t arg3,
150 uint64_t arg4,
151 uint64_t arg5,
152 uint64_t arg6,
153 uint64_t arg7)
154 {
155 return set_smc_args(TSP_ABORT_DONE, 0, 0, 0, 0, 0, 0, 0);
156 }
157