public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Ivan Gorinov <ivan.gorinov@intel.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation
Date: Wed, 6 Jun 2018 11:28:01 -0700	[thread overview]
Message-ID: <20180606182801.GA35519@intel.com> (raw)

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

             reply	other threads:[~2018-06-06 18:28 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-06 18:28 Ivan Gorinov [this message]
2018-06-12 15:57 ` [U-Boot] [PATCH v2] x86: Add 64-bit setjmp/longjmp implementation 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
  -- strict thread matches above, loose matches on Subject: below --
2018-06-06 18:27 Ivan Gorinov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180606182801.GA35519@intel.com \
    --to=ivan.gorinov@intel.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox