123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- /* SPDX-License-Identifier: GPL-2.0 */
- // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
- #include <linux/linkage.h>
- #include <asm/ftrace.h>
- #include <abi/entry.h>
- #include <asm/asm-offsets.h>
- /*
- * csky-gcc with -pg will put the following asm after prologue:
- * push r15
- * jsri _mcount
- *
- * stack layout after mcount_enter in _mcount():
- *
- * current sp => 0:+-------+
- * | a0-a3 | -> must save all argument regs
- * +16:+-------+
- * | lr | -> _mcount lr (instrumente function's pc)
- * +20:+-------+
- * | fp=r8 | -> instrumented function fp
- * +24:+-------+
- * | plr | -> instrumented function lr (parent's pc)
- * +-------+
- */
- .macro mcount_enter
- subi sp, 24
- stw a0, (sp, 0)
- stw a1, (sp, 4)
- stw a2, (sp, 8)
- stw a3, (sp, 12)
- stw lr, (sp, 16)
- stw r8, (sp, 20)
- .endm
- .macro mcount_exit
- ldw a0, (sp, 0)
- ldw a1, (sp, 4)
- ldw a2, (sp, 8)
- ldw a3, (sp, 12)
- ldw t1, (sp, 16)
- ldw r8, (sp, 20)
- ldw lr, (sp, 24)
- addi sp, 28
- jmp t1
- .endm
- .macro mcount_enter_regs
- subi sp, 8
- stw lr, (sp, 0)
- stw r8, (sp, 4)
- SAVE_REGS_FTRACE
- .endm
- .macro mcount_exit_regs
- RESTORE_REGS_FTRACE
- subi sp, 152
- ldw t1, (sp, 4)
- addi sp, 152
- ldw r8, (sp, 4)
- ldw lr, (sp, 8)
- addi sp, 12
- jmp t1
- .endm
- .macro save_return_regs
- subi sp, 16
- stw a0, (sp, 0)
- stw a1, (sp, 4)
- stw a2, (sp, 8)
- stw a3, (sp, 12)
- .endm
- .macro restore_return_regs
- mov lr, a0
- ldw a0, (sp, 0)
- ldw a1, (sp, 4)
- ldw a2, (sp, 8)
- ldw a3, (sp, 12)
- addi sp, 16
- .endm
- .macro nop32_stub
- nop32
- nop32
- nop32
- .endm
- ENTRY(ftrace_stub)
- jmp lr
- END(ftrace_stub)
- #ifndef CONFIG_DYNAMIC_FTRACE
- ENTRY(_mcount)
- mcount_enter
- /* r26 is link register, only used with jsri translation */
- lrw r26, ftrace_trace_function
- ldw r26, (r26, 0)
- lrw a1, ftrace_stub
- cmpne r26, a1
- bf skip_ftrace
- mov a0, lr
- subi a0, 4
- ldw a1, (sp, 24)
- lrw a2, function_trace_op
- ldw a2, (a2, 0)
- jsr r26
- #ifndef CONFIG_FUNCTION_GRAPH_TRACER
- skip_ftrace:
- mcount_exit
- #else
- skip_ftrace:
- lrw a0, ftrace_graph_return
- ldw a0, (a0, 0)
- lrw a1, ftrace_stub
- cmpne a0, a1
- bt ftrace_graph_caller
- lrw a0, ftrace_graph_entry
- ldw a0, (a0, 0)
- lrw a1, ftrace_graph_entry_stub
- cmpne a0, a1
- bt ftrace_graph_caller
- mcount_exit
- #endif
- END(_mcount)
- #else /* CONFIG_DYNAMIC_FTRACE */
- ENTRY(_mcount)
- mov t1, lr
- ldw lr, (sp, 0)
- addi sp, 4
- jmp t1
- ENDPROC(_mcount)
- ENTRY(ftrace_caller)
- mcount_enter
- ldw a0, (sp, 16)
- subi a0, 4
- ldw a1, (sp, 24)
- lrw a2, function_trace_op
- ldw a2, (a2, 0)
- nop
- GLOBAL(ftrace_call)
- nop32_stub
- #ifdef CONFIG_FUNCTION_GRAPH_TRACER
- nop
- GLOBAL(ftrace_graph_call)
- nop32_stub
- #endif
- mcount_exit
- ENDPROC(ftrace_caller)
- #endif /* CONFIG_DYNAMIC_FTRACE */
- #ifdef CONFIG_FUNCTION_GRAPH_TRACER
- ENTRY(ftrace_graph_caller)
- mov a0, sp
- addi a0, 24
- ldw a1, (sp, 16)
- subi a1, 4
- mov a2, r8
- lrw r26, prepare_ftrace_return
- jsr r26
- mcount_exit
- END(ftrace_graph_caller)
- ENTRY(return_to_handler)
- save_return_regs
- mov a0, r8
- jsri ftrace_return_to_handler
- restore_return_regs
- jmp lr
- END(return_to_handler)
- #endif
- #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
- ENTRY(ftrace_regs_caller)
- mcount_enter_regs
- lrw t1, PT_FRAME_SIZE
- add t1, sp
- ldw a0, (t1, 0)
- subi a0, 4
- ldw a1, (t1, 8)
- lrw a2, function_trace_op
- ldw a2, (a2, 0)
- mov a3, sp
- nop
- GLOBAL(ftrace_regs_call)
- nop32_stub
- #ifdef CONFIG_FUNCTION_GRAPH_TRACER
- nop
- GLOBAL(ftrace_graph_regs_call)
- nop32_stub
- #endif
- mcount_exit_regs
- ENDPROC(ftrace_regs_caller)
- #endif /* CONFIG_DYNAMIC_FTRACE */
|