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