blob: 6e616a6c1830b0cf07870c944c320c6e230e91cf [file] [log] [blame]
Varun Wadekar3d4e6a52015-03-13 14:01:03 +05301/*
2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Varun Wadekar3d4e6a52015-03-13 14:01:03 +05305 */
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
Kévin Petita877c252015-03-24 14:03:57 +000045endfunc tlkd_enter_sp
Varun Wadekar3d4e6a52015-03-13 14:01:03 +053046
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
Kévin Petita877c252015-03-24 14:03:57 +000080endfunc tlkd_exit_sp