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