Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux-2.6-microblaze.git] / arch / csky / abiv2 / mcount.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3
4 #include <linux/linkage.h>
5 #include <asm/ftrace.h>
6 #include <abi/entry.h>
7 #include <asm/asm-offsets.h>
8
9 /*
10  * csky-gcc with -pg will put the following asm after prologue:
11  *      push    r15
12  *      jsri    _mcount
13  *
14  * stack layout after mcount_enter in _mcount():
15  *
16  * current sp => 0:+-------+
17  *                 | a0-a3 | -> must save all argument regs
18  *             +16:+-------+
19  *                 | lr    | -> _mcount lr (instrumente function's pc)
20  *             +20:+-------+
21  *                 | fp=r8 | -> instrumented function fp
22  *             +24:+-------+
23  *                 | plr   | -> instrumented function lr (parent's pc)
24  *                 +-------+
25  */
26
27 .macro mcount_enter
28         subi    sp, 24
29         stw     a0, (sp, 0)
30         stw     a1, (sp, 4)
31         stw     a2, (sp, 8)
32         stw     a3, (sp, 12)
33         stw     lr, (sp, 16)
34         stw     r8, (sp, 20)
35 .endm
36
37 .macro mcount_exit
38         ldw     a0, (sp, 0)
39         ldw     a1, (sp, 4)
40         ldw     a2, (sp, 8)
41         ldw     a3, (sp, 12)
42         ldw     t1, (sp, 16)
43         ldw     r8, (sp, 20)
44         ldw     lr, (sp, 24)
45         addi    sp, 28
46         jmp     t1
47 .endm
48
49 .macro mcount_enter_regs
50         subi    sp, 8
51         stw     lr, (sp, 0)
52         stw     r8, (sp, 4)
53         SAVE_REGS_FTRACE
54 .endm
55
56 .macro mcount_exit_regs
57         RESTORE_REGS_FTRACE
58         subi    sp, 152
59         ldw     t1, (sp, 4)
60         addi    sp, 152
61         ldw     r8, (sp, 4)
62         ldw     lr, (sp, 8)
63         addi    sp, 12
64         jmp     t1
65 .endm
66
67 .macro save_return_regs
68         subi    sp, 16
69         stw     a0, (sp, 0)
70         stw     a1, (sp, 4)
71         stw     a2, (sp, 8)
72         stw     a3, (sp, 12)
73 .endm
74
75 .macro restore_return_regs
76         mov     lr, a0
77         ldw     a0, (sp, 0)
78         ldw     a1, (sp, 4)
79         ldw     a2, (sp, 8)
80         ldw     a3, (sp, 12)
81         addi    sp, 16
82 .endm
83
84 .macro nop32_stub
85         nop32
86         nop32
87         nop32
88 .endm
89
90 ENTRY(ftrace_stub)
91         jmp     lr
92 END(ftrace_stub)
93
94 #ifndef CONFIG_DYNAMIC_FTRACE
95 ENTRY(_mcount)
96         mcount_enter
97
98         /* r26 is link register, only used with jsri translation */
99         lrw     r26, ftrace_trace_function
100         ldw     r26, (r26, 0)
101         lrw     a1, ftrace_stub
102         cmpne   r26, a1
103         bf      skip_ftrace
104
105         mov     a0, lr
106         subi    a0, 4
107         ldw     a1, (sp, 24)
108         lrw     a2, function_trace_op
109         ldw     a2, (a2, 0)
110
111         jsr     r26
112
113 #ifndef CONFIG_FUNCTION_GRAPH_TRACER
114 skip_ftrace:
115         mcount_exit
116 #else
117 skip_ftrace:
118         lrw     a0, ftrace_graph_return
119         ldw     a0, (a0, 0)
120         lrw     a1, ftrace_stub
121         cmpne   a0, a1
122         bt      ftrace_graph_caller
123
124         lrw     a0, ftrace_graph_entry
125         ldw     a0, (a0, 0)
126         lrw     a1, ftrace_graph_entry_stub
127         cmpne   a0, a1
128         bt      ftrace_graph_caller
129
130         mcount_exit
131 #endif
132 END(_mcount)
133 #else /* CONFIG_DYNAMIC_FTRACE */
134 ENTRY(_mcount)
135         mov     t1, lr
136         ldw     lr, (sp, 0)
137         addi    sp, 4
138         jmp     t1
139 ENDPROC(_mcount)
140
141 ENTRY(ftrace_caller)
142         mcount_enter
143
144         ldw     a0, (sp, 16)
145         subi    a0, 4
146         ldw     a1, (sp, 24)
147         lrw     a2, function_trace_op
148         ldw     a2, (a2, 0)
149
150         nop
151 GLOBAL(ftrace_call)
152         nop32_stub
153
154 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
155         nop
156 GLOBAL(ftrace_graph_call)
157         nop32_stub
158 #endif
159
160         mcount_exit
161 ENDPROC(ftrace_caller)
162 #endif /* CONFIG_DYNAMIC_FTRACE */
163
164 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
165 ENTRY(ftrace_graph_caller)
166         mov     a0, sp
167         addi    a0, 24
168         ldw     a1, (sp, 16)
169         subi    a1, 4
170         mov     a2, r8
171         lrw     r26, prepare_ftrace_return
172         jsr     r26
173         mcount_exit
174 END(ftrace_graph_caller)
175
176 ENTRY(return_to_handler)
177         save_return_regs
178         mov     a0, r8
179         jsri    ftrace_return_to_handler
180         restore_return_regs
181         jmp     lr
182 END(return_to_handler)
183 #endif
184
185 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
186 ENTRY(ftrace_regs_caller)
187         mcount_enter_regs
188
189         lrw     t1, PT_FRAME_SIZE
190         add     t1, sp
191
192         ldw     a0, (t1, 0)
193         subi    a0, 4
194         ldw     a1, (t1, 8)
195         lrw     a2, function_trace_op
196         ldw     a2, (a2, 0)
197         mov     a3, sp
198
199         nop
200 GLOBAL(ftrace_regs_call)
201         nop32_stub
202
203 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
204         nop
205 GLOBAL(ftrace_graph_regs_call)
206         nop32_stub
207 #endif
208
209         mcount_exit_regs
210 ENDPROC(ftrace_regs_caller)
211 #endif /* CONFIG_DYNAMIC_FTRACE */