/arch/unicore32/lib/backtrace.S

http://github.com/mirrors/linux · Assembly · 160 lines · 118 code · 19 blank · 23 comment · 10 complexity · 40a8b0926e78d8e68b9f082749f631a2 MD5 · raw file

  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * linux/arch/unicore32/lib/backtrace.S
  4. *
  5. * Code specific to PKUnity SoC and UniCore ISA
  6. *
  7. * Copyright (C) 2001-2010 GUAN Xue-tao
  8. */
  9. #include <linux/linkage.h>
  10. #include <asm/assembler.h>
  11. .text
  12. @ fp is 0 or stack frame
  13. #define frame v4
  14. #define sv_fp v5
  15. #define sv_pc v6
  16. #define offset v8
  17. ENTRY(__backtrace)
  18. mov r0, fp
  19. ENTRY(c_backtrace)
  20. #if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
  21. mov pc, lr
  22. ENDPROC(__backtrace)
  23. ENDPROC(c_backtrace)
  24. #else
  25. stm.w (v4 - v8, lr), [sp-] @ Save an extra register
  26. @ so we have a location...
  27. mov.a frame, r0 @ if frame pointer is zero
  28. beq no_frame @ we have no stack frames
  29. 1: stm.w (pc), [sp-] @ calculate offset of PC stored
  30. ldw.w r0, [sp]+, #4 @ by stmfd for this CPU
  31. adr r1, 1b
  32. sub offset, r0, r1
  33. /*
  34. * Stack frame layout:
  35. * optionally saved caller registers (r4 - r10)
  36. * saved fp
  37. * saved sp
  38. * saved lr
  39. * frame => saved pc
  40. * optionally saved arguments (r0 - r3)
  41. * saved sp => <next word>
  42. *
  43. * Functions start with the following code sequence:
  44. * mov ip, sp
  45. * stm.w (r0 - r3), [sp-] (optional)
  46. * corrected pc => stm.w sp, (..., fp, ip, lr, pc)
  47. */
  48. for_each_frame:
  49. 1001: ldw sv_pc, [frame+], #0 @ get saved pc
  50. 1002: ldw sv_fp, [frame+], #-12 @ get saved fp
  51. sub sv_pc, sv_pc, offset @ Correct PC for prefetching
  52. 1003: ldw r2, [sv_pc+], #-4 @ if stmfd sp, {args} exists,
  53. ldw r3, .Ldsi+4 @ adjust saved 'pc' back one
  54. cxor.a r3, r2 >> #14 @ instruction
  55. beq 201f
  56. sub r0, sv_pc, #4 @ allow for mov
  57. b 202f
  58. 201:
  59. sub r0, sv_pc, #8 @ allow for mov + stmia
  60. 202:
  61. ldw r1, [frame+], #-4 @ get saved lr
  62. mov r2, frame
  63. b.l dump_backtrace_entry
  64. ldw r1, [sv_pc+], #-4 @ if stmfd sp, {args} exists,
  65. ldw r3, .Ldsi+4
  66. cxor.a r3, r1 >> #14
  67. bne 1004f
  68. ldw r0, [frame+], #-8 @ get sp
  69. sub r0, r0, #4 @ point at the last arg
  70. b.l .Ldumpstm @ dump saved registers
  71. 1004: ldw r1, [sv_pc+], #0 @ if stmfd {, fp, ip, lr, pc}
  72. ldw r3, .Ldsi @ instruction exists,
  73. cxor.a r3, r1 >> #14
  74. bne 201f
  75. sub r0, frame, #16
  76. b.l .Ldumpstm @ dump saved registers
  77. 201:
  78. cxor.a sv_fp, #0 @ zero saved fp means
  79. beq no_frame @ no further frames
  80. csub.a sv_fp, frame @ next frame must be
  81. mov frame, sv_fp @ above the current frame
  82. bua for_each_frame
  83. 1006: adr r0, .Lbad
  84. mov r1, frame
  85. b.l printk
  86. no_frame: ldm.w (v4 - v8, pc), [sp]+
  87. ENDPROC(__backtrace)
  88. ENDPROC(c_backtrace)
  89. .pushsection __ex_table,"a"
  90. .align 3
  91. .long 1001b, 1006b
  92. .long 1002b, 1006b
  93. .long 1003b, 1006b
  94. .long 1004b, 1006b
  95. .popsection
  96. #define instr v4
  97. #define reg v5
  98. #define stack v6
  99. .Ldumpstm: stm.w (instr, reg, stack, v7, lr), [sp-]
  100. mov stack, r0
  101. mov instr, r1
  102. mov reg, #14
  103. mov v7, #0
  104. 1: mov r3, #1
  105. csub.a reg, #8
  106. bne 201f
  107. sub reg, reg, #3
  108. 201:
  109. cand.a instr, r3 << reg
  110. beq 2f
  111. add v7, v7, #1
  112. cxor.a v7, #6
  113. cmoveq v7, #1
  114. cmoveq r1, #'\n'
  115. cmovne r1, #' '
  116. ldw.w r3, [stack]+, #-4
  117. mov r2, reg
  118. csub.a r2, #8
  119. bsl 201f
  120. sub r2, r2, #3
  121. 201:
  122. cand.a instr, #0x40 @ if H is 1, high 16 regs
  123. beq 201f
  124. add r2, r2, #0x10 @ so r2 need add 16
  125. 201:
  126. adr r0, .Lfp
  127. b.l printk
  128. 2: sub.a reg, reg, #1
  129. bns 1b
  130. cxor.a v7, #0
  131. beq 201f
  132. adr r0, .Lcr
  133. b.l printk
  134. 201: ldm.w (instr, reg, stack, v7, pc), [sp]+
  135. .Lfp: .asciz "%cr%d:%08x"
  136. .Lcr: .asciz "\n"
  137. .Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n"
  138. .align
  139. .Ldsi: .word 0x92eec000 >> 14 @ stm.w sp, (... fp, ip, lr, pc)
  140. .word 0x92e10000 >> 14 @ stm.w sp, ()
  141. #endif