xref: /openbmc/linux/arch/mips/kernel/mcount.S (revision 042e571d)
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