1*22038315SVarun Wadekar/* 2*22038315SVarun Wadekar * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3*22038315SVarun Wadekar * 4*22038315SVarun Wadekar * Redistribution and use in source and binary forms, with or without 5*22038315SVarun Wadekar * modification, are permitted provided that the following conditions are met: 6*22038315SVarun Wadekar * 7*22038315SVarun Wadekar * Redistributions of source code must retain the above copyright notice, this 8*22038315SVarun Wadekar * list of conditions and the following disclaimer. 9*22038315SVarun Wadekar * 10*22038315SVarun Wadekar * Redistributions in binary form must reproduce the above copyright notice, 11*22038315SVarun Wadekar * this list of conditions and the following disclaimer in the documentation 12*22038315SVarun Wadekar * and/or other materials provided with the distribution. 13*22038315SVarun Wadekar * 14*22038315SVarun Wadekar * Neither the name of ARM nor the names of its contributors may be used 15*22038315SVarun Wadekar * to endorse or promote products derived from this software without specific 16*22038315SVarun Wadekar * prior written permission. 17*22038315SVarun Wadekar * 18*22038315SVarun Wadekar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*22038315SVarun Wadekar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*22038315SVarun Wadekar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*22038315SVarun Wadekar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*22038315SVarun Wadekar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*22038315SVarun Wadekar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*22038315SVarun Wadekar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*22038315SVarun Wadekar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*22038315SVarun Wadekar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*22038315SVarun Wadekar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*22038315SVarun Wadekar * POSSIBILITY OF SUCH DAMAGE. 29*22038315SVarun Wadekar */ 30*22038315SVarun Wadekar 31*22038315SVarun Wadekar#include <asm_macros.S> 32*22038315SVarun Wadekar#include "tlkd_private.h" 33*22038315SVarun Wadekar 34*22038315SVarun Wadekar .global tlkd_enter_sp 35*22038315SVarun Wadekar .global tlkd_exit_sp 36*22038315SVarun Wadekar 37*22038315SVarun Wadekar /* --------------------------------------------- 38*22038315SVarun Wadekar * This function is called with SP_EL0 as stack. 39*22038315SVarun Wadekar * Here we stash our EL3 callee-saved registers 40*22038315SVarun Wadekar * on to the stack as a part of saving the C 41*22038315SVarun Wadekar * runtime and enter the secure payload. 42*22038315SVarun Wadekar * 'x0' contains a pointer to the memory where 43*22038315SVarun Wadekar * the address of the C runtime context is to be 44*22038315SVarun Wadekar * saved. 45*22038315SVarun Wadekar * --------------------------------------------- 46*22038315SVarun Wadekar */ 47*22038315SVarun Wadekarfunc tlkd_enter_sp 48*22038315SVarun Wadekar /* Make space for the registers that we're going to save */ 49*22038315SVarun Wadekar mov x3, sp 50*22038315SVarun Wadekar str x3, [x0, #0] 51*22038315SVarun Wadekar sub sp, sp, #TLKD_C_RT_CTX_SIZE 52*22038315SVarun Wadekar 53*22038315SVarun Wadekar /* Save callee-saved registers on to the stack */ 54*22038315SVarun Wadekar stp x19, x20, [sp, #TLKD_C_RT_CTX_X19] 55*22038315SVarun Wadekar stp x21, x22, [sp, #TLKD_C_RT_CTX_X21] 56*22038315SVarun Wadekar stp x23, x24, [sp, #TLKD_C_RT_CTX_X23] 57*22038315SVarun Wadekar stp x25, x26, [sp, #TLKD_C_RT_CTX_X25] 58*22038315SVarun Wadekar stp x27, x28, [sp, #TLKD_C_RT_CTX_X27] 59*22038315SVarun Wadekar stp x29, x30, [sp, #TLKD_C_RT_CTX_X29] 60*22038315SVarun Wadekar 61*22038315SVarun Wadekar /* ---------------------------------------------- 62*22038315SVarun Wadekar * Everything is setup now. el3_exit() will 63*22038315SVarun Wadekar * use the secure context to restore to the 64*22038315SVarun Wadekar * general purpose and EL3 system registers to 65*22038315SVarun Wadekar * ERET into the secure payload. 66*22038315SVarun Wadekar * ---------------------------------------------- 67*22038315SVarun Wadekar */ 68*22038315SVarun Wadekar b el3_exit 69*22038315SVarun Wadekar 70*22038315SVarun Wadekar /* ---------------------------------------------- 71*22038315SVarun Wadekar * This function is called with 'x0' pointing to 72*22038315SVarun Wadekar * a C runtime context saved in tlkd_enter_sp(). 73*22038315SVarun Wadekar * It restores the saved registers and jumps to 74*22038315SVarun Wadekar * that runtime with 'x0' as the new sp. This 75*22038315SVarun Wadekar * destroys the C runtime context that had been 76*22038315SVarun Wadekar * built on the stack below the saved context by 77*22038315SVarun Wadekar * the caller. Later the second parameter 'x1' 78*22038315SVarun Wadekar * is passed as return value to the caller 79*22038315SVarun Wadekar * ---------------------------------------------- 80*22038315SVarun Wadekar */ 81*22038315SVarun Wadekarfunc tlkd_exit_sp 82*22038315SVarun Wadekar /* Restore the previous stack */ 83*22038315SVarun Wadekar mov sp, x0 84*22038315SVarun Wadekar 85*22038315SVarun Wadekar /* Restore callee-saved registers on to the stack */ 86*22038315SVarun Wadekar ldp x19, x20, [x0, #(TLKD_C_RT_CTX_X19 - TLKD_C_RT_CTX_SIZE)] 87*22038315SVarun Wadekar ldp x21, x22, [x0, #(TLKD_C_RT_CTX_X21 - TLKD_C_RT_CTX_SIZE)] 88*22038315SVarun Wadekar ldp x23, x24, [x0, #(TLKD_C_RT_CTX_X23 - TLKD_C_RT_CTX_SIZE)] 89*22038315SVarun Wadekar ldp x25, x26, [x0, #(TLKD_C_RT_CTX_X25 - TLKD_C_RT_CTX_SIZE)] 90*22038315SVarun Wadekar ldp x27, x28, [x0, #(TLKD_C_RT_CTX_X27 - TLKD_C_RT_CTX_SIZE)] 91*22038315SVarun Wadekar ldp x29, x30, [x0, #(TLKD_C_RT_CTX_X29 - TLKD_C_RT_CTX_SIZE)] 92*22038315SVarun Wadekar 93*22038315SVarun Wadekar /* ------------------------------------------------ 94*22038315SVarun Wadekar * This should take us back to the instruction 95*22038315SVarun Wadekar * after the call to the last tlkd_enter_sp(). 96*22038315SVarun Wadekar * Place the second parameter to x0 so that the 97*22038315SVarun Wadekar * caller will see it as a return value from the 98*22038315SVarun Wadekar * original entry call 99*22038315SVarun Wadekar * ------------------------------------------------ 100*22038315SVarun Wadekar */ 101*22038315SVarun Wadekar mov x0, x1 102*22038315SVarun Wadekar ret 103