blob: 7a8572f9d58bcdadc1fa5fb31fad65166907f515 [file] [log] [blame]
Matt Flemingfad57fe2008-11-12 20:11:47 +09001/*
2 * arch/sh/lib/mcount.S
3 *
Paul Mundte460ab22009-07-11 21:06:53 +09004 * Copyright (C) 2008, 2009 Paul Mundt
Matt Flemingc1340c02009-06-28 14:05:44 +01005 * Copyright (C) 2008, 2009 Matt Fleming
Matt Flemingfad57fe2008-11-12 20:11:47 +09006 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#include <asm/ftrace.h>
Matt Flemingb99610f2009-07-11 01:00:23 +000012#include <asm/thread_info.h>
13#include <asm/asm-offsets.h>
Matt Flemingfad57fe2008-11-12 20:11:47 +090014
15#define MCOUNT_ENTER() \
16 mov.l r4, @-r15; \
17 mov.l r5, @-r15; \
18 mov.l r6, @-r15; \
19 mov.l r7, @-r15; \
20 sts.l pr, @-r15; \
21 \
22 mov.l @(20,r15),r4; \
23 sts pr, r5
24
25#define MCOUNT_LEAVE() \
26 lds.l @r15+, pr; \
27 mov.l @r15+, r7; \
28 mov.l @r15+, r6; \
29 mov.l @r15+, r5; \
30 rts; \
31 mov.l @r15+, r4
32
Matt Flemingb99610f2009-07-11 01:00:23 +000033#ifdef CONFIG_STACK_DEBUG
34/*
35 * Perform diagnostic checks on the state of the kernel stack.
36 *
37 * Check for stack overflow. If there is less than 1KB free
38 * then it has overflowed.
39 *
40 * Make sure the stack pointer contains a valid address. Valid
41 * addresses for kernel stacks are anywhere after the bss
Geert Uytterhoeven363737d2012-05-31 22:39:21 +020042 * (after __bss_stop) and anywhere in init_thread_union (init_stack).
Matt Flemingb99610f2009-07-11 01:00:23 +000043 */
44#define STACK_CHECK() \
45 mov #(THREAD_SIZE >> 10), r0; \
46 shll8 r0; \
47 shll2 r0; \
48 \
49 /* r1 = sp & (THREAD_SIZE - 1) */ \
50 mov #-1, r1; \
51 add r0, r1; \
52 and r15, r1; \
53 \
54 mov #TI_SIZE, r3; \
55 mov #(STACK_WARN >> 8), r2; \
56 shll8 r2; \
57 add r3, r2; \
58 \
59 /* Is the stack overflowing? */ \
60 cmp/hi r2, r1; \
61 bf stack_panic; \
62 \
Geert Uytterhoeven363737d2012-05-31 22:39:21 +020063 /* If sp > __bss_stop then we're OK. */ \
Matt Flemingb99610f2009-07-11 01:00:23 +000064 mov.l .L_ebss, r1; \
65 cmp/hi r1, r15; \
66 bt 1f; \
67 \
68 /* If sp < init_stack, we're not OK. */ \
69 mov.l .L_init_thread_union, r1; \
70 cmp/hs r1, r15; \
71 bf stack_panic; \
72 \
Geert Uytterhoeven363737d2012-05-31 22:39:21 +020073 /* If sp > init_stack && sp < __bss_stop, not OK. */ \
Matt Flemingb99610f2009-07-11 01:00:23 +000074 add r0, r1; \
75 cmp/hs r1, r15; \
76 bt stack_panic; \
771:
78#else
79#define STACK_CHECK()
80#endif /* CONFIG_STACK_DEBUG */
81
Matt Flemingfad57fe2008-11-12 20:11:47 +090082 .align 2
83 .globl _mcount
84 .type _mcount,@function
85 .globl mcount
86 .type mcount,@function
87_mcount:
88mcount:
Paul Mundte460ab22009-07-11 21:06:53 +090089 STACK_CHECK()
90
91#ifndef CONFIG_FUNCTION_TRACER
92 rts
93 nop
94#else
Matt Flemingfad57fe2008-11-12 20:11:47 +090095 MCOUNT_ENTER()
96
97#ifdef CONFIG_DYNAMIC_FTRACE
98 .globl mcount_call
99mcount_call:
100 mov.l .Lftrace_stub, r6
101#else
102 mov.l .Lftrace_trace_function, r6
103 mov.l ftrace_stub, r7
104 cmp/eq r6, r7
105 bt skip_trace
106 mov.l @r6, r6
107#endif
108
109 jsr @r6
110 nop
111
Matt Fleming327933f2009-07-11 00:29:03 +0000112#ifdef CONFIG_FUNCTION_GRAPH_TRACER
113 mov.l .Lftrace_graph_return, r6
114 mov.l .Lftrace_stub, r7
115 cmp/eq r6, r7
116 bt 1f
117
118 mov.l .Lftrace_graph_caller, r0
119 jmp @r0
120 nop
121
1221:
123 mov.l .Lftrace_graph_entry, r6
124 mov.l .Lftrace_graph_entry_stub, r7
125 cmp/eq r6, r7
126 bt skip_trace
127
128 mov.l .Lftrace_graph_caller, r0
129 jmp @r0
130 nop
131
132 .align 2
133.Lftrace_graph_return:
134 .long ftrace_graph_return
135.Lftrace_graph_entry:
136 .long ftrace_graph_entry
137.Lftrace_graph_entry_stub:
138 .long ftrace_graph_entry_stub
139.Lftrace_graph_caller:
140 .long ftrace_graph_caller
141#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
142
143 .globl skip_trace
Matt Flemingfad57fe2008-11-12 20:11:47 +0900144skip_trace:
145 MCOUNT_LEAVE()
146
147 .align 2
148.Lftrace_trace_function:
Matt Fleming327933f2009-07-11 00:29:03 +0000149 .long ftrace_trace_function
Matt Flemingfad57fe2008-11-12 20:11:47 +0900150
151#ifdef CONFIG_DYNAMIC_FTRACE
Matt Fleming327933f2009-07-11 00:29:03 +0000152#ifdef CONFIG_FUNCTION_GRAPH_TRACER
153/*
154 * NOTE: Do not move either ftrace_graph_call or ftrace_caller
155 * as this will affect the calculation of GRAPH_INSN_OFFSET.
156 */
157 .globl ftrace_graph_call
158ftrace_graph_call:
159 mov.l .Lskip_trace, r0
160 jmp @r0
161 nop
162
163 .align 2
164.Lskip_trace:
165 .long skip_trace
166#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
167
Matt Flemingfad57fe2008-11-12 20:11:47 +0900168 .globl ftrace_caller
169ftrace_caller:
170 MCOUNT_ENTER()
171
172 .globl ftrace_call
173ftrace_call:
174 mov.l .Lftrace_stub, r6
175 jsr @r6
176 nop
177
Matt Fleming327933f2009-07-11 00:29:03 +0000178#ifdef CONFIG_FUNCTION_GRAPH_TRACER
179 bra ftrace_graph_call
180 nop
181#else
Matt Flemingfad57fe2008-11-12 20:11:47 +0900182 MCOUNT_LEAVE()
Matt Fleming327933f2009-07-11 00:29:03 +0000183#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
Matt Flemingfad57fe2008-11-12 20:11:47 +0900184#endif /* CONFIG_DYNAMIC_FTRACE */
185
Paul Mundta470b952009-07-11 20:33:34 +0900186 .align 2
Paul Mundta470b952009-07-11 20:33:34 +0900187
Matt Flemingfad57fe2008-11-12 20:11:47 +0900188/*
189 * NOTE: From here on the locations of the .Lftrace_stub label and
190 * ftrace_stub itself are fixed. Adding additional data here will skew
191 * the displacement for the memory table and break the block replacement.
192 * Place new labels either after the ftrace_stub body, or before
193 * ftrace_caller. You have been warned.
194 */
Matt Flemingfad57fe2008-11-12 20:11:47 +0900195.Lftrace_stub:
196 .long ftrace_stub
197
198 .globl ftrace_stub
199ftrace_stub:
200 rts
201 nop
Matt Flemingc1340c02009-06-28 14:05:44 +0100202
Matt Fleming327933f2009-07-11 00:29:03 +0000203#ifdef CONFIG_FUNCTION_GRAPH_TRACER
204 .globl ftrace_graph_caller
205ftrace_graph_caller:
Steven Rostedt (Red Hat)41dc27e2014-06-25 12:27:42 -0400206 mov.l 2f, r1
Matt Fleming327933f2009-07-11 00:29:03 +0000207 jmp @r1
208 nop
2091:
210 /*
211 * MCOUNT_ENTER() pushed 5 registers onto the stack, so
212 * the stack address containing our return address is
213 * r15 + 20.
214 */
215 mov #20, r0
216 add r15, r0
217 mov r0, r4
218
219 mov.l .Lprepare_ftrace_return, r0
220 jsr @r0
221 nop
222
223 MCOUNT_LEAVE()
224
225 .align 2
Steven Rostedt (Red Hat)41dc27e2014-06-25 12:27:42 -04002262: .long skip_trace
Matt Fleming327933f2009-07-11 00:29:03 +0000227.Lprepare_ftrace_return:
228 .long prepare_ftrace_return
229
230 .globl return_to_handler
231return_to_handler:
232 /*
233 * Save the return values.
234 */
235 mov.l r0, @-r15
236 mov.l r1, @-r15
237
238 mov #0, r4
239
240 mov.l .Lftrace_return_to_handler, r0
241 jsr @r0
242 nop
243
244 /*
245 * The return value from ftrace_return_handler has the real
246 * address that we should return to.
247 */
248 lds r0, pr
249 mov.l @r15+, r1
250 rts
251 mov.l @r15+, r0
252
253
254 .align 2
255.Lftrace_return_to_handler:
256 .long ftrace_return_to_handler
257#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
Paul Mundte460ab22009-07-11 21:06:53 +0900258#endif /* CONFIG_FUNCTION_TRACER */
259
260#ifdef CONFIG_STACK_DEBUG
261 .globl stack_panic
262stack_panic:
263 mov.l .Ldump_stack, r0
264 jsr @r0
265 nop
266
267 mov.l .Lpanic, r0
268 jsr @r0
269 mov.l .Lpanic_s, r4
270
271 rts
272 nop
273
274 .align 2
Paul Mundte460ab22009-07-11 21:06:53 +0900275.L_init_thread_union:
276 .long init_thread_union
Paul Mundt14eae6e2013-01-14 18:07:36 +0900277.L_ebss:
278 .long __bss_stop
Paul Mundte460ab22009-07-11 21:06:53 +0900279.Lpanic:
280 .long panic
281.Lpanic_s:
282 .long .Lpanic_str
283.Ldump_stack:
284 .long dump_stack
285
286 .section .rodata
287 .align 2
288.Lpanic_str:
289 .string "Stack error"
290#endif /* CONFIG_STACK_DEBUG */