xref: /OK3568_Linux_fs/kernel/arch/csky/abiv2/mcount.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun#include <linux/linkage.h>
5*4882a593Smuzhiyun#include <asm/ftrace.h>
6*4882a593Smuzhiyun#include <abi/entry.h>
7*4882a593Smuzhiyun#include <asm/asm-offsets.h>
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun/*
10*4882a593Smuzhiyun * csky-gcc with -pg will put the following asm after prologue:
11*4882a593Smuzhiyun *      push	r15
12*4882a593Smuzhiyun *      jsri	_mcount
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun * stack layout after mcount_enter in _mcount():
15*4882a593Smuzhiyun *
16*4882a593Smuzhiyun * current sp => 0:+-------+
17*4882a593Smuzhiyun *                 | a0-a3 | -> must save all argument regs
18*4882a593Smuzhiyun *             +16:+-------+
19*4882a593Smuzhiyun *                 | lr    | -> _mcount lr (instrumente function's pc)
20*4882a593Smuzhiyun *             +20:+-------+
21*4882a593Smuzhiyun *                 | fp=r8 | -> instrumented function fp
22*4882a593Smuzhiyun *             +24:+-------+
23*4882a593Smuzhiyun *                 | plr   | -> instrumented function lr (parent's pc)
24*4882a593Smuzhiyun *                 +-------+
25*4882a593Smuzhiyun */
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun.macro mcount_enter
28*4882a593Smuzhiyun	subi	sp, 24
29*4882a593Smuzhiyun	stw	a0, (sp, 0)
30*4882a593Smuzhiyun	stw	a1, (sp, 4)
31*4882a593Smuzhiyun	stw	a2, (sp, 8)
32*4882a593Smuzhiyun	stw	a3, (sp, 12)
33*4882a593Smuzhiyun	stw	lr, (sp, 16)
34*4882a593Smuzhiyun	stw	r8, (sp, 20)
35*4882a593Smuzhiyun.endm
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun.macro mcount_exit
38*4882a593Smuzhiyun	ldw	a0, (sp, 0)
39*4882a593Smuzhiyun	ldw	a1, (sp, 4)
40*4882a593Smuzhiyun	ldw	a2, (sp, 8)
41*4882a593Smuzhiyun	ldw	a3, (sp, 12)
42*4882a593Smuzhiyun	ldw	t1, (sp, 16)
43*4882a593Smuzhiyun	ldw	r8, (sp, 20)
44*4882a593Smuzhiyun	ldw	lr, (sp, 24)
45*4882a593Smuzhiyun	addi	sp, 28
46*4882a593Smuzhiyun	jmp	t1
47*4882a593Smuzhiyun.endm
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun.macro mcount_enter_regs
50*4882a593Smuzhiyun	subi	sp, 8
51*4882a593Smuzhiyun	stw	lr, (sp, 0)
52*4882a593Smuzhiyun	stw	r8, (sp, 4)
53*4882a593Smuzhiyun	SAVE_REGS_FTRACE
54*4882a593Smuzhiyun.endm
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun.macro mcount_exit_regs
57*4882a593Smuzhiyun	RESTORE_REGS_FTRACE
58*4882a593Smuzhiyun	subi	sp, 152
59*4882a593Smuzhiyun	ldw	t1, (sp, 4)
60*4882a593Smuzhiyun	addi	sp, 152
61*4882a593Smuzhiyun	ldw	r8, (sp, 4)
62*4882a593Smuzhiyun	ldw	lr, (sp, 8)
63*4882a593Smuzhiyun	addi	sp, 12
64*4882a593Smuzhiyun	jmp	t1
65*4882a593Smuzhiyun.endm
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun.macro save_return_regs
68*4882a593Smuzhiyun	subi	sp, 16
69*4882a593Smuzhiyun	stw	a0, (sp, 0)
70*4882a593Smuzhiyun	stw	a1, (sp, 4)
71*4882a593Smuzhiyun	stw	a2, (sp, 8)
72*4882a593Smuzhiyun	stw	a3, (sp, 12)
73*4882a593Smuzhiyun.endm
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun.macro restore_return_regs
76*4882a593Smuzhiyun	mov	lr, a0
77*4882a593Smuzhiyun	ldw	a0, (sp, 0)
78*4882a593Smuzhiyun	ldw	a1, (sp, 4)
79*4882a593Smuzhiyun	ldw	a2, (sp, 8)
80*4882a593Smuzhiyun	ldw	a3, (sp, 12)
81*4882a593Smuzhiyun	addi	sp, 16
82*4882a593Smuzhiyun.endm
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun.macro nop32_stub
85*4882a593Smuzhiyun	nop32
86*4882a593Smuzhiyun	nop32
87*4882a593Smuzhiyun	nop32
88*4882a593Smuzhiyun.endm
89*4882a593Smuzhiyun
90*4882a593SmuzhiyunENTRY(ftrace_stub)
91*4882a593Smuzhiyun	jmp	lr
92*4882a593SmuzhiyunEND(ftrace_stub)
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun#ifndef CONFIG_DYNAMIC_FTRACE
95*4882a593SmuzhiyunENTRY(_mcount)
96*4882a593Smuzhiyun	mcount_enter
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun	/* r26 is link register, only used with jsri translation */
99*4882a593Smuzhiyun	lrw	r26, ftrace_trace_function
100*4882a593Smuzhiyun	ldw	r26, (r26, 0)
101*4882a593Smuzhiyun	lrw	a1, ftrace_stub
102*4882a593Smuzhiyun	cmpne	r26, a1
103*4882a593Smuzhiyun	bf	skip_ftrace
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun	mov	a0, lr
106*4882a593Smuzhiyun	subi	a0, 4
107*4882a593Smuzhiyun	ldw	a1, (sp, 24)
108*4882a593Smuzhiyun	lrw	a2, function_trace_op
109*4882a593Smuzhiyun	ldw	a2, (a2, 0)
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun	jsr	r26
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun#ifndef CONFIG_FUNCTION_GRAPH_TRACER
114*4882a593Smuzhiyunskip_ftrace:
115*4882a593Smuzhiyun	mcount_exit
116*4882a593Smuzhiyun#else
117*4882a593Smuzhiyunskip_ftrace:
118*4882a593Smuzhiyun	lrw	a0, ftrace_graph_return
119*4882a593Smuzhiyun	ldw	a0, (a0, 0)
120*4882a593Smuzhiyun	lrw	a1, ftrace_stub
121*4882a593Smuzhiyun	cmpne	a0, a1
122*4882a593Smuzhiyun	bt	ftrace_graph_caller
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun	lrw	a0, ftrace_graph_entry
125*4882a593Smuzhiyun	ldw	a0, (a0, 0)
126*4882a593Smuzhiyun	lrw	a1, ftrace_graph_entry_stub
127*4882a593Smuzhiyun	cmpne	a0, a1
128*4882a593Smuzhiyun	bt	ftrace_graph_caller
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun	mcount_exit
131*4882a593Smuzhiyun#endif
132*4882a593SmuzhiyunEND(_mcount)
133*4882a593Smuzhiyun#else /* CONFIG_DYNAMIC_FTRACE */
134*4882a593SmuzhiyunENTRY(_mcount)
135*4882a593Smuzhiyun	mov	t1, lr
136*4882a593Smuzhiyun	ldw	lr, (sp, 0)
137*4882a593Smuzhiyun	addi	sp, 4
138*4882a593Smuzhiyun	jmp	t1
139*4882a593SmuzhiyunENDPROC(_mcount)
140*4882a593Smuzhiyun
141*4882a593SmuzhiyunENTRY(ftrace_caller)
142*4882a593Smuzhiyun	mcount_enter
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun	ldw	a0, (sp, 16)
145*4882a593Smuzhiyun	subi	a0, 4
146*4882a593Smuzhiyun	ldw	a1, (sp, 24)
147*4882a593Smuzhiyun	lrw	a2, function_trace_op
148*4882a593Smuzhiyun	ldw	a2, (a2, 0)
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun	nop
151*4882a593SmuzhiyunGLOBAL(ftrace_call)
152*4882a593Smuzhiyun	nop32_stub
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun#ifdef CONFIG_FUNCTION_GRAPH_TRACER
155*4882a593Smuzhiyun	nop
156*4882a593SmuzhiyunGLOBAL(ftrace_graph_call)
157*4882a593Smuzhiyun	nop32_stub
158*4882a593Smuzhiyun#endif
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun	mcount_exit
161*4882a593SmuzhiyunENDPROC(ftrace_caller)
162*4882a593Smuzhiyun#endif /* CONFIG_DYNAMIC_FTRACE */
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun#ifdef CONFIG_FUNCTION_GRAPH_TRACER
165*4882a593SmuzhiyunENTRY(ftrace_graph_caller)
166*4882a593Smuzhiyun	mov	a0, sp
167*4882a593Smuzhiyun	addi	a0, 24
168*4882a593Smuzhiyun	ldw	a1, (sp, 16)
169*4882a593Smuzhiyun	subi	a1, 4
170*4882a593Smuzhiyun	mov	a2, r8
171*4882a593Smuzhiyun	lrw	r26, prepare_ftrace_return
172*4882a593Smuzhiyun	jsr	r26
173*4882a593Smuzhiyun	mcount_exit
174*4882a593SmuzhiyunEND(ftrace_graph_caller)
175*4882a593Smuzhiyun
176*4882a593SmuzhiyunENTRY(return_to_handler)
177*4882a593Smuzhiyun	save_return_regs
178*4882a593Smuzhiyun	mov	a0, r8
179*4882a593Smuzhiyun	jsri	ftrace_return_to_handler
180*4882a593Smuzhiyun	restore_return_regs
181*4882a593Smuzhiyun	jmp	lr
182*4882a593SmuzhiyunEND(return_to_handler)
183*4882a593Smuzhiyun#endif
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
186*4882a593SmuzhiyunENTRY(ftrace_regs_caller)
187*4882a593Smuzhiyun	mcount_enter_regs
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun	lrw	t1, PT_FRAME_SIZE
190*4882a593Smuzhiyun	add	t1, sp
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun	ldw	a0, (t1, 0)
193*4882a593Smuzhiyun	subi	a0, 4
194*4882a593Smuzhiyun	ldw	a1, (t1, 8)
195*4882a593Smuzhiyun	lrw	a2, function_trace_op
196*4882a593Smuzhiyun	ldw	a2, (a2, 0)
197*4882a593Smuzhiyun	mov	a3, sp
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun	nop
200*4882a593SmuzhiyunGLOBAL(ftrace_regs_call)
201*4882a593Smuzhiyun	nop32_stub
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun#ifdef CONFIG_FUNCTION_GRAPH_TRACER
204*4882a593Smuzhiyun	nop
205*4882a593SmuzhiyunGLOBAL(ftrace_graph_regs_call)
206*4882a593Smuzhiyun	nop32_stub
207*4882a593Smuzhiyun#endif
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun	mcount_exit_regs
210*4882a593SmuzhiyunENDPROC(ftrace_regs_caller)
211*4882a593Smuzhiyun#endif /* CONFIG_DYNAMIC_FTRACE */
212