* [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
@ 2018-06-06 18:27 Ivan Gorinov
0 siblings, 0 replies; 7+ messages in thread
From: Ivan Gorinov @ 2018-06-06 18:27 UTC (permalink / raw)
To: u-boot
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
^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
2018-06-06 18:28 Ivan Gorinov
2018-06-12 15:57 ` Heinrich Schuchardt
@ 2018-06-19 8:02 ` Bin Meng
1 sibling, 0 replies; 7+ messages in thread
From: Bin Meng @ 2018-06-19 8:02 UTC (permalink / raw)
To: u-boot
Hi Ivan,
On Thu, Jun 7, 2018 at 2:28 AM, Ivan Gorinov <ivan.gorinov@intel.com> 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 <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+
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 <linux/linkage.h>
> +
> +.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
> + 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);
>
> --
Regards,
Bin
^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
2018-06-14 17:15 ` Ivan Gorinov
@ 2018-06-14 17:49 ` Alexander Graf
0 siblings, 0 replies; 7+ messages in thread
From: Alexander Graf @ 2018-06-14 17:49 UTC (permalink / raw)
To: u-boot
> Am 14.06.2018 um 19:15 schrieb Ivan Gorinov <ivan.gorinov@intel.com>:
>
> 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 0x10000000
>
> 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
^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
2018-06-14 0:36 ` Ivan Gorinov
@ 2018-06-14 17:15 ` Ivan Gorinov
2018-06-14 17:49 ` Alexander Graf
0 siblings, 1 reply; 7+ messages in thread
From: Ivan Gorinov @ 2018-06-14 17:15 UTC (permalink / raw)
To: u-boot
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 0x10000000
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.
^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
2018-06-12 15:57 ` Heinrich Schuchardt
@ 2018-06-14 0:36 ` Ivan Gorinov
2018-06-14 17:15 ` Ivan Gorinov
0 siblings, 1 reply; 7+ messages in thread
From: Ivan Gorinov @ 2018-06-14 0:36 UTC (permalink / raw)
To: u-boot
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);
> >
> >
^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
2018-06-06 18:28 Ivan Gorinov
@ 2018-06-12 15:57 ` Heinrich Schuchardt
2018-06-14 0:36 ` Ivan Gorinov
2018-06-19 8:02 ` Bin Meng
1 sibling, 1 reply; 7+ messages in thread
From: Heinrich Schuchardt @ 2018-06-12 15:57 UTC (permalink / raw)
To: u-boot
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 <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);
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
@ 2018-06-06 18:28 Ivan Gorinov
2018-06-12 15:57 ` Heinrich Schuchardt
2018-06-19 8:02 ` Bin Meng
0 siblings, 2 replies; 7+ messages in thread
From: Ivan Gorinov @ 2018-06-06 18:28 UTC (permalink / raw)
To: u-boot
Add setjmp/longjmp functions for x86_64.
The FPU control word and MXCSR control bits are preserved across calls.
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);
--
2.7.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2018-06-19 8:02 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-06 18:27 [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation Ivan Gorinov
2018-06-06 18:28 Ivan Gorinov
2018-06-12 15:57 ` Heinrich Schuchardt
2018-06-14 0:36 ` Ivan Gorinov
2018-06-14 17:15 ` Ivan Gorinov
2018-06-14 17:49 ` Alexander Graf
2018-06-19 8:02 ` Bin Meng
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.