]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - arch/tile/kernel/mcount_64.S
Merge tag 'renesas-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[mirror_ubuntu-zesty-kernel.git] / arch / tile / kernel / mcount_64.S
1 /*
2 * Copyright 2012 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 *
14 * TILE-Gx specific __mcount support
15 */
16
17 #include <linux/linkage.h>
18 #include <asm/ftrace.h>
19
20 #define REGSIZE 8
21
22 .text
23 .global __mcount
24
25 .macro MCOUNT_SAVE_REGS
26 addli sp, sp, -REGSIZE
27 {
28 st sp, lr
29 addli r29, sp, - (12 * REGSIZE)
30 }
31 {
32 addli sp, sp, - (13 * REGSIZE)
33 st r29, sp
34 }
35 addli r29, r29, REGSIZE
36 { st r29, r0; addli r29, r29, REGSIZE }
37 { st r29, r1; addli r29, r29, REGSIZE }
38 { st r29, r2; addli r29, r29, REGSIZE }
39 { st r29, r3; addli r29, r29, REGSIZE }
40 { st r29, r4; addli r29, r29, REGSIZE }
41 { st r29, r5; addli r29, r29, REGSIZE }
42 { st r29, r6; addli r29, r29, REGSIZE }
43 { st r29, r7; addli r29, r29, REGSIZE }
44 { st r29, r8; addli r29, r29, REGSIZE }
45 { st r29, r9; addli r29, r29, REGSIZE }
46 { st r29, r10; addli r29, r29, REGSIZE }
47 .endm
48
49 .macro MCOUNT_RESTORE_REGS
50 addli r29, sp, (2 * REGSIZE)
51 { ld r0, r29; addli r29, r29, REGSIZE }
52 { ld r1, r29; addli r29, r29, REGSIZE }
53 { ld r2, r29; addli r29, r29, REGSIZE }
54 { ld r3, r29; addli r29, r29, REGSIZE }
55 { ld r4, r29; addli r29, r29, REGSIZE }
56 { ld r5, r29; addli r29, r29, REGSIZE }
57 { ld r6, r29; addli r29, r29, REGSIZE }
58 { ld r7, r29; addli r29, r29, REGSIZE }
59 { ld r8, r29; addli r29, r29, REGSIZE }
60 { ld r9, r29; addli r29, r29, REGSIZE }
61 { ld r10, r29; addli lr, sp, (13 * REGSIZE) }
62 { ld lr, lr; addli sp, sp, (14 * REGSIZE) }
63 .endm
64
65 .macro RETURN_BACK
66 { move r12, lr; move lr, r10 }
67 jrp r12
68 .endm
69
70 #ifdef CONFIG_DYNAMIC_FTRACE
71
72 .align 64
73 STD_ENTRY(__mcount)
74 __mcount:
75 j ftrace_stub
76 STD_ENDPROC(__mcount)
77
78 .align 64
79 STD_ENTRY(ftrace_caller)
80 moveli r11, hw2_last(function_trace_stop)
81 { shl16insli r11, r11, hw1(function_trace_stop); move r12, lr }
82 { shl16insli r11, r11, hw0(function_trace_stop); move lr, r10 }
83 ld r11, r11
84 beqz r11, 1f
85 jrp r12
86
87 1:
88 { move r10, lr; move lr, r12 }
89 MCOUNT_SAVE_REGS
90
91 /* arg1: self return address */
92 /* arg2: parent's return address */
93 { move r0, lr; move r1, r10 }
94
95 .global ftrace_call
96 ftrace_call:
97 /*
98 * a placeholder for the call to a real tracing function, i.e.
99 * ftrace_trace_function()
100 */
101 nop
102
103 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
104 .global ftrace_graph_call
105 ftrace_graph_call:
106 /*
107 * a placeholder for the call to a real tracing function, i.e.
108 * ftrace_graph_caller()
109 */
110 nop
111 #endif
112 MCOUNT_RESTORE_REGS
113 .global ftrace_stub
114 ftrace_stub:
115 RETURN_BACK
116 STD_ENDPROC(ftrace_caller)
117
118 #else /* ! CONFIG_DYNAMIC_FTRACE */
119
120 .align 64
121 STD_ENTRY(__mcount)
122 moveli r11, hw2_last(function_trace_stop)
123 { shl16insli r11, r11, hw1(function_trace_stop); move r12, lr }
124 { shl16insli r11, r11, hw0(function_trace_stop); move lr, r10 }
125 ld r11, r11
126 beqz r11, 1f
127 jrp r12
128
129 1:
130 { move r10, lr; move lr, r12 }
131 {
132 moveli r11, hw2_last(ftrace_trace_function)
133 moveli r13, hw2_last(ftrace_stub)
134 }
135 {
136 shl16insli r11, r11, hw1(ftrace_trace_function)
137 shl16insli r13, r13, hw1(ftrace_stub)
138 }
139 {
140 shl16insli r11, r11, hw0(ftrace_trace_function)
141 shl16insli r13, r13, hw0(ftrace_stub)
142 }
143
144 ld r11, r11
145 sub r14, r13, r11
146 bnez r14, static_trace
147
148 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
149 moveli r15, hw2_last(ftrace_graph_return)
150 shl16insli r15, r15, hw1(ftrace_graph_return)
151 shl16insli r15, r15, hw0(ftrace_graph_return)
152 ld r15, r15
153 sub r15, r15, r13
154 bnez r15, ftrace_graph_caller
155
156 {
157 moveli r16, hw2_last(ftrace_graph_entry)
158 moveli r17, hw2_last(ftrace_graph_entry_stub)
159 }
160 {
161 shl16insli r16, r16, hw1(ftrace_graph_entry)
162 shl16insli r17, r17, hw1(ftrace_graph_entry_stub)
163 }
164 {
165 shl16insli r16, r16, hw0(ftrace_graph_entry)
166 shl16insli r17, r17, hw0(ftrace_graph_entry_stub)
167 }
168 ld r16, r16
169 sub r17, r16, r17
170 bnez r17, ftrace_graph_caller
171
172 #endif
173 RETURN_BACK
174
175 static_trace:
176 MCOUNT_SAVE_REGS
177
178 /* arg1: self return address */
179 /* arg2: parent's return address */
180 { move r0, lr; move r1, r10 }
181
182 /* call ftrace_trace_function() */
183 jalr r11
184
185 MCOUNT_RESTORE_REGS
186
187 .global ftrace_stub
188 ftrace_stub:
189 RETURN_BACK
190 STD_ENDPROC(__mcount)
191
192 #endif /* ! CONFIG_DYNAMIC_FTRACE */
193
194 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
195
196 STD_ENTRY(ftrace_graph_caller)
197 ftrace_graph_caller:
198 #ifndef CONFIG_DYNAMIC_FTRACE
199 MCOUNT_SAVE_REGS
200 #endif
201
202 /* arg1: Get the location of the parent's return address */
203 addi r0, sp, 12 * REGSIZE
204 /* arg2: Get self return address */
205 move r1, lr
206
207 jal prepare_ftrace_return
208
209 MCOUNT_RESTORE_REGS
210 RETURN_BACK
211 STD_ENDPROC(ftrace_graph_caller)
212
213 .global return_to_handler
214 return_to_handler:
215 MCOUNT_SAVE_REGS
216
217 jal ftrace_return_to_handler
218 /* restore the real parent address */
219 move r11, r0
220
221 MCOUNT_RESTORE_REGS
222 jr r11
223
224 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */