xref: /openbmc/linux/arch/csky/abiv2/mcount.S (revision ef9303fd)
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	ldw	t1, (sp, 0)
59	ldw	r8, (sp, 4)
60	ldw	lr, (sp, 8)
61	addi	sp, 12
62	jmp	t1
63.endm
64
65.macro save_return_regs
66	subi	sp, 16
67	stw	a0, (sp, 0)
68	stw	a1, (sp, 4)
69	stw	a2, (sp, 8)
70	stw	a3, (sp, 12)
71.endm
72
73.macro restore_return_regs
74	mov	lr, a0
75	ldw	a0, (sp, 0)
76	ldw	a1, (sp, 4)
77	ldw	a2, (sp, 8)
78	ldw	a3, (sp, 12)
79	addi	sp, 16
80.endm
81
82.macro nop32_stub
83	nop32
84	nop32
85	nop32
86.endm
87
88ENTRY(ftrace_stub)
89	jmp	lr
90END(ftrace_stub)
91
92#ifndef CONFIG_DYNAMIC_FTRACE
93ENTRY(_mcount)
94	mcount_enter
95
96	/* r26 is link register, only used with jsri translation */
97	lrw	r26, ftrace_trace_function
98	ldw	r26, (r26, 0)
99	lrw	a1, ftrace_stub
100	cmpne	r26, a1
101	bf	skip_ftrace
102
103	mov	a0, lr
104	subi	a0, 4
105	ldw	a1, (sp, 24)
106	lrw	a2, function_trace_op
107	ldw	a2, (a2, 0)
108
109	jsr	r26
110
111#ifndef CONFIG_FUNCTION_GRAPH_TRACER
112skip_ftrace:
113	mcount_exit
114#else
115skip_ftrace:
116	lrw	a0, ftrace_graph_return
117	ldw	a0, (a0, 0)
118	lrw	a1, ftrace_stub
119	cmpne	a0, a1
120	bt	ftrace_graph_caller
121
122	lrw	a0, ftrace_graph_entry
123	ldw	a0, (a0, 0)
124	lrw	a1, ftrace_graph_entry_stub
125	cmpne	a0, a1
126	bt	ftrace_graph_caller
127
128	mcount_exit
129#endif
130END(_mcount)
131#else /* CONFIG_DYNAMIC_FTRACE */
132ENTRY(_mcount)
133	mov	t1, lr
134	ldw	lr, (sp, 0)
135	addi	sp, 4
136	jmp	t1
137ENDPROC(_mcount)
138
139ENTRY(ftrace_caller)
140	mcount_enter
141
142	ldw	a0, (sp, 16)
143	subi	a0, 4
144	ldw	a1, (sp, 24)
145	lrw	a2, function_trace_op
146	ldw	a2, (a2, 0)
147
148	nop
149GLOBAL(ftrace_call)
150	nop32_stub
151
152#ifdef CONFIG_FUNCTION_GRAPH_TRACER
153	nop
154GLOBAL(ftrace_graph_call)
155	nop32_stub
156#endif
157
158	mcount_exit
159ENDPROC(ftrace_caller)
160#endif /* CONFIG_DYNAMIC_FTRACE */
161
162#ifdef CONFIG_FUNCTION_GRAPH_TRACER
163ENTRY(ftrace_graph_caller)
164	mov	a0, sp
165	addi	a0, 24
166	ldw	a1, (sp, 16)
167	subi	a1, 4
168	mov	a2, r8
169	lrw	r26, prepare_ftrace_return
170	jsr	r26
171	mcount_exit
172END(ftrace_graph_caller)
173
174ENTRY(return_to_handler)
175	save_return_regs
176	mov	a0, r8
177	jsri	ftrace_return_to_handler
178	restore_return_regs
179	jmp	lr
180END(return_to_handler)
181#endif
182
183#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
184ENTRY(ftrace_regs_caller)
185	mcount_enter_regs
186
187	lrw	t1, PT_FRAME_SIZE
188	add	t1, sp
189
190	ldw	a0, (t1, 0)
191	subi	a0, 4
192	ldw	a1, (t1, 8)
193	lrw	a2, function_trace_op
194	ldw	a2, (a2, 0)
195	mov	a3, sp
196
197	nop
198GLOBAL(ftrace_regs_call)
199	nop32_stub
200
201#ifdef CONFIG_FUNCTION_GRAPH_TRACER
202	nop
203GLOBAL(ftrace_graph_regs_call)
204	nop32_stub
205#endif
206
207	mcount_exit_regs
208ENDPROC(ftrace_regs_caller)
209#endif /* CONFIG_DYNAMIC_FTRACE */
210