[v3,1/8] riscv: Add setjmp/longjmp code

Message ID 20180423055950.78818-2-agraf@suse.de
State Accepted
Commit a7f99e5dd7dfa1853dee25e0fcb761eee0fb3ad3
Headers show
Series
  • riscv: Enable efi_loader support
Related show

Commit Message

Alexander Graf April 23, 2018, 5:59 a.m.
To support efi_loader we need to have platform support for setjmp/longjmp.
Add it here.

Signed-off-by: Alexander Graf <agraf@suse.de>

---

v1 -> v2:

  - Allow 32bit target
  - Also save/restore ra, sp
---
 arch/riscv/include/asm/setjmp.h | 26 ++++++++++++++++
 arch/riscv/lib/Makefile         |  1 +
 arch/riscv/lib/setjmp.S         | 66 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 93 insertions(+)
 create mode 100644 arch/riscv/include/asm/setjmp.h
 create mode 100644 arch/riscv/lib/setjmp.S

Comments

rick@andestech.com May 7, 2018, 2:25 a.m. | #1
> -----Original Message-----

> From: Alexander Graf [mailto:agraf@suse.de]

> Sent: Monday, April 23, 2018 2:00 PM

> To: u-boot@lists.denx.de

> Cc: Rick Jian-Zhi Chen(陳建志); Greentime Hu; Philipp Tomsich; Heinrich

> Schuchardt; schwab@suse.de

> Subject: [PATCH v3 1/8] riscv: Add setjmp/longjmp code

>

> To support efi_loader we need to have platform support for setjmp/longjmp.

> Add it here.

>

> Signed-off-by: Alexander Graf <agraf@suse.de>

>

> ---

>

> v1 -> v2:

>

>   - Allow 32bit target

>   - Also save/restore ra, sp

> ---

>  arch/riscv/include/asm/setjmp.h | 26 ++++++++++++++++

>  arch/riscv/lib/Makefile         |  1 +

>  arch/riscv/lib/setjmp.S         | 66

> +++++++++++++++++++++++++++++++++++++++++

>  3 files changed, 93 insertions(+)

>  create mode 100644 arch/riscv/include/asm/setjmp.h  create mode 100644

> arch/riscv/lib/setjmp.S

>

> diff --git a/arch/riscv/include/asm/setjmp.h b/arch/riscv/include/asm/setjmp.h

> new file mode 100644 index 0000000000..01ad6d081f

> --- /dev/null

> +++ b/arch/riscv/include/asm/setjmp.h

> @@ -0,0 +1,26 @@

> +/*

> + * (C) Copyright 2018 Alexander Graf <agraf@suse.de>

> + *

> + * SPDX-License-Identifier:  GPL-2.0+

> + */

> +

> +#ifndef _SETJMP_H_

> +#define _SETJMP_H_   1

> +

> +/*

> + * This really should be opaque, but the EFI implementation wrongly

> + * assumes that a 'struct jmp_buf_data' is defined.

> + */

> +struct jmp_buf_data {

> +     /* x2, x8, x9, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, sp */

> +     unsigned long s_regs[12];       /* s0 - s11 */

> +     unsigned long ra;

> +     unsigned long sp;

> +};

> +

> +typedef struct jmp_buf_data jmp_buf[1];

> +

> +int setjmp(jmp_buf jmp);

> +void longjmp(jmp_buf jmp, int ret);

> +

> +#endif /* _SETJMP_H_ */

> diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index

> 323cf3e835..6d97aa2719 100644

> --- a/arch/riscv/lib/Makefile

> +++ b/arch/riscv/lib/Makefile

> @@ -12,3 +12,4 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o

>  obj-$(CONFIG_CMD_GO) += boot.o

>  obj-y        += cache.o

>  obj-y        += interrupts.o

> +obj-y   += setjmp.o

> diff --git a/arch/riscv/lib/setjmp.S b/arch/riscv/lib/setjmp.S new file mode 100644

> index 0000000000..103f359185

> --- /dev/null

> +++ b/arch/riscv/lib/setjmp.S

> @@ -0,0 +1,66 @@

> +/*

> + * (C) 2018 Alexander Graf <agraf@suse.de>

> + *

> + * SPDX-License-Identifier:  GPL-2.0+

> + */

> +

> +#include <config.h>

> +#include <linux/linkage.h>

> +

> +#ifdef CONFIG_CPU_RISCV_64

> +#define STORE_IDX(reg, idx)  sd reg, (idx*8)(a0)

> +#define LOAD_IDX(reg, idx)   ld reg, (idx*8)(a0)

> +#else

> +#define STORE_IDX(reg, idx)  sw reg, (idx*4)(a0)

> +#define LOAD_IDX(reg, idx)   lw reg, (idx*4)(a0)

> +#endif

> +

> +.pushsection .text.setjmp, "ax"

> +ENTRY(setjmp)

> +     /* Preserve all callee-saved registers and the SP */

> +     STORE_IDX(s0, 0)

> +     STORE_IDX(s1, 1)

> +     STORE_IDX(s2, 2)

> +     STORE_IDX(s3, 3)

> +     STORE_IDX(s4, 4)

> +     STORE_IDX(s5, 5)

> +     STORE_IDX(s6, 6)

> +     STORE_IDX(s7, 7)

> +     STORE_IDX(s8, 8)

> +     STORE_IDX(s9, 9)

> +     STORE_IDX(s10, 10)

> +     STORE_IDX(s11, 11)

> +     STORE_IDX(ra, 12)

> +     STORE_IDX(sp, 13)

> +     li  a0, 0

> +     ret

> +ENDPROC(setjmp)

> +.popsection

> +

> +.pushsection .text.longjmp, "ax"

> +ENTRY(longjmp)

> +     LOAD_IDX(s0, 0)

> +     LOAD_IDX(s1, 1)

> +     LOAD_IDX(s2, 2)

> +     LOAD_IDX(s3, 3)

> +     LOAD_IDX(s4, 4)

> +     LOAD_IDX(s5, 5)

> +     LOAD_IDX(s6, 6)

> +     LOAD_IDX(s7, 7)

> +     LOAD_IDX(s8, 8)

> +     LOAD_IDX(s9, 9)

> +     LOAD_IDX(s10, 10)

> +     LOAD_IDX(s11, 11)

> +     LOAD_IDX(ra, 12)

> +     LOAD_IDX(sp, 13)

> +

> +     /* Move the return value in place, but return 1 if passed 0. */

> +     beq a1, zero, longjmp_1

> +     mv a0, a1

> +     ret

> +

> +     longjmp_1:

> +     li a0, 1

> +     ret

> +ENDPROC(longjmp)

> +.popsection


Reviewed-by: Rick Chen <rick@andestech.com>


> --

> 2.12.3


CONFIDENTIALITY NOTICE:

This e-mail (and its attachments) may contain confidential and legally privileged information or information protected from disclosure. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein is strictly prohibited. In this case, please immediately notify the sender by return e-mail, delete the message (and any accompanying documents) and destroy all printed hard copies. Thank you for your cooperation.

Copyright ANDES TECHNOLOGY CORPORATION - All Rights Reserved.

Patch

diff --git a/arch/riscv/include/asm/setjmp.h b/arch/riscv/include/asm/setjmp.h
new file mode 100644
index 0000000000..01ad6d081f
--- /dev/null
+++ b/arch/riscv/include/asm/setjmp.h
@@ -0,0 +1,26 @@ 
+/*
+ * (C) Copyright 2018 Alexander Graf <agraf@suse.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _SETJMP_H_
+#define _SETJMP_H_	1
+
+/*
+ * This really should be opaque, but the EFI implementation wrongly
+ * assumes that a 'struct jmp_buf_data' is defined.
+ */
+struct jmp_buf_data {
+	/* x2, x8, x9, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, sp */
+	unsigned long s_regs[12];	/* s0 - s11 */
+	unsigned long ra;
+	unsigned long sp;
+};
+
+typedef struct jmp_buf_data jmp_buf[1];
+
+int setjmp(jmp_buf jmp);
+void longjmp(jmp_buf jmp, int ret);
+
+#endif /* _SETJMP_H_ */
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 323cf3e835..6d97aa2719 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -12,3 +12,4 @@  obj-$(CONFIG_CMD_BOOTM) += bootm.o
 obj-$(CONFIG_CMD_GO) += boot.o
 obj-y	+= cache.o
 obj-y	+= interrupts.o
+obj-y   += setjmp.o
diff --git a/arch/riscv/lib/setjmp.S b/arch/riscv/lib/setjmp.S
new file mode 100644
index 0000000000..103f359185
--- /dev/null
+++ b/arch/riscv/lib/setjmp.S
@@ -0,0 +1,66 @@ 
+/*
+ * (C) 2018 Alexander Graf <agraf@suse.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+
+#ifdef CONFIG_CPU_RISCV_64
+#define STORE_IDX(reg, idx)	sd reg, (idx*8)(a0)
+#define LOAD_IDX(reg, idx)	ld reg, (idx*8)(a0)
+#else
+#define STORE_IDX(reg, idx)	sw reg, (idx*4)(a0)
+#define LOAD_IDX(reg, idx)	lw reg, (idx*4)(a0)
+#endif
+
+.pushsection .text.setjmp, "ax"
+ENTRY(setjmp)
+	/* Preserve all callee-saved registers and the SP */
+	STORE_IDX(s0, 0)
+	STORE_IDX(s1, 1)
+	STORE_IDX(s2, 2)
+	STORE_IDX(s3, 3)
+	STORE_IDX(s4, 4)
+	STORE_IDX(s5, 5)
+	STORE_IDX(s6, 6)
+	STORE_IDX(s7, 7)
+	STORE_IDX(s8, 8)
+	STORE_IDX(s9, 9)
+	STORE_IDX(s10, 10)
+	STORE_IDX(s11, 11)
+	STORE_IDX(ra, 12)
+	STORE_IDX(sp, 13)
+	li  a0, 0
+	ret
+ENDPROC(setjmp)
+.popsection
+
+.pushsection .text.longjmp, "ax"
+ENTRY(longjmp)
+	LOAD_IDX(s0, 0)
+	LOAD_IDX(s1, 1)
+	LOAD_IDX(s2, 2)
+	LOAD_IDX(s3, 3)
+	LOAD_IDX(s4, 4)
+	LOAD_IDX(s5, 5)
+	LOAD_IDX(s6, 6)
+	LOAD_IDX(s7, 7)
+	LOAD_IDX(s8, 8)
+	LOAD_IDX(s9, 9)
+	LOAD_IDX(s10, 10)
+	LOAD_IDX(s11, 11)
+	LOAD_IDX(ra, 12)
+	LOAD_IDX(sp, 13)
+
+	/* Move the return value in place, but return 1 if passed 0. */
+	beq a1, zero, longjmp_1
+	mv a0, a1
+	ret
+
+	longjmp_1:
+	li a0, 1
+	ret
+ENDPROC(longjmp)
+.popsection