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