122038315SVarun Wadekar /* 222038315SVarun Wadekar * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3*0600cf63SVarun Wadekar * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. 422038315SVarun Wadekar * 582cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 622038315SVarun Wadekar */ 722038315SVarun Wadekar 8cb790c5eSVarun Wadekar #include <assert.h> 909d40e0eSAntonio Nino Diaz 1009d40e0eSAntonio Nino Diaz #include <arch_helpers.h> 11b29c1b00SAntonio Nino Diaz #include <bl32/payloads/tlk.h> 1209d40e0eSAntonio Nino Diaz #include <common/bl_common.h> 1309d40e0eSAntonio Nino Diaz #include <common/debug.h> 1409d40e0eSAntonio Nino Diaz #include <lib/el3_runtime/context_mgmt.h> 1509d40e0eSAntonio Nino Diaz #include <lib/psci/psci.h> 16cb790c5eSVarun Wadekar 17cb790c5eSVarun Wadekar #include "tlkd_private.h" 18cb790c5eSVarun Wadekar 19cb790c5eSVarun Wadekar extern tlk_context_t tlk_ctx; 2022038315SVarun Wadekar 2122038315SVarun Wadekar #define MPIDR_CPU0 0x80000000 2222038315SVarun Wadekar 2322038315SVarun Wadekar /******************************************************************************* 2422038315SVarun Wadekar * Return the type of payload TLKD is dealing with. Report the current 2522038315SVarun Wadekar * resident cpu (mpidr format) if it is a UP/UP migratable payload. 2622038315SVarun Wadekar ******************************************************************************/ 2757d1e5faSMasahiro Yamada static int32_t cpu_migrate_info(u_register_t *resident_cpu) 2822038315SVarun Wadekar { 2922038315SVarun Wadekar /* the payload runs only on CPU0 */ 3022038315SVarun Wadekar *resident_cpu = MPIDR_CPU0; 3122038315SVarun Wadekar 3222038315SVarun Wadekar /* Uniprocessor, not migrate capable payload */ 3322038315SVarun Wadekar return PSCI_TOS_NOT_UP_MIG_CAP; 3422038315SVarun Wadekar } 3522038315SVarun Wadekar 3622038315SVarun Wadekar /******************************************************************************* 37cb790c5eSVarun Wadekar * This cpu is being suspended. Inform TLK of the SYSTEM_SUSPEND event, so 38cb790c5eSVarun Wadekar * that it can pass this information to its Trusted Apps. 39cb790c5eSVarun Wadekar ******************************************************************************/ 4057d1e5faSMasahiro Yamada static void cpu_suspend_handler(u_register_t suspend_level) 41cb790c5eSVarun Wadekar { 42cb790c5eSVarun Wadekar gp_regs_t *gp_regs; 43cb790c5eSVarun Wadekar int cpu = read_mpidr() & MPIDR_CPU_MASK; 44cb790c5eSVarun Wadekar int32_t rc = 0; 45cb790c5eSVarun Wadekar 46cb790c5eSVarun Wadekar /* 47cb790c5eSVarun Wadekar * TLK runs only on CPU0 and suspends its Trusted Apps during 48cb790c5eSVarun Wadekar * SYSTEM_SUSPEND. It has no role to play during CPU_SUSPEND. 49cb790c5eSVarun Wadekar */ 50cb790c5eSVarun Wadekar if ((cpu != 0) || (suspend_level != PLAT_MAX_PWR_LVL)) 51cb790c5eSVarun Wadekar return; 52cb790c5eSVarun Wadekar 53cb790c5eSVarun Wadekar /* pass system suspend event to TLK */ 54cb790c5eSVarun Wadekar gp_regs = get_gpregs_ctx(&tlk_ctx.cpu_ctx); 55cb790c5eSVarun Wadekar write_ctx_reg(gp_regs, CTX_GPREG_X0, TLK_SYSTEM_SUSPEND); 56cb790c5eSVarun Wadekar 57cb790c5eSVarun Wadekar /* Program the entry point and enter TLK */ 58cb790c5eSVarun Wadekar rc = tlkd_synchronous_sp_entry(&tlk_ctx); 59cb790c5eSVarun Wadekar 60cb790c5eSVarun Wadekar /* 61cb790c5eSVarun Wadekar * Read the response from TLK. A non-zero return means that 62cb790c5eSVarun Wadekar * something went wrong while communicating with it. 63cb790c5eSVarun Wadekar */ 64cb790c5eSVarun Wadekar if (rc != 0) 65cb790c5eSVarun Wadekar panic(); 66cb790c5eSVarun Wadekar } 67cb790c5eSVarun Wadekar 68cb790c5eSVarun Wadekar /******************************************************************************* 69cb790c5eSVarun Wadekar * This cpu is being resumed. Inform TLK of the SYSTEM_SUSPEND exit, so 70cb790c5eSVarun Wadekar * that it can pass this information to its Trusted Apps. 71cb790c5eSVarun Wadekar ******************************************************************************/ 7257d1e5faSMasahiro Yamada static void cpu_resume_handler(u_register_t suspend_level) 73cb790c5eSVarun Wadekar { 74cb790c5eSVarun Wadekar gp_regs_t *gp_regs; 75cb790c5eSVarun Wadekar int cpu = read_mpidr() & MPIDR_CPU_MASK; 76cb790c5eSVarun Wadekar int32_t rc = 0; 77cb790c5eSVarun Wadekar 78cb790c5eSVarun Wadekar /* 79cb790c5eSVarun Wadekar * TLK runs only on CPU0 and resumes its Trusted Apps during 80cb790c5eSVarun Wadekar * SYSTEM_SUSPEND exit. It has no role to play during CPU_SUSPEND 81cb790c5eSVarun Wadekar * exit. 82cb790c5eSVarun Wadekar */ 83cb790c5eSVarun Wadekar if ((cpu != 0) || (suspend_level != PLAT_MAX_PWR_LVL)) 84cb790c5eSVarun Wadekar return; 85cb790c5eSVarun Wadekar 86cb790c5eSVarun Wadekar /* pass system resume event to TLK */ 87cb790c5eSVarun Wadekar gp_regs = get_gpregs_ctx(&tlk_ctx.cpu_ctx); 88cb790c5eSVarun Wadekar write_ctx_reg(gp_regs, CTX_GPREG_X0, TLK_SYSTEM_RESUME); 89cb790c5eSVarun Wadekar 90cb790c5eSVarun Wadekar /* Program the entry point and enter TLK */ 91cb790c5eSVarun Wadekar rc = tlkd_synchronous_sp_entry(&tlk_ctx); 92cb790c5eSVarun Wadekar 93cb790c5eSVarun Wadekar /* 94cb790c5eSVarun Wadekar * Read the response from TLK. A non-zero return means that 95cb790c5eSVarun Wadekar * something went wrong while communicating with it. 96cb790c5eSVarun Wadekar */ 97cb790c5eSVarun Wadekar if (rc != 0) 98cb790c5eSVarun Wadekar panic(); 99cb790c5eSVarun Wadekar } 100cb790c5eSVarun Wadekar 101cb790c5eSVarun Wadekar /******************************************************************************* 10222038315SVarun Wadekar * Structure populated by the Dispatcher to be given a chance to perform any 10322038315SVarun Wadekar * bookkeeping before PSCI executes a power mgmt. operation. 10422038315SVarun Wadekar ******************************************************************************/ 10522038315SVarun Wadekar const spd_pm_ops_t tlkd_pm_ops = { 10622038315SVarun Wadekar .svc_migrate_info = cpu_migrate_info, 107cb790c5eSVarun Wadekar .svc_suspend = cpu_suspend_handler, 108cb790c5eSVarun Wadekar .svc_suspend_finish = cpu_resume_handler, 10922038315SVarun Wadekar }; 110