diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2021-03-10 09:47:54 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2021-03-17 11:55:30 +0100 |
commit | 1825472a82a849de4860cad563df72218028d4f0 (patch) | |
tree | 0f0aa641bd86d4a9112e7f17cbe6cce88d6e6c90 /arch/powerpc | |
parent | 3fb8894d4004e80f14ad66c05ed72f722fc30586 (diff) | |
download | barebox-1825472a82a849de4860cad563df72218028d4f0.tar.gz barebox-1825472a82a849de4860cad563df72218028d4f0.tar.xz |
powerpc: Implement initjmp/setjmp/longjmp
Implementation has been taken from newlib as this is much simpler than
the glibc version.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/Kconfig | 1 | ||||
-rw-r--r-- | arch/powerpc/include/asm/linkage.h | 5 | ||||
-rw-r--r-- | arch/powerpc/include/asm/setjmp.h | 21 | ||||
-rw-r--r-- | arch/powerpc/lib/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/lib/setjmp.S | 86 |
5 files changed, 114 insertions, 1 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 90ec7b1702..376c1bf42b 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -6,6 +6,7 @@ config PPC select HAS_CACHE select GENERIC_FIND_NEXT_BIT select OFTREE + select HAS_ARCH_SJLJ default y choice diff --git a/arch/powerpc/include/asm/linkage.h b/arch/powerpc/include/asm/linkage.h new file mode 100644 index 0000000000..370eb27728 --- /dev/null +++ b/arch/powerpc/include/asm/linkage.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_LINKAGE_H +#define _ASM_POWERPC_LINKAGE_H + +#endif /* _ASM_POWERPC_LINKAGE_H */ diff --git a/arch/powerpc/include/asm/setjmp.h b/arch/powerpc/include/asm/setjmp.h new file mode 100644 index 0000000000..91bfcdb7f4 --- /dev/null +++ b/arch/powerpc/include/asm/setjmp.h @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH + * (C) Copyright 2016 Alexander Graf <agraf@suse.de> + */ + +#ifndef _SETJMP_H_ +#define _SETJMP_H_ 1 + +#include <asm/types.h> + +typedef struct __jmp_buf_internal_tag { + long int __regs[24]; +} 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 /* _SETJMP_H_ */ diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index ba2f078b62..405351c199 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -9,4 +9,4 @@ obj-$(CONFIG_CMD_BOOTM) += ppclinux.o obj-$(CONFIG_MODULES) += module.o obj-y += crtsavres.o obj-y += reloc.o - +obj-y += setjmp.o diff --git a/arch/powerpc/lib/setjmp.S b/arch/powerpc/lib/setjmp.S new file mode 100644 index 0000000000..021a57eebc --- /dev/null +++ b/arch/powerpc/lib/setjmp.S @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This is a simple version of setjmp and longjmp for the PowerPC. + * Ian Lance Taylor, Cygnus Support, 9 Feb 1994. + */ + +#include <linux/linkage.h> +#include <asm/ppc_asm.tmpl> + +ENTRY(setjmp) + addi r3,r3,7 # align to 8 byte boundary + rlwinm r3,r3,0,0,28 + stw r1,0(r3) # offset 0 + stwu r2,4(r3) # offset 4 + stwu r13,4(r3) # offset 8 + stwu r14,4(r3) # offset 12 + stwu r15,4(r3) # offset 16 + stwu r16,4(r3) # offset 20 + stwu r17,4(r3) # offset 24 + stwu r18,4(r3) # offset 28 + stwu r19,4(r3) # offset 32 + stwu r20,4(r3) # offset 36 + stwu r21,4(r3) # offset 40 + stwu r22,4(r3) # offset 44 + stwu r23,4(r3) # offset 48 + stwu r24,4(r3) # offset 52 + stwu r25,4(r3) # offset 56 + stwu r26,4(r3) # offset 60 + stwu r27,4(r3) # offset 64 + stwu r28,4(r3) # offset 68 + stwu r29,4(r3) # offset 72 + stwu r30,4(r3) # offset 76 + stwu r31,4(r3) # offset 80 + mflr r4 + stwu r4,4(r3) # offset 84 + mfcr r4 + stwu r4,4(r3) # offset 88 + + li r3,0 + blr +END(setjmp) + +ENTRY(longjmp) + addi r3,r3,7 # align to 8 byte boundary + rlwinm r3,r3,0,0,28 + lwz r1,0(r3) # offset 0 + lwzu r2,4(r3) # offset 4 + lwzu r13,4(r3) # offset 8 + lwzu r14,4(r3) # offset 12 + lwzu r15,4(r3) # offset 16 + lwzu r16,4(r3) # offset 20 + lwzu r17,4(r3) # offset 24 + lwzu r18,4(r3) # offset 28 + lwzu r19,4(r3) # offset 32 + lwzu r20,4(r3) # offset 36 + lwzu r21,4(r3) # offset 40 + lwzu r22,4(r3) # offset 44 + lwzu r23,4(r3) # offset 48 + lwzu r24,4(r3) # offset 52 + lwzu r25,4(r3) # offset 56 + lwzu r26,4(r3) # offset 60 + lwzu r27,4(r3) # offset 64 + lwzu r28,4(r3) # offset 68 + lwzu r29,4(r3) # offset 72 + lwzu r30,4(r3) # offset 76 + lwzu r31,4(r3) # offset 80 + lwzu r5,4(r3) # offset 84 + mtlr r5 + lwzu r5,4(r3) # offset 88 + mtcrf 255,r5 + + mr. r3,r4 + bclr+ 4,2 + li r3,1 + blr +END(longjmp) + +ENTRY(initjmp) + addi r3,r3,7 # align to 8 byte boundary + rlwinm r3,r3,0,0,28 + stw r5,0(r3) # offset 0 + stwu r4,88(r3) # offset 88 + li r3,0 + blr +END(initjmp) |