diff options
author | Alexander Graf <agraf@suse.de> | 2018-04-23 07:59:43 +0200 |
---|---|---|
committer | Andes <uboot@andestech.com> | 2018-05-29 14:43:12 +0800 |
commit | a7f99e5dd7dfa1853dee25e0fcb761eee0fb3ad3 (patch) | |
tree | 4a22ea380b55b8b74e0ca03d6c96dc472bdf07f1 | |
parent | c3c863880479edeb5b08226e622d13c91326e4a7 (diff) | |
download | u-boot-a7f99e5dd7dfa1853dee25e0fcb761eee0fb3ad3.zip u-boot-a7f99e5dd7dfa1853dee25e0fcb761eee0fb3ad3.tar.gz u-boot-a7f99e5dd7dfa1853dee25e0fcb761eee0fb3ad3.tar.bz2 |
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>
-rw-r--r-- | arch/riscv/include/asm/setjmp.h | 26 | ||||
-rw-r--r-- | arch/riscv/lib/Makefile | 1 | ||||
-rw-r--r-- | arch/riscv/lib/setjmp.S | 66 |
3 files changed, 93 insertions, 0 deletions
diff --git a/arch/riscv/include/asm/setjmp.h b/arch/riscv/include/asm/setjmp.h new file mode 100644 index 0000000..01ad6d0 --- /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 0b671f7..2eafd71 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -10,3 +10,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 0000000..103f359 --- /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 |