diff options
author | Alexander Graf <agraf@suse.de> | 2016-09-27 09:30:32 +0200 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2016-10-08 09:33:34 -0400 |
commit | 692fcdd800e1987e69294e11f8cf570771c528c5 (patch) | |
tree | e196a4c634a52f10502af3b41f54e74365917544 /arch/arm/include | |
parent | d40dbfb7405cb74946ba0a6e9058045fdb5bddaf (diff) | |
download | u-boot-imx-692fcdd800e1987e69294e11f8cf570771c528c5.zip u-boot-imx-692fcdd800e1987e69294e11f8cf570771c528c5.tar.gz u-boot-imx-692fcdd800e1987e69294e11f8cf570771c528c5.tar.bz2 |
arm: Add return value argument to longjmp
The normal longjmp command allows for a caller to pass the return value
of the setjmp() invocation. This patch adds that semantic to the arm
implementation of it and adjusts the efi_loader call respectively.
Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'arch/arm/include')
-rw-r--r-- | arch/arm/include/asm/setjmp.h | 32 |
1 files changed, 14 insertions, 18 deletions
diff --git a/arch/arm/include/asm/setjmp.h b/arch/arm/include/asm/setjmp.h index f7b97ef..df9934b 100644 --- a/arch/arm/include/asm/setjmp.h +++ b/arch/arm/include/asm/setjmp.h @@ -11,29 +11,26 @@ struct jmp_buf_data { ulong target; ulong regs[5]; + int ret; }; typedef struct jmp_buf_data jmp_buf[1]; static inline int setjmp(jmp_buf jmp) { - long r = 0; + jmp->ret = 0; #ifdef CONFIG_ARM64 asm volatile( "adr x1, jmp_target\n" - "str x1, %1\n" - "stp x26, x27, %2\n" - "stp x28, x29, %3\n" + "str x1, %0\n" + "stp x26, x27, %1\n" + "stp x28, x29, %2\n" "mov x1, sp\n" - "str x1, %4\n" - "b 2f\n" + "str x1, %3\n" "jmp_target: " - "mov %0, #1\n" - "2:\n" - : "+r" (r), "=m" (jmp->target), - "=m" (jmp->regs[0]), "=m" (jmp->regs[2]), - "=m" (jmp->regs[4]) + : "=m" (jmp->target), "=m" (jmp->regs[0]), + "=m" (jmp->regs[2]), "=m" (jmp->regs[4]) : : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", @@ -49,26 +46,25 @@ static inline int setjmp(jmp_buf jmp) #else "adr r0, jmp_target\n" #endif - "mov r1, %1\n" + "mov r1, %0\n" "mov r2, sp\n" "stm r1!, {r0, r2, r4, r5, r6, r7}\n" - "b 2f\n" ".align 2\n" "jmp_target: \n" - "mov %0, #1\n" - "2:\n" - : "+l" (r) + : : "l" (&jmp->target) : "r0", "r1", "r2", "r3", /* "r4", "r5", "r6", "r7", */ "r8", "r9", "r10", "r11", /* sp, */ "ip", "lr", "cc", "memory"); #endif - return r; + return jmp->ret; } -static inline __noreturn void longjmp(jmp_buf jmp) +static inline __noreturn void longjmp(jmp_buf jmp, int ret) { + jmp->ret = ret; + #ifdef CONFIG_ARM64 asm volatile( "ldr x0, %0\n" |