1 /* 2 * (C) Copyright 2016 3 * Alexander Graf <agraf@suse.de> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #ifndef _SETJMP_H_ 9 #define _SETJMP_H_ 1 10 11 struct jmp_buf_data { 12 ulong target; 13 ulong regs[5]; 14 }; 15 16 typedef struct jmp_buf_data jmp_buf[1]; 17 18 static inline int setjmp(jmp_buf jmp) 19 { 20 long r = 0; 21 22 #ifdef CONFIG_ARM64 23 asm volatile( 24 "adr x1, jmp_target\n" 25 "str x1, %1\n" 26 "stp x26, x27, %2\n" 27 "stp x28, x29, %3\n" 28 "mov x1, sp\n" 29 "str x1, %4\n" 30 "b 2f\n" 31 "jmp_target: " 32 "mov %0, #1\n" 33 "2:\n" 34 : "+r" (r), "=m" (jmp->target), 35 "=m" (jmp->regs[0]), "=m" (jmp->regs[2]), 36 "=m" (jmp->regs[4]) 37 : 38 : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", 39 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", 40 "x16", "x17", "x18", "x19", "x20", "x21", "x22", 41 "x23", "x24", "x25", /* x26, x27, x28, x29, sp */ 42 "x30", "cc", "memory"); 43 #else 44 asm volatile( 45 #ifdef CONFIG_SYS_THUMB_BUILD 46 "adr r0, jmp_target + 1\n" 47 #else 48 "adr r0, jmp_target\n" 49 #endif 50 "mov r1, %1\n" 51 "mov r2, sp\n" 52 "stm r1, {r0, r2, r4, r5, r6, r7}\n" 53 "b 2f\n" 54 "jmp_target: " 55 "mov %0, #1\n" 56 "2:\n" 57 : "+l" (r) 58 : "l" (&jmp->target) 59 : "r0", "r1", "r2", "r3", /* "r4", "r5", "r6", "r7", */ 60 "r8", "r9", "r10", "r11", /* sp, */ "ip", "lr", 61 "cc", "memory"); 62 #endif 63 64 printf("%s:%d target=%#lx\n", __func__, __LINE__, jmp->target); 65 66 return r; 67 } 68 69 static inline __noreturn void longjmp(jmp_buf jmp) 70 { 71 #ifdef CONFIG_ARM64 72 asm volatile( 73 "ldr x0, %0\n" 74 "ldr x1, %3\n" 75 "mov sp, x1\n" 76 "ldp x26, x27, %1\n" 77 "ldp x28, x25, %2\n" 78 "mov x29, x25\n" 79 "br x0\n" 80 : 81 : "m" (jmp->target), "m" (jmp->regs[0]), "m" (jmp->regs[2]), 82 "m" (jmp->regs[4]) 83 : "x0", "x1", "x25", "x26", "x27", "x28"); 84 #else 85 asm volatile( 86 "mov r1, %0\n" 87 "ldm r1, {r0, r2, r4, r5, r6, r7}\n" 88 "mov sp, r2\n" 89 "bx r0\n" 90 : 91 : "l" (&jmp->target) 92 : "r1"); 93 #endif 94 95 while (1) { } 96 } 97 98 99 #endif /* _SETJMP_H_ */ 100