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
90ENTRY(ftrace_stub)
91 jmp lr
92END(ftrace_stub)
93
94#ifndef CONFIG_DYNAMIC_FTRACE
95ENTRY(_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
114skip_ftrace:
115 mcount_exit
116#else
117skip_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
132END(_mcount)
133#else /* CONFIG_DYNAMIC_FTRACE */
134ENTRY(_mcount)
135 mov t1, lr
136 ldw lr, (sp, 0)
137 addi sp, 4
138 jmp t1
139ENDPROC(_mcount)
140
141ENTRY(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
151GLOBAL(ftrace_call)
152 nop32_stub
153
154#ifdef CONFIG_FUNCTION_GRAPH_TRACER
155 nop
156GLOBAL(ftrace_graph_call)
157 nop32_stub
158#endif
159
160 mcount_exit
161ENDPROC(ftrace_caller)
162#endif /* CONFIG_DYNAMIC_FTRACE */
163
164#ifdef CONFIG_FUNCTION_GRAPH_TRACER
165ENTRY(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
174END(ftrace_graph_caller)
175
176ENTRY(return_to_handler)
177 save_return_regs
178 mov a0, r8
179 jsri ftrace_return_to_handler
180 restore_return_regs
181 jmp lr
182END(return_to_handler)
183#endif
184
185#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
186ENTRY(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
200GLOBAL(ftrace_regs_call)
201 nop32_stub
202
203#ifdef CONFIG_FUNCTION_GRAPH_TRACER
204 nop
205GLOBAL(ftrace_graph_regs_call)
206 nop32_stub
207#endif
208
209 mcount_exit_regs
210ENDPROC(ftrace_regs_caller)
211#endif /* CONFIG_DYNAMIC_FTRACE */
212

source code of linux/arch/csky/abiv2/mcount.S