1*91f16700Schasinglulu/* 2*91f16700Schasinglulu * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu#include <asm_macros.S> 8*91f16700Schasinglulu#include "tlkd_private.h" 9*91f16700Schasinglulu 10*91f16700Schasinglulu .global tlkd_enter_sp 11*91f16700Schasinglulu .global tlkd_exit_sp 12*91f16700Schasinglulu 13*91f16700Schasinglulu /* --------------------------------------------- 14*91f16700Schasinglulu * This function is called with SP_EL0 as stack. 15*91f16700Schasinglulu * Here we stash our EL3 callee-saved registers 16*91f16700Schasinglulu * on to the stack as a part of saving the C 17*91f16700Schasinglulu * runtime and enter the secure payload. 18*91f16700Schasinglulu * 'x0' contains a pointer to the memory where 19*91f16700Schasinglulu * the address of the C runtime context is to be 20*91f16700Schasinglulu * saved. 21*91f16700Schasinglulu * --------------------------------------------- 22*91f16700Schasinglulu */ 23*91f16700Schasinglulufunc tlkd_enter_sp 24*91f16700Schasinglulu /* Make space for the registers that we're going to save */ 25*91f16700Schasinglulu mov x3, sp 26*91f16700Schasinglulu str x3, [x0, #0] 27*91f16700Schasinglulu sub sp, sp, #TLKD_C_RT_CTX_SIZE 28*91f16700Schasinglulu 29*91f16700Schasinglulu /* Save callee-saved registers on to the stack */ 30*91f16700Schasinglulu stp x19, x20, [sp, #TLKD_C_RT_CTX_X19] 31*91f16700Schasinglulu stp x21, x22, [sp, #TLKD_C_RT_CTX_X21] 32*91f16700Schasinglulu stp x23, x24, [sp, #TLKD_C_RT_CTX_X23] 33*91f16700Schasinglulu stp x25, x26, [sp, #TLKD_C_RT_CTX_X25] 34*91f16700Schasinglulu stp x27, x28, [sp, #TLKD_C_RT_CTX_X27] 35*91f16700Schasinglulu stp x29, x30, [sp, #TLKD_C_RT_CTX_X29] 36*91f16700Schasinglulu 37*91f16700Schasinglulu /* ---------------------------------------------- 38*91f16700Schasinglulu * Everything is setup now. el3_exit() will 39*91f16700Schasinglulu * use the secure context to restore to the 40*91f16700Schasinglulu * general purpose and EL3 system registers to 41*91f16700Schasinglulu * ERET into the secure payload. 42*91f16700Schasinglulu * ---------------------------------------------- 43*91f16700Schasinglulu */ 44*91f16700Schasinglulu b el3_exit 45*91f16700Schasingluluendfunc tlkd_enter_sp 46*91f16700Schasinglulu 47*91f16700Schasinglulu /* ---------------------------------------------- 48*91f16700Schasinglulu * This function is called with 'x0' pointing to 49*91f16700Schasinglulu * a C runtime context saved in tlkd_enter_sp(). 50*91f16700Schasinglulu * It restores the saved registers and jumps to 51*91f16700Schasinglulu * that runtime with 'x0' as the new sp. This 52*91f16700Schasinglulu * destroys the C runtime context that had been 53*91f16700Schasinglulu * built on the stack below the saved context by 54*91f16700Schasinglulu * the caller. Later the second parameter 'x1' 55*91f16700Schasinglulu * is passed as return value to the caller 56*91f16700Schasinglulu * ---------------------------------------------- 57*91f16700Schasinglulu */ 58*91f16700Schasinglulufunc tlkd_exit_sp 59*91f16700Schasinglulu /* Restore the previous stack */ 60*91f16700Schasinglulu mov sp, x0 61*91f16700Schasinglulu 62*91f16700Schasinglulu /* Restore callee-saved registers on to the stack */ 63*91f16700Schasinglulu ldp x19, x20, [x0, #(TLKD_C_RT_CTX_X19 - TLKD_C_RT_CTX_SIZE)] 64*91f16700Schasinglulu ldp x21, x22, [x0, #(TLKD_C_RT_CTX_X21 - TLKD_C_RT_CTX_SIZE)] 65*91f16700Schasinglulu ldp x23, x24, [x0, #(TLKD_C_RT_CTX_X23 - TLKD_C_RT_CTX_SIZE)] 66*91f16700Schasinglulu ldp x25, x26, [x0, #(TLKD_C_RT_CTX_X25 - TLKD_C_RT_CTX_SIZE)] 67*91f16700Schasinglulu ldp x27, x28, [x0, #(TLKD_C_RT_CTX_X27 - TLKD_C_RT_CTX_SIZE)] 68*91f16700Schasinglulu ldp x29, x30, [x0, #(TLKD_C_RT_CTX_X29 - TLKD_C_RT_CTX_SIZE)] 69*91f16700Schasinglulu 70*91f16700Schasinglulu /* ------------------------------------------------ 71*91f16700Schasinglulu * This should take us back to the instruction 72*91f16700Schasinglulu * after the call to the last tlkd_enter_sp(). 73*91f16700Schasinglulu * Place the second parameter to x0 so that the 74*91f16700Schasinglulu * caller will see it as a return value from the 75*91f16700Schasinglulu * original entry call 76*91f16700Schasinglulu * ------------------------------------------------ 77*91f16700Schasinglulu */ 78*91f16700Schasinglulu mov x0, x1 79*91f16700Schasinglulu ret 80*91f16700Schasingluluendfunc tlkd_exit_sp 81