blob: 30bf6ffc8da66e7fca6d181fb9eb2fd4dd295944 [file] [log] [blame]
Achin Gupta7c88f3f2014-02-18 18:09:12 +00001/*
Paul Beesley1fbc97b2019-01-11 18:26:51 +00002 * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
Achin Gupta7c88f3f2014-02-18 18:09:12 +00003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Achin Gupta7c88f3f2014-02-18 18:09:12 +00005 */
6
Dan Handleyed6ff952014-05-14 17:44:19 +01007#include <platform_def.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00008
9#include <arch_helpers.h>
10#include <bl32/tsp/tsp.h>
11#include <common/bl_common.h>
12#include <common/debug.h>
13#include <lib/spinlock.h>
14#include <plat/common/platform.h>
Dan Handley4fd2f5c2014-08-04 11:41:20 +010015#include <platform_tsp.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000016
Dan Handleye2c27f52014-08-01 17:58:27 +010017#include "tsp_private.h"
Achin Gupta7c88f3f2014-02-18 18:09:12 +000018
Vikram Kanigirid8c9d262014-05-16 18:48:12 +010019
20/*******************************************************************************
Achin Gupta7c88f3f2014-02-18 18:09:12 +000021 * Lock to control access to the console
22 ******************************************************************************/
23spinlock_t console_lock;
24
25/*******************************************************************************
26 * Per cpu data structure to populate parameters for an SMC in C code and use
27 * a pointer to this structure in assembler code to populate x0-x7
28 ******************************************************************************/
Dan Handleye2712bc2014-04-10 15:37:22 +010029static tsp_args_t tsp_smc_args[PLATFORM_CORE_COUNT];
Achin Gupta7c88f3f2014-02-18 18:09:12 +000030
31/*******************************************************************************
32 * Per cpu data structure to keep track of TSP activity
33 ******************************************************************************/
Achin Gupta76717892014-05-09 11:42:56 +010034work_statistics_t tsp_stats[PLATFORM_CORE_COUNT];
Achin Gupta7c88f3f2014-02-18 18:09:12 +000035
36/*******************************************************************************
Sandrine Bailleuxbdba5e52016-06-16 14:24:26 +010037 * The TSP memory footprint starts at address BL32_BASE and ends with the
38 * linker symbol __BL32_END__. Use these addresses to compute the TSP image
39 * size.
Vikram Kanigirid8c9d262014-05-16 18:48:12 +010040 ******************************************************************************/
Antonio Nino Diazde97ff32019-01-25 13:28:38 +000041#define BL32_TOTAL_LIMIT BL32_END
Sandrine Bailleuxbdba5e52016-06-16 14:24:26 +010042#define BL32_TOTAL_SIZE (BL32_TOTAL_LIMIT - (unsigned long) BL32_BASE)
Vikram Kanigirid8c9d262014-05-16 18:48:12 +010043
Dan Handleye2712bc2014-04-10 15:37:22 +010044static tsp_args_t *set_smc_args(uint64_t arg0,
Achin Gupta7c88f3f2014-02-18 18:09:12 +000045 uint64_t arg1,
46 uint64_t arg2,
47 uint64_t arg3,
48 uint64_t arg4,
49 uint64_t arg5,
50 uint64_t arg6,
51 uint64_t arg7)
52{
Achin Gupta7c88f3f2014-02-18 18:09:12 +000053 uint32_t linear_id;
Dan Handleye2712bc2014-04-10 15:37:22 +010054 tsp_args_t *pcpu_smc_args;
Achin Gupta7c88f3f2014-02-18 18:09:12 +000055
56 /*
57 * Return to Secure Monitor by raising an SMC. The results of the
58 * service are passed as an arguments to the SMC
59 */
Soby Mathewda43b662015-07-08 21:45:46 +010060 linear_id = plat_my_core_pos();
Achin Gupta7c88f3f2014-02-18 18:09:12 +000061 pcpu_smc_args = &tsp_smc_args[linear_id];
62 write_sp_arg(pcpu_smc_args, TSP_ARG0, arg0);
63 write_sp_arg(pcpu_smc_args, TSP_ARG1, arg1);
64 write_sp_arg(pcpu_smc_args, TSP_ARG2, arg2);
65 write_sp_arg(pcpu_smc_args, TSP_ARG3, arg3);
66 write_sp_arg(pcpu_smc_args, TSP_ARG4, arg4);
67 write_sp_arg(pcpu_smc_args, TSP_ARG5, arg5);
68 write_sp_arg(pcpu_smc_args, TSP_ARG6, arg6);
69 write_sp_arg(pcpu_smc_args, TSP_ARG7, arg7);
70
71 return pcpu_smc_args;
72}
73
74/*******************************************************************************
Antonio Nino Diaze61ece02019-02-26 11:41:03 +000075 * Setup function for TSP.
76 ******************************************************************************/
77void tsp_setup(void)
78{
79 /* Perform early platform-specific setup */
80 tsp_early_platform_setup();
81
82 /*
83 * Update pointer authentication key before the MMU is enabled. It is
84 * saved in the rodata section, that can be writen before enabling the
85 * MMU. This function must be called after the console is initialized
86 * in the early platform setup.
87 */
88 bl_handle_pauth();
89
90 /* Perform late platform-specific setup */
91 tsp_plat_arch_setup();
92}
93
94/*******************************************************************************
Achin Gupta7c88f3f2014-02-18 18:09:12 +000095 * TSP main entry point where it gets the opportunity to initialize its secure
96 * state/applications. Once the state is initialized, it must return to the
Andrew Thoelke891c4ca2014-05-20 21:43:27 +010097 * SPD with a pointer to the 'tsp_vector_table' jump table.
Achin Gupta7c88f3f2014-02-18 18:09:12 +000098 ******************************************************************************/
99uint64_t tsp_main(void)
100{
Dan Handley91b624e2014-07-29 17:14:00 +0100101 NOTICE("TSP: %s\n", version_string);
102 NOTICE("TSP: %s\n", build_message);
Sandrine Bailleuxbdba5e52016-06-16 14:24:26 +0100103 INFO("TSP: Total memory base : 0x%lx\n", (unsigned long) BL32_BASE);
104 INFO("TSP: Total memory size : 0x%lx bytes\n", BL32_TOTAL_SIZE);
Dan Handley91b624e2014-07-29 17:14:00 +0100105
Soby Mathewda43b662015-07-08 21:45:46 +0100106 uint32_t linear_id = plat_my_core_pos();
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000107
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000108 /* Initialize the platform */
Dan Handley4fd2f5c2014-08-04 11:41:20 +0100109 tsp_platform_setup();
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000110
111 /* Initialize secure/applications state here */
Achin Guptabbc33f22014-05-09 13:33:42 +0100112 tsp_generic_timer_start();
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000113
114 /* Update this cpu's statistics */
115 tsp_stats[linear_id].smc_count++;
116 tsp_stats[linear_id].eret_count++;
117 tsp_stats[linear_id].cpu_on_count++;
118
Dan Handley91b624e2014-07-29 17:14:00 +0100119#if LOG_LEVEL >= LOG_LEVEL_INFO
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000120 spin_lock(&console_lock);
Soby Mathewda43b662015-07-08 21:45:46 +0100121 INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
122 read_mpidr(),
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000123 tsp_stats[linear_id].smc_count,
124 tsp_stats[linear_id].eret_count,
125 tsp_stats[linear_id].cpu_on_count);
126 spin_unlock(&console_lock);
Dan Handley91b624e2014-07-29 17:14:00 +0100127#endif
Andrew Thoelke891c4ca2014-05-20 21:43:27 +0100128 return (uint64_t) &tsp_vector_table;
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000129}
130
131/*******************************************************************************
132 * This function performs any remaining book keeping in the test secure payload
133 * after this cpu's architectural state has been setup in response to an earlier
134 * psci cpu_on request.
135 ******************************************************************************/
Dan Handleye2712bc2014-04-10 15:37:22 +0100136tsp_args_t *tsp_cpu_on_main(void)
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000137{
Soby Mathewda43b662015-07-08 21:45:46 +0100138 uint32_t linear_id = plat_my_core_pos();
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000139
Achin Guptabbc33f22014-05-09 13:33:42 +0100140 /* Initialize secure/applications state here */
141 tsp_generic_timer_start();
142
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000143 /* Update this cpu's statistics */
144 tsp_stats[linear_id].smc_count++;
145 tsp_stats[linear_id].eret_count++;
146 tsp_stats[linear_id].cpu_on_count++;
147
Dan Handley91b624e2014-07-29 17:14:00 +0100148#if LOG_LEVEL >= LOG_LEVEL_INFO
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000149 spin_lock(&console_lock);
Soby Mathewda43b662015-07-08 21:45:46 +0100150 INFO("TSP: cpu 0x%lx turned on\n", read_mpidr());
151 INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
152 read_mpidr(),
Dan Handley91b624e2014-07-29 17:14:00 +0100153 tsp_stats[linear_id].smc_count,
154 tsp_stats[linear_id].eret_count,
155 tsp_stats[linear_id].cpu_on_count);
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000156 spin_unlock(&console_lock);
Dan Handley91b624e2014-07-29 17:14:00 +0100157#endif
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000158 /* Indicate to the SPD that we have completed turned ourselves on */
159 return set_smc_args(TSP_ON_DONE, 0, 0, 0, 0, 0, 0, 0);
160}
161
162/*******************************************************************************
163 * This function performs any remaining book keeping in the test secure payload
164 * before this cpu is turned off in response to a psci cpu_off request.
165 ******************************************************************************/
Dan Handleye2712bc2014-04-10 15:37:22 +0100166tsp_args_t *tsp_cpu_off_main(uint64_t arg0,
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000167 uint64_t arg1,
168 uint64_t arg2,
169 uint64_t arg3,
170 uint64_t arg4,
171 uint64_t arg5,
172 uint64_t arg6,
173 uint64_t arg7)
174{
Soby Mathewda43b662015-07-08 21:45:46 +0100175 uint32_t linear_id = plat_my_core_pos();
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000176
Achin Guptabbc33f22014-05-09 13:33:42 +0100177 /*
178 * This cpu is being turned off, so disable the timer to prevent the
179 * secure timer interrupt from interfering with power down. A pending
180 * interrupt will be lost but we do not care as we are turning off.
181 */
182 tsp_generic_timer_stop();
183
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000184 /* Update this cpu's statistics */
185 tsp_stats[linear_id].smc_count++;
186 tsp_stats[linear_id].eret_count++;
187 tsp_stats[linear_id].cpu_off_count++;
188
Dan Handley91b624e2014-07-29 17:14:00 +0100189#if LOG_LEVEL >= LOG_LEVEL_INFO
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000190 spin_lock(&console_lock);
Soby Mathewda43b662015-07-08 21:45:46 +0100191 INFO("TSP: cpu 0x%lx off request\n", read_mpidr());
192 INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu off requests\n",
193 read_mpidr(),
Dan Handley91b624e2014-07-29 17:14:00 +0100194 tsp_stats[linear_id].smc_count,
195 tsp_stats[linear_id].eret_count,
196 tsp_stats[linear_id].cpu_off_count);
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000197 spin_unlock(&console_lock);
Dan Handley91b624e2014-07-29 17:14:00 +0100198#endif
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000199
Achin Gupta607084e2014-02-09 18:24:19 +0000200 /* Indicate to the SPD that we have completed this request */
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000201 return set_smc_args(TSP_OFF_DONE, 0, 0, 0, 0, 0, 0, 0);
202}
203
204/*******************************************************************************
205 * This function performs any book keeping in the test secure payload before
206 * this cpu's architectural state is saved in response to an earlier psci
207 * cpu_suspend request.
208 ******************************************************************************/
Soby Mathewf5121572014-09-30 11:19:51 +0100209tsp_args_t *tsp_cpu_suspend_main(uint64_t arg0,
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000210 uint64_t arg1,
211 uint64_t arg2,
212 uint64_t arg3,
213 uint64_t arg4,
214 uint64_t arg5,
215 uint64_t arg6,
216 uint64_t arg7)
217{
Soby Mathewda43b662015-07-08 21:45:46 +0100218 uint32_t linear_id = plat_my_core_pos();
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000219
Achin Guptabbc33f22014-05-09 13:33:42 +0100220 /*
221 * Save the time context and disable it to prevent the secure timer
222 * interrupt from interfering with wakeup from the suspend state.
223 */
224 tsp_generic_timer_save();
225 tsp_generic_timer_stop();
226
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000227 /* Update this cpu's statistics */
228 tsp_stats[linear_id].smc_count++;
229 tsp_stats[linear_id].eret_count++;
230 tsp_stats[linear_id].cpu_suspend_count++;
231
Dan Handley91b624e2014-07-29 17:14:00 +0100232#if LOG_LEVEL >= LOG_LEVEL_INFO
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000233 spin_lock(&console_lock);
Sandrine Bailleux8723adf2015-02-05 15:42:31 +0000234 INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n",
Soby Mathewda43b662015-07-08 21:45:46 +0100235 read_mpidr(),
Dan Handley91b624e2014-07-29 17:14:00 +0100236 tsp_stats[linear_id].smc_count,
237 tsp_stats[linear_id].eret_count,
238 tsp_stats[linear_id].cpu_suspend_count);
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000239 spin_unlock(&console_lock);
Dan Handley91b624e2014-07-29 17:14:00 +0100240#endif
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000241
Achin Gupta607084e2014-02-09 18:24:19 +0000242 /* Indicate to the SPD that we have completed this request */
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000243 return set_smc_args(TSP_SUSPEND_DONE, 0, 0, 0, 0, 0, 0, 0);
244}
245
246/*******************************************************************************
247 * This function performs any book keeping in the test secure payload after this
248 * cpu's architectural state has been restored after wakeup from an earlier psci
249 * cpu_suspend request.
250 ******************************************************************************/
Achin Gupta9a0ff9b2015-09-07 20:43:27 +0100251tsp_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl,
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000252 uint64_t arg1,
253 uint64_t arg2,
254 uint64_t arg3,
255 uint64_t arg4,
256 uint64_t arg5,
257 uint64_t arg6,
258 uint64_t arg7)
259{
Soby Mathewda43b662015-07-08 21:45:46 +0100260 uint32_t linear_id = plat_my_core_pos();
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000261
Achin Guptabbc33f22014-05-09 13:33:42 +0100262 /* Restore the generic timer context */
263 tsp_generic_timer_restore();
264
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000265 /* Update this cpu's statistics */
266 tsp_stats[linear_id].smc_count++;
267 tsp_stats[linear_id].eret_count++;
268 tsp_stats[linear_id].cpu_resume_count++;
269
Dan Handley91b624e2014-07-29 17:14:00 +0100270#if LOG_LEVEL >= LOG_LEVEL_INFO
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000271 spin_lock(&console_lock);
Masahiro Yamadae93a0f42018-02-02 15:09:36 +0900272 INFO("TSP: cpu 0x%lx resumed. maximum off power level %lld\n",
Achin Gupta9a0ff9b2015-09-07 20:43:27 +0100273 read_mpidr(), max_off_pwrlvl);
Sandrine Bailleux8723adf2015-02-05 15:42:31 +0000274 INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n",
Soby Mathewda43b662015-07-08 21:45:46 +0100275 read_mpidr(),
Dan Handley91b624e2014-07-29 17:14:00 +0100276 tsp_stats[linear_id].smc_count,
277 tsp_stats[linear_id].eret_count,
278 tsp_stats[linear_id].cpu_suspend_count);
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000279 spin_unlock(&console_lock);
Dan Handley91b624e2014-07-29 17:14:00 +0100280#endif
Achin Gupta607084e2014-02-09 18:24:19 +0000281 /* Indicate to the SPD that we have completed this request */
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000282 return set_smc_args(TSP_RESUME_DONE, 0, 0, 0, 0, 0, 0, 0);
283}
284
285/*******************************************************************************
Juan Castillo4dc4a472014-08-12 11:17:06 +0100286 * This function performs any remaining bookkeeping in the test secure payload
287 * before the system is switched off (in response to a psci SYSTEM_OFF request)
288 ******************************************************************************/
289tsp_args_t *tsp_system_off_main(uint64_t arg0,
290 uint64_t arg1,
291 uint64_t arg2,
292 uint64_t arg3,
293 uint64_t arg4,
294 uint64_t arg5,
295 uint64_t arg6,
296 uint64_t arg7)
297{
Soby Mathewda43b662015-07-08 21:45:46 +0100298 uint32_t linear_id = plat_my_core_pos();
Juan Castillo4dc4a472014-08-12 11:17:06 +0100299
300 /* Update this cpu's statistics */
301 tsp_stats[linear_id].smc_count++;
302 tsp_stats[linear_id].eret_count++;
303
304#if LOG_LEVEL >= LOG_LEVEL_INFO
305 spin_lock(&console_lock);
Soby Mathewda43b662015-07-08 21:45:46 +0100306 INFO("TSP: cpu 0x%lx SYSTEM_OFF request\n", read_mpidr());
307 INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(),
Juan Castillo4dc4a472014-08-12 11:17:06 +0100308 tsp_stats[linear_id].smc_count,
309 tsp_stats[linear_id].eret_count);
310 spin_unlock(&console_lock);
311#endif
312
313 /* Indicate to the SPD that we have completed this request */
314 return set_smc_args(TSP_SYSTEM_OFF_DONE, 0, 0, 0, 0, 0, 0, 0);
315}
316
317/*******************************************************************************
318 * This function performs any remaining bookkeeping in the test secure payload
319 * before the system is reset (in response to a psci SYSTEM_RESET request)
320 ******************************************************************************/
321tsp_args_t *tsp_system_reset_main(uint64_t arg0,
322 uint64_t arg1,
323 uint64_t arg2,
324 uint64_t arg3,
325 uint64_t arg4,
326 uint64_t arg5,
327 uint64_t arg6,
328 uint64_t arg7)
329{
Soby Mathewda43b662015-07-08 21:45:46 +0100330 uint32_t linear_id = plat_my_core_pos();
Juan Castillo4dc4a472014-08-12 11:17:06 +0100331
332 /* Update this cpu's statistics */
333 tsp_stats[linear_id].smc_count++;
334 tsp_stats[linear_id].eret_count++;
335
336#if LOG_LEVEL >= LOG_LEVEL_INFO
337 spin_lock(&console_lock);
Soby Mathewda43b662015-07-08 21:45:46 +0100338 INFO("TSP: cpu 0x%lx SYSTEM_RESET request\n", read_mpidr());
339 INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(),
Juan Castillo4dc4a472014-08-12 11:17:06 +0100340 tsp_stats[linear_id].smc_count,
341 tsp_stats[linear_id].eret_count);
342 spin_unlock(&console_lock);
343#endif
344
345 /* Indicate to the SPD that we have completed this request */
346 return set_smc_args(TSP_SYSTEM_RESET_DONE, 0, 0, 0, 0, 0, 0, 0);
347}
348
349/*******************************************************************************
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000350 * TSP fast smc handler. The secure monitor jumps to this function by
351 * doing the ERET after populating X0-X7 registers. The arguments are received
352 * in the function arguments in order. Once the service is rendered, this
Soby Mathew9f71f702014-05-09 20:49:17 +0100353 * function returns to Secure Monitor by raising SMC.
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000354 ******************************************************************************/
Soby Mathew9f71f702014-05-09 20:49:17 +0100355tsp_args_t *tsp_smc_handler(uint64_t func,
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000356 uint64_t arg1,
357 uint64_t arg2,
358 uint64_t arg3,
359 uint64_t arg4,
360 uint64_t arg5,
361 uint64_t arg6,
362 uint64_t arg7)
363{
Achin Gupta916a2c12014-02-09 23:11:46 +0000364 uint64_t results[2];
365 uint64_t service_args[2];
Soby Mathewda43b662015-07-08 21:45:46 +0100366 uint32_t linear_id = plat_my_core_pos();
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000367
Achin Gupta916a2c12014-02-09 23:11:46 +0000368 /* Update this cpu's statistics */
369 tsp_stats[linear_id].smc_count++;
370 tsp_stats[linear_id].eret_count++;
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000371
Masahiro Yamadae93a0f42018-02-02 15:09:36 +0900372 INFO("TSP: cpu 0x%lx received %s smc 0x%llx\n", read_mpidr(),
David Cunado28f69ab2017-04-05 11:34:03 +0100373 ((func >> 31) & 1) == 1 ? "fast" : "yielding",
Dan Handley91b624e2014-07-29 17:14:00 +0100374 func);
Soby Mathewda43b662015-07-08 21:45:46 +0100375 INFO("TSP: cpu 0x%lx: %d smcs, %d erets\n", read_mpidr(),
Dan Handley91b624e2014-07-29 17:14:00 +0100376 tsp_stats[linear_id].smc_count,
377 tsp_stats[linear_id].eret_count);
Achin Gupta916a2c12014-02-09 23:11:46 +0000378
379 /* Render secure services and obtain results here */
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000380 results[0] = arg1;
381 results[1] = arg2;
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000382
383 /*
384 * Request a service back from dispatcher/secure monitor. This call
Paul Beesley1fbc97b2019-01-11 18:26:51 +0000385 * return and thereafter resume execution
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000386 */
387 tsp_get_magic(service_args);
388
389 /* Determine the function to perform based on the function ID */
Soby Mathew9f71f702014-05-09 20:49:17 +0100390 switch (TSP_BARE_FID(func)) {
391 case TSP_ADD:
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000392 results[0] += service_args[0];
393 results[1] += service_args[1];
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000394 break;
Soby Mathew9f71f702014-05-09 20:49:17 +0100395 case TSP_SUB:
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000396 results[0] -= service_args[0];
397 results[1] -= service_args[1];
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000398 break;
Soby Mathew9f71f702014-05-09 20:49:17 +0100399 case TSP_MUL:
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000400 results[0] *= service_args[0];
401 results[1] *= service_args[1];
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000402 break;
Soby Mathew9f71f702014-05-09 20:49:17 +0100403 case TSP_DIV:
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000404 results[0] /= service_args[0] ? service_args[0] : 1;
405 results[1] /= service_args[1] ? service_args[1] : 1;
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000406 break;
407 default:
408 break;
409 }
410
Soby Mathew9f71f702014-05-09 20:49:17 +0100411 return set_smc_args(func, 0,
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000412 results[0],
413 results[1],
Soby Mathew9f71f702014-05-09 20:49:17 +0100414 0, 0, 0, 0);
Achin Gupta7c88f3f2014-02-18 18:09:12 +0000415}
416
Douglas Raillardf2129652016-11-24 15:43:19 +0000417/*******************************************************************************
Paul Beesley1fbc97b2019-01-11 18:26:51 +0000418 * TSP smc abort handler. This function is called when aborting a preempted
David Cunado28f69ab2017-04-05 11:34:03 +0100419 * yielding SMC request. It should cleanup all resources owned by the SMC
Douglas Raillardf2129652016-11-24 15:43:19 +0000420 * handler such as locks or dynamically allocated memory so following SMC
421 * request are executed in a clean environment.
422 ******************************************************************************/
423tsp_args_t *tsp_abort_smc_handler(uint64_t func,
424 uint64_t arg1,
425 uint64_t arg2,
426 uint64_t arg3,
427 uint64_t arg4,
428 uint64_t arg5,
429 uint64_t arg6,
430 uint64_t arg7)
431{
432 return set_smc_args(TSP_ABORT_DONE, 0, 0, 0, 0, 0, 0, 0);
433}