diff options
author | Jeenu Viswambharan <jeenu.viswambharan@arm.com> | 2018-02-16 11:54:24 +0000 |
---|---|---|
committer | Jeenu Viswambharan <jeenu.viswambharan@arm.com> | 2018-06-21 16:15:23 +0100 |
commit | e7b9473e1591d4ab375a95ebbb9256adfe9d4670 (patch) | |
tree | 97e17803652b72586ae0e099e6e367f534dea2e5 /lib/aarch64 | |
parent | 2ccfcb2ea555eb86122e7780010cc50fcee08f54 (diff) |
BL31: Introduce jump primitives
This patch introduces setjmp() and ongjmp() primitives to enable
standard setjmp/longjmp style execution. Both APIs parameters take a
pointer to struct jmpbuf type, which hosts CPU registers saved/restored
during jump.
As per the standard usage:
- setjmp() return 0 when a jump is setup; and a non-zero value when
returning from jump.
- The caller of setjmp() must not return, or otherwise update stack
pointer since.
Change-Id: I4af1d32e490cfa547979631b762b4cba188d0551
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Diffstat (limited to 'lib/aarch64')
-rw-r--r-- | lib/aarch64/setjmp.S | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/lib/aarch64/setjmp.S b/lib/aarch64/setjmp.S new file mode 100644 index 00000000..9060cb75 --- /dev/null +++ b/lib/aarch64/setjmp.S @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <asm_macros.S> +#include <assert_macros.S> +#include <setjmp.h> + + .globl setjmp + .globl longjmp + +/* + * int setjmp(struct jmpbuf *buf); + * + * Sets a jump point in the buffer specified in x0. Returns 0 to the caller when + * when setting up the jump, and 1 when returning from the jump. + */ +func setjmp + mov x7, sp + + stp x19, x20, [x0, #JMP_CTX_X19] + stp x21, x22, [x0, #JMP_CTX_X21] + stp x23, x24, [x0, #JMP_CTX_X23] + stp x25, x26, [x0, #JMP_CTX_X25] + stp x27, x28, [x0, #JMP_CTX_X27] + stp x29, x30, [x0, #JMP_CTX_X29] + stp x7, xzr, [x0, #JMP_CTX_SP] + + mov x0, #0 + ret +endfunc setjmp + + +/* + * void longjmp(struct jmpbuf *buf); + * + * Return to a jump point setup by setjmp() + */ +func longjmp + ldp x7, xzr, [x0, #JMP_CTX_SP] + +#if ENABLE_ASSERTIONS + /* + * Since we're unwinding the stack, assert that the stack being reset to + * is shallower. + */ + mov x19, sp + cmp x7, x19 + ASM_ASSERT(ge) +#endif + + ldp x19, x20, [x0, #JMP_CTX_X19] + ldp x21, x22, [x0, #JMP_CTX_X21] + ldp x23, x24, [x0, #JMP_CTX_X23] + ldp x25, x26, [x0, #JMP_CTX_X25] + ldp x27, x28, [x0, #JMP_CTX_X27] + ldp x29, x30, [x0, #JMP_CTX_X29] + + mov sp, x7 + + mov x0, #1 + ret +endfunc longjmp |