1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (C) 2017 Andes Technology Corporation */
4 #include <linux/init.h>
5 #include <linux/linkage.h>
6 #include <linux/cfi_types.h>
7 #include <linux/export.h>
10 #include <asm/unistd.h>
11 #include <asm/thread_info.h>
12 #include <asm/asm-offsets.h>
13 #include <asm/ftrace.h>
25 * The call to ftrace_return_to_handler would overwrite the return
26 * register if a0 was not saved.
28 .macro SAVE_RET_ABI_STATE
37 .macro RESTORE_ABI_STATE
43 .macro RESTORE_RET_ABI_STATE
51 SYM_TYPED_FUNC_START(ftrace_stub)
52 #ifdef CONFIG_DYNAMIC_FTRACE
54 .set _mcount, ftrace_stub
57 SYM_FUNC_END(ftrace_stub)
59 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
60 SYM_TYPED_FUNC_START(ftrace_stub_graph)
62 SYM_FUNC_END(ftrace_stub_graph)
64 SYM_FUNC_START(return_to_handler)
66 * On implementing the frame point test, the ideal way is to compare the
67 * s0 (frame pointer, if enabled) on entry and the sp (stack pointer) on return.
68 * However, the psABI of variable-length-argument functions does not allow this.
70 * So alternatively we check the *old* frame pointer position, that is, the
71 * value stored in -16(s0) on entry, and the s0 on return.
75 call ftrace_return_to_handler
79 SYM_FUNC_END(return_to_handler)
82 #ifndef CONFIG_DYNAMIC_FTRACE
83 SYM_FUNC_START(_mcount)
85 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
86 la t0, ftrace_graph_return
88 bne t1, t4, .Ldo_ftrace_graph_caller
90 la t3, ftrace_graph_entry
92 la t6, ftrace_graph_entry_stub
93 bne t2, t6, .Ldo_ftrace_graph_caller
95 la t3, ftrace_trace_function
97 bne t5, t4, .Ldo_trace
100 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
102 * A pseudo representation for the function graph tracer:
103 * prepare_to_return(&ra_to_caller_of_caller, ra_to_caller)
105 .Ldo_ftrace_graph_caller:
108 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
109 REG_L a2, -2*SZREG(s0)
112 call prepare_ftrace_return
118 * A pseudo representation for the function tracer:
119 * (*ftrace_trace_function)(ra_to_caller, ra_to_caller_of_caller)
129 SYM_FUNC_END(_mcount)
131 EXPORT_SYMBOL(_mcount)