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