17c88f3f6SAchin Gupta /* 2*4d482156SDaniel Boulby * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved. 37c88f3f6SAchin Gupta * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 57c88f3f6SAchin Gupta */ 67c88f3f6SAchin Gupta 7ed108b56SAlexei Fedorov #include <assert.h> 84ce3e99aSScott Branden #include <inttypes.h> 94ce3e99aSScott Branden #include <stdint.h> 1009d40e0eSAntonio Nino Diaz 11ed108b56SAlexei Fedorov #include <arch_features.h> 1209d40e0eSAntonio Nino Diaz #include <arch_helpers.h> 1309d40e0eSAntonio Nino Diaz #include <bl32/tsp/tsp.h> 1409d40e0eSAntonio Nino Diaz #include <common/bl_common.h> 1509d40e0eSAntonio Nino Diaz #include <common/debug.h> 1609d40e0eSAntonio Nino Diaz #include <lib/spinlock.h> 1709d40e0eSAntonio Nino Diaz #include <plat/common/platform.h> 18ed108b56SAlexei Fedorov #include <platform_def.h> 195a06bb7eSDan Handley #include <platform_tsp.h> 2009d40e0eSAntonio Nino Diaz 21da0af78aSDan Handley #include "tsp_private.h" 227c88f3f6SAchin Gupta 236871c5d3SVikram Kanigiri 246871c5d3SVikram Kanigiri /******************************************************************************* 257c88f3f6SAchin Gupta * Lock to control access to the console 267c88f3f6SAchin Gupta ******************************************************************************/ 277c88f3f6SAchin Gupta spinlock_t console_lock; 287c88f3f6SAchin Gupta 297c88f3f6SAchin Gupta /******************************************************************************* 307c88f3f6SAchin Gupta * Per cpu data structure to populate parameters for an SMC in C code and use 317c88f3f6SAchin Gupta * a pointer to this structure in assembler code to populate x0-x7 327c88f3f6SAchin Gupta ******************************************************************************/ 33fb037bfbSDan Handley static tsp_args_t tsp_smc_args[PLATFORM_CORE_COUNT]; 347c88f3f6SAchin Gupta 357c88f3f6SAchin Gupta /******************************************************************************* 367c88f3f6SAchin Gupta * Per cpu data structure to keep track of TSP activity 377c88f3f6SAchin Gupta ******************************************************************************/ 386cf89021SAchin Gupta work_statistics_t tsp_stats[PLATFORM_CORE_COUNT]; 397c88f3f6SAchin Gupta 407c88f3f6SAchin Gupta /******************************************************************************* 41a604623cSSandrine Bailleux * The TSP memory footprint starts at address BL32_BASE and ends with the 42a604623cSSandrine Bailleux * linker symbol __BL32_END__. Use these addresses to compute the TSP image 43a604623cSSandrine Bailleux * size. 446871c5d3SVikram Kanigiri ******************************************************************************/ 45f6605337SAntonio Nino Diaz #define BL32_TOTAL_LIMIT BL32_END 46a604623cSSandrine Bailleux #define BL32_TOTAL_SIZE (BL32_TOTAL_LIMIT - (unsigned long) BL32_BASE) 476871c5d3SVikram Kanigiri 48fb037bfbSDan Handley static tsp_args_t *set_smc_args(uint64_t arg0, 497c88f3f6SAchin Gupta uint64_t arg1, 507c88f3f6SAchin Gupta uint64_t arg2, 517c88f3f6SAchin Gupta uint64_t arg3, 527c88f3f6SAchin Gupta uint64_t arg4, 537c88f3f6SAchin Gupta uint64_t arg5, 547c88f3f6SAchin Gupta uint64_t arg6, 557c88f3f6SAchin Gupta uint64_t arg7) 567c88f3f6SAchin Gupta { 577c88f3f6SAchin Gupta uint32_t linear_id; 58fb037bfbSDan Handley tsp_args_t *pcpu_smc_args; 597c88f3f6SAchin Gupta 607c88f3f6SAchin Gupta /* 617c88f3f6SAchin Gupta * Return to Secure Monitor by raising an SMC. The results of the 627c88f3f6SAchin Gupta * service are passed as an arguments to the SMC 637c88f3f6SAchin Gupta */ 64fd650ff6SSoby Mathew linear_id = plat_my_core_pos(); 657c88f3f6SAchin Gupta pcpu_smc_args = &tsp_smc_args[linear_id]; 667c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG0, arg0); 677c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG1, arg1); 687c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG2, arg2); 697c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG3, arg3); 707c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG4, arg4); 717c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG5, arg5); 727c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG6, arg6); 737c88f3f6SAchin Gupta write_sp_arg(pcpu_smc_args, TSP_ARG7, arg7); 747c88f3f6SAchin Gupta 757c88f3f6SAchin Gupta return pcpu_smc_args; 767c88f3f6SAchin Gupta } 777c88f3f6SAchin Gupta 787c88f3f6SAchin Gupta /******************************************************************************* 7967b6ff9fSAntonio Nino Diaz * Setup function for TSP. 8067b6ff9fSAntonio Nino Diaz ******************************************************************************/ 8167b6ff9fSAntonio Nino Diaz void tsp_setup(void) 8267b6ff9fSAntonio Nino Diaz { 8367b6ff9fSAntonio Nino Diaz /* Perform early platform-specific setup */ 8467b6ff9fSAntonio Nino Diaz tsp_early_platform_setup(); 8567b6ff9fSAntonio Nino Diaz 8667b6ff9fSAntonio Nino Diaz /* Perform late platform-specific setup */ 8767b6ff9fSAntonio Nino Diaz tsp_plat_arch_setup(); 88ed108b56SAlexei Fedorov 89ed108b56SAlexei Fedorov #if ENABLE_PAUTH 90ed108b56SAlexei Fedorov /* 91ed108b56SAlexei Fedorov * Assert that the ARMv8.3-PAuth registers are present or an access 92ed108b56SAlexei Fedorov * fault will be triggered when they are being saved or restored. 93ed108b56SAlexei Fedorov */ 94ed108b56SAlexei Fedorov assert(is_armv8_3_pauth_present()); 95ed108b56SAlexei Fedorov #endif /* ENABLE_PAUTH */ 9667b6ff9fSAntonio Nino Diaz } 9767b6ff9fSAntonio Nino Diaz 9867b6ff9fSAntonio Nino Diaz /******************************************************************************* 997c88f3f6SAchin Gupta * TSP main entry point where it gets the opportunity to initialize its secure 1007c88f3f6SAchin Gupta * state/applications. Once the state is initialized, it must return to the 101399fb08fSAndrew Thoelke * SPD with a pointer to the 'tsp_vector_table' jump table. 1027c88f3f6SAchin Gupta ******************************************************************************/ 1037c88f3f6SAchin Gupta uint64_t tsp_main(void) 1047c88f3f6SAchin Gupta { 1056ad2e461SDan Handley NOTICE("TSP: %s\n", version_string); 1066ad2e461SDan Handley NOTICE("TSP: %s\n", build_message); 107a604623cSSandrine Bailleux INFO("TSP: Total memory base : 0x%lx\n", (unsigned long) BL32_BASE); 108a604623cSSandrine Bailleux INFO("TSP: Total memory size : 0x%lx bytes\n", BL32_TOTAL_SIZE); 1096ad2e461SDan Handley 110fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 1117c88f3f6SAchin Gupta 1127c88f3f6SAchin Gupta /* Initialize the platform */ 1135a06bb7eSDan Handley tsp_platform_setup(); 1147c88f3f6SAchin Gupta 1157c88f3f6SAchin Gupta /* Initialize secure/applications state here */ 116a20a81e5SAchin Gupta tsp_generic_timer_start(); 1177c88f3f6SAchin Gupta 1187c88f3f6SAchin Gupta /* Update this cpu's statistics */ 1197c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count++; 1207c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count++; 1217c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_on_count++; 1227c88f3f6SAchin Gupta 1236ad2e461SDan Handley #if LOG_LEVEL >= LOG_LEVEL_INFO 1247c88f3f6SAchin Gupta spin_lock(&console_lock); 125fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n", 126fd650ff6SSoby Mathew read_mpidr(), 1277c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count, 1287c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count, 1297c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_on_count); 1307c88f3f6SAchin Gupta spin_unlock(&console_lock); 1316ad2e461SDan Handley #endif 132399fb08fSAndrew Thoelke return (uint64_t) &tsp_vector_table; 1337c88f3f6SAchin Gupta } 1347c88f3f6SAchin Gupta 1357c88f3f6SAchin Gupta /******************************************************************************* 1367c88f3f6SAchin Gupta * This function performs any remaining book keeping in the test secure payload 1377c88f3f6SAchin Gupta * after this cpu's architectural state has been setup in response to an earlier 1387c88f3f6SAchin Gupta * psci cpu_on request. 1397c88f3f6SAchin Gupta ******************************************************************************/ 140fb037bfbSDan Handley tsp_args_t *tsp_cpu_on_main(void) 1417c88f3f6SAchin Gupta { 142fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 1437c88f3f6SAchin Gupta 144a20a81e5SAchin Gupta /* Initialize secure/applications state here */ 145a20a81e5SAchin Gupta tsp_generic_timer_start(); 146a20a81e5SAchin Gupta 1477c88f3f6SAchin Gupta /* Update this cpu's statistics */ 1487c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count++; 1497c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count++; 1507c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_on_count++; 1517c88f3f6SAchin Gupta 1526ad2e461SDan Handley #if LOG_LEVEL >= LOG_LEVEL_INFO 1537c88f3f6SAchin Gupta spin_lock(&console_lock); 154fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx turned on\n", read_mpidr()); 155fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n", 156fd650ff6SSoby Mathew read_mpidr(), 1577c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count, 1587c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count, 1597c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_on_count); 1607c88f3f6SAchin Gupta spin_unlock(&console_lock); 1616ad2e461SDan Handley #endif 1627c88f3f6SAchin Gupta /* Indicate to the SPD that we have completed turned ourselves on */ 1637c88f3f6SAchin Gupta return set_smc_args(TSP_ON_DONE, 0, 0, 0, 0, 0, 0, 0); 1647c88f3f6SAchin Gupta } 1657c88f3f6SAchin Gupta 1667c88f3f6SAchin Gupta /******************************************************************************* 1677c88f3f6SAchin Gupta * This function performs any remaining book keeping in the test secure payload 1687c88f3f6SAchin Gupta * before this cpu is turned off in response to a psci cpu_off request. 1697c88f3f6SAchin Gupta ******************************************************************************/ 170fb037bfbSDan Handley tsp_args_t *tsp_cpu_off_main(uint64_t arg0, 1717c88f3f6SAchin Gupta uint64_t arg1, 1727c88f3f6SAchin Gupta uint64_t arg2, 1737c88f3f6SAchin Gupta uint64_t arg3, 1747c88f3f6SAchin Gupta uint64_t arg4, 1757c88f3f6SAchin Gupta uint64_t arg5, 1767c88f3f6SAchin Gupta uint64_t arg6, 1777c88f3f6SAchin Gupta uint64_t arg7) 1787c88f3f6SAchin Gupta { 179fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 1807c88f3f6SAchin Gupta 181a20a81e5SAchin Gupta /* 182a20a81e5SAchin Gupta * This cpu is being turned off, so disable the timer to prevent the 183a20a81e5SAchin Gupta * secure timer interrupt from interfering with power down. A pending 184a20a81e5SAchin Gupta * interrupt will be lost but we do not care as we are turning off. 185a20a81e5SAchin Gupta */ 186a20a81e5SAchin Gupta tsp_generic_timer_stop(); 187a20a81e5SAchin Gupta 1887c88f3f6SAchin Gupta /* Update this cpu's statistics */ 1897c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count++; 1907c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count++; 1917c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_off_count++; 1927c88f3f6SAchin Gupta 1936ad2e461SDan Handley #if LOG_LEVEL >= LOG_LEVEL_INFO 1947c88f3f6SAchin Gupta spin_lock(&console_lock); 195fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx off request\n", read_mpidr()); 196fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu off requests\n", 197fd650ff6SSoby Mathew read_mpidr(), 1987c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count, 1997c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count, 2007c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_off_count); 2017c88f3f6SAchin Gupta spin_unlock(&console_lock); 2026ad2e461SDan Handley #endif 2037c88f3f6SAchin Gupta 204607084eeSAchin Gupta /* Indicate to the SPD that we have completed this request */ 2057c88f3f6SAchin Gupta return set_smc_args(TSP_OFF_DONE, 0, 0, 0, 0, 0, 0, 0); 2067c88f3f6SAchin Gupta } 2077c88f3f6SAchin Gupta 2087c88f3f6SAchin Gupta /******************************************************************************* 2097c88f3f6SAchin Gupta * This function performs any book keeping in the test secure payload before 2107c88f3f6SAchin Gupta * this cpu's architectural state is saved in response to an earlier psci 2117c88f3f6SAchin Gupta * cpu_suspend request. 2127c88f3f6SAchin Gupta ******************************************************************************/ 21331244d74SSoby Mathew tsp_args_t *tsp_cpu_suspend_main(uint64_t arg0, 2147c88f3f6SAchin Gupta uint64_t arg1, 2157c88f3f6SAchin Gupta uint64_t arg2, 2167c88f3f6SAchin Gupta uint64_t arg3, 2177c88f3f6SAchin Gupta uint64_t arg4, 2187c88f3f6SAchin Gupta uint64_t arg5, 2197c88f3f6SAchin Gupta uint64_t arg6, 2207c88f3f6SAchin Gupta uint64_t arg7) 2217c88f3f6SAchin Gupta { 222fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 2237c88f3f6SAchin Gupta 224a20a81e5SAchin Gupta /* 225a20a81e5SAchin Gupta * Save the time context and disable it to prevent the secure timer 226a20a81e5SAchin Gupta * interrupt from interfering with wakeup from the suspend state. 227a20a81e5SAchin Gupta */ 228a20a81e5SAchin Gupta tsp_generic_timer_save(); 229a20a81e5SAchin Gupta tsp_generic_timer_stop(); 230a20a81e5SAchin Gupta 2317c88f3f6SAchin Gupta /* Update this cpu's statistics */ 2327c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count++; 2337c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count++; 2347c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_suspend_count++; 2357c88f3f6SAchin Gupta 2366ad2e461SDan Handley #if LOG_LEVEL >= LOG_LEVEL_INFO 2377c88f3f6SAchin Gupta spin_lock(&console_lock); 238dad25049SSandrine Bailleux INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n", 239fd650ff6SSoby Mathew read_mpidr(), 2407c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count, 2417c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count, 2427c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_suspend_count); 2437c88f3f6SAchin Gupta spin_unlock(&console_lock); 2446ad2e461SDan Handley #endif 2457c88f3f6SAchin Gupta 246607084eeSAchin Gupta /* Indicate to the SPD that we have completed this request */ 2477c88f3f6SAchin Gupta return set_smc_args(TSP_SUSPEND_DONE, 0, 0, 0, 0, 0, 0, 0); 2487c88f3f6SAchin Gupta } 2497c88f3f6SAchin Gupta 2507c88f3f6SAchin Gupta /******************************************************************************* 2517c88f3f6SAchin Gupta * This function performs any book keeping in the test secure payload after this 2527c88f3f6SAchin Gupta * cpu's architectural state has been restored after wakeup from an earlier psci 2537c88f3f6SAchin Gupta * cpu_suspend request. 2547c88f3f6SAchin Gupta ******************************************************************************/ 255f1054c93SAchin Gupta tsp_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl, 2567c88f3f6SAchin Gupta uint64_t arg1, 2577c88f3f6SAchin Gupta uint64_t arg2, 2587c88f3f6SAchin Gupta uint64_t arg3, 2597c88f3f6SAchin Gupta uint64_t arg4, 2607c88f3f6SAchin Gupta uint64_t arg5, 2617c88f3f6SAchin Gupta uint64_t arg6, 2627c88f3f6SAchin Gupta uint64_t arg7) 2637c88f3f6SAchin Gupta { 264fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 2657c88f3f6SAchin Gupta 266a20a81e5SAchin Gupta /* Restore the generic timer context */ 267a20a81e5SAchin Gupta tsp_generic_timer_restore(); 268a20a81e5SAchin Gupta 2697c88f3f6SAchin Gupta /* Update this cpu's statistics */ 2707c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count++; 2717c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count++; 2727c88f3f6SAchin Gupta tsp_stats[linear_id].cpu_resume_count++; 2737c88f3f6SAchin Gupta 2746ad2e461SDan Handley #if LOG_LEVEL >= LOG_LEVEL_INFO 2757c88f3f6SAchin Gupta spin_lock(&console_lock); 2764ce3e99aSScott Branden INFO("TSP: cpu 0x%lx resumed. maximum off power level %" PRId64 "\n", 277f1054c93SAchin Gupta read_mpidr(), max_off_pwrlvl); 278a16bc845SManish Pandey INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu resume requests\n", 279fd650ff6SSoby Mathew read_mpidr(), 2807c88f3f6SAchin Gupta tsp_stats[linear_id].smc_count, 2817c88f3f6SAchin Gupta tsp_stats[linear_id].eret_count, 282a16bc845SManish Pandey tsp_stats[linear_id].cpu_resume_count); 2837c88f3f6SAchin Gupta spin_unlock(&console_lock); 2846ad2e461SDan Handley #endif 285607084eeSAchin Gupta /* Indicate to the SPD that we have completed this request */ 2867c88f3f6SAchin Gupta return set_smc_args(TSP_RESUME_DONE, 0, 0, 0, 0, 0, 0, 0); 2877c88f3f6SAchin Gupta } 2887c88f3f6SAchin Gupta 2897c88f3f6SAchin Gupta /******************************************************************************* 290d5f13093SJuan Castillo * This function performs any remaining bookkeeping in the test secure payload 291d5f13093SJuan Castillo * before the system is switched off (in response to a psci SYSTEM_OFF request) 292d5f13093SJuan Castillo ******************************************************************************/ 293d5f13093SJuan Castillo tsp_args_t *tsp_system_off_main(uint64_t arg0, 294d5f13093SJuan Castillo uint64_t arg1, 295d5f13093SJuan Castillo uint64_t arg2, 296d5f13093SJuan Castillo uint64_t arg3, 297d5f13093SJuan Castillo uint64_t arg4, 298d5f13093SJuan Castillo uint64_t arg5, 299d5f13093SJuan Castillo uint64_t arg6, 300d5f13093SJuan Castillo uint64_t arg7) 301d5f13093SJuan Castillo { 302fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 303d5f13093SJuan Castillo 304d5f13093SJuan Castillo /* Update this cpu's statistics */ 305d5f13093SJuan Castillo tsp_stats[linear_id].smc_count++; 306d5f13093SJuan Castillo tsp_stats[linear_id].eret_count++; 307d5f13093SJuan Castillo 308d5f13093SJuan Castillo #if LOG_LEVEL >= LOG_LEVEL_INFO 309d5f13093SJuan Castillo spin_lock(&console_lock); 310fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx SYSTEM_OFF request\n", read_mpidr()); 311fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(), 312d5f13093SJuan Castillo tsp_stats[linear_id].smc_count, 313d5f13093SJuan Castillo tsp_stats[linear_id].eret_count); 314d5f13093SJuan Castillo spin_unlock(&console_lock); 315d5f13093SJuan Castillo #endif 316d5f13093SJuan Castillo 317d5f13093SJuan Castillo /* Indicate to the SPD that we have completed this request */ 318d5f13093SJuan Castillo return set_smc_args(TSP_SYSTEM_OFF_DONE, 0, 0, 0, 0, 0, 0, 0); 319d5f13093SJuan Castillo } 320d5f13093SJuan Castillo 321d5f13093SJuan Castillo /******************************************************************************* 322d5f13093SJuan Castillo * This function performs any remaining bookkeeping in the test secure payload 323d5f13093SJuan Castillo * before the system is reset (in response to a psci SYSTEM_RESET request) 324d5f13093SJuan Castillo ******************************************************************************/ 325d5f13093SJuan Castillo tsp_args_t *tsp_system_reset_main(uint64_t arg0, 326d5f13093SJuan Castillo uint64_t arg1, 327d5f13093SJuan Castillo uint64_t arg2, 328d5f13093SJuan Castillo uint64_t arg3, 329d5f13093SJuan Castillo uint64_t arg4, 330d5f13093SJuan Castillo uint64_t arg5, 331d5f13093SJuan Castillo uint64_t arg6, 332d5f13093SJuan Castillo uint64_t arg7) 333d5f13093SJuan Castillo { 334fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 335d5f13093SJuan Castillo 336d5f13093SJuan Castillo /* Update this cpu's statistics */ 337d5f13093SJuan Castillo tsp_stats[linear_id].smc_count++; 338d5f13093SJuan Castillo tsp_stats[linear_id].eret_count++; 339d5f13093SJuan Castillo 340d5f13093SJuan Castillo #if LOG_LEVEL >= LOG_LEVEL_INFO 341d5f13093SJuan Castillo spin_lock(&console_lock); 342fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx SYSTEM_RESET request\n", read_mpidr()); 343fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(), 344d5f13093SJuan Castillo tsp_stats[linear_id].smc_count, 345d5f13093SJuan Castillo tsp_stats[linear_id].eret_count); 346d5f13093SJuan Castillo spin_unlock(&console_lock); 347d5f13093SJuan Castillo #endif 348d5f13093SJuan Castillo 349d5f13093SJuan Castillo /* Indicate to the SPD that we have completed this request */ 350d5f13093SJuan Castillo return set_smc_args(TSP_SYSTEM_RESET_DONE, 0, 0, 0, 0, 0, 0, 0); 351d5f13093SJuan Castillo } 352d5f13093SJuan Castillo 353d5f13093SJuan Castillo /******************************************************************************* 3547c88f3f6SAchin Gupta * TSP fast smc handler. The secure monitor jumps to this function by 3557c88f3f6SAchin Gupta * doing the ERET after populating X0-X7 registers. The arguments are received 3567c88f3f6SAchin Gupta * in the function arguments in order. Once the service is rendered, this 357239b04faSSoby Mathew * function returns to Secure Monitor by raising SMC. 3587c88f3f6SAchin Gupta ******************************************************************************/ 359239b04faSSoby Mathew tsp_args_t *tsp_smc_handler(uint64_t func, 3607c88f3f6SAchin Gupta uint64_t arg1, 3617c88f3f6SAchin Gupta uint64_t arg2, 3627c88f3f6SAchin Gupta uint64_t arg3, 3637c88f3f6SAchin Gupta uint64_t arg4, 3647c88f3f6SAchin Gupta uint64_t arg5, 3657c88f3f6SAchin Gupta uint64_t arg6, 3667c88f3f6SAchin Gupta uint64_t arg7) 3677c88f3f6SAchin Gupta { 368caff3c87SAlexei Fedorov uint128_t service_args; 369caff3c87SAlexei Fedorov uint64_t service_arg0; 370caff3c87SAlexei Fedorov uint64_t service_arg1; 371916a2c1eSAchin Gupta uint64_t results[2]; 372fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 373*4d482156SDaniel Boulby u_register_t dit; 3747c88f3f6SAchin Gupta 375916a2c1eSAchin Gupta /* Update this cpu's statistics */ 376916a2c1eSAchin Gupta tsp_stats[linear_id].smc_count++; 377916a2c1eSAchin Gupta tsp_stats[linear_id].eret_count++; 3787c88f3f6SAchin Gupta 379ae7b922dSMadhukar Pappireddy #if LOG_LEVEL >= LOG_LEVEL_INFO 380ae7b922dSMadhukar Pappireddy spin_lock(&console_lock); 3814ce3e99aSScott Branden INFO("TSP: cpu 0x%lx received %s smc 0x%" PRIx64 "\n", read_mpidr(), 38216292f54SDavid Cunado ((func >> 31) & 1) == 1 ? "fast" : "yielding", 3836ad2e461SDan Handley func); 384fd650ff6SSoby Mathew INFO("TSP: cpu 0x%lx: %d smcs, %d erets\n", read_mpidr(), 385916a2c1eSAchin Gupta tsp_stats[linear_id].smc_count, 386916a2c1eSAchin Gupta tsp_stats[linear_id].eret_count); 387ae7b922dSMadhukar Pappireddy spin_unlock(&console_lock); 388ae7b922dSMadhukar Pappireddy #endif 389916a2c1eSAchin Gupta 390916a2c1eSAchin Gupta /* Render secure services and obtain results here */ 3917c88f3f6SAchin Gupta results[0] = arg1; 3927c88f3f6SAchin Gupta results[1] = arg2; 3937c88f3f6SAchin Gupta 3947c88f3f6SAchin Gupta /* 395caff3c87SAlexei Fedorov * Request a service back from dispatcher/secure monitor. 396caff3c87SAlexei Fedorov * This call returns and thereafter resumes execution. 3977c88f3f6SAchin Gupta */ 398caff3c87SAlexei Fedorov service_args = tsp_get_magic(); 399caff3c87SAlexei Fedorov service_arg0 = (uint64_t)service_args; 400caff3c87SAlexei Fedorov service_arg1 = (uint64_t)(service_args >> 64U); 4017c88f3f6SAchin Gupta 4029dd94382SJustin Chadwell #if CTX_INCLUDE_MTE_REGS 4039dd94382SJustin Chadwell /* 4049dd94382SJustin Chadwell * Write a dummy value to an MTE register, to simulate usage in the 4059dd94382SJustin Chadwell * secure world 4069dd94382SJustin Chadwell */ 4079dd94382SJustin Chadwell write_gcr_el1(0x99); 4089dd94382SJustin Chadwell #endif 4099dd94382SJustin Chadwell 4107c88f3f6SAchin Gupta /* Determine the function to perform based on the function ID */ 411239b04faSSoby Mathew switch (TSP_BARE_FID(func)) { 412239b04faSSoby Mathew case TSP_ADD: 413caff3c87SAlexei Fedorov results[0] += service_arg0; 414caff3c87SAlexei Fedorov results[1] += service_arg1; 4157c88f3f6SAchin Gupta break; 416239b04faSSoby Mathew case TSP_SUB: 417caff3c87SAlexei Fedorov results[0] -= service_arg0; 418caff3c87SAlexei Fedorov results[1] -= service_arg1; 4197c88f3f6SAchin Gupta break; 420239b04faSSoby Mathew case TSP_MUL: 421caff3c87SAlexei Fedorov results[0] *= service_arg0; 422caff3c87SAlexei Fedorov results[1] *= service_arg1; 4237c88f3f6SAchin Gupta break; 424239b04faSSoby Mathew case TSP_DIV: 425caff3c87SAlexei Fedorov results[0] /= service_arg0 ? service_arg0 : 1; 426caff3c87SAlexei Fedorov results[1] /= service_arg1 ? service_arg1 : 1; 4277c88f3f6SAchin Gupta break; 428*4d482156SDaniel Boulby case TSP_CHECK_DIT: 429*4d482156SDaniel Boulby if (!is_armv8_4_dit_present()) { 430*4d482156SDaniel Boulby #if LOG_LEVEL >= LOG_LEVEL_ERROR 431*4d482156SDaniel Boulby spin_lock(&console_lock); 432*4d482156SDaniel Boulby ERROR("DIT not supported\n"); 433*4d482156SDaniel Boulby spin_unlock(&console_lock); 434*4d482156SDaniel Boulby #endif 435*4d482156SDaniel Boulby results[0] = 0; 436*4d482156SDaniel Boulby results[1] = 0xffff; 437*4d482156SDaniel Boulby break; 438*4d482156SDaniel Boulby } 439*4d482156SDaniel Boulby dit = read_dit(); 440*4d482156SDaniel Boulby results[0] = dit == service_arg0; 441*4d482156SDaniel Boulby results[1] = dit; 442*4d482156SDaniel Boulby /* Toggle the dit bit */ 443*4d482156SDaniel Boulby write_dit(service_arg0 != 0U ? 0 : DIT_BIT); 444*4d482156SDaniel Boulby break; 4457c88f3f6SAchin Gupta default: 4467c88f3f6SAchin Gupta break; 4477c88f3f6SAchin Gupta } 4487c88f3f6SAchin Gupta 449239b04faSSoby Mathew return set_smc_args(func, 0, 4507c88f3f6SAchin Gupta results[0], 4517c88f3f6SAchin Gupta results[1], 452239b04faSSoby Mathew 0, 0, 0, 0); 4537c88f3f6SAchin Gupta } 4547c88f3f6SAchin Gupta 4553df6012aSDouglas Raillard /******************************************************************************* 4568aabea33SPaul Beesley * TSP smc abort handler. This function is called when aborting a preempted 45716292f54SDavid Cunado * yielding SMC request. It should cleanup all resources owned by the SMC 4583df6012aSDouglas Raillard * handler such as locks or dynamically allocated memory so following SMC 4593df6012aSDouglas Raillard * request are executed in a clean environment. 4603df6012aSDouglas Raillard ******************************************************************************/ 4613df6012aSDouglas Raillard tsp_args_t *tsp_abort_smc_handler(uint64_t func, 4623df6012aSDouglas Raillard uint64_t arg1, 4633df6012aSDouglas Raillard uint64_t arg2, 4643df6012aSDouglas Raillard uint64_t arg3, 4653df6012aSDouglas Raillard uint64_t arg4, 4663df6012aSDouglas Raillard uint64_t arg5, 4673df6012aSDouglas Raillard uint64_t arg6, 4683df6012aSDouglas Raillard uint64_t arg7) 4693df6012aSDouglas Raillard { 4703df6012aSDouglas Raillard return set_smc_args(TSP_ABORT_DONE, 0, 0, 0, 0, 0, 0, 0); 4713df6012aSDouglas Raillard } 472