xref: /openbmc/linux/arch/csky/abiv2/mcount.S (revision a13d5887)
1230c77a5SGuo Ren/* SPDX-License-Identifier: GPL-2.0 */
2230c77a5SGuo Ren// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3230c77a5SGuo Ren
4230c77a5SGuo Ren#include <linux/linkage.h>
5d7950be1SGuo Ren#include <asm/ftrace.h>
689a3927aSGuo Ren#include <abi/entry.h>
789a3927aSGuo Ren#include <asm/asm-offsets.h>
8230c77a5SGuo Ren
9d7950be1SGuo Ren/*
10d7950be1SGuo Ren * csky-gcc with -pg will put the following asm after prologue:
11d7950be1SGuo Ren *      push	r15
12d7950be1SGuo Ren *      jsri	_mcount
13d7950be1SGuo Ren *
14d7950be1SGuo Ren * stack layout after mcount_enter in _mcount():
15d7950be1SGuo Ren *
16d7950be1SGuo Ren * current sp => 0:+-------+
17d7950be1SGuo Ren *                 | a0-a3 | -> must save all argument regs
18d7950be1SGuo Ren *             +16:+-------+
19d7950be1SGuo Ren *                 | lr    | -> _mcount lr (instrumente function's pc)
20d7950be1SGuo Ren *             +20:+-------+
21d7950be1SGuo Ren *                 | fp=r8 | -> instrumented function fp
22d7950be1SGuo Ren *             +24:+-------+
23d7950be1SGuo Ren *                 | plr   | -> instrumented function lr (parent's pc)
24d7950be1SGuo Ren *                 +-------+
25d7950be1SGuo Ren */
26d7950be1SGuo Ren
27d7950be1SGuo Ren.macro mcount_enter
28d7950be1SGuo Ren	subi	sp, 24
29230c77a5SGuo Ren	stw	a0, (sp, 0)
30230c77a5SGuo Ren	stw	a1, (sp, 4)
31230c77a5SGuo Ren	stw	a2, (sp, 8)
32230c77a5SGuo Ren	stw	a3, (sp, 12)
33230c77a5SGuo Ren	stw	lr, (sp, 16)
34d7950be1SGuo Ren	stw	r8, (sp, 20)
35d7950be1SGuo Ren.endm
36d7950be1SGuo Ren
37d7950be1SGuo Ren.macro mcount_exit
38230c77a5SGuo Ren	ldw	a0, (sp, 0)
39230c77a5SGuo Ren	ldw	a1, (sp, 4)
40230c77a5SGuo Ren	ldw	a2, (sp, 8)
41230c77a5SGuo Ren	ldw	a3, (sp, 12)
42230c77a5SGuo Ren	ldw	t1, (sp, 16)
43d7950be1SGuo Ren	ldw	r8, (sp, 20)
44d7950be1SGuo Ren	ldw	lr, (sp, 24)
45d7950be1SGuo Ren	addi	sp, 28
46230c77a5SGuo Ren	jmp	t1
47d7950be1SGuo Ren.endm
48d7950be1SGuo Ren
4989a3927aSGuo Ren.macro mcount_enter_regs
5089a3927aSGuo Ren	subi	sp, 8
5189a3927aSGuo Ren	stw	lr, (sp, 0)
5289a3927aSGuo Ren	stw	r8, (sp, 4)
5389a3927aSGuo Ren	SAVE_REGS_FTRACE
5489a3927aSGuo Ren.endm
5589a3927aSGuo Ren
5689a3927aSGuo Ren.macro mcount_exit_regs
5789a3927aSGuo Ren	RESTORE_REGS_FTRACE
5889a3927aSGuo Ren	ldw	t1, (sp, 0)
5989a3927aSGuo Ren	ldw	r8, (sp, 4)
6089a3927aSGuo Ren	ldw	lr, (sp, 8)
6189a3927aSGuo Ren	addi	sp, 12
6289a3927aSGuo Ren	jmp	t1
6389a3927aSGuo Ren.endm
6489a3927aSGuo Ren
65d7950be1SGuo Ren.macro save_return_regs
66d7950be1SGuo Ren	subi	sp, 16
67d7950be1SGuo Ren	stw	a0, (sp, 0)
68d7950be1SGuo Ren	stw	a1, (sp, 4)
69d7950be1SGuo Ren	stw	a2, (sp, 8)
70d7950be1SGuo Ren	stw	a3, (sp, 12)
71d7950be1SGuo Ren.endm
72d7950be1SGuo Ren
73d7950be1SGuo Ren.macro restore_return_regs
74d7950be1SGuo Ren	mov	lr, a0
75d7950be1SGuo Ren	ldw	a0, (sp, 0)
76d7950be1SGuo Ren	ldw	a1, (sp, 4)
77d7950be1SGuo Ren	ldw	a2, (sp, 8)
78d7950be1SGuo Ren	ldw	a3, (sp, 12)
79d7950be1SGuo Ren	addi	sp, 16
80d7950be1SGuo Ren.endm
81d7950be1SGuo Ren
8228bb030fSGuo Ren.macro nop32_stub
8328bb030fSGuo Ren	nop32
8428bb030fSGuo Ren	nop32
8528bb030fSGuo Ren	nop32
8628bb030fSGuo Ren.endm
8728bb030fSGuo Ren
88d7950be1SGuo RenENTRY(ftrace_stub)
89d7950be1SGuo Ren	jmp	lr
90d7950be1SGuo RenEND(ftrace_stub)
91d7950be1SGuo Ren
9228bb030fSGuo Ren#ifndef CONFIG_DYNAMIC_FTRACE
93d7950be1SGuo RenENTRY(_mcount)
94d7950be1SGuo Ren	mcount_enter
95d7950be1SGuo Ren
96d7950be1SGuo Ren	/* r26 is link register, only used with jsri translation */
97d7950be1SGuo Ren	lrw	r26, ftrace_trace_function
98d7950be1SGuo Ren	ldw	r26, (r26, 0)
99d7950be1SGuo Ren	lrw	a1, ftrace_stub
100d7950be1SGuo Ren	cmpne	r26, a1
101d7950be1SGuo Ren	bf	skip_ftrace
102d7950be1SGuo Ren
103d7950be1SGuo Ren	mov	a0, lr
10428bb030fSGuo Ren	subi	a0, 4
105d7950be1SGuo Ren	ldw	a1, (sp, 24)
106a13d5887SGuo Ren	lrw	a2, function_trace_op
107a13d5887SGuo Ren	ldw	a2, (a2, 0)
108d7950be1SGuo Ren
109d7950be1SGuo Ren	jsr	r26
110d7950be1SGuo Ren
111d7950be1SGuo Ren#ifndef CONFIG_FUNCTION_GRAPH_TRACER
112d7950be1SGuo Renskip_ftrace:
113d7950be1SGuo Ren	mcount_exit
114d7950be1SGuo Ren#else
115d7950be1SGuo Renskip_ftrace:
116d7950be1SGuo Ren	lrw	a0, ftrace_graph_return
117d7950be1SGuo Ren	ldw	a0, (a0, 0)
118d7950be1SGuo Ren	lrw	a1, ftrace_stub
119d7950be1SGuo Ren	cmpne	a0, a1
120d7950be1SGuo Ren	bt	ftrace_graph_caller
121d7950be1SGuo Ren
122d7950be1SGuo Ren	lrw	a0, ftrace_graph_entry
123d7950be1SGuo Ren	ldw	a0, (a0, 0)
124d7950be1SGuo Ren	lrw	a1, ftrace_graph_entry_stub
125d7950be1SGuo Ren	cmpne	a0, a1
126d7950be1SGuo Ren	bt	ftrace_graph_caller
127d7950be1SGuo Ren
128d7950be1SGuo Ren	mcount_exit
129d7950be1SGuo Ren#endif
130230c77a5SGuo RenEND(_mcount)
13128bb030fSGuo Ren#else /* CONFIG_DYNAMIC_FTRACE */
13228bb030fSGuo RenENTRY(_mcount)
13328bb030fSGuo Ren	mov	t1, lr
13428bb030fSGuo Ren	ldw	lr, (sp, 0)
13528bb030fSGuo Ren	addi	sp, 4
13628bb030fSGuo Ren	jmp	t1
13728bb030fSGuo RenENDPROC(_mcount)
13828bb030fSGuo Ren
13928bb030fSGuo RenENTRY(ftrace_caller)
14028bb030fSGuo Ren	mcount_enter
14128bb030fSGuo Ren
14228bb030fSGuo Ren	ldw	a0, (sp, 16)
14328bb030fSGuo Ren	subi	a0, 4
14428bb030fSGuo Ren	ldw	a1, (sp, 24)
14589a3927aSGuo Ren	lrw	a2, function_trace_op
14689a3927aSGuo Ren	ldw	a2, (a2, 0)
14728bb030fSGuo Ren
14828bb030fSGuo Ren	nop
14928bb030fSGuo RenGLOBAL(ftrace_call)
15028bb030fSGuo Ren	nop32_stub
15128bb030fSGuo Ren
15228bb030fSGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER
15328bb030fSGuo Ren	nop
15428bb030fSGuo RenGLOBAL(ftrace_graph_call)
15528bb030fSGuo Ren	nop32_stub
15628bb030fSGuo Ren#endif
15728bb030fSGuo Ren
15828bb030fSGuo Ren	mcount_exit
15928bb030fSGuo RenENDPROC(ftrace_caller)
16028bb030fSGuo Ren#endif /* CONFIG_DYNAMIC_FTRACE */
161d7950be1SGuo Ren
162d7950be1SGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER
163d7950be1SGuo RenENTRY(ftrace_graph_caller)
164d7950be1SGuo Ren	mov	a0, sp
165d7950be1SGuo Ren	addi	a0, 24
166d7950be1SGuo Ren	ldw	a1, (sp, 16)
16728bb030fSGuo Ren	subi	a1, 4
168d7950be1SGuo Ren	mov	a2, r8
169d7950be1SGuo Ren	lrw	r26, prepare_ftrace_return
170d7950be1SGuo Ren	jsr	r26
171d7950be1SGuo Ren	mcount_exit
172d7950be1SGuo RenEND(ftrace_graph_caller)
173d7950be1SGuo Ren
174d7950be1SGuo RenENTRY(return_to_handler)
175d7950be1SGuo Ren	save_return_regs
176d7950be1SGuo Ren	mov	a0, r8
177d7950be1SGuo Ren	jsri	ftrace_return_to_handler
178d7950be1SGuo Ren	restore_return_regs
179d7950be1SGuo Ren	jmp	lr
180d7950be1SGuo RenEND(return_to_handler)
181d7950be1SGuo Ren#endif
18289a3927aSGuo Ren
18389a3927aSGuo Ren#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
18489a3927aSGuo RenENTRY(ftrace_regs_caller)
18589a3927aSGuo Ren	mcount_enter_regs
18689a3927aSGuo Ren
18789a3927aSGuo Ren	lrw	t1, PT_FRAME_SIZE
18889a3927aSGuo Ren	add	t1, sp
18989a3927aSGuo Ren
19089a3927aSGuo Ren	ldw	a0, (t1, 0)
19189a3927aSGuo Ren	subi	a0, 4
19289a3927aSGuo Ren	ldw	a1, (t1, 8)
19389a3927aSGuo Ren	lrw	a2, function_trace_op
19489a3927aSGuo Ren	ldw	a2, (a2, 0)
19589a3927aSGuo Ren	mov	a3, sp
19689a3927aSGuo Ren
19789a3927aSGuo Ren	nop
19889a3927aSGuo RenGLOBAL(ftrace_regs_call)
19989a3927aSGuo Ren	nop32_stub
20089a3927aSGuo Ren
20189a3927aSGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER
20289a3927aSGuo Ren	nop
20389a3927aSGuo RenGLOBAL(ftrace_graph_regs_call)
20489a3927aSGuo Ren	nop32_stub
20589a3927aSGuo Ren#endif
20689a3927aSGuo Ren
20789a3927aSGuo Ren	mcount_exit_regs
20889a3927aSGuo RenENDPROC(ftrace_regs_caller)
20989a3927aSGuo Ren#endif /* CONFIG_DYNAMIC_FTRACE */
210