Message ID | 20240517-mips-efi-v1-1-79096e3ca3b3@flygoat.com |
---|---|
State | New |
Delegated to: | Heinrich Schuchardt |
Headers | show |
Series | MIPS: Enable EFI support | expand |
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 >
在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 --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
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(+)