mcount.S 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
  3. #include <linux/linkage.h>
  4. #include <asm/ftrace.h>
  5. #include <abi/entry.h>
  6. #include <asm/asm-offsets.h>
  7. /*
  8. * csky-gcc with -pg will put the following asm after prologue:
  9. * push r15
  10. * jsri _mcount
  11. *
  12. * stack layout after mcount_enter in _mcount():
  13. *
  14. * current sp => 0:+-------+
  15. * | a0-a3 | -> must save all argument regs
  16. * +16:+-------+
  17. * | lr | -> _mcount lr (instrumente function's pc)
  18. * +20:+-------+
  19. * | fp=r8 | -> instrumented function fp
  20. * +24:+-------+
  21. * | plr | -> instrumented function lr (parent's pc)
  22. * +-------+
  23. */
  24. .macro mcount_enter
  25. subi sp, 24
  26. stw a0, (sp, 0)
  27. stw a1, (sp, 4)
  28. stw a2, (sp, 8)
  29. stw a3, (sp, 12)
  30. stw lr, (sp, 16)
  31. stw r8, (sp, 20)
  32. .endm
  33. .macro mcount_exit
  34. ldw a0, (sp, 0)
  35. ldw a1, (sp, 4)
  36. ldw a2, (sp, 8)
  37. ldw a3, (sp, 12)
  38. ldw t1, (sp, 16)
  39. ldw r8, (sp, 20)
  40. ldw lr, (sp, 24)
  41. addi sp, 28
  42. jmp t1
  43. .endm
  44. .macro mcount_enter_regs
  45. subi sp, 8
  46. stw lr, (sp, 0)
  47. stw r8, (sp, 4)
  48. SAVE_REGS_FTRACE
  49. .endm
  50. .macro mcount_exit_regs
  51. RESTORE_REGS_FTRACE
  52. subi sp, 152
  53. ldw t1, (sp, 4)
  54. addi sp, 152
  55. ldw r8, (sp, 4)
  56. ldw lr, (sp, 8)
  57. addi sp, 12
  58. jmp t1
  59. .endm
  60. .macro save_return_regs
  61. subi sp, 16
  62. stw a0, (sp, 0)
  63. stw a1, (sp, 4)
  64. stw a2, (sp, 8)
  65. stw a3, (sp, 12)
  66. .endm
  67. .macro restore_return_regs
  68. mov lr, a0
  69. ldw a0, (sp, 0)
  70. ldw a1, (sp, 4)
  71. ldw a2, (sp, 8)
  72. ldw a3, (sp, 12)
  73. addi sp, 16
  74. .endm
  75. .macro nop32_stub
  76. nop32
  77. nop32
  78. nop32
  79. .endm
  80. ENTRY(ftrace_stub)
  81. jmp lr
  82. END(ftrace_stub)
  83. #ifndef CONFIG_DYNAMIC_FTRACE
  84. ENTRY(_mcount)
  85. mcount_enter
  86. /* r26 is link register, only used with jsri translation */
  87. lrw r26, ftrace_trace_function
  88. ldw r26, (r26, 0)
  89. lrw a1, ftrace_stub
  90. cmpne r26, a1
  91. bf skip_ftrace
  92. mov a0, lr
  93. subi a0, 4
  94. ldw a1, (sp, 24)
  95. lrw a2, function_trace_op
  96. ldw a2, (a2, 0)
  97. jsr r26
  98. #ifndef CONFIG_FUNCTION_GRAPH_TRACER
  99. skip_ftrace:
  100. mcount_exit
  101. #else
  102. skip_ftrace:
  103. lrw a0, ftrace_graph_return
  104. ldw a0, (a0, 0)
  105. lrw a1, ftrace_stub
  106. cmpne a0, a1
  107. bt ftrace_graph_caller
  108. lrw a0, ftrace_graph_entry
  109. ldw a0, (a0, 0)
  110. lrw a1, ftrace_graph_entry_stub
  111. cmpne a0, a1
  112. bt ftrace_graph_caller
  113. mcount_exit
  114. #endif
  115. END(_mcount)
  116. #else /* CONFIG_DYNAMIC_FTRACE */
  117. ENTRY(_mcount)
  118. mov t1, lr
  119. ldw lr, (sp, 0)
  120. addi sp, 4
  121. jmp t1
  122. ENDPROC(_mcount)
  123. ENTRY(ftrace_caller)
  124. mcount_enter
  125. ldw a0, (sp, 16)
  126. subi a0, 4
  127. ldw a1, (sp, 24)
  128. lrw a2, function_trace_op
  129. ldw a2, (a2, 0)
  130. nop
  131. GLOBAL(ftrace_call)
  132. nop32_stub
  133. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  134. nop
  135. GLOBAL(ftrace_graph_call)
  136. nop32_stub
  137. #endif
  138. mcount_exit
  139. ENDPROC(ftrace_caller)
  140. #endif /* CONFIG_DYNAMIC_FTRACE */
  141. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  142. ENTRY(ftrace_graph_caller)
  143. mov a0, sp
  144. addi a0, 24
  145. ldw a1, (sp, 16)
  146. subi a1, 4
  147. mov a2, r8
  148. lrw r26, prepare_ftrace_return
  149. jsr r26
  150. mcount_exit
  151. END(ftrace_graph_caller)
  152. ENTRY(return_to_handler)
  153. save_return_regs
  154. mov a0, r8
  155. jsri ftrace_return_to_handler
  156. restore_return_regs
  157. jmp lr
  158. END(return_to_handler)
  159. #endif
  160. #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
  161. ENTRY(ftrace_regs_caller)
  162. mcount_enter_regs
  163. lrw t1, PT_FRAME_SIZE
  164. add t1, sp
  165. ldw a0, (t1, 0)
  166. subi a0, 4
  167. ldw a1, (t1, 8)
  168. lrw a2, function_trace_op
  169. ldw a2, (a2, 0)
  170. mov a3, sp
  171. nop
  172. GLOBAL(ftrace_regs_call)
  173. nop32_stub
  174. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  175. nop
  176. GLOBAL(ftrace_graph_regs_call)
  177. nop32_stub
  178. #endif
  179. mcount_exit_regs
  180. ENDPROC(ftrace_regs_caller)
  181. #endif /* CONFIG_DYNAMIC_FTRACE */