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