1/* 2 * MIPS specific _mcount support 3 * 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 6 * more details. 7 * 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> 11 */ 12 13#include <asm/regdef.h> 14#include <asm/stackframe.h> 15#include <asm/ftrace.h> 16 17 .text 18 .set noreorder 19 .set noat 20 21 .macro MCOUNT_SAVE_REGS 22 PTR_SUBU sp, PT_SIZE 23 PTR_S ra, PT_R31(sp) 24 PTR_S AT, PT_R1(sp) 25 PTR_S a0, PT_R4(sp) 26 PTR_S a1, PT_R5(sp) 27 PTR_S a2, PT_R6(sp) 28 PTR_S a3, PT_R7(sp) 29#ifdef CONFIG_64BIT 30 PTR_S a4, PT_R8(sp) 31 PTR_S a5, PT_R9(sp) 32 PTR_S a6, PT_R10(sp) 33 PTR_S a7, PT_R11(sp) 34#endif 35 .endm 36 37 .macro MCOUNT_RESTORE_REGS 38 PTR_L ra, PT_R31(sp) 39 PTR_L AT, PT_R1(sp) 40 PTR_L a0, PT_R4(sp) 41 PTR_L a1, PT_R5(sp) 42 PTR_L a2, PT_R6(sp) 43 PTR_L a3, PT_R7(sp) 44#ifdef CONFIG_64BIT 45 PTR_L a4, PT_R8(sp) 46 PTR_L a5, PT_R9(sp) 47 PTR_L a6, PT_R10(sp) 48 PTR_L a7, PT_R11(sp) 49 PTR_ADDIU sp, PT_SIZE 50#else 51 PTR_ADDIU sp, (PT_SIZE + 8) 52#endif 53.endm 54 55 .macro RETURN_BACK 56 jr ra 57 move ra, AT 58 .endm 59 60#ifdef CONFIG_DYNAMIC_FTRACE 61 62NESTED(ftrace_caller, PT_SIZE, ra) 63 .globl _mcount 64_mcount: 65 b ftrace_stub 66 nop 67 lw t1, function_trace_stop 68 bnez t1, ftrace_stub 69 nop 70 71 MCOUNT_SAVE_REGS 72#ifdef KBUILD_MCOUNT_RA_ADDRESS 73 PTR_S t0, PT_R12(sp) /* save location of parent's return address */ 74#endif 75 76 move a0, ra /* arg1: self return address */ 77 .globl ftrace_call 78ftrace_call: 79 nop /* a placeholder for the call to a real tracing function */ 80 move a1, AT /* arg2: parent's return address */ 81 82#ifdef CONFIG_FUNCTION_GRAPH_TRACER 83 .globl ftrace_graph_call 84ftrace_graph_call: 85 nop 86 nop 87#endif 88 89 MCOUNT_RESTORE_REGS 90 .globl ftrace_stub 91ftrace_stub: 92 RETURN_BACK 93 END(ftrace_caller) 94 95#else /* ! CONFIG_DYNAMIC_FTRACE */ 96 97NESTED(_mcount, PT_SIZE, ra) 98 lw t1, function_trace_stop 99 bnez t1, ftrace_stub 100 nop 101 PTR_LA t1, ftrace_stub 102 PTR_L t2, ftrace_trace_function /* Prepare t2 for (1) */ 103 bne t1, t2, static_trace 104 nop 105 106#ifdef CONFIG_FUNCTION_GRAPH_TRACER 107 PTR_L t3, ftrace_graph_return 108 bne t1, t3, ftrace_graph_caller 109 nop 110 PTR_LA t1, ftrace_graph_entry_stub 111 PTR_L t3, ftrace_graph_entry 112 bne t1, t3, ftrace_graph_caller 113 nop 114#endif 115 b ftrace_stub 116 nop 117 118static_trace: 119 MCOUNT_SAVE_REGS 120 121 move a0, ra /* arg1: self return address */ 122 jalr t2 /* (1) call *ftrace_trace_function */ 123 move a1, AT /* arg2: parent's return address */ 124 125 MCOUNT_RESTORE_REGS 126 .globl ftrace_stub 127ftrace_stub: 128 RETURN_BACK 129 END(_mcount) 130 131#endif /* ! CONFIG_DYNAMIC_FTRACE */ 132 133#ifdef CONFIG_FUNCTION_GRAPH_TRACER 134 135NESTED(ftrace_graph_caller, PT_SIZE, ra) 136#ifndef CONFIG_DYNAMIC_FTRACE 137 MCOUNT_SAVE_REGS 138#endif 139 140 /* arg1: Get the location of the parent's return address */ 141#ifdef KBUILD_MCOUNT_RA_ADDRESS 142#ifdef CONFIG_DYNAMIC_FTRACE 143 PTR_L a0, PT_R12(sp) 144#else 145 move a0, t0 146#endif 147 bnez a0, 1f /* non-leaf func: stored in t0 */ 148 nop 149#endif 150 PTR_LA a0, PT_R1(sp) /* leaf func: the location in current stack */ 1511: 152 153 /* arg2: Get self return address */ 154#ifdef CONFIG_DYNAMIC_FTRACE 155 PTR_L a1, PT_R31(sp) 156#else 157 move a1, ra 158#endif 159 160 /* arg3: Get frame pointer of current stack */ 161#ifdef CONFIG_FRAME_POINTER 162 move a2, fp 163#else /* ! CONFIG_FRAME_POINTER */ 164#ifdef CONFIG_64BIT 165 PTR_LA a2, PT_SIZE(sp) 166#else 167 PTR_LA a2, (PT_SIZE+8)(sp) 168#endif 169#endif 170 171 jal prepare_ftrace_return 172 nop 173 MCOUNT_RESTORE_REGS 174 RETURN_BACK 175 END(ftrace_graph_caller) 176 177 .align 2 178 .globl return_to_handler 179return_to_handler: 180 PTR_SUBU sp, PT_SIZE 181 PTR_S v0, PT_R2(sp) 182 183 jal ftrace_return_to_handler 184 PTR_S v1, PT_R3(sp) 185 186 /* restore the real parent address: v0 -> ra */ 187 move ra, v0 188 189 PTR_L v0, PT_R2(sp) 190 PTR_L v1, PT_R3(sp) 191 jr ra 192 PTR_ADDIU sp, PT_SIZE 193#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 194 195 .set at 196 .set reorder 197