17c88f3f6SAchin Gupta /* 28aabea33SPaul Beesley * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. 37c88f3f6SAchin Gupta * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 57c88f3f6SAchin Gupta */ 67c88f3f6SAchin Gupta 75f0cdb05SDan Handley #include <platform_def.h> 809d40e0eSAntonio Nino Diaz 909d40e0eSAntonio Nino Diaz #include <arch_helpers.h> 1009d40e0eSAntonio Nino Diaz #include <bl32/tsp/tsp.h> 1109d40e0eSAntonio Nino Diaz #include <common/bl_common.h> 1209d40e0eSAntonio Nino Diaz #include <common/debug.h> 1309d40e0eSAntonio Nino Diaz #include <lib/spinlock.h> 1409d40e0eSAntonio Nino Diaz #include <plat/common/platform.h> 155a06bb7eSDan Handley #include <platform_tsp.h> 1609d40e0eSAntonio Nino Diaz 17da0af78aSDan Handley #include "tsp_private.h" 187c88f3f6SAchin Gupta 196871c5d3SVikram Kanigiri 206871c5d3SVikram Kanigiri /******************************************************************************* 217c88f3f6SAchin Gupta * Lock to control access to the console 227c88f3f6SAchin Gupta ******************************************************************************/ 237c88f3f6SAchin Gupta spinlock_t console_lock; 247c88f3f6SAchin Gupta 257c88f3f6SAchin Gupta /******************************************************************************* 267c88f3f6SAchin Gupta * Per cpu data structure to populate parameters for an SMC in C code and use 277c88f3f6SAchin Gupta * a pointer to this structure in assembler code to populate x0-x7 287c88f3f6SAchin Gupta ******************************************************************************/ 29fb037bfbSDan Handley static tsp_args_t tsp_smc_args[PLATFORM_CORE_COUNT]; 307c88f3f6SAchin Gupta 317c88f3f6SAchin Gupta /******************************************************************************* 327c88f3f6SAchin Gupta * Per cpu data structure to keep track of TSP activity 337c88f3f6SAchin Gupta ******************************************************************************/ 346cf89021SAchin Gupta work_statistics_t tsp_stats[PLATFORM_CORE_COUNT]; 357c88f3f6SAchin Gupta 367c88f3f6SAchin Gupta /******************************************************************************* 37a604623cSSandrine Bailleux * The TSP memory footprint starts at address BL32_BASE and ends with the 38a604623cSSandrine Bailleux * linker symbol __BL32_END__. Use these addresses to compute the TSP image 39a604623cSSandrine Bailleux * size. 406871c5d3SVikram Kanigiri ******************************************************************************/ 41f6605337SAntonio Nino Diaz #define BL32_TOTAL_LIMIT BL32_END 42a604623cSSandrine Bailleux #define BL32_TOTAL_SIZE (BL32_TOTAL_LIMIT - (unsigned long) BL32_BASE) 436871c5d3SVikram Kanigiri 44fb037bfbSDan Handley static tsp_args_t *set_smc_args(uint64_t arg0, 457c88f3f6SAchin Gupta uint64_t arg1, 467c88f3f6SAchin Gupta uint64_t arg2, 477c88f3f6SAchin Gupta uint64_t arg3, 487c88f3f6SAchin Gupta uint64_t arg4, 497c88f3f6SAchin Gupta uint64_t arg5, 507c88f3f6SAchin Gupta uint64_t arg6, 517c88f3f6SAchin Gupta uint64_t arg7) 527c88f3f6SAchin Gupta { 537c88f3f6SAchin Gupta uint32_t linear_id; 54fb037bfbSDan Handley tsp_args_t *pcpu_smc_args; 557c88f3f6SAchin Gupta 567c88f3f6SAchin Gupta /* 577c88f3f6SAchin Gupta * Return to Secure Monitor by raising an SMC. The results of the 587c88f3f6SAchin Gupta * service are passed as an arguments to the SMC 597c88f3f6SAchin Gupta */ 60fd650ff6SSoby Mathew linear_id = plat_my_core_pos(); 617c88f3f6SAchin Gupta pcpu_smc_args = &tsp_smc_args[linear_id]; 627c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG0, arg0); 637c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG1, arg1); 647c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG2, arg2); 657c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG3, arg3); 667c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG4, arg4); 677c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG5, arg5); 687c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG6, arg6); 697c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG7, arg7); 707c88f3f6SAchin Gupta 717c88f3f6SAchin Gupta return pcpu_smc_args; 727c88f3f6SAchin Gupta } 737c88f3f6SAchin Gupta 747c88f3f6SAchin Gupta /******************************************************************************* 75*67b6ff9fSAntonio Nino Diaz * Setup function for TSP. 76*67b6ff9fSAntonio Nino Diaz ******************************************************************************/ 77*67b6ff9fSAntonio Nino Diaz void tsp_setup(void) 78*67b6ff9fSAntonio Nino Diaz { 79*67b6ff9fSAntonio Nino Diaz /* Perform early platform-specific setup */ 80*67b6ff9fSAntonio Nino Diaz tsp_early_platform_setup(); 81*67b6ff9fSAntonio Nino Diaz 82*67b6ff9fSAntonio Nino Diaz /* 83*67b6ff9fSAntonio Nino Diaz * Update pointer authentication key before the MMU is enabled. It is 84*67b6ff9fSAntonio Nino Diaz * saved in the rodata section, that can be writen before enabling the 85*67b6ff9fSAntonio Nino Diaz * MMU. This function must be called after the console is initialized 86*67b6ff9fSAntonio Nino Diaz * in the early platform setup. 87*67b6ff9fSAntonio Nino Diaz */ 88*67b6ff9fSAntonio Nino Diaz bl_handle_pauth(); 89*67b6ff9fSAntonio Nino Diaz 90*67b6ff9fSAntonio Nino Diaz /* Perform late platform-specific setup */ 91*67b6ff9fSAntonio Nino Diaz tsp_plat_arch_setup(); 92*67b6ff9fSAntonio Nino Diaz } 93*67b6ff9fSAntonio Nino Diaz 94*67b6ff9fSAntonio Nino Diaz /******************************************************************************* 957c88f3f6SAchin Gupta * TSP main entry point where it gets the opportunity to initialize its secure 967c88f3f6SAchin Gupta * state/applications. Once the state is initialized, it must return to the 97399fb08fSAndrew Thoelke * SPD with a pointer to the 'tsp_vector_table' jump table. 987c88f3f6SAchin Gupta ******************************************************************************/ 997c88f3f6SAchin Gupta uint64_t tsp_main(void) 1007c88f3f6SAchin Gupta { 1016ad2e461SDan Handley NOTICE("TSP: %s\n", version_string); 1026ad2e461SDan Handley NOTICE("TSP: %s\n", build_message); 103a604623cSSandrine Bailleux INFO("TSP: Total memory base : 0x%lx\n", (unsigned long) BL32_BASE); 104a604623cSSandrine Bailleux INFO("TSP: Total memory size : 0x%lx bytes\n", BL32_TOTAL_SIZE); 1056ad2e461SDan Handley 106fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 1077c88f3f6SAchin Gupta 1087c88f3f6SAchin Gupta /* Initialize the platform */ 1095a06bb7eSDan Handley tsp_platform_setup(); 1107c88f3f6SAchin Gupta 1117c88f3f6SAchin Gupta /* Initialize secure/applications state here */ 112a20a81e5SAchin Gupta tsp_generic_timer_start(); 1137c88f3f6SAchin Gupta 1147c88f3f6SAchin Gupta /* Update this cpu's statistics */ 1157c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count++; 1167c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count++; 1177c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_on_count++; 1187c88f3f6SAchin Gupta 1196ad2e461SDan Handley #if LOG_LEVEL >= LOG_LEVEL_INFO 1207c88f3f6SAchin Gupta spin_lock(&console_lock); 121fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n", 122fd650ff6SSoby Mathew read_mpidr(), 1237c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count, 1247c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count, 1257c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_on_count); 1267c88f3f6SAchin Gupta spin_unlock(&console_lock); 1276ad2e461SDan Handley #endif 128399fb08fSAndrew Thoelke return (uint64_t) &tsp_vector_table; 1297c88f3f6SAchin Gupta } 1307c88f3f6SAchin Gupta 1317c88f3f6SAchin Gupta /******************************************************************************* 1327c88f3f6SAchin Gupta * This function performs any remaining book keeping in the test secure payload 1337c88f3f6SAchin Gupta * after this cpu's architectural state has been setup in response to an earlier 1347c88f3f6SAchin Gupta * psci cpu_on request. 1357c88f3f6SAchin Gupta ******************************************************************************/ 136fb037bfbSDan Handley tsp_args_t *tsp_cpu_on_main(void) 1377c88f3f6SAchin Gupta { 138fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 1397c88f3f6SAchin Gupta 140a20a81e5SAchin Gupta /* Initialize secure/applications state here */ 141a20a81e5SAchin Gupta tsp_generic_timer_start(); 142a20a81e5SAchin Gupta 1437c88f3f6SAchin Gupta /* Update this cpu's statistics */ 1447c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count++; 1457c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count++; 1467c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_on_count++; 1477c88f3f6SAchin Gupta 1486ad2e461SDan Handley #if LOG_LEVEL >= LOG_LEVEL_INFO 1497c88f3f6SAchin Gupta spin_lock(&console_lock); 150fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx turned on\n", read_mpidr()); 151fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n", 152fd650ff6SSoby Mathew read_mpidr(), 1537c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count, 1547c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count, 1557c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_on_count); 1567c88f3f6SAchin Gupta spin_unlock(&console_lock); 1576ad2e461SDan Handley #endif 1587c88f3f6SAchin Gupta /* Indicate to the SPD that we have completed turned ourselves on */ 1597c88f3f6SAchin Gupta return set_smc_args(TSP_ON_DONE, 0, 0, 0, 0, 0, 0, 0); 1607c88f3f6SAchin Gupta } 1617c88f3f6SAchin Gupta 1627c88f3f6SAchin Gupta /******************************************************************************* 1637c88f3f6SAchin Gupta * This function performs any remaining book keeping in the test secure payload 1647c88f3f6SAchin Gupta * before this cpu is turned off in response to a psci cpu_off request. 1657c88f3f6SAchin Gupta ******************************************************************************/ 166fb037bfbSDan Handley tsp_args_t *tsp_cpu_off_main(uint64_t arg0, 1677c88f3f6SAchin Gupta uint64_t arg1, 1687c88f3f6SAchin Gupta uint64_t arg2, 1697c88f3f6SAchin Gupta uint64_t arg3, 1707c88f3f6SAchin Gupta uint64_t arg4, 1717c88f3f6SAchin Gupta uint64_t arg5, 1727c88f3f6SAchin Gupta uint64_t arg6, 1737c88f3f6SAchin Gupta uint64_t arg7) 1747c88f3f6SAchin Gupta { 175fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 1767c88f3f6SAchin Gupta 177a20a81e5SAchin Gupta /* 178a20a81e5SAchin Gupta * This cpu is being turned off, so disable the timer to prevent the 179a20a81e5SAchin Gupta * secure timer interrupt from interfering with power down. A pending 180a20a81e5SAchin Gupta * interrupt will be lost but we do not care as we are turning off. 181a20a81e5SAchin Gupta */ 182a20a81e5SAchin Gupta tsp_generic_timer_stop(); 183a20a81e5SAchin Gupta 1847c88f3f6SAchin Gupta /* Update this cpu's statistics */ 1857c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count++; 1867c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count++; 1877c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_off_count++; 1887c88f3f6SAchin Gupta 1896ad2e461SDan Handley #if LOG_LEVEL >= LOG_LEVEL_INFO 1907c88f3f6SAchin Gupta spin_lock(&console_lock); 191fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx off request\n", read_mpidr()); 192fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu off requests\n", 193fd650ff6SSoby Mathew read_mpidr(), 1947c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count, 1957c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count, 1967c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_off_count); 1977c88f3f6SAchin Gupta spin_unlock(&console_lock); 1986ad2e461SDan Handley #endif 1997c88f3f6SAchin Gupta 200607084eeSAchin Gupta /* Indicate to the SPD that we have completed this request */ 2017c88f3f6SAchin Gupta return set_smc_args(TSP_OFF_DONE, 0, 0, 0, 0, 0, 0, 0); 2027c88f3f6SAchin Gupta } 2037c88f3f6SAchin Gupta 2047c88f3f6SAchin Gupta /******************************************************************************* 2057c88f3f6SAchin Gupta * This function performs any book keeping in the test secure payload before 2067c88f3f6SAchin Gupta * this cpu's architectural state is saved in response to an earlier psci 2077c88f3f6SAchin Gupta * cpu_suspend request. 2087c88f3f6SAchin Gupta ******************************************************************************/ 20931244d74SSoby Mathew tsp_args_t *tsp_cpu_suspend_main(uint64_t arg0, 2107c88f3f6SAchin Gupta uint64_t arg1, 2117c88f3f6SAchin Gupta uint64_t arg2, 2127c88f3f6SAchin Gupta uint64_t arg3, 2137c88f3f6SAchin Gupta uint64_t arg4, 2147c88f3f6SAchin Gupta uint64_t arg5, 2157c88f3f6SAchin Gupta uint64_t arg6, 2167c88f3f6SAchin Gupta uint64_t arg7) 2177c88f3f6SAchin Gupta { 218fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 2197c88f3f6SAchin Gupta 220a20a81e5SAchin Gupta /* 221a20a81e5SAchin Gupta * Save the time context and disable it to prevent the secure timer 222a20a81e5SAchin Gupta * interrupt from interfering with wakeup from the suspend state. 223a20a81e5SAchin Gupta */ 224a20a81e5SAchin Gupta tsp_generic_timer_save(); 225a20a81e5SAchin Gupta tsp_generic_timer_stop(); 226a20a81e5SAchin Gupta 2277c88f3f6SAchin Gupta /* Update this cpu's statistics */ 2287c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count++; 2297c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count++; 2307c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_suspend_count++; 2317c88f3f6SAchin Gupta 2326ad2e461SDan Handley #if LOG_LEVEL >= LOG_LEVEL_INFO 2337c88f3f6SAchin Gupta spin_lock(&console_lock); 234dad25049SSandrine Bailleux INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n", 235fd650ff6SSoby Mathew read_mpidr(), 2367c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count, 2377c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count, 2387c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_suspend_count); 2397c88f3f6SAchin Gupta spin_unlock(&console_lock); 2406ad2e461SDan Handley #endif 2417c88f3f6SAchin Gupta 242607084eeSAchin Gupta /* Indicate to the SPD that we have completed this request */ 2437c88f3f6SAchin Gupta return set_smc_args(TSP_SUSPEND_DONE, 0, 0, 0, 0, 0, 0, 0); 2447c88f3f6SAchin Gupta } 2457c88f3f6SAchin Gupta 2467c88f3f6SAchin Gupta /******************************************************************************* 2477c88f3f6SAchin Gupta * This function performs any book keeping in the test secure payload after this 2487c88f3f6SAchin Gupta * cpu's architectural state has been restored after wakeup from an earlier psci 2497c88f3f6SAchin Gupta * cpu_suspend request. 2507c88f3f6SAchin Gupta ******************************************************************************/ 251f1054c93SAchin Gupta tsp_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl, 2527c88f3f6SAchin Gupta uint64_t arg1, 2537c88f3f6SAchin Gupta uint64_t arg2, 2547c88f3f6SAchin Gupta uint64_t arg3, 2557c88f3f6SAchin Gupta uint64_t arg4, 2567c88f3f6SAchin Gupta uint64_t arg5, 2577c88f3f6SAchin Gupta uint64_t arg6, 2587c88f3f6SAchin Gupta uint64_t arg7) 2597c88f3f6SAchin Gupta { 260fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 2617c88f3f6SAchin Gupta 262a20a81e5SAchin Gupta /* Restore the generic timer context */ 263a20a81e5SAchin Gupta tsp_generic_timer_restore(); 264a20a81e5SAchin Gupta 2657c88f3f6SAchin Gupta /* Update this cpu's statistics */ 2667c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count++; 2677c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count++; 2687c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_resume_count++; 2697c88f3f6SAchin Gupta 2706ad2e461SDan Handley #if LOG_LEVEL >= LOG_LEVEL_INFO 2717c88f3f6SAchin Gupta spin_lock(&console_lock); 2720a2d5b43SMasahiro Yamada INFO("TSP: cpu 0x%lx resumed. maximum off power level %lld\n", 273f1054c93SAchin Gupta read_mpidr(), max_off_pwrlvl); 274dad25049SSandrine Bailleux INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n", 275fd650ff6SSoby Mathew read_mpidr(), 2767c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count, 2777c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count, 2787c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_suspend_count); 2797c88f3f6SAchin Gupta spin_unlock(&console_lock); 2806ad2e461SDan Handley #endif 281607084eeSAchin Gupta /* Indicate to the SPD that we have completed this request */ 2827c88f3f6SAchin Gupta return set_smc_args(TSP_RESUME_DONE, 0, 0, 0, 0, 0, 0, 0); 2837c88f3f6SAchin Gupta } 2847c88f3f6SAchin Gupta 2857c88f3f6SAchin Gupta /******************************************************************************* 286d5f13093SJuan Castillo * This function performs any remaining bookkeeping in the test secure payload 287d5f13093SJuan Castillo * before the system is switched off (in response to a psci SYSTEM_OFF request) 288d5f13093SJuan Castillo ******************************************************************************/ 289d5f13093SJuan Castillo tsp_args_t *tsp_system_off_main(uint64_t arg0, 290d5f13093SJuan Castillo uint64_t arg1, 291d5f13093SJuan Castillo uint64_t arg2, 292d5f13093SJuan Castillo uint64_t arg3, 293d5f13093SJuan Castillo uint64_t arg4, 294d5f13093SJuan Castillo uint64_t arg5, 295d5f13093SJuan Castillo uint64_t arg6, 296d5f13093SJuan Castillo uint64_t arg7) 297d5f13093SJuan Castillo { 298fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 299d5f13093SJuan Castillo 300d5f13093SJuan Castillo /* Update this cpu's statistics */ 301d5f13093SJuan Castillo tsp_stats[linear_id].smc_count++; 302d5f13093SJuan Castillo tsp_stats[linear_id].eret_count++; 303d5f13093SJuan Castillo 304d5f13093SJuan Castillo #if LOG_LEVEL >= LOG_LEVEL_INFO 305d5f13093SJuan Castillo spin_lock(&console_lock); 306fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx SYSTEM_OFF request\n", read_mpidr()); 307fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(), 308d5f13093SJuan Castillo tsp_stats[linear_id].smc_count, 309d5f13093SJuan Castillo tsp_stats[linear_id].eret_count); 310d5f13093SJuan Castillo spin_unlock(&console_lock); 311d5f13093SJuan Castillo #endif 312d5f13093SJuan Castillo 313d5f13093SJuan Castillo /* Indicate to the SPD that we have completed this request */ 314d5f13093SJuan Castillo return set_smc_args(TSP_SYSTEM_OFF_DONE, 0, 0, 0, 0, 0, 0, 0); 315d5f13093SJuan Castillo } 316d5f13093SJuan Castillo 317d5f13093SJuan Castillo /******************************************************************************* 318d5f13093SJuan Castillo * This function performs any remaining bookkeeping in the test secure payload 319d5f13093SJuan Castillo * before the system is reset (in response to a psci SYSTEM_RESET request) 320d5f13093SJuan Castillo ******************************************************************************/ 321d5f13093SJuan Castillo tsp_args_t *tsp_system_reset_main(uint64_t arg0, 322d5f13093SJuan Castillo uint64_t arg1, 323d5f13093SJuan Castillo uint64_t arg2, 324d5f13093SJuan Castillo uint64_t arg3, 325d5f13093SJuan Castillo uint64_t arg4, 326d5f13093SJuan Castillo uint64_t arg5, 327d5f13093SJuan Castillo uint64_t arg6, 328d5f13093SJuan Castillo uint64_t arg7) 329d5f13093SJuan Castillo { 330fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 331d5f13093SJuan Castillo 332d5f13093SJuan Castillo /* Update this cpu's statistics */ 333d5f13093SJuan Castillo tsp_stats[linear_id].smc_count++; 334d5f13093SJuan Castillo tsp_stats[linear_id].eret_count++; 335d5f13093SJuan Castillo 336d5f13093SJuan Castillo #if LOG_LEVEL >= LOG_LEVEL_INFO 337d5f13093SJuan Castillo spin_lock(&console_lock); 338fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx SYSTEM_RESET request\n", read_mpidr()); 339fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(), 340d5f13093SJuan Castillo tsp_stats[linear_id].smc_count, 341d5f13093SJuan Castillo tsp_stats[linear_id].eret_count); 342d5f13093SJuan Castillo spin_unlock(&console_lock); 343d5f13093SJuan Castillo #endif 344d5f13093SJuan Castillo 345d5f13093SJuan Castillo /* Indicate to the SPD that we have completed this request */ 346d5f13093SJuan Castillo return set_smc_args(TSP_SYSTEM_RESET_DONE, 0, 0, 0, 0, 0, 0, 0); 347d5f13093SJuan Castillo } 348d5f13093SJuan Castillo 349d5f13093SJuan Castillo /******************************************************************************* 3507c88f3f6SAchin Gupta * TSP fast smc handler. The secure monitor jumps to this function by 3517c88f3f6SAchin Gupta * doing the ERET after populating X0-X7 registers. The arguments are received 3527c88f3f6SAchin Gupta * in the function arguments in order. Once the service is rendered, this 353239b04faSSoby Mathew * function returns to Secure Monitor by raising SMC. 3547c88f3f6SAchin Gupta ******************************************************************************/ 355239b04faSSoby Mathew tsp_args_t *tsp_smc_handler(uint64_t func, 3567c88f3f6SAchin Gupta uint64_t arg1, 3577c88f3f6SAchin Gupta uint64_t arg2, 3587c88f3f6SAchin Gupta uint64_t arg3, 3597c88f3f6SAchin Gupta uint64_t arg4, 3607c88f3f6SAchin Gupta uint64_t arg5, 3617c88f3f6SAchin Gupta uint64_t arg6, 3627c88f3f6SAchin Gupta uint64_t arg7) 3637c88f3f6SAchin Gupta { 364916a2c1eSAchin Gupta uint64_t results[2]; 365916a2c1eSAchin Gupta uint64_t service_args[2]; 366fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 3677c88f3f6SAchin Gupta 368916a2c1eSAchin Gupta /* Update this cpu's statistics */ 369916a2c1eSAchin Gupta tsp_stats[linear_id].smc_count++; 370916a2c1eSAchin Gupta tsp_stats[linear_id].eret_count++; 3717c88f3f6SAchin Gupta 3720a2d5b43SMasahiro Yamada INFO("TSP: cpu 0x%lx received %s smc 0x%llx\n", read_mpidr(), 37316292f54SDavid Cunado ((func >> 31) & 1) == 1 ? "fast" : "yielding", 3746ad2e461SDan Handley func); 375fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx: %d smcs, %d erets\n", read_mpidr(), 376916a2c1eSAchin Gupta tsp_stats[linear_id].smc_count, 377916a2c1eSAchin Gupta tsp_stats[linear_id].eret_count); 378916a2c1eSAchin Gupta 379916a2c1eSAchin Gupta /* Render secure services and obtain results here */ 3807c88f3f6SAchin Gupta results[0] = arg1; 3817c88f3f6SAchin Gupta results[1] = arg2; 3827c88f3f6SAchin Gupta 3837c88f3f6SAchin Gupta /* 3847c88f3f6SAchin Gupta * Request a service back from dispatcher/secure monitor. This call 3858aabea33SPaul Beesley * return and thereafter resume execution 3867c88f3f6SAchin Gupta */ 3877c88f3f6SAchin Gupta tsp_get_magic(service_args); 3887c88f3f6SAchin Gupta 3897c88f3f6SAchin Gupta /* Determine the function to perform based on the function ID */ 390239b04faSSoby Mathew switch (TSP_BARE_FID(func)) { 391239b04faSSoby Mathew case TSP_ADD: 3927c88f3f6SAchin Gupta results[0] += service_args[0]; 3937c88f3f6SAchin Gupta results[1] += service_args[1]; 3947c88f3f6SAchin Gupta break; 395239b04faSSoby Mathew case TSP_SUB: 3967c88f3f6SAchin Gupta results[0] -= service_args[0]; 3977c88f3f6SAchin Gupta results[1] -= service_args[1]; 3987c88f3f6SAchin Gupta break; 399239b04faSSoby Mathew case TSP_MUL: 4007c88f3f6SAchin Gupta results[0] *= service_args[0]; 4017c88f3f6SAchin Gupta results[1] *= service_args[1]; 4027c88f3f6SAchin Gupta break; 403239b04faSSoby Mathew case TSP_DIV: 4047c88f3f6SAchin Gupta results[0] /= service_args[0] ? service_args[0] : 1; 4057c88f3f6SAchin Gupta results[1] /= service_args[1] ? service_args[1] : 1; 4067c88f3f6SAchin Gupta break; 4077c88f3f6SAchin Gupta default: 4087c88f3f6SAchin Gupta break; 4097c88f3f6SAchin Gupta } 4107c88f3f6SAchin Gupta 411239b04faSSoby Mathew return set_smc_args(func, 0, 4127c88f3f6SAchin Gupta results[0], 4137c88f3f6SAchin Gupta results[1], 414239b04faSSoby Mathew 0, 0, 0, 0); 4157c88f3f6SAchin Gupta } 4167c88f3f6SAchin Gupta 4173df6012aSDouglas Raillard /******************************************************************************* 4188aabea33SPaul Beesley * TSP smc abort handler. This function is called when aborting a preempted 41916292f54SDavid Cunado * yielding SMC request. It should cleanup all resources owned by the SMC 4203df6012aSDouglas Raillard * handler such as locks or dynamically allocated memory so following SMC 4213df6012aSDouglas Raillard * request are executed in a clean environment. 4223df6012aSDouglas Raillard ******************************************************************************/ 4233df6012aSDouglas Raillard tsp_args_t *tsp_abort_smc_handler(uint64_t func, 4243df6012aSDouglas Raillard uint64_t arg1, 4253df6012aSDouglas Raillard uint64_t arg2, 4263df6012aSDouglas Raillard uint64_t arg3, 4273df6012aSDouglas Raillard uint64_t arg4, 4283df6012aSDouglas Raillard uint64_t arg5, 4293df6012aSDouglas Raillard uint64_t arg6, 4303df6012aSDouglas Raillard uint64_t arg7) 4313df6012aSDouglas Raillard { 4323df6012aSDouglas Raillard return set_smc_args(TSP_ABORT_DONE, 0, 0, 0, 0, 0, 0, 0); 4333df6012aSDouglas Raillard } 434