mcount.S 3.45 KB
Newer Older
Guo Ren's avatar
Guo Ren committed
1 2 3 4
/* SPDX-License-Identifier: GPL-2.0 */
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.

#include <linux/linkage.h>
Guo Ren's avatar
Guo Ren committed
5
#include <asm/ftrace.h>
Guo Ren's avatar
Guo Ren committed
6 7
#include <abi/entry.h>
#include <asm/asm-offsets.h>
Guo Ren's avatar
Guo Ren committed
8

Guo Ren's avatar
Guo Ren committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*
 * csky-gcc with -pg will put the following asm after prologue:
 *      push	r15
 *      jsri	_mcount
 *
 * stack layout after mcount_enter in _mcount():
 *
 * current sp => 0:+-------+
 *                 | a0-a3 | -> must save all argument regs
 *             +16:+-------+
 *                 | lr    | -> _mcount lr (instrumente function's pc)
 *             +20:+-------+
 *                 | fp=r8 | -> instrumented function fp
 *             +24:+-------+
 *                 | plr   | -> instrumented function lr (parent's pc)
 *                 +-------+
 */

.macro mcount_enter
	subi	sp, 24
Guo Ren's avatar
Guo Ren committed
29 30 31 32 33
	stw	a0, (sp, 0)
	stw	a1, (sp, 4)
	stw	a2, (sp, 8)
	stw	a3, (sp, 12)
	stw	lr, (sp, 16)
Guo Ren's avatar
Guo Ren committed
34 35 36 37
	stw	r8, (sp, 20)
.endm

.macro mcount_exit
Guo Ren's avatar
Guo Ren committed
38 39 40 41 42
	ldw	a0, (sp, 0)
	ldw	a1, (sp, 4)
	ldw	a2, (sp, 8)
	ldw	a3, (sp, 12)
	ldw	t1, (sp, 16)
Guo Ren's avatar
Guo Ren committed
43 44 45
	ldw	r8, (sp, 20)
	ldw	lr, (sp, 24)
	addi	sp, 28
Guo Ren's avatar
Guo Ren committed
46
	jmp	t1
Guo Ren's avatar
Guo Ren committed
47 48
.endm

Guo Ren's avatar
Guo Ren committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
.macro mcount_enter_regs
	subi	sp, 8
	stw	lr, (sp, 0)
	stw	r8, (sp, 4)
	SAVE_REGS_FTRACE
.endm

.macro mcount_exit_regs
	RESTORE_REGS_FTRACE
	ldw	t1, (sp, 0)
	ldw	r8, (sp, 4)
	ldw	lr, (sp, 8)
	addi	sp, 12
	jmp	t1
.endm

Guo Ren's avatar
Guo Ren committed
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
.macro save_return_regs
	subi	sp, 16
	stw	a0, (sp, 0)
	stw	a1, (sp, 4)
	stw	a2, (sp, 8)
	stw	a3, (sp, 12)
.endm

.macro restore_return_regs
	mov	lr, a0
	ldw	a0, (sp, 0)
	ldw	a1, (sp, 4)
	ldw	a2, (sp, 8)
	ldw	a3, (sp, 12)
	addi	sp, 16
.endm

82 83 84 85 86 87
.macro nop32_stub
	nop32
	nop32
	nop32
.endm

Guo Ren's avatar
Guo Ren committed
88 89 90 91
ENTRY(ftrace_stub)
	jmp	lr
END(ftrace_stub)

92
#ifndef CONFIG_DYNAMIC_FTRACE
Guo Ren's avatar
Guo Ren committed
93 94 95 96 97 98 99 100 101 102 103
ENTRY(_mcount)
	mcount_enter

	/* r26 is link register, only used with jsri translation */
	lrw	r26, ftrace_trace_function
	ldw	r26, (r26, 0)
	lrw	a1, ftrace_stub
	cmpne	r26, a1
	bf	skip_ftrace

	mov	a0, lr
104
	subi	a0, 4
Guo Ren's avatar
Guo Ren committed
105
	ldw	a1, (sp, 24)
106 107
	lrw	a2, function_trace_op
	ldw	a2, (a2, 0)
Guo Ren's avatar
Guo Ren committed
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130

	jsr	r26

#ifndef CONFIG_FUNCTION_GRAPH_TRACER
skip_ftrace:
	mcount_exit
#else
skip_ftrace:
	lrw	a0, ftrace_graph_return
	ldw	a0, (a0, 0)
	lrw	a1, ftrace_stub
	cmpne	a0, a1
	bt	ftrace_graph_caller

	lrw	a0, ftrace_graph_entry
	ldw	a0, (a0, 0)
	lrw	a1, ftrace_graph_entry_stub
	cmpne	a0, a1
	bt	ftrace_graph_caller

	mcount_exit
#endif
END(_mcount)
131 132 133 134 135 136 137 138 139 140 141 142 143 144
#else /* CONFIG_DYNAMIC_FTRACE */
ENTRY(_mcount)
	mov	t1, lr
	ldw	lr, (sp, 0)
	addi	sp, 4
	jmp	t1
ENDPROC(_mcount)

ENTRY(ftrace_caller)
	mcount_enter

	ldw	a0, (sp, 16)
	subi	a0, 4
	ldw	a1, (sp, 24)
Guo Ren's avatar
Guo Ren committed
145 146
	lrw	a2, function_trace_op
	ldw	a2, (a2, 0)
147 148 149 150 151 152 153 154 155 156 157 158 159 160

	nop
GLOBAL(ftrace_call)
	nop32_stub

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
	nop
GLOBAL(ftrace_graph_call)
	nop32_stub
#endif

	mcount_exit
ENDPROC(ftrace_caller)
#endif /* CONFIG_DYNAMIC_FTRACE */
Guo Ren's avatar
Guo Ren committed
161 162 163 164 165 166

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
ENTRY(ftrace_graph_caller)
	mov	a0, sp
	addi	a0, 24
	ldw	a1, (sp, 16)
167
	subi	a1, 4
Guo Ren's avatar
Guo Ren committed
168 169 170 171 172 173 174 175 176 177 178 179 180 181
	mov	a2, r8
	lrw	r26, prepare_ftrace_return
	jsr	r26
	mcount_exit
END(ftrace_graph_caller)

ENTRY(return_to_handler)
	save_return_regs
	mov	a0, r8
	jsri	ftrace_return_to_handler
	restore_return_regs
	jmp	lr
END(return_to_handler)
#endif
Guo Ren's avatar
Guo Ren committed
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209

#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
ENTRY(ftrace_regs_caller)
	mcount_enter_regs

	lrw	t1, PT_FRAME_SIZE
	add	t1, sp

	ldw	a0, (t1, 0)
	subi	a0, 4
	ldw	a1, (t1, 8)
	lrw	a2, function_trace_op
	ldw	a2, (a2, 0)
	mov	a3, sp

	nop
GLOBAL(ftrace_regs_call)
	nop32_stub

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
	nop
GLOBAL(ftrace_graph_regs_call)
	nop32_stub
#endif

	mcount_exit_regs
ENDPROC(ftrace_regs_caller)
#endif /* CONFIG_DYNAMIC_FTRACE */