diff mbox series

[1/7] MIPS: Implement setjmp

Message ID 20240517-mips-efi-v1-1-79096e3ca3b3@flygoat.com
State New
Delegated to: Heinrich Schuchardt
Headers show
Series MIPS: Enable EFI support | expand

Commit Message

Jiaxun Yang May 17, 2024, 4:32 p.m. UTC
Implement setjmp with o32/n64 ABI's standard stack frame.
Note that those two ABIs slightly disagreed on placement of
registers so they are being implemented in two different
files.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/include/asm/setjmp.h | 36 +++++++++++++++++++++++++++
 arch/mips/lib/Makefile         |  2 ++
 arch/mips/lib/setjmp32.S       | 51 ++++++++++++++++++++++++++++++++++++++
 arch/mips/lib/setjmp64.S       | 56 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 145 insertions(+)

Comments

Heinrich Schuchardt May 17, 2024, 9:11 p.m. UTC | #1
Am 17. Mai 2024 18:32:52 MESZ schrieb Jiaxun Yang <jiaxun.yang@flygoat.com>:
>Implement setjmp with o32/n64 ABI's standard stack frame.
>Note that those two ABIs slightly disagreed on placement of
>registers so they are being implemented in two different
>files.
>
>Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>---
> arch/mips/include/asm/setjmp.h | 36 +++++++++++++++++++++++++++
> arch/mips/lib/Makefile         |  2 ++
> arch/mips/lib/setjmp32.S       | 51 ++++++++++++++++++++++++++++++++++++++
> arch/mips/lib/setjmp64.S       | 56 ++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 145 insertions(+)
>
>diff --git a/arch/mips/include/asm/setjmp.h b/arch/mips/include/asm/setjmp.h
>new file mode 100644
>index 000000000000..afa2ffb007e6
>--- /dev/null
>+++ b/arch/mips/include/asm/setjmp.h
>@@ -0,0 +1,36 @@
>+/* SPDX-License-Identifier: GPL-2.0+ */
>+/*
>+ * Copyright (c) 2024 Jiaxun Yang <jiaxun.yang@flygoat.com>
>+ */
>+
>+#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.
>+ */
>+#if __mips == 64
>+struct jmp_buf_data {
>+	unsigned long ra;
>+	unsigned long sp;
>+	unsigned long fp;
>+	unsigned long gp;
>+	unsigned long s_regs[8];	/* s0 - s7 */
>+};
>+#else
>+struct jmp_buf_data {
>+	unsigned long ra;
>+	unsigned long sp;
>+	unsigned long s_regs[8];	/* s0 - s7 */
>+	unsigned long fp;
>+	unsigned long gp;
>+};

As the jumpbuffer is only used inside U-Boot we should be able to use the same register sequence independant of the bitness.

Best regards

Heinrich

>+#endif
>+
>+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/mips/lib/Makefile b/arch/mips/lib/Makefile
>index 1621cc9a1ff9..e36dfd0547b5 100644
>--- a/arch/mips/lib/Makefile
>+++ b/arch/mips/lib/Makefile
>@@ -10,6 +10,8 @@ obj-y	+= reloc.o
> obj-y	+= stack.o
> obj-y	+= traps.o
> 
>+obj-$(CONFIG_32BIT) += setjmp32.o
>+obj-$(CONFIG_64BIT) += setjmp64.o
> obj-$(CONFIG_CMD_BOOTM) += bootm.o
> obj-$(CONFIG_CMD_GO) += boot.o
> obj-$(CONFIG_SPL_BUILD) += spl.o
>diff --git a/arch/mips/lib/setjmp32.S b/arch/mips/lib/setjmp32.S
>new file mode 100644
>index 000000000000..4a2661d29249
>--- /dev/null
>+++ b/arch/mips/lib/setjmp32.S
>@@ -0,0 +1,51 @@
>+/* SPDX-License-Identifier: GPL-2.0+ */
>+/*
>+ * Copyright (c) 2024 Jiaxun Yang <jiaxun.yang@flygoat.com>
>+ */
>+
>+#include <linux/linkage.h>
>+#include <asm/regdef.h>
>+
>+.pushsection .text.setjmp, "ax"
>+ENTRY(setjmp)
>+	sw      ra,  0(a0)
>+	sw      sp,  4(a0)
>+	sw      s0,  8(a0)
>+	sw      s1, 12(a0)
>+	sw      s2, 16(a0)
>+	sw      s3, 20(a0)
>+	sw      s4, 24(a0)
>+	sw      s5, 28(a0)
>+	sw      s6, 32(a0)
>+	sw      s7, 36(a0)
>+	sw      fp, 40(a0)
>+	sw      gp, 44(a0)
>+
>+	move	v0, zero
>+	jr	ra
>+ENDPROC(setjmp)
>+.popsection
>+
>+.pushsection .text.longjmp, "ax"
>+ENTRY(longjmp)
>+	lw      ra,  0(a0)
>+	lw      sp,  4(a0)
>+	lw      s0,  8(a0)
>+	lw      s1, 12(a0)
>+	lw      s2, 16(a0)
>+	lw      s3, 20(a0)
>+	lw      s4, 24(a0)
>+	lw      s5, 28(a0)
>+	lw      s6, 32(a0)
>+	lw      s7, 36(a0)
>+	lw      fp, 40(a0)
>+	lw      gp, 44(a0)
>+
>+	beqz	a1, 1f
>+	move	v0, a1
>+	jr	ra
>+1:
>+	li	v0, 1
>+	jr	ra
>+ENDPROC(longjmp)
>+.popsection
>diff --git a/arch/mips/lib/setjmp64.S b/arch/mips/lib/setjmp64.S
>new file mode 100644
>index 000000000000..6f615bb10014
>--- /dev/null
>+++ b/arch/mips/lib/setjmp64.S
>@@ -0,0 +1,56 @@
>+/* SPDX-License-Identifier: GPL-2.0+ */
>+/*
>+ * Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
>+ * Copyright (c) 2017 Lemote Co.Ltd
>+ * 	Author: Heiher <r@hev.cc>
>+ * Copyright (c) 2024 Jiaxun Yang <jiaxun.yang@flygoat.com>
>+ */
>+
>+#include <linux/linkage.h>
>+#include <asm/regdef.h>
>+
>+.pushsection .text.setjmp, "ax"
>+ENTRY(setjmp)
>+	sd	ra, 0x00(a0)
>+	sd	sp, 0x08(a0)
>+	sd	fp, 0x10(a0)
>+	sd	gp, 0x18(a0)
>+
>+	sd	s0, 0x20(a0)
>+	sd	s1, 0x28(a0)
>+	sd	s2, 0x30(a0)
>+	sd	s3, 0x38(a0)
>+	sd	s4, 0x40(a0)
>+	sd	s5, 0x48(a0)
>+	sd	s6, 0x50(a0)
>+	sd	s7, 0x58(a0)
>+
>+	move	v0, zero
>+	jr	ra
>+ENDPROC(setjmp)
>+.popsection
>+
>+.pushsection .text.longjmp, "ax"
>+ENTRY(longjmp)
>+	ld	ra, 0x00(a0)
>+	ld	sp, 0x08(a0)
>+	ld	fp, 0x10(a0)
>+	ld	gp, 0x18(a0)
>+
>+	ld	s0, 0x20(a0)
>+	ld	s1, 0x28(a0)
>+	ld	s2, 0x30(a0)
>+	ld	s3, 0x38(a0)
>+	ld	s4, 0x40(a0)
>+	ld	s5, 0x48(a0)
>+	ld	s6, 0x50(a0)
>+	ld	s7, 0x58(a0)
>+
>+	beqz	a1, 1f
>+	move	v0, a1
>+	jr	ra
>+1:
>+	li	v0, 1
>+	jr	ra
>+ENDPROC(longjmp)
>+.popsection
>
Jiaxun Yang May 17, 2024, 10:14 p.m. UTC | #2
在2024年5月17日五月 下午10:11,Heinrich Schuchardt写道:
[...]
> As the jumpbuffer is only used inside U-Boot we should be able to use 
> the same register sequence independant of the bitness.

Hi Heinrich,

I chose to use ABI's stack frame because GDB requires it to perform proper
unwinding and it helped debugging a lot.

But I'm fine with unifying them if you think it's necessary, what's your opinion?

Thanks
- Jiaxun

>
> Best regards
>
> Heinrich
>
diff mbox series

Patch

diff --git a/arch/mips/include/asm/setjmp.h b/arch/mips/include/asm/setjmp.h
new file mode 100644
index 000000000000..afa2ffb007e6
--- /dev/null
+++ b/arch/mips/include/asm/setjmp.h
@@ -0,0 +1,36 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2024 Jiaxun Yang <jiaxun.yang@flygoat.com>
+ */
+
+#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.
+ */
+#if __mips == 64
+struct jmp_buf_data {
+	unsigned long ra;
+	unsigned long sp;
+	unsigned long fp;
+	unsigned long gp;
+	unsigned long s_regs[8];	/* s0 - s7 */
+};
+#else
+struct jmp_buf_data {
+	unsigned long ra;
+	unsigned long sp;
+	unsigned long s_regs[8];	/* s0 - s7 */
+	unsigned long fp;
+	unsigned long gp;
+};
+#endif
+
+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/mips/lib/Makefile b/arch/mips/lib/Makefile
index 1621cc9a1ff9..e36dfd0547b5 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -10,6 +10,8 @@  obj-y	+= reloc.o
 obj-y	+= stack.o
 obj-y	+= traps.o
 
+obj-$(CONFIG_32BIT) += setjmp32.o
+obj-$(CONFIG_64BIT) += setjmp64.o
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
 obj-$(CONFIG_CMD_GO) += boot.o
 obj-$(CONFIG_SPL_BUILD) += spl.o
diff --git a/arch/mips/lib/setjmp32.S b/arch/mips/lib/setjmp32.S
new file mode 100644
index 000000000000..4a2661d29249
--- /dev/null
+++ b/arch/mips/lib/setjmp32.S
@@ -0,0 +1,51 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2024 Jiaxun Yang <jiaxun.yang@flygoat.com>
+ */
+
+#include <linux/linkage.h>
+#include <asm/regdef.h>
+
+.pushsection .text.setjmp, "ax"
+ENTRY(setjmp)
+	sw      ra,  0(a0)
+	sw      sp,  4(a0)
+	sw      s0,  8(a0)
+	sw      s1, 12(a0)
+	sw      s2, 16(a0)
+	sw      s3, 20(a0)
+	sw      s4, 24(a0)
+	sw      s5, 28(a0)
+	sw      s6, 32(a0)
+	sw      s7, 36(a0)
+	sw      fp, 40(a0)
+	sw      gp, 44(a0)
+
+	move	v0, zero
+	jr	ra
+ENDPROC(setjmp)
+.popsection
+
+.pushsection .text.longjmp, "ax"
+ENTRY(longjmp)
+	lw      ra,  0(a0)
+	lw      sp,  4(a0)
+	lw      s0,  8(a0)
+	lw      s1, 12(a0)
+	lw      s2, 16(a0)
+	lw      s3, 20(a0)
+	lw      s4, 24(a0)
+	lw      s5, 28(a0)
+	lw      s6, 32(a0)
+	lw      s7, 36(a0)
+	lw      fp, 40(a0)
+	lw      gp, 44(a0)
+
+	beqz	a1, 1f
+	move	v0, a1
+	jr	ra
+1:
+	li	v0, 1
+	jr	ra
+ENDPROC(longjmp)
+.popsection
diff --git a/arch/mips/lib/setjmp64.S b/arch/mips/lib/setjmp64.S
new file mode 100644
index 000000000000..6f615bb10014
--- /dev/null
+++ b/arch/mips/lib/setjmp64.S
@@ -0,0 +1,56 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+ * Copyright (c) 2017 Lemote Co.Ltd
+ * 	Author: Heiher <r@hev.cc>
+ * Copyright (c) 2024 Jiaxun Yang <jiaxun.yang@flygoat.com>
+ */
+
+#include <linux/linkage.h>
+#include <asm/regdef.h>
+
+.pushsection .text.setjmp, "ax"
+ENTRY(setjmp)
+	sd	ra, 0x00(a0)
+	sd	sp, 0x08(a0)
+	sd	fp, 0x10(a0)
+	sd	gp, 0x18(a0)
+
+	sd	s0, 0x20(a0)
+	sd	s1, 0x28(a0)
+	sd	s2, 0x30(a0)
+	sd	s3, 0x38(a0)
+	sd	s4, 0x40(a0)
+	sd	s5, 0x48(a0)
+	sd	s6, 0x50(a0)
+	sd	s7, 0x58(a0)
+
+	move	v0, zero
+	jr	ra
+ENDPROC(setjmp)
+.popsection
+
+.pushsection .text.longjmp, "ax"
+ENTRY(longjmp)
+	ld	ra, 0x00(a0)
+	ld	sp, 0x08(a0)
+	ld	fp, 0x10(a0)
+	ld	gp, 0x18(a0)
+
+	ld	s0, 0x20(a0)
+	ld	s1, 0x28(a0)
+	ld	s2, 0x30(a0)
+	ld	s3, 0x38(a0)
+	ld	s4, 0x40(a0)
+	ld	s5, 0x48(a0)
+	ld	s6, 0x50(a0)
+	ld	s7, 0x58(a0)
+
+	beqz	a1, 1f
+	move	v0, a1
+	jr	ra
+1:
+	li	v0, 1
+	jr	ra
+ENDPROC(longjmp)
+.popsection