18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * This file implements mcount(), which is used to collect profiling data.
68c2ecf20Sopenharmony_ci * This can also be tweaked for kernel stack overflow detection.
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/linkage.h>
108c2ecf20Sopenharmony_ci#include <asm/export.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/*
138c2ecf20Sopenharmony_ci * This is the main variant and is called by C code.  GCC's -pg option
148c2ecf20Sopenharmony_ci * automatically instruments every C function with a call to this.
158c2ecf20Sopenharmony_ci */
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci	.text
188c2ecf20Sopenharmony_ci	.align		32
198c2ecf20Sopenharmony_ci	.globl		_mcount
208c2ecf20Sopenharmony_ci	.type		_mcount,#function
218c2ecf20Sopenharmony_ci	EXPORT_SYMBOL(_mcount)
228c2ecf20Sopenharmony_ci	.globl		mcount
238c2ecf20Sopenharmony_ci	.type		mcount,#function
248c2ecf20Sopenharmony_ci_mcount:
258c2ecf20Sopenharmony_cimcount:
268c2ecf20Sopenharmony_ci#ifdef CONFIG_FUNCTION_TRACER
278c2ecf20Sopenharmony_ci#ifdef CONFIG_DYNAMIC_FTRACE
288c2ecf20Sopenharmony_ci	/* Do nothing, the retl/nop below is all we need.  */
298c2ecf20Sopenharmony_ci#else
308c2ecf20Sopenharmony_ci	sethi		%hi(ftrace_trace_function), %g1
318c2ecf20Sopenharmony_ci	sethi		%hi(ftrace_stub), %g2
328c2ecf20Sopenharmony_ci	ldx		[%g1 + %lo(ftrace_trace_function)], %g1
338c2ecf20Sopenharmony_ci	or		%g2, %lo(ftrace_stub), %g2
348c2ecf20Sopenharmony_ci	cmp		%g1, %g2
358c2ecf20Sopenharmony_ci	be,pn		%icc, 1f
368c2ecf20Sopenharmony_ci	 mov		%i7, %g3
378c2ecf20Sopenharmony_ci	save		%sp, -176, %sp
388c2ecf20Sopenharmony_ci	mov		%g3, %o1
398c2ecf20Sopenharmony_ci	jmpl		%g1, %o7
408c2ecf20Sopenharmony_ci	 mov		%i7, %o0
418c2ecf20Sopenharmony_ci	ret
428c2ecf20Sopenharmony_ci	 restore
438c2ecf20Sopenharmony_ci	/* not reached */
448c2ecf20Sopenharmony_ci1:
458c2ecf20Sopenharmony_ci#ifdef CONFIG_FUNCTION_GRAPH_TRACER
468c2ecf20Sopenharmony_ci	sethi		%hi(ftrace_graph_return), %g1
478c2ecf20Sopenharmony_ci	ldx		[%g1 + %lo(ftrace_graph_return)], %g3
488c2ecf20Sopenharmony_ci	cmp		%g2, %g3
498c2ecf20Sopenharmony_ci	bne,pn		%xcc, 5f
508c2ecf20Sopenharmony_ci	 sethi		%hi(ftrace_graph_entry_stub), %g2
518c2ecf20Sopenharmony_ci	sethi		%hi(ftrace_graph_entry), %g1
528c2ecf20Sopenharmony_ci	or		%g2, %lo(ftrace_graph_entry_stub), %g2
538c2ecf20Sopenharmony_ci	ldx		[%g1 + %lo(ftrace_graph_entry)], %g1
548c2ecf20Sopenharmony_ci	cmp		%g1, %g2
558c2ecf20Sopenharmony_ci	be,pt		%xcc, 2f
568c2ecf20Sopenharmony_ci	 nop
578c2ecf20Sopenharmony_ci5:	mov		%i7, %g2
588c2ecf20Sopenharmony_ci	mov		%fp, %g3
598c2ecf20Sopenharmony_ci	save		%sp, -176, %sp
608c2ecf20Sopenharmony_ci	mov		%g2, %l0
618c2ecf20Sopenharmony_ci	ba,pt		%xcc, ftrace_graph_caller
628c2ecf20Sopenharmony_ci	 mov		%g3, %l1
638c2ecf20Sopenharmony_ci#endif
648c2ecf20Sopenharmony_ci2:
658c2ecf20Sopenharmony_ci#endif
668c2ecf20Sopenharmony_ci#endif
678c2ecf20Sopenharmony_ci	retl
688c2ecf20Sopenharmony_ci	 nop
698c2ecf20Sopenharmony_ci	.size		_mcount,.-_mcount
708c2ecf20Sopenharmony_ci	.size		mcount,.-mcount
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci#ifdef CONFIG_FUNCTION_TRACER
738c2ecf20Sopenharmony_ci	.globl		ftrace_stub
748c2ecf20Sopenharmony_ci	.type		ftrace_stub,#function
758c2ecf20Sopenharmony_ciftrace_stub:
768c2ecf20Sopenharmony_ci	retl
778c2ecf20Sopenharmony_ci	 nop
788c2ecf20Sopenharmony_ci	.size		ftrace_stub,.-ftrace_stub
798c2ecf20Sopenharmony_ci#ifdef CONFIG_DYNAMIC_FTRACE
808c2ecf20Sopenharmony_ci	.globl		ftrace_caller
818c2ecf20Sopenharmony_ci	.type		ftrace_caller,#function
828c2ecf20Sopenharmony_ciftrace_caller:
838c2ecf20Sopenharmony_ci	mov		%i7, %g2
848c2ecf20Sopenharmony_ci	mov		%fp, %g3
858c2ecf20Sopenharmony_ci	save		%sp, -176, %sp
868c2ecf20Sopenharmony_ci	mov		%g2, %o1
878c2ecf20Sopenharmony_ci	mov		%g2, %l0
888c2ecf20Sopenharmony_ci	mov		%g3, %l1
898c2ecf20Sopenharmony_ci	.globl		ftrace_call
908c2ecf20Sopenharmony_ciftrace_call:
918c2ecf20Sopenharmony_ci	call		ftrace_stub
928c2ecf20Sopenharmony_ci	 mov		%i7, %o0
938c2ecf20Sopenharmony_ci#ifdef CONFIG_FUNCTION_GRAPH_TRACER
948c2ecf20Sopenharmony_ci	.globl		ftrace_graph_call
958c2ecf20Sopenharmony_ciftrace_graph_call:
968c2ecf20Sopenharmony_ci	call		ftrace_stub
978c2ecf20Sopenharmony_ci	 nop
988c2ecf20Sopenharmony_ci#endif
998c2ecf20Sopenharmony_ci	ret
1008c2ecf20Sopenharmony_ci	 restore
1018c2ecf20Sopenharmony_ci#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1028c2ecf20Sopenharmony_ci	.size		ftrace_graph_call,.-ftrace_graph_call
1038c2ecf20Sopenharmony_ci#endif
1048c2ecf20Sopenharmony_ci	.size		ftrace_call,.-ftrace_call
1058c2ecf20Sopenharmony_ci	.size		ftrace_caller,.-ftrace_caller
1068c2ecf20Sopenharmony_ci#endif
1078c2ecf20Sopenharmony_ci#endif
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1108c2ecf20Sopenharmony_ciENTRY(ftrace_graph_caller)
1118c2ecf20Sopenharmony_ci	mov		%l0, %o0
1128c2ecf20Sopenharmony_ci	mov		%i7, %o1
1138c2ecf20Sopenharmony_ci	call		prepare_ftrace_return
1148c2ecf20Sopenharmony_ci	 mov		%l1, %o2
1158c2ecf20Sopenharmony_ci	ret
1168c2ecf20Sopenharmony_ci	 restore	%o0, -8, %i7
1178c2ecf20Sopenharmony_ciEND(ftrace_graph_caller)
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ciENTRY(return_to_handler)
1208c2ecf20Sopenharmony_ci	save		%sp, -176, %sp
1218c2ecf20Sopenharmony_ci	call		ftrace_return_to_handler
1228c2ecf20Sopenharmony_ci	 mov		%fp, %o0
1238c2ecf20Sopenharmony_ci	jmpl		%o0 + 8, %g0
1248c2ecf20Sopenharmony_ci	 restore
1258c2ecf20Sopenharmony_ciEND(return_to_handler)
1268c2ecf20Sopenharmony_ci#endif
127