lin
2025-03-21 c2c82c91f6acd44c57766034b6ced0c53c164a55
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
/*
 * Copyright 2012 Tilera Corporation. All Rights Reserved.
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation, version 2.
 *
 *   This program is distributed in the hope that it will be useful, but
 *   WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 *
 * TILE-Gx specific __mcount support
 */
 
#include <linux/linkage.h>
#include <asm/ftrace.h>
 
#define REGSIZE 8
 
   .text
   .global __mcount
 
   .macro    MCOUNT_SAVE_REGS
   addli    sp, sp, -REGSIZE
   {
    st     sp, lr
    addli    r29, sp, - (12 * REGSIZE)
   }
   {
    addli    sp, sp, - (13 * REGSIZE)
    st     r29, sp
   }
   addli    r29, r29, REGSIZE
   { st    r29, r0; addli    r29, r29, REGSIZE }
   { st    r29, r1; addli    r29, r29, REGSIZE }
   { st    r29, r2; addli    r29, r29, REGSIZE }
   { st    r29, r3; addli    r29, r29, REGSIZE }
   { st    r29, r4; addli    r29, r29, REGSIZE }
   { st    r29, r5; addli    r29, r29, REGSIZE }
   { st    r29, r6; addli    r29, r29, REGSIZE }
   { st    r29, r7; addli    r29, r29, REGSIZE }
   { st    r29, r8; addli    r29, r29, REGSIZE }
   { st    r29, r9; addli    r29, r29, REGSIZE }
   { st    r29, r10; addli    r29, r29, REGSIZE }
   .endm
 
   .macro    MCOUNT_RESTORE_REGS
   addli    r29, sp, (2 * REGSIZE)
   { ld    r0, r29; addli    r29, r29, REGSIZE }
   { ld    r1, r29; addli    r29, r29, REGSIZE }
   { ld    r2, r29; addli    r29, r29, REGSIZE }
   { ld    r3, r29; addli    r29, r29, REGSIZE }
   { ld    r4, r29; addli    r29, r29, REGSIZE }
   { ld    r5, r29; addli    r29, r29, REGSIZE }
   { ld    r6, r29; addli    r29, r29, REGSIZE }
   { ld    r7, r29; addli    r29, r29, REGSIZE }
   { ld    r8, r29; addli    r29, r29, REGSIZE }
   { ld    r9, r29; addli    r29, r29, REGSIZE }
   { ld    r10, r29; addli    lr, sp, (13 * REGSIZE) }
   { ld    lr, lr;  addli    sp, sp, (14 * REGSIZE) }
   .endm
 
   .macro  RETURN_BACK
   { move    r12, lr; move    lr, r10 }
   jrp    r12
   .endm
 
#ifdef CONFIG_DYNAMIC_FTRACE
 
   .align    64
STD_ENTRY(__mcount)
__mcount:
   j    ftrace_stub
STD_ENDPROC(__mcount)
 
   .align    64
STD_ENTRY(ftrace_caller)
   MCOUNT_SAVE_REGS
 
   /* arg1: self return address */
   /* arg2: parent's return address */
   /* arg3: ftrace_ops */
   /* arg4: regs (but make it NULL) */
   { move    r0, lr;  moveli        r2, hw2_last(function_trace_op) }
   { move    r1, r10; shl16insli    r2, r2, hw1(function_trace_op) }
   { movei    r3, 0;   shl16insli    r2, r2, hw0(function_trace_op) }
   ld    r2,r2
 
   .global    ftrace_call
ftrace_call:
   /*
    * a placeholder for the call to a real tracing function, i.e.
    * ftrace_trace_function()
    */
   nop
 
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
   .global    ftrace_graph_call
ftrace_graph_call:
   /*
    * a placeholder for the call to a real tracing function, i.e.
    * ftrace_graph_caller()
    */
   nop
#endif
   MCOUNT_RESTORE_REGS
   .global    ftrace_stub
ftrace_stub:
   RETURN_BACK
STD_ENDPROC(ftrace_caller)
 
#else /* ! CONFIG_DYNAMIC_FTRACE */
 
   .align    64
STD_ENTRY(__mcount)
   {
    moveli    r11, hw2_last(ftrace_trace_function)
    moveli    r13, hw2_last(ftrace_stub)
   }
   {
    shl16insli    r11, r11, hw1(ftrace_trace_function)
    shl16insli    r13, r13, hw1(ftrace_stub)
   }
   {
    shl16insli    r11, r11, hw0(ftrace_trace_function)
    shl16insli    r13, r13, hw0(ftrace_stub)
   }
 
   ld    r11, r11
   sub    r14, r13, r11
   bnez    r14, static_trace
 
#ifdef    CONFIG_FUNCTION_GRAPH_TRACER
   moveli    r15, hw2_last(ftrace_graph_return)
   shl16insli    r15, r15, hw1(ftrace_graph_return)
   shl16insli    r15, r15, hw0(ftrace_graph_return)
   ld    r15, r15
   sub    r15, r15, r13
   bnez    r15, ftrace_graph_caller
 
   {
    moveli    r16, hw2_last(ftrace_graph_entry)
    moveli    r17, hw2_last(ftrace_graph_entry_stub)
   }
   {
    shl16insli    r16, r16, hw1(ftrace_graph_entry)
    shl16insli    r17, r17, hw1(ftrace_graph_entry_stub)
   }
   {
    shl16insli    r16, r16, hw0(ftrace_graph_entry)
    shl16insli    r17, r17, hw0(ftrace_graph_entry_stub)
   }
   ld    r16, r16
   sub    r17, r16, r17
   bnez    r17, ftrace_graph_caller
 
#endif
   RETURN_BACK
 
static_trace:
   MCOUNT_SAVE_REGS
 
   /* arg1: self return address */
   /* arg2: parent's return address */
   { move    r0, lr; move    r1, r10 }
 
   /* call ftrace_trace_function() */
   jalr    r11
 
   MCOUNT_RESTORE_REGS
 
   .global ftrace_stub
ftrace_stub:
   RETURN_BACK
STD_ENDPROC(__mcount)
 
#endif    /* ! CONFIG_DYNAMIC_FTRACE */
 
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
 
STD_ENTRY(ftrace_graph_caller)
ftrace_graph_caller:
#ifndef CONFIG_DYNAMIC_FTRACE
   MCOUNT_SAVE_REGS
#endif
 
   /* arg1: Get the location of the parent's return address */
   addi    r0, sp, 12 * REGSIZE
   /* arg2: Get self return address */
   move    r1, lr
 
   jal prepare_ftrace_return
 
   MCOUNT_RESTORE_REGS
   RETURN_BACK
STD_ENDPROC(ftrace_graph_caller)
 
   .global return_to_handler
return_to_handler:
   MCOUNT_SAVE_REGS
 
   jal    ftrace_return_to_handler
   /* restore the real parent address */
   move    r11, r0
 
   MCOUNT_RESTORE_REGS
   jr    r11
 
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */