mcount.S 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * Low-level ftrace handling
  3. *
  4. * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
  5. * Copyright (C) 2009 PetaLogix
  6. *
  7. * This file is subject to the terms and conditions of the GNU General
  8. * Public License. See the file COPYING in the main directory of this
  9. * archive for more details.
  10. */
  11. #include <linux/linkage.h>
  12. #define NOALIGN_ENTRY(name) .globl name; name:
  13. /* FIXME MS: I think that I don't need to save all regs */
  14. #define SAVE_REGS \
  15. addik r1, r1, -120; \
  16. swi r2, r1, 4; \
  17. swi r3, r1, 8; \
  18. swi r4, r1, 12; \
  19. swi r5, r1, 116; \
  20. swi r6, r1, 16; \
  21. swi r7, r1, 20; \
  22. swi r8, r1, 24; \
  23. swi r9, r1, 28; \
  24. swi r10, r1, 32; \
  25. swi r11, r1, 36; \
  26. swi r12, r1, 40; \
  27. swi r13, r1, 44; \
  28. swi r14, r1, 48; \
  29. swi r16, r1, 52; \
  30. swi r17, r1, 56; \
  31. swi r18, r1, 60; \
  32. swi r19, r1, 64; \
  33. swi r20, r1, 68; \
  34. swi r21, r1, 72; \
  35. swi r22, r1, 76; \
  36. swi r23, r1, 80; \
  37. swi r24, r1, 84; \
  38. swi r25, r1, 88; \
  39. swi r26, r1, 92; \
  40. swi r27, r1, 96; \
  41. swi r28, r1, 100; \
  42. swi r29, r1, 104; \
  43. swi r30, r1, 108; \
  44. swi r31, r1, 112;
  45. #define RESTORE_REGS \
  46. lwi r2, r1, 4; \
  47. lwi r3, r1, 8; \
  48. lwi r4, r1, 12; \
  49. lwi r5, r1, 116; \
  50. lwi r6, r1, 16; \
  51. lwi r7, r1, 20; \
  52. lwi r8, r1, 24; \
  53. lwi r9, r1, 28; \
  54. lwi r10, r1, 32; \
  55. lwi r11, r1, 36; \
  56. lwi r12, r1, 40; \
  57. lwi r13, r1, 44; \
  58. lwi r14, r1, 48; \
  59. lwi r16, r1, 52; \
  60. lwi r17, r1, 56; \
  61. lwi r18, r1, 60; \
  62. lwi r19, r1, 64; \
  63. lwi r20, r1, 68; \
  64. lwi r21, r1, 72; \
  65. lwi r22, r1, 76; \
  66. lwi r23, r1, 80; \
  67. lwi r24, r1, 84; \
  68. lwi r25, r1, 88; \
  69. lwi r26, r1, 92; \
  70. lwi r27, r1, 96; \
  71. lwi r28, r1, 100; \
  72. lwi r29, r1, 104; \
  73. lwi r30, r1, 108; \
  74. lwi r31, r1, 112; \
  75. addik r1, r1, 120;
  76. ENTRY(ftrace_stub)
  77. rtsd r15, 8;
  78. nop;
  79. ENTRY(_mcount)
  80. #ifdef CONFIG_DYNAMIC_FTRACE
  81. ENTRY(ftrace_caller)
  82. /* MS: It is just barrier which is removed from C code */
  83. rtsd r15, 8
  84. nop
  85. #endif /* CONFIG_DYNAMIC_FTRACE */
  86. SAVE_REGS
  87. swi r15, r1, 0;
  88. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  89. #ifndef CONFIG_DYNAMIC_FTRACE
  90. lwi r5, r0, ftrace_graph_return;
  91. addik r6, r0, ftrace_stub; /* asm implementation */
  92. cmpu r5, r5, r6; /* ftrace_graph_return != ftrace_stub */
  93. beqid r5, end_graph_tracer;
  94. nop;
  95. lwi r6, r0, ftrace_graph_entry;
  96. addik r5, r0, ftrace_graph_entry_stub; /* implemented in C */
  97. cmpu r5, r5, r6; /* ftrace_graph_entry != ftrace_graph_entry_stub */
  98. beqid r5, end_graph_tracer;
  99. nop;
  100. #else /* CONFIG_DYNAMIC_FTRACE */
  101. NOALIGN_ENTRY(ftrace_call_graph)
  102. /* MS: jump over graph function - replaced from C code */
  103. bri end_graph_tracer
  104. #endif /* CONFIG_DYNAMIC_FTRACE */
  105. addik r5, r1, 120; /* MS: load parent addr */
  106. addik r6, r15, 0; /* MS: load current function addr */
  107. bralid r15, prepare_ftrace_return;
  108. nop;
  109. /* MS: graph was taken that's why - can jump over function trace */
  110. brid end;
  111. nop;
  112. end_graph_tracer:
  113. #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
  114. #ifndef CONFIG_DYNAMIC_FTRACE
  115. /* MS: test function trace if is taken or not */
  116. lwi r20, r0, ftrace_trace_function;
  117. addik r6, r0, ftrace_stub;
  118. cmpu r5, r20, r6; /* ftrace_trace_function != ftrace_stub */
  119. beqid r5, end; /* MS: not taken -> jump over */
  120. nop;
  121. #else /* CONFIG_DYNAMIC_FTRACE */
  122. NOALIGN_ENTRY(ftrace_call)
  123. /* instruction for setup imm FUNC_part1, addik r20, r0, FUNC_part2 */
  124. nop
  125. nop
  126. #endif /* CONFIG_DYNAMIC_FTRACE */
  127. /* static normal trace */
  128. lwi r6, r1, 120; /* MS: load parent addr */
  129. addik r5, r15, -4; /* MS: load current function addr */
  130. /* MS: here is dependency on previous code */
  131. brald r15, r20; /* MS: jump to ftrace handler */
  132. nop;
  133. end:
  134. lwi r15, r1, 0;
  135. RESTORE_REGS
  136. rtsd r15, 8; /* MS: jump back */
  137. nop;
  138. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  139. ENTRY(return_to_handler)
  140. nop; /* MS: just barrier for rtsd r15, 8 */
  141. nop;
  142. SAVE_REGS
  143. swi r15, r1, 0;
  144. /* MS: find out returning address */
  145. bralid r15, ftrace_return_to_handler;
  146. nop;
  147. /* MS: return value from ftrace_return_to_handler is my returning addr
  148. * must be before restore regs because I have to restore r3 content */
  149. addik r15, r3, 0;
  150. RESTORE_REGS
  151. rtsd r15, 8; /* MS: jump back */
  152. nop;
  153. #endif /* CONFIG_FUNCTION_TRACER */