1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (C) 2017 Andes Technology Corporation */
4 #include <linux/init.h>
5 #include <linux/linkage.h>
8 #include <asm/unistd.h>
9 #include <asm/thread_info.h>
10 #include <asm/asm-offsets.h>
11 #include <asm-generic/export.h>
12 #include <asm/ftrace.h>
17 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
24 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
35 .macro RESTORE_ABI_STATE
36 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
47 .macro RESTORE_GRAPH_ARGS
50 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
55 ENTRY(ftrace_graph_caller)
61 .global ftrace_graph_call
63 * Calling ftrace_enable/disable_ftrace_graph_caller would overwrite the
64 * call below. Check ftrace_modify_all_code for details.
71 ENDPROC(ftrace_graph_caller)
75 * a0: the address in the caller when calling ftrace_caller
76 * a1: the caller's return address
77 * a2: the address of global variable function_trace_op
80 addi a0, ra, -MCOUNT_INSN_SIZE
81 la t5, function_trace_op
84 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
86 * the graph tracer (specifically, prepare_ftrace_return) needs these
87 * arguments but for now the function tracer occupies the regs, so we
88 * save them in temporary regs to recover later.
92 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
101 * For the dynamic ftrace to work, here we should reserve at least
102 * 8 bytes for a functional auipc-jalr pair. The following call
103 * serves this purpose.
105 * Calling ftrace_update_ftrace_func would overwrite the nops below.
106 * Check ftrace_modify_all_code for details.
110 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
112 call ftrace_graph_caller
117 ENDPROC(ftrace_caller)
119 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
121 addi sp, sp, -(PT_SIZE_ON_STACK+16)
122 sd s0, (PT_SIZE_ON_STACK)(sp)
123 sd ra, (PT_SIZE_ON_STACK+8)(sp)
124 addi s0, sp, (PT_SIZE_ON_STACK+16)
192 ld s0, (PT_SIZE_ON_STACK)(sp)
193 ld ra, (PT_SIZE_ON_STACK+8)(sp)
194 addi sp, sp, (PT_SIZE_ON_STACK+16)
197 .macro RESTORE_GRAPH_REG_ARGS
200 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
206 * Most of the contents are the same as ftrace_caller.
208 ENTRY(ftrace_regs_caller)
210 * a3: the address of all registers in the stack
213 addi a0, ra, -MCOUNT_INSN_SIZE
214 la t5, function_trace_op
216 addi a3, sp, -(PT_SIZE_ON_STACK+16)
218 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
221 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
228 .global ftrace_regs_call
231 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
232 RESTORE_GRAPH_REG_ARGS
233 call ftrace_graph_caller
238 ENDPROC(ftrace_regs_caller)
239 #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */