ftrace_32.S 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * Split from entry_32.S
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version
  7. * 2 of the License, or (at your option) any later version.
  8. */
  9. #include <linux/magic.h>
  10. #include <asm/reg.h>
  11. #include <asm/ppc_asm.h>
  12. #include <asm/asm-offsets.h>
  13. #include <asm/ftrace.h>
  14. #include <asm/export.h>
  15. #ifdef CONFIG_DYNAMIC_FTRACE
  16. _GLOBAL(mcount)
  17. _GLOBAL(_mcount)
  18. /*
  19. * It is required that _mcount on PPC32 must preserve the
  20. * link register. But we have r0 to play with. We use r0
  21. * to push the return address back to the caller of mcount
  22. * into the ctr register, restore the link register and
  23. * then jump back using the ctr register.
  24. */
  25. mflr r0
  26. mtctr r0
  27. lwz r0, 4(r1)
  28. mtlr r0
  29. bctr
  30. _GLOBAL(ftrace_caller)
  31. MCOUNT_SAVE_FRAME
  32. /* r3 ends up with link register */
  33. subi r3, r3, MCOUNT_INSN_SIZE
  34. .globl ftrace_call
  35. ftrace_call:
  36. bl ftrace_stub
  37. nop
  38. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  39. .globl ftrace_graph_call
  40. ftrace_graph_call:
  41. b ftrace_graph_stub
  42. _GLOBAL(ftrace_graph_stub)
  43. #endif
  44. MCOUNT_RESTORE_FRAME
  45. /* old link register ends up in ctr reg */
  46. bctr
  47. #else
  48. _GLOBAL(mcount)
  49. _GLOBAL(_mcount)
  50. MCOUNT_SAVE_FRAME
  51. subi r3, r3, MCOUNT_INSN_SIZE
  52. LOAD_REG_ADDR(r5, ftrace_trace_function)
  53. lwz r5,0(r5)
  54. mtctr r5
  55. bctrl
  56. nop
  57. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  58. b ftrace_graph_caller
  59. #endif
  60. MCOUNT_RESTORE_FRAME
  61. bctr
  62. #endif
  63. EXPORT_SYMBOL(_mcount)
  64. _GLOBAL(ftrace_stub)
  65. blr
  66. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  67. _GLOBAL(ftrace_graph_caller)
  68. /* load r4 with local address */
  69. lwz r4, 44(r1)
  70. subi r4, r4, MCOUNT_INSN_SIZE
  71. /* Grab the LR out of the caller stack frame */
  72. lwz r3,52(r1)
  73. bl prepare_ftrace_return
  74. nop
  75. /*
  76. * prepare_ftrace_return gives us the address we divert to.
  77. * Change the LR in the callers stack frame to this.
  78. */
  79. stw r3,52(r1)
  80. MCOUNT_RESTORE_FRAME
  81. /* old link register ends up in ctr reg */
  82. bctr
  83. _GLOBAL(return_to_handler)
  84. /* need to save return values */
  85. stwu r1, -32(r1)
  86. stw r3, 20(r1)
  87. stw r4, 16(r1)
  88. stw r31, 12(r1)
  89. mr r31, r1
  90. bl ftrace_return_to_handler
  91. nop
  92. /* return value has real return address */
  93. mtlr r3
  94. lwz r3, 20(r1)
  95. lwz r4, 16(r1)
  96. lwz r31,12(r1)
  97. lwz r1, 0(r1)
  98. /* Jump back to real return address */
  99. blr
  100. #endif /* CONFIG_FUNCTION_GRAPH_TRACER */