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