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