
On Tue, Jun 12, 2018 at 05:57:34PM +0200, Heinrich Schuchardt wrote:
On 06/06/2018 08:28 PM, Ivan Gorinov wrote:
Add setjmp/longjmp functions for x86_64. The FPU control word and MXCSR control bits are preserved across calls.
With this patch
make mrproper && make qemu-x86_64_defconfig && make -j6
produces
arch/x86/cpu/built-in.o: In function `car_init': arch/x86/cpu/qemu/car.S:25: undefined reference to `car_init_ret'
The error does not occur without this patch.
The missing symbol is defined in arch/x86/cpu/start.S:98:car_init_ret: but it is not defined in arch/x86/cpu/start64.S
The following patch helps:
[PATCH 1/1] x86: qemu: do not build car.o with start64.o https://lists.denx.de/pipermail/u-boot/2018-June/331440.html
Thank you! Now it builds.
But bootefi selftest with your patch leads to an immediate reset of the qemu-x86_64 board.
Reproduced the qemu-x86_64 reset. The "info registers" command shows CR0.MP = 0. Setting it in 64-bit startup code did not help. I will try to fix that.
On a 64-bit Minnowboard configuration, bootefi works without reset.
Best regards
Heinrich
Signed-off-by: Ivan Gorinov ivan.gorinov@intel.com
arch/x86/cpu/x86_64/setjmp.S | 66 +++++++++++++++++++++++++++++++++++++++++++ arch/x86/cpu/x86_64/setjmp.c | 19 ------------- arch/x86/include/asm/setjmp.h | 19 +++++++++++++ 3 files changed, 85 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..ef61a4a --- /dev/null +++ b/arch/x86/cpu/x86_64/setjmp.S @@ -0,0 +1,66 @@ +/*
- Copyright (C) 2018 Intel Corporation
- SPDX-License-Identifier: GPL-2.0+
- See arch/x86/include/asm/setjmp.h for jmp_buf format
- */
+#include <linux/linkage.h>
+.text +.align 8
+ENTRY(setjmp)
- pop %rcx
- movq %rcx, (%rdi) /* Return address */
- movq %rsp, 8 (%rdi)
- movq %rbp, 16 (%rdi)
- movq %rbx, 24 (%rdi)
- movq %r12, 32 (%rdi)
- movq %r13, 40 (%rdi)
- movq %r14, 48 (%rdi)
- movq %r15, 56 (%rdi)
- fnstcw 64 (%rdi)
- stmxcsr 68 (%rdi)
- xorq %rax, %rax /* Direct invocation returns 0 */
- jmpq *%rcx
+ENDPROC(setjmp)
+.align 8
+ENTRY(longjmp)
- subq $8, %rsp
+/* Restore the control bits of MXCSR */
- stmxcsr (%rsp)
- movl $0x3f, %eax
- andl %eax, (%rsp)
- notl %eax
- andl 68 (%rdi), %eax
- orl %eax, (%rsp)
- ldmxcsr (%rsp)
- fldcw 64 (%rdi)
- movq (%rdi), %rcx /* Return address */
- movq 8 (%rdi), %rsp
- movq 16 (%rdi), %rbp
- movq 24 (%rdi), %rbx
- movq 32 (%rdi), %r12
- movq 40 (%rdi), %r13
- movq 48 (%rdi), %r14
- movq 56 (%rdi), %r15
- movq %rsi, %rax /* Value to be returned by setjmp() */
- testq %rax, %rax /* cannot be 0 in this case */
- jnz 1f
- incq %rax /* Return 1 instead */
+1:
- jmpq *%rcx
+ENDPROC(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..eae33fb 100644 --- a/arch/x86/include/asm/setjmp.h +++ b/arch/x86/include/asm/setjmp.h @@ -8,6 +8,23 @@ #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;
- unsigned int __fcw;
- unsigned int __mxcsr;
+};
+#else
struct jmp_buf_data { unsigned int __ebx; unsigned int __esp; @@ -17,6 +34,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);