xref: /openbmc/linux/arch/csky/abiv2/mcount.S (revision 28bb030f)
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>
6230c77a5SGuo Ren
7d7950be1SGuo Ren/*
8d7950be1SGuo Ren * csky-gcc with -pg will put the following asm after prologue:
9d7950be1SGuo Ren *      push	r15
10d7950be1SGuo Ren *      jsri	_mcount
11d7950be1SGuo Ren *
12d7950be1SGuo Ren * stack layout after mcount_enter in _mcount():
13d7950be1SGuo Ren *
14d7950be1SGuo Ren * current sp => 0:+-------+
15d7950be1SGuo Ren *                 | a0-a3 | -> must save all argument regs
16d7950be1SGuo Ren *             +16:+-------+
17d7950be1SGuo Ren *                 | lr    | -> _mcount lr (instrumente function's pc)
18d7950be1SGuo Ren *             +20:+-------+
19d7950be1SGuo Ren *                 | fp=r8 | -> instrumented function fp
20d7950be1SGuo Ren *             +24:+-------+
21d7950be1SGuo Ren *                 | plr   | -> instrumented function lr (parent's pc)
22d7950be1SGuo Ren *                 +-------+
23d7950be1SGuo Ren */
24d7950be1SGuo Ren
25d7950be1SGuo Ren.macro mcount_enter
26d7950be1SGuo Ren	subi	sp, 24
27230c77a5SGuo Ren	stw	a0, (sp, 0)
28230c77a5SGuo Ren	stw	a1, (sp, 4)
29230c77a5SGuo Ren	stw	a2, (sp, 8)
30230c77a5SGuo Ren	stw	a3, (sp, 12)
31230c77a5SGuo Ren	stw	lr, (sp, 16)
32d7950be1SGuo Ren	stw	r8, (sp, 20)
33d7950be1SGuo Ren.endm
34d7950be1SGuo Ren
35d7950be1SGuo Ren.macro mcount_exit
36230c77a5SGuo Ren	ldw	a0, (sp, 0)
37230c77a5SGuo Ren	ldw	a1, (sp, 4)
38230c77a5SGuo Ren	ldw	a2, (sp, 8)
39230c77a5SGuo Ren	ldw	a3, (sp, 12)
40230c77a5SGuo Ren	ldw	t1, (sp, 16)
41d7950be1SGuo Ren	ldw	r8, (sp, 20)
42d7950be1SGuo Ren	ldw	lr, (sp, 24)
43d7950be1SGuo Ren	addi	sp, 28
44230c77a5SGuo Ren	jmp	t1
45d7950be1SGuo Ren.endm
46d7950be1SGuo Ren
47d7950be1SGuo Ren.macro save_return_regs
48d7950be1SGuo Ren	subi	sp, 16
49d7950be1SGuo Ren	stw	a0, (sp, 0)
50d7950be1SGuo Ren	stw	a1, (sp, 4)
51d7950be1SGuo Ren	stw	a2, (sp, 8)
52d7950be1SGuo Ren	stw	a3, (sp, 12)
53d7950be1SGuo Ren.endm
54d7950be1SGuo Ren
55d7950be1SGuo Ren.macro restore_return_regs
56d7950be1SGuo Ren	mov	lr, a0
57d7950be1SGuo Ren	ldw	a0, (sp, 0)
58d7950be1SGuo Ren	ldw	a1, (sp, 4)
59d7950be1SGuo Ren	ldw	a2, (sp, 8)
60d7950be1SGuo Ren	ldw	a3, (sp, 12)
61d7950be1SGuo Ren	addi	sp, 16
62d7950be1SGuo Ren.endm
63d7950be1SGuo Ren
6428bb030fSGuo Ren.macro nop32_stub
6528bb030fSGuo Ren	nop32
6628bb030fSGuo Ren	nop32
6728bb030fSGuo Ren	nop32
6828bb030fSGuo Ren.endm
6928bb030fSGuo Ren
70d7950be1SGuo RenENTRY(ftrace_stub)
71d7950be1SGuo Ren	jmp	lr
72d7950be1SGuo RenEND(ftrace_stub)
73d7950be1SGuo Ren
7428bb030fSGuo Ren#ifndef CONFIG_DYNAMIC_FTRACE
75d7950be1SGuo RenENTRY(_mcount)
76d7950be1SGuo Ren	mcount_enter
77d7950be1SGuo Ren
78d7950be1SGuo Ren	/* r26 is link register, only used with jsri translation */
79d7950be1SGuo Ren	lrw	r26, ftrace_trace_function
80d7950be1SGuo Ren	ldw	r26, (r26, 0)
81d7950be1SGuo Ren	lrw	a1, ftrace_stub
82d7950be1SGuo Ren	cmpne	r26, a1
83d7950be1SGuo Ren	bf	skip_ftrace
84d7950be1SGuo Ren
85d7950be1SGuo Ren	mov	a0, lr
8628bb030fSGuo Ren	subi	a0, 4
87d7950be1SGuo Ren	ldw	a1, (sp, 24)
88d7950be1SGuo Ren
89d7950be1SGuo Ren	jsr	r26
90d7950be1SGuo Ren
91d7950be1SGuo Ren#ifndef CONFIG_FUNCTION_GRAPH_TRACER
92d7950be1SGuo Renskip_ftrace:
93d7950be1SGuo Ren	mcount_exit
94d7950be1SGuo Ren#else
95d7950be1SGuo Renskip_ftrace:
96d7950be1SGuo Ren	lrw	a0, ftrace_graph_return
97d7950be1SGuo Ren	ldw	a0, (a0, 0)
98d7950be1SGuo Ren	lrw	a1, ftrace_stub
99d7950be1SGuo Ren	cmpne	a0, a1
100d7950be1SGuo Ren	bt	ftrace_graph_caller
101d7950be1SGuo Ren
102d7950be1SGuo Ren	lrw	a0, ftrace_graph_entry
103d7950be1SGuo Ren	ldw	a0, (a0, 0)
104d7950be1SGuo Ren	lrw	a1, ftrace_graph_entry_stub
105d7950be1SGuo Ren	cmpne	a0, a1
106d7950be1SGuo Ren	bt	ftrace_graph_caller
107d7950be1SGuo Ren
108d7950be1SGuo Ren	mcount_exit
109d7950be1SGuo Ren#endif
110230c77a5SGuo RenEND(_mcount)
11128bb030fSGuo Ren#else /* CONFIG_DYNAMIC_FTRACE */
11228bb030fSGuo RenENTRY(_mcount)
11328bb030fSGuo Ren	mov	t1, lr
11428bb030fSGuo Ren	ldw	lr, (sp, 0)
11528bb030fSGuo Ren	addi	sp, 4
11628bb030fSGuo Ren	jmp	t1
11728bb030fSGuo RenENDPROC(_mcount)
11828bb030fSGuo Ren
11928bb030fSGuo RenENTRY(ftrace_caller)
12028bb030fSGuo Ren	mcount_enter
12128bb030fSGuo Ren
12228bb030fSGuo Ren	ldw	a0, (sp, 16)
12328bb030fSGuo Ren	subi	a0, 4
12428bb030fSGuo Ren	ldw	a1, (sp, 24)
12528bb030fSGuo Ren
12628bb030fSGuo Ren	nop
12728bb030fSGuo RenGLOBAL(ftrace_call)
12828bb030fSGuo Ren	nop32_stub
12928bb030fSGuo Ren
13028bb030fSGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER
13128bb030fSGuo Ren	nop
13228bb030fSGuo RenGLOBAL(ftrace_graph_call)
13328bb030fSGuo Ren	nop32_stub
13428bb030fSGuo Ren#endif
13528bb030fSGuo Ren
13628bb030fSGuo Ren	mcount_exit
13728bb030fSGuo RenENDPROC(ftrace_caller)
13828bb030fSGuo Ren#endif /* CONFIG_DYNAMIC_FTRACE */
139d7950be1SGuo Ren
140d7950be1SGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER
141d7950be1SGuo RenENTRY(ftrace_graph_caller)
142d7950be1SGuo Ren	mov	a0, sp
143d7950be1SGuo Ren	addi	a0, 24
144d7950be1SGuo Ren	ldw	a1, (sp, 16)
14528bb030fSGuo Ren	subi	a1, 4
146d7950be1SGuo Ren	mov	a2, r8
147d7950be1SGuo Ren	lrw	r26, prepare_ftrace_return
148d7950be1SGuo Ren	jsr	r26
149d7950be1SGuo Ren	mcount_exit
150d7950be1SGuo RenEND(ftrace_graph_caller)
151d7950be1SGuo Ren
152d7950be1SGuo RenENTRY(return_to_handler)
153d7950be1SGuo Ren	save_return_regs
154d7950be1SGuo Ren	mov	a0, r8
155d7950be1SGuo Ren	jsri	ftrace_return_to_handler
156d7950be1SGuo Ren	restore_return_regs
157d7950be1SGuo Ren	jmp	lr
158d7950be1SGuo RenEND(return_to_handler)
159d7950be1SGuo Ren#endif
160