From 3fb8894d4004e80f14ad66c05ed72f722fc30586 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 10 Mar 2021 09:47:53 +0100 Subject: mips: Implement setjmp/longjmp/initjmp for 32BIT The header has been taken from glibc, the implementation itself is based on the newlib implementation. Signed-off-by: Sascha Hauer Signed-off-by: Ahmad Fatoum Signed-off-by: Sascha Hauer --- arch/mips/Kconfig | 1 + arch/mips/include/asm/setjmp.h | 32 +++++++++++++++++++++++++++ arch/mips/lib/Makefile | 1 + arch/mips/lib/setjmp.S | 50 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 arch/mips/include/asm/setjmp.h create mode 100644 arch/mips/lib/setjmp.S (limited to 'arch/mips') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 48f97c4bbf..7774abe948 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -303,6 +303,7 @@ choice config 32BIT bool "32-bit barebox" depends on CPU_SUPPORTS_32BIT_KERNEL && SYS_SUPPORTS_32BIT_KERNEL + select HAS_ARCH_SJLJ help Select this option if you want to build a 32-bit barebox. diff --git a/arch/mips/include/asm/setjmp.h b/arch/mips/include/asm/setjmp.h new file mode 100644 index 0000000000..81f4d4c15f --- /dev/null +++ b/arch/mips/include/asm/setjmp.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* + * Define the machine-dependent type `jmp_buf'. MIPS version. + * Copyright (C) 1992-2021 Free Software Foundation, Inc. + * This file is part of the GNU C Library. + */ + +#ifndef _MIPS_BITS_SETJMP_H +#define _MIPS_BITS_SETJMP_H 1 + +#include + +typedef struct __jmp_buf_internal_tag { + /* Program counter. */ + void *__pc; + + /* Stack pointer. */ + void *__sp; + + /* Callee-saved registers s0 through s7. */ + int __regs[8]; + + /* The frame pointer. */ + void *__fp; +} jmp_buf[1]; + +int setjmp(jmp_buf jmp) __attribute__((returns_twice)); +void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn)); +int initjmp(jmp_buf jmp, void __attribute__((noreturn)) (*func)(void), void *stack_top); + +#endif /* _MIPS_BITS_SETJMP_H */ diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 0761588ae8..88a2bdbd28 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -8,6 +8,7 @@ obj-y += reloc.o obj-y += sections.o obj-y += shutdown.o obj-y += dma-default.o +obj-$(CONFIG_HAS_ARCH_SJLJ) += setjmp.o obj-$(CONFIG_MIPS_OPTIMIZED_STRING_FUNCTIONS) += memcpy.o obj-$(CONFIG_MIPS_OPTIMIZED_STRING_FUNCTIONS) += memset.o diff --git a/arch/mips/lib/setjmp.S b/arch/mips/lib/setjmp.S new file mode 100644 index 0000000000..b09a7c5529 --- /dev/null +++ b/arch/mips/lib/setjmp.S @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +/* int setjmp (jmp_buf); */ +LEAF(setjmp) + sw ra, (0 * 4)(a0) + sw sp, (1 * 4)(a0) + sw s0, (2 * 4)(a0) + sw s1, (3 * 4)(a0) + sw s2, (4 * 4)(a0) + sw s3, (5 * 4)(a0) + sw s4, (6 * 4)(a0) + sw s5, (7 * 4)(a0) + sw s6, (8 * 4)(a0) + sw s7, (9 * 4)(a0) + sw fp, (10 * 4)(a0) + move v0, zero + j ra +END(setjmp) + +/* volatile void longjmp (jmp_buf, int); */ +LEAF(longjmp) + lw ra, (0 * 4)(a0) + lw sp, (1 * 4)(a0) + lw s0, (2 * 4)(a0) + lw s1, (3 * 4)(a0) + lw s2, (4 * 4)(a0) + lw s3, (5 * 4)(a0) + lw s4, (6 * 4)(a0) + lw s5, (7 * 4)(a0) + lw s6, (8 * 4)(a0) + lw s7, (9 * 4)(a0) + lw fp, (10 * 4)(a0) + bne a1, zero, 1f + li a1, 1 +1: + move v0, a1 + j ra +END(longjmp) + +/* int initjmp(jmp_buf jmp, void __noreturn (*func)(void), void *stack_top); */ +LEAF(initjmp) + sw a1, (0 * 4)(a0) + sw a2, (1 * 4)(a0) + move v0, zero + j ra +END(initjmp) -- cgit v1.2.3