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.gori...@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);
> >  
> > 
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to