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#else 50 PTR_ADDIU sp, PT_SIZE 51#endif 52.endm 53 54 .macro RETURN_BACK 55 jr ra 56 move ra, AT 57 .endm 58 59/* 60 * The -mmcount-ra-address option of gcc 4.5 uses register $12 to pass 61 * the location of the parent's return address. 62 */ 63#define MCOUNT_RA_ADDRESS_REG $12 64 65#ifdef CONFIG_DYNAMIC_FTRACE 66 67NESTED(ftrace_caller, PT_SIZE, ra) 68 .globl _mcount 69_mcount: 70 b ftrace_stub 71 addiu sp,sp,8 72 73 /* When tracing is activated, it calls ftrace_caller+8 (aka here) */ 74 lw t1, function_trace_stop 75 bnez t1, ftrace_stub 76 nop 77 78 MCOUNT_SAVE_REGS 79#ifdef KBUILD_MCOUNT_RA_ADDRESS 80 PTR_S MCOUNT_RA_ADDRESS_REG, PT_R12(sp) 81#endif 82 83 move a0, ra /* arg1: self return address */ 84 .globl ftrace_call 85ftrace_call: 86 nop /* a placeholder for the call to a real tracing function */ 87 move a1, AT /* arg2: parent's return address */ 88 89#ifdef CONFIG_FUNCTION_GRAPH_TRACER 90 .globl ftrace_graph_call 91ftrace_graph_call: 92 nop 93 nop 94#endif 95 96 MCOUNT_RESTORE_REGS 97 .globl ftrace_stub 98ftrace_stub: 99 RETURN_BACK 100 END(ftrace_caller) 101 102#else /* ! CONFIG_DYNAMIC_FTRACE */ 103 104NESTED(_mcount, PT_SIZE, ra) 105 lw t1, function_trace_stop 106 bnez t1, ftrace_stub 107 nop 108 PTR_LA t1, ftrace_stub 109 PTR_L t2, ftrace_trace_function /* Prepare t2 for (1) */ 110 bne t1, t2, static_trace 111 nop 112 113#ifdef CONFIG_FUNCTION_GRAPH_TRACER 114 PTR_L t3, ftrace_graph_return 115 bne t1, t3, ftrace_graph_caller 116 nop 117 PTR_LA t1, ftrace_graph_entry_stub 118 PTR_L t3, ftrace_graph_entry 119 bne t1, t3, ftrace_graph_caller 120 nop 121#endif 122 b ftrace_stub 123 nop 124 125static_trace: 126 MCOUNT_SAVE_REGS 127 128 move a0, ra /* arg1: self return address */ 129 jalr t2 /* (1) call *ftrace_trace_function */ 130 move a1, AT /* arg2: parent's return address */ 131 132 MCOUNT_RESTORE_REGS 133 .globl ftrace_stub 134ftrace_stub: 135 RETURN_BACK 136 END(_mcount) 137 138#endif /* ! CONFIG_DYNAMIC_FTRACE */ 139 140#ifdef CONFIG_FUNCTION_GRAPH_TRACER 141 142NESTED(ftrace_graph_caller, PT_SIZE, ra) 143#ifndef CONFIG_DYNAMIC_FTRACE 144 MCOUNT_SAVE_REGS 145#endif 146 147 /* arg1: Get the location of the parent's return address */ 148#ifdef KBUILD_MCOUNT_RA_ADDRESS 149#ifdef CONFIG_DYNAMIC_FTRACE 150 PTR_L a0, PT_R12(sp) 151#else 152 move a0, MCOUNT_RA_ADDRESS_REG 153#endif 154 bnez a0, 1f /* non-leaf func: stored in MCOUNT_RA_ADDRESS_REG */ 155 nop 156#endif 157 PTR_LA a0, PT_R1(sp) /* leaf func: the location in current stack */ 1581: 159 160 /* arg2: Get self return address */ 161#ifdef CONFIG_DYNAMIC_FTRACE 162 PTR_L a1, PT_R31(sp) 163#else 164 move a1, ra 165#endif 166 167 /* arg3: Get frame pointer of current stack */ 168#ifdef CONFIG_FRAME_POINTER 169 move a2, fp 170#else /* ! CONFIG_FRAME_POINTER */ 171#ifdef CONFIG_64BIT 172 PTR_LA a2, PT_SIZE(sp) 173#else 174 PTR_LA a2, (PT_SIZE+8)(sp) 175#endif 176#endif 177 178 jal prepare_ftrace_return 179 nop 180 MCOUNT_RESTORE_REGS 181 RETURN_BACK 182 END(ftrace_graph_caller) 183 184 .align 2 185 .globl return_to_handler 186return_to_handler: 187 PTR_SUBU sp, PT_SIZE 188 PTR_S v0, PT_R2(sp) 189 190 jal ftrace_return_to_handler 191 PTR_S v1, PT_R3(sp) 192 193 /* restore the real parent address: v0 -> ra */ 194 move ra, v0 195 196 PTR_L v0, PT_R2(sp) 197 PTR_L v1, PT_R3(sp) 198 jr ra 199 PTR_ADDIU sp, PT_SIZE 200#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 201 202 .set at 203 .set reorder 204