summaryrefslogtreecommitdiff
path: root/lib/aarch64
diff options
context:
space:
mode:
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>2018-02-16 11:54:24 +0000
committerJeenu Viswambharan <jeenu.viswambharan@arm.com>2018-06-21 16:15:23 +0100
commite7b9473e1591d4ab375a95ebbb9256adfe9d4670 (patch)
tree97e17803652b72586ae0e099e6e367f534dea2e5 /lib/aarch64
parent2ccfcb2ea555eb86122e7780010cc50fcee08f54 (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.S65
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