xref: /openbmc/linux/arch/csky/abiv2/mcount.S (revision a5447fb9)
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
58a5447fb9SGuo Ren	subi	sp, 152
59a5447fb9SGuo Ren	ldw	t1, (sp, 4)
60a5447fb9SGuo Ren	addi	sp, 152
6189a3927aSGuo Ren	ldw	r8, (sp, 4)
6289a3927aSGuo Ren	ldw	lr, (sp, 8)
6389a3927aSGuo Ren	addi	sp, 12
6489a3927aSGuo Ren	jmp	t1
6589a3927aSGuo Ren.endm
6689a3927aSGuo Ren
67d7950be1SGuo Ren.macro save_return_regs
68d7950be1SGuo Ren	subi	sp, 16
69d7950be1SGuo Ren	stw	a0, (sp, 0)
70d7950be1SGuo Ren	stw	a1, (sp, 4)
71d7950be1SGuo Ren	stw	a2, (sp, 8)
72d7950be1SGuo Ren	stw	a3, (sp, 12)
73d7950be1SGuo Ren.endm
74d7950be1SGuo Ren
75d7950be1SGuo Ren.macro restore_return_regs
76d7950be1SGuo Ren	mov	lr, a0
77d7950be1SGuo Ren	ldw	a0, (sp, 0)
78d7950be1SGuo Ren	ldw	a1, (sp, 4)
79d7950be1SGuo Ren	ldw	a2, (sp, 8)
80d7950be1SGuo Ren	ldw	a3, (sp, 12)
81d7950be1SGuo Ren	addi	sp, 16
82d7950be1SGuo Ren.endm
83d7950be1SGuo Ren
8428bb030fSGuo Ren.macro nop32_stub
8528bb030fSGuo Ren	nop32
8628bb030fSGuo Ren	nop32
8728bb030fSGuo Ren	nop32
8828bb030fSGuo Ren.endm
8928bb030fSGuo Ren
90d7950be1SGuo RenENTRY(ftrace_stub)
91d7950be1SGuo Ren	jmp	lr
92d7950be1SGuo RenEND(ftrace_stub)
93d7950be1SGuo Ren
9428bb030fSGuo Ren#ifndef CONFIG_DYNAMIC_FTRACE
95d7950be1SGuo RenENTRY(_mcount)
96d7950be1SGuo Ren	mcount_enter
97d7950be1SGuo Ren
98d7950be1SGuo Ren	/* r26 is link register, only used with jsri translation */
99d7950be1SGuo Ren	lrw	r26, ftrace_trace_function
100d7950be1SGuo Ren	ldw	r26, (r26, 0)
101d7950be1SGuo Ren	lrw	a1, ftrace_stub
102d7950be1SGuo Ren	cmpne	r26, a1
103d7950be1SGuo Ren	bf	skip_ftrace
104d7950be1SGuo Ren
105d7950be1SGuo Ren	mov	a0, lr
10628bb030fSGuo Ren	subi	a0, 4
107d7950be1SGuo Ren	ldw	a1, (sp, 24)
108a13d5887SGuo Ren	lrw	a2, function_trace_op
109a13d5887SGuo Ren	ldw	a2, (a2, 0)
110d7950be1SGuo Ren
111d7950be1SGuo Ren	jsr	r26
112d7950be1SGuo Ren
113d7950be1SGuo Ren#ifndef CONFIG_FUNCTION_GRAPH_TRACER
114d7950be1SGuo Renskip_ftrace:
115d7950be1SGuo Ren	mcount_exit
116d7950be1SGuo Ren#else
117d7950be1SGuo Renskip_ftrace:
118d7950be1SGuo Ren	lrw	a0, ftrace_graph_return
119d7950be1SGuo Ren	ldw	a0, (a0, 0)
120d7950be1SGuo Ren	lrw	a1, ftrace_stub
121d7950be1SGuo Ren	cmpne	a0, a1
122d7950be1SGuo Ren	bt	ftrace_graph_caller
123d7950be1SGuo Ren
124d7950be1SGuo Ren	lrw	a0, ftrace_graph_entry
125d7950be1SGuo Ren	ldw	a0, (a0, 0)
126d7950be1SGuo Ren	lrw	a1, ftrace_graph_entry_stub
127d7950be1SGuo Ren	cmpne	a0, a1
128d7950be1SGuo Ren	bt	ftrace_graph_caller
129d7950be1SGuo Ren
130d7950be1SGuo Ren	mcount_exit
131d7950be1SGuo Ren#endif
132230c77a5SGuo RenEND(_mcount)
13328bb030fSGuo Ren#else /* CONFIG_DYNAMIC_FTRACE */
13428bb030fSGuo RenENTRY(_mcount)
13528bb030fSGuo Ren	mov	t1, lr
13628bb030fSGuo Ren	ldw	lr, (sp, 0)
13728bb030fSGuo Ren	addi	sp, 4
13828bb030fSGuo Ren	jmp	t1
13928bb030fSGuo RenENDPROC(_mcount)
14028bb030fSGuo Ren
14128bb030fSGuo RenENTRY(ftrace_caller)
14228bb030fSGuo Ren	mcount_enter
14328bb030fSGuo Ren
14428bb030fSGuo Ren	ldw	a0, (sp, 16)
14528bb030fSGuo Ren	subi	a0, 4
14628bb030fSGuo Ren	ldw	a1, (sp, 24)
14789a3927aSGuo Ren	lrw	a2, function_trace_op
14889a3927aSGuo Ren	ldw	a2, (a2, 0)
14928bb030fSGuo Ren
15028bb030fSGuo Ren	nop
15128bb030fSGuo RenGLOBAL(ftrace_call)
15228bb030fSGuo Ren	nop32_stub
15328bb030fSGuo Ren
15428bb030fSGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER
15528bb030fSGuo Ren	nop
15628bb030fSGuo RenGLOBAL(ftrace_graph_call)
15728bb030fSGuo Ren	nop32_stub
15828bb030fSGuo Ren#endif
15928bb030fSGuo Ren
16028bb030fSGuo Ren	mcount_exit
16128bb030fSGuo RenENDPROC(ftrace_caller)
16228bb030fSGuo Ren#endif /* CONFIG_DYNAMIC_FTRACE */
163d7950be1SGuo Ren
164d7950be1SGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER
165d7950be1SGuo RenENTRY(ftrace_graph_caller)
166d7950be1SGuo Ren	mov	a0, sp
167d7950be1SGuo Ren	addi	a0, 24
168d7950be1SGuo Ren	ldw	a1, (sp, 16)
16928bb030fSGuo Ren	subi	a1, 4
170d7950be1SGuo Ren	mov	a2, r8
171d7950be1SGuo Ren	lrw	r26, prepare_ftrace_return
172d7950be1SGuo Ren	jsr	r26
173d7950be1SGuo Ren	mcount_exit
174d7950be1SGuo RenEND(ftrace_graph_caller)
175d7950be1SGuo Ren
176d7950be1SGuo RenENTRY(return_to_handler)
177d7950be1SGuo Ren	save_return_regs
178d7950be1SGuo Ren	mov	a0, r8
179d7950be1SGuo Ren	jsri	ftrace_return_to_handler
180d7950be1SGuo Ren	restore_return_regs
181d7950be1SGuo Ren	jmp	lr
182d7950be1SGuo RenEND(return_to_handler)
183d7950be1SGuo Ren#endif
18489a3927aSGuo Ren
18589a3927aSGuo Ren#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
18689a3927aSGuo RenENTRY(ftrace_regs_caller)
18789a3927aSGuo Ren	mcount_enter_regs
18889a3927aSGuo Ren
18989a3927aSGuo Ren	lrw	t1, PT_FRAME_SIZE
19089a3927aSGuo Ren	add	t1, sp
19189a3927aSGuo Ren
19289a3927aSGuo Ren	ldw	a0, (t1, 0)
19389a3927aSGuo Ren	subi	a0, 4
19489a3927aSGuo Ren	ldw	a1, (t1, 8)
19589a3927aSGuo Ren	lrw	a2, function_trace_op
19689a3927aSGuo Ren	ldw	a2, (a2, 0)
19789a3927aSGuo Ren	mov	a3, sp
19889a3927aSGuo Ren
19989a3927aSGuo Ren	nop
20089a3927aSGuo RenGLOBAL(ftrace_regs_call)
20189a3927aSGuo Ren	nop32_stub
20289a3927aSGuo Ren
20389a3927aSGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER
20489a3927aSGuo Ren	nop
20589a3927aSGuo RenGLOBAL(ftrace_graph_regs_call)
20689a3927aSGuo Ren	nop32_stub
20789a3927aSGuo Ren#endif
20889a3927aSGuo Ren
20989a3927aSGuo Ren	mcount_exit_regs
21089a3927aSGuo RenENDPROC(ftrace_regs_caller)
21189a3927aSGuo Ren#endif /* CONFIG_DYNAMIC_FTRACE */
212