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