xref: /openbmc/linux/arch/csky/abiv2/mcount.S (revision 4bb9d46d)
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
107	jsr	r26
108
109#ifndef CONFIG_FUNCTION_GRAPH_TRACER
110skip_ftrace:
111	mcount_exit
112#else
113skip_ftrace:
114	lrw	a0, ftrace_graph_return
115	ldw	a0, (a0, 0)
116	lrw	a1, ftrace_stub
117	cmpne	a0, a1
118	bt	ftrace_graph_caller
119
120	lrw	a0, ftrace_graph_entry
121	ldw	a0, (a0, 0)
122	lrw	a1, ftrace_graph_entry_stub
123	cmpne	a0, a1
124	bt	ftrace_graph_caller
125
126	mcount_exit
127#endif
128END(_mcount)
129#else /* CONFIG_DYNAMIC_FTRACE */
130ENTRY(_mcount)
131	mov	t1, lr
132	ldw	lr, (sp, 0)
133	addi	sp, 4
134	jmp	t1
135ENDPROC(_mcount)
136
137ENTRY(ftrace_caller)
138	mcount_enter
139
140	ldw	a0, (sp, 16)
141	subi	a0, 4
142	ldw	a1, (sp, 24)
143	lrw	a2, function_trace_op
144	ldw	a2, (a2, 0)
145
146	nop
147GLOBAL(ftrace_call)
148	nop32_stub
149
150#ifdef CONFIG_FUNCTION_GRAPH_TRACER
151	nop
152GLOBAL(ftrace_graph_call)
153	nop32_stub
154#endif
155
156	mcount_exit
157ENDPROC(ftrace_caller)
158#endif /* CONFIG_DYNAMIC_FTRACE */
159
160#ifdef CONFIG_FUNCTION_GRAPH_TRACER
161ENTRY(ftrace_graph_caller)
162	mov	a0, sp
163	addi	a0, 24
164	ldw	a1, (sp, 16)
165	subi	a1, 4
166	mov	a2, r8
167	lrw	r26, prepare_ftrace_return
168	jsr	r26
169	mcount_exit
170END(ftrace_graph_caller)
171
172ENTRY(return_to_handler)
173	save_return_regs
174	mov	a0, r8
175	jsri	ftrace_return_to_handler
176	restore_return_regs
177	jmp	lr
178END(return_to_handler)
179#endif
180
181#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
182ENTRY(ftrace_regs_caller)
183	mcount_enter_regs
184
185	lrw	t1, PT_FRAME_SIZE
186	add	t1, sp
187
188	ldw	a0, (t1, 0)
189	subi	a0, 4
190	ldw	a1, (t1, 8)
191	lrw	a2, function_trace_op
192	ldw	a2, (a2, 0)
193	mov	a3, sp
194
195	nop
196GLOBAL(ftrace_regs_call)
197	nop32_stub
198
199#ifdef CONFIG_FUNCTION_GRAPH_TRACER
200	nop
201GLOBAL(ftrace_graph_regs_call)
202	nop32_stub
203#endif
204
205	mcount_exit_regs
206ENDPROC(ftrace_regs_caller)
207#endif /* CONFIG_DYNAMIC_FTRACE */
208