1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
4 *
5 * This file implements mcount(), which is used to collect profiling data.
6 * This can also be tweaked for kernel stack overflow detection.
7 */
8
9#include <linux/linkage.h>
10#include <asm/export.h>
11
12/*
13 * This is the main variant and is called by C code.  GCC's -pg option
14 * automatically instruments every C function with a call to this.
15 */
16
17	.text
18	.align		32
19	.globl		_mcount
20	.type		_mcount,#function
21	EXPORT_SYMBOL(_mcount)
22	.globl		mcount
23	.type		mcount,#function
24_mcount:
25mcount:
26#ifdef CONFIG_FUNCTION_TRACER
27#ifdef CONFIG_DYNAMIC_FTRACE
28	/* Do nothing, the retl/nop below is all we need.  */
29#else
30	sethi		%hi(ftrace_trace_function), %g1
31	sethi		%hi(ftrace_stub), %g2
32	ldx		[%g1 + %lo(ftrace_trace_function)], %g1
33	or		%g2, %lo(ftrace_stub), %g2
34	cmp		%g1, %g2
35	be,pn		%icc, 1f
36	 mov		%i7, %g3
37	save		%sp, -176, %sp
38	mov		%g3, %o1
39	jmpl		%g1, %o7
40	 mov		%i7, %o0
41	ret
42	 restore
43	/* not reached */
441:
45#ifdef CONFIG_FUNCTION_GRAPH_TRACER
46	sethi		%hi(ftrace_graph_return), %g1
47	ldx		[%g1 + %lo(ftrace_graph_return)], %g3
48	cmp		%g2, %g3
49	bne,pn		%xcc, 5f
50	 sethi		%hi(ftrace_graph_entry_stub), %g2
51	sethi		%hi(ftrace_graph_entry), %g1
52	or		%g2, %lo(ftrace_graph_entry_stub), %g2
53	ldx		[%g1 + %lo(ftrace_graph_entry)], %g1
54	cmp		%g1, %g2
55	be,pt		%xcc, 2f
56	 nop
575:	mov		%i7, %g2
58	mov		%fp, %g3
59	save		%sp, -176, %sp
60	mov		%g2, %l0
61	ba,pt		%xcc, ftrace_graph_caller
62	 mov		%g3, %l1
63#endif
642:
65#endif
66#endif
67	retl
68	 nop
69	.size		_mcount,.-_mcount
70	.size		mcount,.-mcount
71
72#ifdef CONFIG_FUNCTION_TRACER
73	.globl		ftrace_stub
74	.type		ftrace_stub,#function
75ftrace_stub:
76	retl
77	 nop
78	.size		ftrace_stub,.-ftrace_stub
79#ifdef CONFIG_DYNAMIC_FTRACE
80	.globl		ftrace_caller
81	.type		ftrace_caller,#function
82ftrace_caller:
83	mov		%i7, %g2
84	mov		%fp, %g3
85	save		%sp, -176, %sp
86	mov		%g2, %o1
87	mov		%g2, %l0
88	mov		%g3, %l1
89	.globl		ftrace_call
90ftrace_call:
91	call		ftrace_stub
92	 mov		%i7, %o0
93#ifdef CONFIG_FUNCTION_GRAPH_TRACER
94	.globl		ftrace_graph_call
95ftrace_graph_call:
96	call		ftrace_stub
97	 nop
98#endif
99	ret
100	 restore
101#ifdef CONFIG_FUNCTION_GRAPH_TRACER
102	.size		ftrace_graph_call,.-ftrace_graph_call
103#endif
104	.size		ftrace_call,.-ftrace_call
105	.size		ftrace_caller,.-ftrace_caller
106#endif
107#endif
108
109#ifdef CONFIG_FUNCTION_GRAPH_TRACER
110ENTRY(ftrace_graph_caller)
111	mov		%l0, %o0
112	mov		%i7, %o1
113	call		prepare_ftrace_return
114	 mov		%l1, %o2
115	ret
116	 restore	%o0, -8, %i7
117END(ftrace_graph_caller)
118
119ENTRY(return_to_handler)
120	save		%sp, -176, %sp
121	call		ftrace_return_to_handler
122	 mov		%fp, %o0
123	jmpl		%o0 + 8, %g0
124	 restore
125END(return_to_handler)
126#endif
127