2 * MIPS specific _mcount support
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive for
8 * Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China
9 * Copyright (C) 2010 DSLab, Lanzhou University, China
10 * Author: Wu Zhangjin <wuzhangjin@gmail.com>
13 #include <linux/export.h>
14 #include <asm/regdef.h>
15 #include <asm/stackframe.h>
16 #include <asm/ftrace.h>
22 .macro MCOUNT_SAVE_REGS
38 .macro MCOUNT_RESTORE_REGS
60 * The -mmcount-ra-address option of gcc 4.5 uses register $12 to pass
61 * the location of the parent's return address.
63 #define MCOUNT_RA_ADDRESS_REG $12
65 #ifdef CONFIG_DYNAMIC_FTRACE
67 NESTED(ftrace_caller, PT_SIZE, ra)
70 EXPORT_SYMBOL(_mcount)
78 /* When tracing is activated, it calls ftrace_caller+8 (aka here) */
80 #ifdef KBUILD_MCOUNT_RA_ADDRESS
81 PTR_S MCOUNT_RA_ADDRESS_REG, PT_R12(sp)
84 PTR_SUBU a0, ra, 8 /* arg1: self address */
86 sltu t2, a0, t1 /* t2 = (a0 < _stext) */
88 sltu t3, t1, a0 /* t3 = (a0 > _etext) */
92 #if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT)
93 PTR_SUBU a0, a0, 16 /* arg1: adjust to module's recorded callsite */
100 nop /* a placeholder for the call to a real tracing function */
101 move a1, AT /* arg2: parent's return address */
103 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
104 .globl ftrace_graph_call
116 #else /* ! CONFIG_DYNAMIC_FTRACE */
118 NESTED(_mcount, PT_SIZE, ra)
119 EXPORT_SYMBOL(_mcount)
120 PTR_LA t1, ftrace_stub
121 PTR_L t2, ftrace_trace_function /* Prepare t2 for (1) */
122 beq t1, t2, fgraph_trace
127 move a0, ra /* arg1: self return address */
128 jalr t2 /* (1) call *ftrace_trace_function */
129 move a1, AT /* arg2: parent's return address */
134 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
135 PTR_LA t1, ftrace_stub
136 PTR_L t3, ftrace_graph_return
137 bne t1, t3, ftrace_graph_caller
139 PTR_LA t1, ftrace_graph_entry_stub
140 PTR_L t3, ftrace_graph_entry
141 bne t1, t3, ftrace_graph_caller
154 #endif /* ! CONFIG_DYNAMIC_FTRACE */
156 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
158 NESTED(ftrace_graph_caller, PT_SIZE, ra)
159 #ifndef CONFIG_DYNAMIC_FTRACE
163 /* arg1: Get the location of the parent's return address */
164 #ifdef KBUILD_MCOUNT_RA_ADDRESS
165 #ifdef CONFIG_DYNAMIC_FTRACE
168 move a0, MCOUNT_RA_ADDRESS_REG
170 bnez a0, 1f /* non-leaf func: stored in MCOUNT_RA_ADDRESS_REG */
173 PTR_LA a0, PT_R1(sp) /* leaf func: the location in current stack */
176 /* arg2: Get self return address */
177 #ifdef CONFIG_DYNAMIC_FTRACE
183 /* arg3: Get frame pointer of current stack */
185 PTR_LA a2, PT_SIZE(sp)
187 PTR_LA a2, (PT_SIZE+8)(sp)
190 jal prepare_ftrace_return
193 #ifndef CONFIG_DYNAMIC_FTRACE
199 END(ftrace_graph_caller)
202 .globl return_to_handler
207 jal ftrace_return_to_handler
210 /* restore the real parent address: v0 -> ra */
216 PTR_ADDIU sp, PT_SIZE
217 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */