1dbe3ba30SQing Zhang/* SPDX-License-Identifier: GPL-2.0 */ 2dbe3ba30SQing Zhang/* 3dbe3ba30SQing Zhang * LoongArch specific _mcount support 4dbe3ba30SQing Zhang * 5dbe3ba30SQing Zhang * Copyright (C) 2022 Loongson Technology Corporation Limited 6dbe3ba30SQing Zhang */ 7dbe3ba30SQing Zhang 8*55b46ff9SMasahiro Yamada#include <linux/export.h> 9dbe3ba30SQing Zhang#include <asm/ftrace.h> 10dbe3ba30SQing Zhang#include <asm/regdef.h> 11dbe3ba30SQing Zhang#include <asm/stackframe.h> 12dbe3ba30SQing Zhang 13dbe3ba30SQing Zhang .text 14dbe3ba30SQing Zhang 15dbe3ba30SQing Zhang#define MCOUNT_S0_OFFSET (0) 16dbe3ba30SQing Zhang#define MCOUNT_RA_OFFSET (SZREG) 17dbe3ba30SQing Zhang#define MCOUNT_STACK_SIZE (2 * SZREG) 18dbe3ba30SQing Zhang 19dbe3ba30SQing Zhang .macro MCOUNT_SAVE_REGS 20dbe3ba30SQing Zhang PTR_ADDI sp, sp, -MCOUNT_STACK_SIZE 21dbe3ba30SQing Zhang PTR_S s0, sp, MCOUNT_S0_OFFSET 22dbe3ba30SQing Zhang PTR_S ra, sp, MCOUNT_RA_OFFSET 23dbe3ba30SQing Zhang move s0, a0 24dbe3ba30SQing Zhang .endm 25dbe3ba30SQing Zhang 26dbe3ba30SQing Zhang .macro MCOUNT_RESTORE_REGS 27dbe3ba30SQing Zhang move a0, s0 28dbe3ba30SQing Zhang PTR_L ra, sp, MCOUNT_RA_OFFSET 29dbe3ba30SQing Zhang PTR_L s0, sp, MCOUNT_S0_OFFSET 30dbe3ba30SQing Zhang PTR_ADDI sp, sp, MCOUNT_STACK_SIZE 31dbe3ba30SQing Zhang .endm 32dbe3ba30SQing Zhang 33dbe3ba30SQing ZhangSYM_FUNC_START(_mcount) 34dbe3ba30SQing Zhang la.pcrel t1, ftrace_stub 35dbe3ba30SQing Zhang la.pcrel t2, ftrace_trace_function /* Prepare t2 for (1) */ 36dbe3ba30SQing Zhang PTR_L t2, t2, 0 37dbe3ba30SQing Zhang beq t1, t2, fgraph_trace 38dbe3ba30SQing Zhang 39dbe3ba30SQing Zhang MCOUNT_SAVE_REGS 40dbe3ba30SQing Zhang 41dbe3ba30SQing Zhang move a0, ra /* arg0: self return address */ 42dbe3ba30SQing Zhang move a1, s0 /* arg1: parent's return address */ 43dbe3ba30SQing Zhang jirl ra, t2, 0 /* (1) call *ftrace_trace_function */ 44dbe3ba30SQing Zhang 45dbe3ba30SQing Zhang MCOUNT_RESTORE_REGS 46dbe3ba30SQing Zhang 47dbe3ba30SQing Zhangfgraph_trace: 48dbe3ba30SQing Zhang#ifdef CONFIG_FUNCTION_GRAPH_TRACER 49dbe3ba30SQing Zhang la.pcrel t1, ftrace_stub 50dbe3ba30SQing Zhang la.pcrel t3, ftrace_graph_return 51dbe3ba30SQing Zhang PTR_L t3, t3, 0 52dbe3ba30SQing Zhang bne t1, t3, ftrace_graph_caller 53dbe3ba30SQing Zhang la.pcrel t1, ftrace_graph_entry_stub 54dbe3ba30SQing Zhang la.pcrel t3, ftrace_graph_entry 55dbe3ba30SQing Zhang PTR_L t3, t3, 0 56dbe3ba30SQing Zhang bne t1, t3, ftrace_graph_caller 57dbe3ba30SQing Zhang#endif 58dbe3ba30SQing Zhang 59dbe3ba30SQing ZhangSYM_INNER_LABEL(ftrace_stub, SYM_L_GLOBAL) 60dbe3ba30SQing Zhang jr ra 61dbe3ba30SQing Zhang#ifdef CONFIG_FUNCTION_GRAPH_TRACER 62dbe3ba30SQing ZhangSYM_INNER_LABEL(ftrace_graph_func, SYM_L_GLOBAL) 63dbe3ba30SQing Zhang bl ftrace_stub 64dbe3ba30SQing Zhang#endif 65dbe3ba30SQing ZhangSYM_FUNC_END(_mcount) 66dbe3ba30SQing ZhangEXPORT_SYMBOL(_mcount) 67dbe3ba30SQing Zhang 68dbe3ba30SQing Zhang#ifdef CONFIG_FUNCTION_GRAPH_TRACER 69dbe3ba30SQing ZhangSYM_FUNC_START(ftrace_graph_caller) 70dbe3ba30SQing Zhang MCOUNT_SAVE_REGS 71dbe3ba30SQing Zhang 72dbe3ba30SQing Zhang PTR_ADDI a0, ra, -4 /* arg0: Callsite self return addr */ 73dbe3ba30SQing Zhang PTR_ADDI a1, sp, MCOUNT_STACK_SIZE /* arg1: Callsite sp */ 74dbe3ba30SQing Zhang move a2, s0 /* arg2: Callsite parent ra */ 75dbe3ba30SQing Zhang bl prepare_ftrace_return 76dbe3ba30SQing Zhang 77dbe3ba30SQing Zhang MCOUNT_RESTORE_REGS 78dbe3ba30SQing Zhang jr ra 79dbe3ba30SQing ZhangSYM_FUNC_END(ftrace_graph_caller) 80dbe3ba30SQing Zhang 81dbe3ba30SQing ZhangSYM_FUNC_START(return_to_handler) 825779e3c0SDonglin Peng PTR_ADDI sp, sp, -FGRET_REGS_SIZE 835779e3c0SDonglin Peng PTR_S a0, sp, FGRET_REGS_A0 845779e3c0SDonglin Peng PTR_S a1, sp, FGRET_REGS_A1 855779e3c0SDonglin Peng PTR_S zero, sp, FGRET_REGS_FP 86dbe3ba30SQing Zhang 875779e3c0SDonglin Peng move a0, sp 88dbe3ba30SQing Zhang bl ftrace_return_to_handler 89dbe3ba30SQing Zhang 90dbe3ba30SQing Zhang /* Restore the real parent address: a0 -> ra */ 91dbe3ba30SQing Zhang move ra, a0 92dbe3ba30SQing Zhang 935779e3c0SDonglin Peng PTR_L a0, sp, FGRET_REGS_A0 945779e3c0SDonglin Peng PTR_L a1, sp, FGRET_REGS_A1 955779e3c0SDonglin Peng PTR_ADDI sp, sp, FGRET_REGS_SIZE 96dbe3ba30SQing Zhang jr ra 97dbe3ba30SQing ZhangSYM_FUNC_END(return_to_handler) 98dbe3ba30SQing Zhang#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 99