mcount.S 3.8 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 * MIPS specific _mcount support
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive for
 * more details.
 *
 * Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China
9
 * Author: Wu Zhangjin <wuzhangjin@gmail.com>
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
 */

#include <asm/regdef.h>
#include <asm/stackframe.h>
#include <asm/ftrace.h>

	.text
	.set noreorder
	.set noat

	.macro MCOUNT_SAVE_REGS
	PTR_SUBU	sp, PT_SIZE
	PTR_S	ra, PT_R31(sp)
	PTR_S	AT, PT_R1(sp)
	PTR_S	a0, PT_R4(sp)
	PTR_S	a1, PT_R5(sp)
	PTR_S	a2, PT_R6(sp)
	PTR_S	a3, PT_R7(sp)
#ifdef CONFIG_64BIT
	PTR_S	a4, PT_R8(sp)
	PTR_S	a5, PT_R9(sp)
	PTR_S	a6, PT_R10(sp)
	PTR_S	a7, PT_R11(sp)
#endif
	.endm

	.macro MCOUNT_RESTORE_REGS
	PTR_L	ra, PT_R31(sp)
	PTR_L	AT, PT_R1(sp)
	PTR_L	a0, PT_R4(sp)
	PTR_L	a1, PT_R5(sp)
	PTR_L	a2, PT_R6(sp)
	PTR_L	a3, PT_R7(sp)
#ifdef CONFIG_64BIT
	PTR_L	a4, PT_R8(sp)
	PTR_L	a5, PT_R9(sp)
	PTR_L	a6, PT_R10(sp)
	PTR_L	a7, PT_R11(sp)
#endif
#ifdef CONFIG_64BIT
	PTR_ADDIU	sp, PT_SIZE
#else
	PTR_ADDIU	sp, (PT_SIZE + 8)
#endif
.endm

	.macro RETURN_BACK
	jr ra
	 move ra, AT
	.endm

61 62 63 64 65 66 67
#ifdef CONFIG_DYNAMIC_FTRACE

NESTED(ftrace_caller, PT_SIZE, ra)
	.globl _mcount
_mcount:
	b	ftrace_stub
	 nop
68 69
	lw	t1, function_trace_stop
	bnez	t1, ftrace_stub
70 71 72
	 nop

	MCOUNT_SAVE_REGS
73 74 75
#ifdef KBUILD_MCOUNT_RA_ADDRESS
	PTR_S	t0, PT_R12(sp)	/* t0 saved the location of the return address(at) by -mmcount-ra-address */
#endif
76 77 78 79 80 81 82

	move	a0, ra		/* arg1: next ip, selfaddr */
	.globl ftrace_call
ftrace_call:
	nop	/* a placeholder for the call to a real tracing function */
	 move	a1, AT		/* arg2: the caller's next ip, parent */

83 84 85 86 87 88 89
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
	.globl ftrace_graph_call
ftrace_graph_call:
	nop
	 nop
#endif

90 91 92 93 94 95 96 97
	MCOUNT_RESTORE_REGS
	.globl ftrace_stub
ftrace_stub:
	RETURN_BACK
	END(ftrace_caller)

#else	/* ! CONFIG_DYNAMIC_FTRACE */

98
NESTED(_mcount, PT_SIZE, ra)
99 100
	lw	t1, function_trace_stop
	bnez	t1, ftrace_stub
101
	 nop
102 103 104
	PTR_LA	t1, ftrace_stub
	PTR_L	t2, ftrace_trace_function /* Prepare t2 for (1) */
	bne	t1, t2, static_trace
105
	 nop
106 107

#ifdef	CONFIG_FUNCTION_GRAPH_TRACER
108 109
	PTR_L	t3, ftrace_graph_return
	bne	t1, t3, ftrace_graph_caller
110
	 nop
111 112 113
	PTR_LA	t1, ftrace_graph_entry_stub
	PTR_L	t3, ftrace_graph_entry
	bne	t1, t3, ftrace_graph_caller
114 115
	 nop
#endif
116 117 118 119 120 121 122
	b	ftrace_stub
	 nop

static_trace:
	MCOUNT_SAVE_REGS

	move	a0, ra		/* arg1: next ip, selfaddr */
123
	jalr	t2		/* (1) call *ftrace_trace_function */
124 125 126 127 128 129 130 131
	 move	a1, AT		/* arg2: the caller's next ip, parent */

	MCOUNT_RESTORE_REGS
	.globl ftrace_stub
ftrace_stub:
	RETURN_BACK
	END(_mcount)

132 133
#endif	/* ! CONFIG_DYNAMIC_FTRACE */

134 135 136
#ifdef CONFIG_FUNCTION_GRAPH_TRACER

NESTED(ftrace_graph_caller, PT_SIZE, ra)
137 138
#ifdef CONFIG_DYNAMIC_FTRACE
	PTR_L	a1, PT_R31(sp)	/* load the original ra from the stack */
139 140 141
#ifdef KBUILD_MCOUNT_RA_ADDRESS
	PTR_L	t0, PT_R12(sp)	/* load the original t0 from the stack */
#endif
142
#else
143 144
	MCOUNT_SAVE_REGS
	move	a1, ra		/* arg2: next ip, selfaddr */
145
#endif
146 147 148 149 150 151 152

#ifdef KBUILD_MCOUNT_RA_ADDRESS
	bnez	t0, 1f		/* non-leaf func: t0 saved the location of the return address */
	 nop
	PTR_LA	t0, PT_R1(sp)	/* leaf func: get the location of at(old ra) from our own stack */
1:	move	a0, t0		/* arg1: the location of the return address */
#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 159 160 161 162 163 164
#else
#ifdef CONFIG_64BIT
	 PTR_LA	a2, PT_SIZE(sp)
#else
	 PTR_LA	a2, (PT_SIZE+8)(sp)
#endif
#endif
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

	MCOUNT_RESTORE_REGS
	RETURN_BACK
	END(ftrace_graph_caller)

	.align	2
	.globl	return_to_handler
return_to_handler:
	PTR_SUBU	sp, PT_SIZE
	PTR_S	v0, PT_R2(sp)

	jal	ftrace_return_to_handler
	 PTR_S	v1, PT_R3(sp)

	/* restore the real parent address: v0 -> ra */
	move	ra, v0

	PTR_L	v0, PT_R2(sp)
	PTR_L	v1, PT_R3(sp)
	jr	ra
	 PTR_ADDIU	sp, PT_SIZE
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */

188 189
	.set at
	.set reorder