1/* 2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <arch_helpers.h> 8#include <assert.h> 9#include <bl_common.h> 10#include <context_mgmt.h> 11#include <debug.h> 12#include <psci.h> 13#include <tlk.h> 14 15#include "tlkd_private.h" 16 17extern tlk_context_t tlk_ctx; 18 19#define MPIDR_CPU0 0x80000000 20 21/******************************************************************************* 22 * Return the type of payload TLKD is dealing with. Report the current 23 * resident cpu (mpidr format) if it is a UP/UP migratable payload. 24 ******************************************************************************/ 25static int32_t cpu_migrate_info(uint64_t *resident_cpu) 26{ 27 /* the payload runs only on CPU0 */ 28 *resident_cpu = MPIDR_CPU0; 29 30 /* Uniprocessor, not migrate capable payload */ 31 return PSCI_TOS_NOT_UP_MIG_CAP; 32} 33 34/******************************************************************************* 35 * This cpu is being suspended. Inform TLK of the SYSTEM_SUSPEND event, so 36 * that it can pass this information to its Trusted Apps. 37 ******************************************************************************/ 38static void cpu_suspend_handler(uint64_t suspend_level) 39{ 40 gp_regs_t *gp_regs; 41 int cpu = read_mpidr() & MPIDR_CPU_MASK; 42 int32_t rc = 0; 43 44 /* 45 * TLK runs only on CPU0 and suspends its Trusted Apps during 46 * SYSTEM_SUSPEND. It has no role to play during CPU_SUSPEND. 47 */ 48 if ((cpu != 0) || (suspend_level != PLAT_MAX_PWR_LVL)) 49 return; 50 51 /* pass system suspend event to TLK */ 52 gp_regs = get_gpregs_ctx(&tlk_ctx.cpu_ctx); 53 write_ctx_reg(gp_regs, CTX_GPREG_X0, TLK_SYSTEM_SUSPEND); 54 55 /* Program the entry point and enter TLK */ 56 rc = tlkd_synchronous_sp_entry(&tlk_ctx); 57 58 /* 59 * Read the response from TLK. A non-zero return means that 60 * something went wrong while communicating with it. 61 */ 62 if (rc != 0) 63 panic(); 64} 65 66/******************************************************************************* 67 * This cpu is being resumed. Inform TLK of the SYSTEM_SUSPEND exit, so 68 * that it can pass this information to its Trusted Apps. 69 ******************************************************************************/ 70static void cpu_resume_handler(uint64_t suspend_level) 71{ 72 gp_regs_t *gp_regs; 73 int cpu = read_mpidr() & MPIDR_CPU_MASK; 74 int32_t rc = 0; 75 76 /* 77 * TLK runs only on CPU0 and resumes its Trusted Apps during 78 * SYSTEM_SUSPEND exit. It has no role to play during CPU_SUSPEND 79 * exit. 80 */ 81 if ((cpu != 0) || (suspend_level != PLAT_MAX_PWR_LVL)) 82 return; 83 84 /* pass system resume event to TLK */ 85 gp_regs = get_gpregs_ctx(&tlk_ctx.cpu_ctx); 86 write_ctx_reg(gp_regs, CTX_GPREG_X0, TLK_SYSTEM_RESUME); 87 88 /* Program the entry point and enter TLK */ 89 rc = tlkd_synchronous_sp_entry(&tlk_ctx); 90 91 /* 92 * Read the response from TLK. A non-zero return means that 93 * something went wrong while communicating with it. 94 */ 95 if (rc != 0) 96 panic(); 97} 98 99/******************************************************************************* 100 * System is about to be reset. Inform the SP to allow any book-keeping 101 ******************************************************************************/ 102static void system_off_handler(void) 103{ 104 int cpu = read_mpidr() & MPIDR_CPU_MASK; 105 gp_regs_t *gp_regs; 106 107 /* TLK runs only on CPU0 */ 108 if (cpu != 0) 109 return; 110 111 /* pass system off/reset events to TLK */ 112 gp_regs = get_gpregs_ctx(&tlk_ctx.cpu_ctx); 113 write_ctx_reg(gp_regs, CTX_GPREG_X0, TLK_SYSTEM_OFF); 114 115 /* 116 * Enter the SP. We do not care about the return value because we 117 * must continue with the shutdown anyway. 118 */ 119 (void)tlkd_synchronous_sp_entry(&tlk_ctx); 120} 121 122/******************************************************************************* 123 * Structure populated by the Dispatcher to be given a chance to perform any 124 * bookkeeping before PSCI executes a power mgmt. operation. 125 ******************************************************************************/ 126const spd_pm_ops_t tlkd_pm_ops = { 127 .svc_migrate_info = cpu_migrate_info, 128 .svc_suspend = cpu_suspend_handler, 129 .svc_suspend_finish = cpu_resume_handler, 130 .svc_system_off = system_off_handler, 131 .svc_system_reset = system_off_handler 132}; 133