Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / arch / riscv / kernel / mcount-dyn.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (C) 2017 Andes Technology Corporation */
3
4 #include <linux/init.h>
5 #include <linux/linkage.h>
6 #include <asm/asm.h>
7 #include <asm/csr.h>
8 #include <asm/unistd.h>
9 #include <asm/thread_info.h>
10 #include <asm/asm-offsets.h>
11 #include <asm-generic/export.h>
12 #include <asm/ftrace.h>
13
14         .text
15
16         .macro SAVE_ABI_STATE
17 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
18         addi    sp, sp, -48
19         sd      s0, 32(sp)
20         sd      ra, 40(sp)
21         addi    s0, sp, 48
22         sd      t0, 24(sp)
23         sd      t1, 16(sp)
24 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
25         sd      t2, 8(sp)
26 #endif
27 #else
28         addi    sp, sp, -16
29         sd      s0, 0(sp)
30         sd      ra, 8(sp)
31         addi    s0, sp, 16
32 #endif
33         .endm
34
35         .macro RESTORE_ABI_STATE
36 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
37         ld      s0, 32(sp)
38         ld      ra, 40(sp)
39         addi    sp, sp, 48
40 #else
41         ld      ra, 8(sp)
42         ld      s0, 0(sp)
43         addi    sp, sp, 16
44 #endif
45         .endm
46
47         .macro RESTORE_GRAPH_ARGS
48         ld      a0, 24(sp)
49         ld      a1, 16(sp)
50 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
51         ld      a2, 8(sp)
52 #endif
53         .endm
54
55 ENTRY(ftrace_graph_caller)
56         addi    sp, sp, -16
57         sd      s0, 0(sp)
58         sd      ra, 8(sp)
59         addi    s0, sp, 16
60 ftrace_graph_call:
61         .global ftrace_graph_call
62         /*
63          * Calling ftrace_enable/disable_ftrace_graph_caller would overwrite the
64          * call below.  Check ftrace_modify_all_code for details.
65          */
66         call    ftrace_stub
67         ld      ra, 8(sp)
68         ld      s0, 0(sp)
69         addi    sp, sp, 16
70         ret
71 ENDPROC(ftrace_graph_caller)
72
73 ENTRY(ftrace_caller)
74         /*
75          * a0: the address in the caller when calling ftrace_caller
76          * a1: the caller's return address
77          * a2: the address of global variable function_trace_op
78          */
79         ld      a1, -8(s0)
80         addi    a0, ra, -MCOUNT_INSN_SIZE
81         la      t5, function_trace_op
82         ld      a2, 0(t5)
83
84 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
85         /*
86          * the graph tracer (specifically, prepare_ftrace_return) needs these
87          * arguments but for now the function tracer occupies the regs, so we
88          * save them in temporary regs to recover later.
89          */
90         addi    t0, s0, -8
91         mv      t1, a0
92 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
93         ld      t2, -16(s0)
94 #endif
95 #endif
96
97         SAVE_ABI_STATE
98 ftrace_call:
99         .global ftrace_call
100         /*
101          * For the dynamic ftrace to work, here we should reserve at least
102          * 8 bytes for a functional auipc-jalr pair.  The following call
103          * serves this purpose.
104          *
105          * Calling ftrace_update_ftrace_func would overwrite the nops below.
106          * Check ftrace_modify_all_code for details.
107          */
108         call    ftrace_stub
109
110 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
111         RESTORE_GRAPH_ARGS
112         call    ftrace_graph_caller
113 #endif
114
115         RESTORE_ABI_STATE
116         ret
117 ENDPROC(ftrace_caller)
118
119 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
120         .macro SAVE_ALL
121         addi    sp, sp, -(PT_SIZE_ON_STACK+16)
122         sd      s0, (PT_SIZE_ON_STACK)(sp)
123         sd      ra, (PT_SIZE_ON_STACK+8)(sp)
124         addi    s0, sp, (PT_SIZE_ON_STACK+16)
125
126         sd x1,  PT_RA(sp)
127         sd x2,  PT_SP(sp)
128         sd x3,  PT_GP(sp)
129         sd x4,  PT_TP(sp)
130         sd x5,  PT_T0(sp)
131         sd x6,  PT_T1(sp)
132         sd x7,  PT_T2(sp)
133         sd x8,  PT_S0(sp)
134         sd x9,  PT_S1(sp)
135         sd x10, PT_A0(sp)
136         sd x11, PT_A1(sp)
137         sd x12, PT_A2(sp)
138         sd x13, PT_A3(sp)
139         sd x14, PT_A4(sp)
140         sd x15, PT_A5(sp)
141         sd x16, PT_A6(sp)
142         sd x17, PT_A7(sp)
143         sd x18, PT_S2(sp)
144         sd x19, PT_S3(sp)
145         sd x20, PT_S4(sp)
146         sd x21, PT_S5(sp)
147         sd x22, PT_S6(sp)
148         sd x23, PT_S7(sp)
149         sd x24, PT_S8(sp)
150         sd x25, PT_S9(sp)
151         sd x26, PT_S10(sp)
152         sd x27, PT_S11(sp)
153         sd x28, PT_T3(sp)
154         sd x29, PT_T4(sp)
155         sd x30, PT_T5(sp)
156         sd x31, PT_T6(sp)
157         .endm
158
159         .macro RESTORE_ALL
160         ld x1,  PT_RA(sp)
161         ld x2,  PT_SP(sp)
162         ld x3,  PT_GP(sp)
163         ld x4,  PT_TP(sp)
164         ld x5,  PT_T0(sp)
165         ld x6,  PT_T1(sp)
166         ld x7,  PT_T2(sp)
167         ld x8,  PT_S0(sp)
168         ld x9,  PT_S1(sp)
169         ld x10, PT_A0(sp)
170         ld x11, PT_A1(sp)
171         ld x12, PT_A2(sp)
172         ld x13, PT_A3(sp)
173         ld x14, PT_A4(sp)
174         ld x15, PT_A5(sp)
175         ld x16, PT_A6(sp)
176         ld x17, PT_A7(sp)
177         ld x18, PT_S2(sp)
178         ld x19, PT_S3(sp)
179         ld x20, PT_S4(sp)
180         ld x21, PT_S5(sp)
181         ld x22, PT_S6(sp)
182         ld x23, PT_S7(sp)
183         ld x24, PT_S8(sp)
184         ld x25, PT_S9(sp)
185         ld x26, PT_S10(sp)
186         ld x27, PT_S11(sp)
187         ld x28, PT_T3(sp)
188         ld x29, PT_T4(sp)
189         ld x30, PT_T5(sp)
190         ld x31, PT_T6(sp)
191
192         ld      s0, (PT_SIZE_ON_STACK)(sp)
193         ld      ra, (PT_SIZE_ON_STACK+8)(sp)
194         addi    sp, sp, (PT_SIZE_ON_STACK+16)
195         .endm
196
197         .macro RESTORE_GRAPH_REG_ARGS
198         ld      a0, PT_T0(sp)
199         ld      a1, PT_T1(sp)
200 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
201         ld      a2, PT_T2(sp)
202 #endif
203         .endm
204
205 /*
206  * Most of the contents are the same as ftrace_caller.
207  */
208 ENTRY(ftrace_regs_caller)
209         /*
210          * a3: the address of all registers in the stack
211          */
212         ld      a1, -8(s0)
213         addi    a0, ra, -MCOUNT_INSN_SIZE
214         la      t5, function_trace_op
215         ld      a2, 0(t5)
216         addi    a3, sp, -(PT_SIZE_ON_STACK+16)
217
218 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
219         addi    t0, s0, -8
220         mv      t1, a0
221 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
222         ld      t2, -16(s0)
223 #endif
224 #endif
225         SAVE_ALL
226
227 ftrace_regs_call:
228         .global ftrace_regs_call
229         call    ftrace_stub
230
231 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
232         RESTORE_GRAPH_REG_ARGS
233         call    ftrace_graph_caller
234 #endif
235
236         RESTORE_ALL
237         ret
238 ENDPROC(ftrace_regs_caller)
239 #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */