GNU Linux-libre 6.7.9-gnu
[releases.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 #define FENTRY_RA_OFFSET        8
17 #define ABI_SIZE_ON_STACK       80
18 #define ABI_A0                  0
19 #define ABI_A1                  8
20 #define ABI_A2                  16
21 #define ABI_A3                  24
22 #define ABI_A4                  32
23 #define ABI_A5                  40
24 #define ABI_A6                  48
25 #define ABI_A7                  56
26 #define ABI_T0                  64
27 #define ABI_RA                  72
28
29         .macro SAVE_ABI
30         addi    sp, sp, -ABI_SIZE_ON_STACK
31
32         REG_S   a0, ABI_A0(sp)
33         REG_S   a1, ABI_A1(sp)
34         REG_S   a2, ABI_A2(sp)
35         REG_S   a3, ABI_A3(sp)
36         REG_S   a4, ABI_A4(sp)
37         REG_S   a5, ABI_A5(sp)
38         REG_S   a6, ABI_A6(sp)
39         REG_S   a7, ABI_A7(sp)
40         REG_S   t0, ABI_T0(sp)
41         REG_S   ra, ABI_RA(sp)
42         .endm
43
44         .macro RESTORE_ABI
45         REG_L   a0, ABI_A0(sp)
46         REG_L   a1, ABI_A1(sp)
47         REG_L   a2, ABI_A2(sp)
48         REG_L   a3, ABI_A3(sp)
49         REG_L   a4, ABI_A4(sp)
50         REG_L   a5, ABI_A5(sp)
51         REG_L   a6, ABI_A6(sp)
52         REG_L   a7, ABI_A7(sp)
53         REG_L   t0, ABI_T0(sp)
54         REG_L   ra, ABI_RA(sp)
55
56         addi    sp, sp, ABI_SIZE_ON_STACK
57         .endm
58
59 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
60         .macro SAVE_ALL
61         addi    sp, sp, -PT_SIZE_ON_STACK
62
63         REG_S t0,  PT_EPC(sp)
64         REG_S x1,  PT_RA(sp)
65         REG_S x2,  PT_SP(sp)
66         REG_S x3,  PT_GP(sp)
67         REG_S x4,  PT_TP(sp)
68         REG_S x5,  PT_T0(sp)
69         save_from_x6_to_x31
70         .endm
71
72         .macro RESTORE_ALL
73         REG_L x1,  PT_RA(sp)
74         REG_L x2,  PT_SP(sp)
75         REG_L x3,  PT_GP(sp)
76         REG_L x4,  PT_TP(sp)
77         /* Restore t0 with PT_EPC */
78         REG_L x5,  PT_EPC(sp)
79         restore_from_x6_to_x31
80
81         addi    sp, sp, PT_SIZE_ON_STACK
82         .endm
83 #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
84
85 SYM_FUNC_START(ftrace_caller)
86         SAVE_ABI
87
88         addi    a0, t0, -FENTRY_RA_OFFSET
89         la      a1, function_trace_op
90         REG_L   a2, 0(a1)
91         mv      a1, ra
92         mv      a3, sp
93
94 SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
95         call    ftrace_stub
96
97 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
98         addi    a0, sp, ABI_RA
99         REG_L   a1, ABI_T0(sp)
100         addi    a1, a1, -FENTRY_RA_OFFSET
101 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
102         mv      a2, s0
103 #endif
104 SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL)
105         call    ftrace_stub
106 #endif
107         RESTORE_ABI
108         jr t0
109 SYM_FUNC_END(ftrace_caller)
110
111 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
112 SYM_FUNC_START(ftrace_regs_caller)
113         SAVE_ALL
114
115         addi    a0, t0, -FENTRY_RA_OFFSET
116         la      a1, function_trace_op
117         REG_L   a2, 0(a1)
118         mv      a1, ra
119         mv      a3, sp
120
121 SYM_INNER_LABEL(ftrace_regs_call, SYM_L_GLOBAL)
122         call    ftrace_stub
123
124 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
125         addi    a0, sp, PT_RA
126         REG_L   a1, PT_EPC(sp)
127         addi    a1, a1, -FENTRY_RA_OFFSET
128 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST
129         mv      a2, s0
130 #endif
131 SYM_INNER_LABEL(ftrace_graph_regs_call, SYM_L_GLOBAL)
132         call    ftrace_stub
133 #endif
134
135         RESTORE_ALL
136         jr t0
137 SYM_FUNC_END(ftrace_regs_caller)
138 #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */