xref: /openbmc/linux/arch/csky/abiv2/mcount.S (revision 89a3927a)
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)
106d7950be1SGuo Ren
107d7950be1SGuo Ren	jsr	r26
108d7950be1SGuo Ren
109d7950be1SGuo Ren#ifndef CONFIG_FUNCTION_GRAPH_TRACER
110d7950be1SGuo Renskip_ftrace:
111d7950be1SGuo Ren	mcount_exit
112d7950be1SGuo Ren#else
113d7950be1SGuo Renskip_ftrace:
114d7950be1SGuo Ren	lrw	a0, ftrace_graph_return
115d7950be1SGuo Ren	ldw	a0, (a0, 0)
116d7950be1SGuo Ren	lrw	a1, ftrace_stub
117d7950be1SGuo Ren	cmpne	a0, a1
118d7950be1SGuo Ren	bt	ftrace_graph_caller
119d7950be1SGuo Ren
120d7950be1SGuo Ren	lrw	a0, ftrace_graph_entry
121d7950be1SGuo Ren	ldw	a0, (a0, 0)
122d7950be1SGuo Ren	lrw	a1, ftrace_graph_entry_stub
123d7950be1SGuo Ren	cmpne	a0, a1
124d7950be1SGuo Ren	bt	ftrace_graph_caller
125d7950be1SGuo Ren
126d7950be1SGuo Ren	mcount_exit
127d7950be1SGuo Ren#endif
128230c77a5SGuo RenEND(_mcount)
12928bb030fSGuo Ren#else /* CONFIG_DYNAMIC_FTRACE */
13028bb030fSGuo RenENTRY(_mcount)
13128bb030fSGuo Ren	mov	t1, lr
13228bb030fSGuo Ren	ldw	lr, (sp, 0)
13328bb030fSGuo Ren	addi	sp, 4
13428bb030fSGuo Ren	jmp	t1
13528bb030fSGuo RenENDPROC(_mcount)
13628bb030fSGuo Ren
13728bb030fSGuo RenENTRY(ftrace_caller)
13828bb030fSGuo Ren	mcount_enter
13928bb030fSGuo Ren
14028bb030fSGuo Ren	ldw	a0, (sp, 16)
14128bb030fSGuo Ren	subi	a0, 4
14228bb030fSGuo Ren	ldw	a1, (sp, 24)
14389a3927aSGuo Ren	lrw	a2, function_trace_op
14489a3927aSGuo Ren	ldw	a2, (a2, 0)
14528bb030fSGuo Ren
14628bb030fSGuo Ren	nop
14728bb030fSGuo RenGLOBAL(ftrace_call)
14828bb030fSGuo Ren	nop32_stub
14928bb030fSGuo Ren
15028bb030fSGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER
15128bb030fSGuo Ren	nop
15228bb030fSGuo RenGLOBAL(ftrace_graph_call)
15328bb030fSGuo Ren	nop32_stub
15428bb030fSGuo Ren#endif
15528bb030fSGuo Ren
15628bb030fSGuo Ren	mcount_exit
15728bb030fSGuo RenENDPROC(ftrace_caller)
15828bb030fSGuo Ren#endif /* CONFIG_DYNAMIC_FTRACE */
159d7950be1SGuo Ren
160d7950be1SGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER
161d7950be1SGuo RenENTRY(ftrace_graph_caller)
162d7950be1SGuo Ren	mov	a0, sp
163d7950be1SGuo Ren	addi	a0, 24
164d7950be1SGuo Ren	ldw	a1, (sp, 16)
16528bb030fSGuo Ren	subi	a1, 4
166d7950be1SGuo Ren	mov	a2, r8
167d7950be1SGuo Ren	lrw	r26, prepare_ftrace_return
168d7950be1SGuo Ren	jsr	r26
169d7950be1SGuo Ren	mcount_exit
170d7950be1SGuo RenEND(ftrace_graph_caller)
171d7950be1SGuo Ren
172d7950be1SGuo RenENTRY(return_to_handler)
173d7950be1SGuo Ren	save_return_regs
174d7950be1SGuo Ren	mov	a0, r8
175d7950be1SGuo Ren	jsri	ftrace_return_to_handler
176d7950be1SGuo Ren	restore_return_regs
177d7950be1SGuo Ren	jmp	lr
178d7950be1SGuo RenEND(return_to_handler)
179d7950be1SGuo Ren#endif
18089a3927aSGuo Ren
18189a3927aSGuo Ren#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
18289a3927aSGuo RenENTRY(ftrace_regs_caller)
18389a3927aSGuo Ren	mcount_enter_regs
18489a3927aSGuo Ren
18589a3927aSGuo Ren	lrw	t1, PT_FRAME_SIZE
18689a3927aSGuo Ren	add	t1, sp
18789a3927aSGuo Ren
18889a3927aSGuo Ren	ldw	a0, (t1, 0)
18989a3927aSGuo Ren	subi	a0, 4
19089a3927aSGuo Ren	ldw	a1, (t1, 8)
19189a3927aSGuo Ren	lrw	a2, function_trace_op
19289a3927aSGuo Ren	ldw	a2, (a2, 0)
19389a3927aSGuo Ren	mov	a3, sp
19489a3927aSGuo Ren
19589a3927aSGuo Ren	nop
19689a3927aSGuo RenGLOBAL(ftrace_regs_call)
19789a3927aSGuo Ren	nop32_stub
19889a3927aSGuo Ren
19989a3927aSGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER
20089a3927aSGuo Ren	nop
20189a3927aSGuo RenGLOBAL(ftrace_graph_regs_call)
20289a3927aSGuo Ren	nop32_stub
20389a3927aSGuo Ren#endif
20489a3927aSGuo Ren
20589a3927aSGuo Ren	mcount_exit_regs
20689a3927aSGuo RenENDPROC(ftrace_regs_caller)
20789a3927aSGuo Ren#endif /* CONFIG_DYNAMIC_FTRACE */
208