Re: [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
Hi Ivan, On Thu, Jun 7, 2018 at 2:28 AM, Ivan Gorinov wrote: > Add setjmp/longjmp functions for x86_64. > The FPU control word and MXCSR control bits are preserved across calls. > > Signed-off-by: Ivan Gorinov > --- > 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 000..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+ This line should be put at the first line of this file, otherwise it causes checkpatch to report warnings. > + * > + * See arch/x86/include/asm/setjmp.h for jmp_buf format > + */ > + > +#include > + > +.text > +.align 8 > + > +ENTRY(setjmp) > + > + pop %rcx > + movq%rcx, (%rdi)/* Return address */ > + movq%rsp, 8 (%rdi) nits: can we eliminate the space between 8 and (%edi)? and others in this file too? > + 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) I don't think we need worry about these FP registers as U-Boot does not enable them at all. It looks your v1 patch does not include this but was added in v2. See the 32-bit setjmp/longjmp() implementation in U-Boot and there is no FP save/restore too. > + xorq%rax, %rax /* Direct invocation returns 0 */ > + jmpq*%rcx > + > +ENDPROC(setjmp) > + > +.align 8 > + > +ENTRY(longjmp) > + > + subq$8, %rsp > + > +/* Restore the control bits of MXCSR */ nits: comment indention should align to the assembly code > + > + stmxcsr (%rsp) > + movl$0x3f, %eax > + andl%eax, (%rsp) > + notl%eax > + andl68 (%rdi), %eax > + orl %eax, (%rsp) > + ldmxcsr (%rsp) > + > + fldcw 64 (%rdi) > + > + movq(%rdi), %rcx/* Return address */ > + movq8 (%rdi), %rsp > + movq16 (%rdi), %rbp > + movq24 (%rdi), %rbx > + movq32 (%rdi), %r12 > + movq40 (%rdi), %r13 > + movq48 (%rdi), %r14 > + movq56 (%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..000 > --- 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 > -#include > - > -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); > > -- Regards, Bin ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
> Am 14.06.2018 um 19:15 schrieb Ivan Gorinov : > > On Wed, Jun 13, 2018 at 05:36:26PM -0700, Ivan Gorinov wrote: > >>> 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. > > The "bootefi selftest" command works on qemu-x86_64 when $loadaddr is changed: > => env set loadaddr 0x1000 > > Another patch "x86: use EFI calling convention for efi_main on x86_64" > also needs to be applied. > > The self test starts but crashes on 'manage protocols': > > Tearing down 'graphical output' > Tearing down 'graphical output' succeeded > > Setting up 'manage protocols' > > > Same effect with a 64-bit build for Minnowboard. I see the same with the sandbox patch set I just sent. IIUC sonething goes wrong in varargs handling. Alex ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
On Wed, Jun 13, 2018 at 05:36:26PM -0700, Ivan Gorinov wrote: > > 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. The "bootefi selftest" command works on qemu-x86_64 when $loadaddr is changed: => env set loadaddr 0x1000 Another patch "x86: use EFI calling convention for efi_main on x86_64" also needs to be applied. The self test starts but crashes on 'manage protocols': Tearing down 'graphical output' Tearing down 'graphical output' succeeded Setting up 'manage protocols' Same effect with a 64-bit build for Minnowboard. ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
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 > > --- > > 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 000..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 > > + > > +.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 > > + andl68 (%rdi), %eax > > + orl %eax, (%rsp) > > + ldmxcsr (%rsp) > > + > > + fldcw 64 (%rdi) > > + > > + movq(%rdi), %rcx/* Return address */ > > + movq8 (%rdi), %rsp > > + movq16 (%rdi), %rbp > > + movq24 (%rdi), %rbx > > + movq32 (%rdi), %r12 > > + movq40 (%rdi), %r13 > > + movq48 (%rdi), %r14 > > + movq56 (%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..000 > > --- 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 > > -#include > > - > > -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); > > > >
Re: [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
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 But bootefi selftest with your patch leads to an immediate reset of the qemu-x86_64 board. Best regards Heinrich > > Signed-off-by: Ivan Gorinov > --- > 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 000..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 > + > +.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 > + andl68 (%rdi), %eax > + orl %eax, (%rsp) > + ldmxcsr (%rsp) > + > + fldcw 64 (%rdi) > + > + movq(%rdi), %rcx/* Return address */ > + movq8 (%rdi), %rsp > + movq16 (%rdi), %rbp > + movq24 (%rdi), %rbx > + movq32 (%rdi), %r12 > + movq40 (%rdi), %r13 > + movq48 (%rdi), %r14 > + movq56 (%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..000 > --- 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 > -#include > - > -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); > > ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
Add setjmp/longjmp functions for x86_64. The FPU control word and MXCSR control bits are preserved across calls. Signed-off-by: Ivan Gorinov --- 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 000..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 + +.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 + andl68 (%rdi), %eax + orl %eax, (%rsp) + ldmxcsr (%rsp) + + fldcw 64 (%rdi) + + movq(%rdi), %rcx/* Return address */ + movq8 (%rdi), %rsp + movq16 (%rdi), %rbp + movq24 (%rdi), %rbx + movq32 (%rdi), %r12 + movq40 (%rdi), %r13 + movq48 (%rdi), %r14 + movq56 (%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..000 --- 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 -#include - -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); -- 2.7.4 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
Add setjmp/longjmp functions for x86_64. The FPU control word and MXCSR control bits are preserved across calls. v2: Added the FPU control word and MXCSR to jmp_buf; Using ENTRY/ENDPROC macros. Ivan Gorinov (1): x86: Add 64-bit setjmp/longjmp implementation 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 -- 2.7.4 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot