blob: 028421e6d92b18796cfeb6492e8bf0b9b4dd4e6c [file] [log] [blame]
Achin Gupta6b4ec242021-10-04 20:13:36 +01001/*
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 ******************************************************************************/
26spinlock_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 ******************************************************************************/
32static smc_args_t tsp_smc_args[PLATFORM_CORE_COUNT];
33
34/*******************************************************************************
35 * Per cpu data structure to keep track of TSP activity
36 ******************************************************************************/
37work_statistics_t tsp_stats[PLATFORM_CORE_COUNT];
38
39smc_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 ******************************************************************************/
72void 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 ******************************************************************************/
93smc_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 ******************************************************************************/
125smc_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 ******************************************************************************/
159smc_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}