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