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