]> git.karo-electronics.de Git - mv-sheeva.git/blob - arch/mips/kernel/mcount.S
d4a00d29c0bf0c02ca13e1aed17851fb42f49b2e
[mv-sheeva.git] / arch / mips / kernel / mcount.S
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 <wuzhangjin@gmail.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         PTR_ADDIU       sp, PT_SIZE
49 #else
50         PTR_ADDIU       sp, (PT_SIZE + 8)
51 #endif
52 .endm
53
54         .macro RETURN_BACK
55         jr ra
56          move ra, AT
57         .endm
58
59 #ifdef CONFIG_DYNAMIC_FTRACE
60
61 NESTED(ftrace_caller, PT_SIZE, ra)
62         .globl _mcount
63 _mcount:
64         b       ftrace_stub
65          nop
66         lw      t1, function_trace_stop
67         bnez    t1, ftrace_stub
68          nop
69
70         MCOUNT_SAVE_REGS
71 #ifdef KBUILD_MCOUNT_RA_ADDRESS
72         PTR_S   t0, PT_R12(sp)  /* t0 saved the location of the return address(at) by -mmcount-ra-address */
73 #endif
74
75         move    a0, ra          /* arg1: next ip, selfaddr */
76         .globl ftrace_call
77 ftrace_call:
78         nop     /* a placeholder for the call to a real tracing function */
79          move   a1, AT          /* arg2: the caller's next ip, parent */
80
81 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
82         .globl ftrace_graph_call
83 ftrace_graph_call:
84         nop
85          nop
86 #endif
87
88         MCOUNT_RESTORE_REGS
89         .globl ftrace_stub
90 ftrace_stub:
91         RETURN_BACK
92         END(ftrace_caller)
93
94 #else   /* ! CONFIG_DYNAMIC_FTRACE */
95
96 NESTED(_mcount, PT_SIZE, ra)
97         lw      t1, function_trace_stop
98         bnez    t1, ftrace_stub
99          nop
100         PTR_LA  t1, ftrace_stub
101         PTR_L   t2, ftrace_trace_function /* Prepare t2 for (1) */
102         bne     t1, t2, static_trace
103          nop
104
105 #ifdef  CONFIG_FUNCTION_GRAPH_TRACER
106         PTR_L   t3, ftrace_graph_return
107         bne     t1, t3, ftrace_graph_caller
108          nop
109         PTR_LA  t1, ftrace_graph_entry_stub
110         PTR_L   t3, ftrace_graph_entry
111         bne     t1, t3, ftrace_graph_caller
112          nop
113 #endif
114         b       ftrace_stub
115          nop
116
117 static_trace:
118         MCOUNT_SAVE_REGS
119
120         move    a0, ra          /* arg1: next ip, selfaddr */
121         jalr    t2              /* (1) call *ftrace_trace_function */
122          move   a1, AT          /* arg2: the caller's next ip, parent */
123
124         MCOUNT_RESTORE_REGS
125         .globl ftrace_stub
126 ftrace_stub:
127         RETURN_BACK
128         END(_mcount)
129
130 #endif  /* ! CONFIG_DYNAMIC_FTRACE */
131
132 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
133
134 NESTED(ftrace_graph_caller, PT_SIZE, ra)
135 #ifndef CONFIG_DYNAMIC_FTRACE
136         MCOUNT_SAVE_REGS
137 #endif
138
139         /* arg1: Get the location of the parent's return address */
140 #ifdef KBUILD_MCOUNT_RA_ADDRESS
141 #ifdef CONFIG_DYNAMIC_FTRACE
142         PTR_L   a0, PT_R12(sp)
143 #else
144         move    a0, t0
145 #endif
146         bnez    a0, 1f          /* non-leaf func: stored in t0 */
147          nop
148 #endif
149         PTR_LA  a0, PT_R1(sp)   /* leaf func: the location in current stack */
150 1:
151
152         /* arg2: Get self return address */
153 #ifdef CONFIG_DYNAMIC_FTRACE
154         PTR_L   a1, PT_R31(sp)
155 #else
156         move    a1, ra
157 #endif
158
159         /* arg3: Get frame pointer of current stack */
160 #ifdef CONFIG_FRAME_POINTER
161          move   a2, fp
162 #else /* ! CONFIG_FRAME_POINTER */
163 #ifdef CONFIG_64BIT
164          PTR_LA a2, PT_SIZE(sp)
165 #else
166          PTR_LA a2, (PT_SIZE+8)(sp)
167 #endif
168 #endif
169
170         jal     prepare_ftrace_return
171          nop
172         MCOUNT_RESTORE_REGS
173         RETURN_BACK
174         END(ftrace_graph_caller)
175
176         .align  2
177         .globl  return_to_handler
178 return_to_handler:
179         PTR_SUBU        sp, PT_SIZE
180         PTR_S   v0, PT_R2(sp)
181
182         jal     ftrace_return_to_handler
183          PTR_S  v1, PT_R3(sp)
184
185         /* restore the real parent address: v0 -> ra */
186         move    ra, v0
187
188         PTR_L   v0, PT_R2(sp)
189         PTR_L   v1, PT_R3(sp)
190         jr      ra
191          PTR_ADDIU      sp, PT_SIZE
192 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
193
194         .set at
195         .set reorder