setjmp.h 1.8 KB

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