mcount.S 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * LoongArch specific _mcount support
  4. *
  5. * Copyright (C) 2022 Loongson Technology Corporation Limited
  6. */
  7. #include <linux/export.h>
  8. #include <asm/ftrace.h>
  9. #include <asm/regdef.h>
  10. #include <asm/stackframe.h>
  11. .text
  12. #define MCOUNT_S0_OFFSET (0)
  13. #define MCOUNT_RA_OFFSET (SZREG)
  14. #define MCOUNT_STACK_SIZE (2 * SZREG)
  15. .macro MCOUNT_SAVE_REGS
  16. PTR_ADDI sp, sp, -MCOUNT_STACK_SIZE
  17. PTR_S s0, sp, MCOUNT_S0_OFFSET
  18. PTR_S ra, sp, MCOUNT_RA_OFFSET
  19. move s0, a0
  20. .endm
  21. .macro MCOUNT_RESTORE_REGS
  22. move a0, s0
  23. PTR_L ra, sp, MCOUNT_RA_OFFSET
  24. PTR_L s0, sp, MCOUNT_S0_OFFSET
  25. PTR_ADDI sp, sp, MCOUNT_STACK_SIZE
  26. .endm
  27. SYM_FUNC_START(_mcount)
  28. la.pcrel t1, ftrace_stub
  29. la.pcrel t2, ftrace_trace_function /* Prepare t2 for (1) */
  30. PTR_L t2, t2, 0
  31. beq t1, t2, fgraph_trace
  32. MCOUNT_SAVE_REGS
  33. move a0, ra /* arg0: self return address */
  34. move a1, s0 /* arg1: parent's return address */
  35. jirl ra, t2, 0 /* (1) call *ftrace_trace_function */
  36. MCOUNT_RESTORE_REGS
  37. fgraph_trace:
  38. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  39. la.pcrel t1, ftrace_stub
  40. la.pcrel t3, ftrace_graph_return
  41. PTR_L t3, t3, 0
  42. bne t1, t3, ftrace_graph_caller
  43. la.pcrel t1, ftrace_graph_entry_stub
  44. la.pcrel t3, ftrace_graph_entry
  45. PTR_L t3, t3, 0
  46. bne t1, t3, ftrace_graph_caller
  47. #endif
  48. SYM_INNER_LABEL(ftrace_stub, SYM_L_GLOBAL)
  49. jr ra
  50. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  51. SYM_INNER_LABEL(ftrace_graph_func, SYM_L_GLOBAL)
  52. bl ftrace_stub
  53. #endif
  54. SYM_FUNC_END(_mcount)
  55. EXPORT_SYMBOL(_mcount)
  56. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  57. SYM_FUNC_START(ftrace_graph_caller)
  58. MCOUNT_SAVE_REGS
  59. PTR_ADDI a0, ra, -4 /* arg0: Callsite self return addr */
  60. PTR_ADDI a1, sp, MCOUNT_STACK_SIZE /* arg1: Callsite sp */
  61. move a2, s0 /* arg2: Callsite parent ra */
  62. bl prepare_ftrace_return
  63. MCOUNT_RESTORE_REGS
  64. jr ra
  65. SYM_FUNC_END(ftrace_graph_caller)
  66. SYM_FUNC_START(return_to_handler)
  67. PTR_ADDI sp, sp, -FGRET_REGS_SIZE
  68. PTR_S a0, sp, FGRET_REGS_A0
  69. PTR_S a1, sp, FGRET_REGS_A1
  70. PTR_S zero, sp, FGRET_REGS_FP
  71. move a0, sp
  72. bl ftrace_return_to_handler
  73. /* Restore the real parent address: a0 -> ra */
  74. move ra, a0
  75. PTR_L a0, sp, FGRET_REGS_A0
  76. PTR_L a1, sp, FGRET_REGS_A1
  77. PTR_ADDI sp, sp, FGRET_REGS_SIZE
  78. jr ra
  79. SYM_FUNC_END(return_to_handler)
  80. #endif /* CONFIG_FUNCTION_GRAPH_TRACER */