[U-Boot] [PATCH] x86: Add 64-bit setjmp/longjmp implementation
Ivan Gorinov
ivan.gorinov at intel.com
Wed May 30 22:50:08 UTC 2018
Add setjmp/longjmp functions for x86_64,
based on existing 32-bit implementation.
Signed-off-by: Ivan Gorinov <ivan.gorinov at intel.com>
---
arch/x86/cpu/x86_64/setjmp.S | 56 +++++++++++++++++++++++++++++++++++++++++++
arch/x86/cpu/x86_64/setjmp.c | 19 ---------------
arch/x86/include/asm/setjmp.h | 17 +++++++++++++
3 files changed, 73 insertions(+), 19 deletions(-)
create mode 100644 arch/x86/cpu/x86_64/setjmp.S
delete mode 100644 arch/x86/cpu/x86_64/setjmp.c
diff --git a/arch/x86/cpu/x86_64/setjmp.S b/arch/x86/cpu/x86_64/setjmp.S
new file mode 100644
index 0000000..e10ee49
--- /dev/null
+++ b/arch/x86/cpu/x86_64/setjmp.S
@@ -0,0 +1,56 @@
+/*
+ * Based on arch/x86/cpu/i386/setjmp.S by H. Peter Anvin <hpa at zytor.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+/*
+ * The jmp_buf is assumed to contain the following, in order:
+ * <return address>
+ * %rsp
+ * %rbp
+ * %rbx
+ * %r12
+ * %r13
+ * %r14
+ * %r15
+ */
+
+.text
+.align 8
+.globl setjmp
+.type setjmp, @function
+
+setjmp:
+ pop %rcx
+ movq %rcx, (%rdi) /* Return address */
+ movq %rsp, 8 (%rdi) /* Post-return %rsp! */
+ movq %rbp, 16 (%rdi)
+ movq %rbx, 24 (%rdi)
+ movq %r12, 32 (%rdi)
+ movq %r13, 40 (%rdi)
+ movq %r14, 48 (%rdi)
+ movq %r15, 56 (%rdi)
+ xorq %rax, %rax /* Return value */
+ jmpq *%rcx
+
+/* Provide function size if needed */
+.size setjmp, .-setjmp
+
+.align 8
+.globl longjmp
+.type longjmp, @function
+
+longjmp:
+ movq 32 (%rdi), %r12
+ movq 40 (%rdi), %r13
+ movq 48 (%rdi), %r14
+ movq 56 (%rdi), %r15
+ movq 16 (%rdi), %rbp
+ movq 24 (%rdi), %rbx
+ movq 8 (%rdi), %rsp
+ movq (%rdi), %rcx
+ movq %rsi, %rdi
+ jmpq *%rcx
+
+ .size longjmp, .-longjmp
diff --git a/arch/x86/cpu/x86_64/setjmp.c b/arch/x86/cpu/x86_64/setjmp.c
deleted file mode 100644
index 5d4a74a..0000000
--- a/arch/x86/cpu/x86_64/setjmp.c
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2016 Google, Inc
- */
-
-#include <common.h>
-#include <asm/setjmp.h>
-
-int setjmp(struct jmp_buf_data *jmp_buf)
-{
- printf("WARNING: setjmp() is not supported\n");
-
- return 0;
-}
-
-void longjmp(struct jmp_buf_data *jmp_buf, int val)
-{
- printf("WARNING: longjmp() is not supported\n");
-}
diff --git a/arch/x86/include/asm/setjmp.h b/arch/x86/include/asm/setjmp.h
index f25975f..49c36c1 100644
--- a/arch/x86/include/asm/setjmp.h
+++ b/arch/x86/include/asm/setjmp.h
@@ -8,6 +8,21 @@
#ifndef __setjmp_h
#define __setjmp_h
+#ifdef CONFIG_X86_64
+
+struct jmp_buf_data {
+ unsigned long __rip;
+ unsigned long __rsp;
+ unsigned long __rbp;
+ unsigned long __rbx;
+ unsigned long __r12;
+ unsigned long __r13;
+ unsigned long __r14;
+ unsigned long __r15;
+};
+
+#else
+
struct jmp_buf_data {
unsigned int __ebx;
unsigned int __esp;
@@ -17,6 +32,8 @@ struct jmp_buf_data {
unsigned int __eip;
};
+#endif
+
int setjmp(struct jmp_buf_data *jmp_buf);
void longjmp(struct jmp_buf_data *jmp_buf, int val);
--
2.7.4
More information about the U-Boot
mailing list