1/* SPDX-License-Identifier: GPL-2.0 */ 2// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3 4#include <linux/linkage.h> 5#include <asm/ftrace.h> 6#include <abi/entry.h> 7#include <asm/asm-offsets.h> 8 9/* 10 * csky-gcc with -pg will put the following asm after prologue: 11 * push r15 12 * jsri _mcount 13 * 14 * stack layout after mcount_enter in _mcount(): 15 * 16 * current sp => 0:+-------+ 17 * | a0-a3 | -> must save all argument regs 18 * +16:+-------+ 19 * | lr | -> _mcount lr (instrumente function's pc) 20 * +20:+-------+ 21 * | fp=r8 | -> instrumented function fp 22 * +24:+-------+ 23 * | plr | -> instrumented function lr (parent's pc) 24 * +-------+ 25 */ 26 27.macro mcount_enter 28 subi sp, 24 29 stw a0, (sp, 0) 30 stw a1, (sp, 4) 31 stw a2, (sp, 8) 32 stw a3, (sp, 12) 33 stw lr, (sp, 16) 34 stw r8, (sp, 20) 35.endm 36 37.macro mcount_exit 38 ldw a0, (sp, 0) 39 ldw a1, (sp, 4) 40 ldw a2, (sp, 8) 41 ldw a3, (sp, 12) 42 ldw t1, (sp, 16) 43 ldw r8, (sp, 20) 44 ldw lr, (sp, 24) 45 addi sp, 28 46 jmp t1 47.endm 48 49.macro mcount_enter_regs 50 subi sp, 8 51 stw lr, (sp, 0) 52 stw r8, (sp, 4) 53 SAVE_REGS_FTRACE 54.endm 55 56.macro mcount_exit_regs 57 RESTORE_REGS_FTRACE 58 ldw t1, (sp, 0) 59 ldw r8, (sp, 4) 60 ldw lr, (sp, 8) 61 addi sp, 12 62 jmp t1 63.endm 64 65.macro save_return_regs 66 subi sp, 16 67 stw a0, (sp, 0) 68 stw a1, (sp, 4) 69 stw a2, (sp, 8) 70 stw a3, (sp, 12) 71.endm 72 73.macro restore_return_regs 74 mov lr, a0 75 ldw a0, (sp, 0) 76 ldw a1, (sp, 4) 77 ldw a2, (sp, 8) 78 ldw a3, (sp, 12) 79 addi sp, 16 80.endm 81 82.macro nop32_stub 83 nop32 84 nop32 85 nop32 86.endm 87 88ENTRY(ftrace_stub) 89 jmp lr 90END(ftrace_stub) 91 92#ifndef CONFIG_DYNAMIC_FTRACE 93ENTRY(_mcount) 94 mcount_enter 95 96 /* r26 is link register, only used with jsri translation */ 97 lrw r26, ftrace_trace_function 98 ldw r26, (r26, 0) 99 lrw a1, ftrace_stub 100 cmpne r26, a1 101 bf skip_ftrace 102 103 mov a0, lr 104 subi a0, 4 105 ldw a1, (sp, 24) 106 lrw a2, function_trace_op 107 ldw a2, (a2, 0) 108 109 jsr r26 110 111#ifndef CONFIG_FUNCTION_GRAPH_TRACER 112skip_ftrace: 113 mcount_exit 114#else 115skip_ftrace: 116 lrw a0, ftrace_graph_return 117 ldw a0, (a0, 0) 118 lrw a1, ftrace_stub 119 cmpne a0, a1 120 bt ftrace_graph_caller 121 122 lrw a0, ftrace_graph_entry 123 ldw a0, (a0, 0) 124 lrw a1, ftrace_graph_entry_stub 125 cmpne a0, a1 126 bt ftrace_graph_caller 127 128 mcount_exit 129#endif 130END(_mcount) 131#else /* CONFIG_DYNAMIC_FTRACE */ 132ENTRY(_mcount) 133 mov t1, lr 134 ldw lr, (sp, 0) 135 addi sp, 4 136 jmp t1 137ENDPROC(_mcount) 138 139ENTRY(ftrace_caller) 140 mcount_enter 141 142 ldw a0, (sp, 16) 143 subi a0, 4 144 ldw a1, (sp, 24) 145 lrw a2, function_trace_op 146 ldw a2, (a2, 0) 147 148 nop 149GLOBAL(ftrace_call) 150 nop32_stub 151 152#ifdef CONFIG_FUNCTION_GRAPH_TRACER 153 nop 154GLOBAL(ftrace_graph_call) 155 nop32_stub 156#endif 157 158 mcount_exit 159ENDPROC(ftrace_caller) 160#endif /* CONFIG_DYNAMIC_FTRACE */ 161 162#ifdef CONFIG_FUNCTION_GRAPH_TRACER 163ENTRY(ftrace_graph_caller) 164 mov a0, sp 165 addi a0, 24 166 ldw a1, (sp, 16) 167 subi a1, 4 168 mov a2, r8 169 lrw r26, prepare_ftrace_return 170 jsr r26 171 mcount_exit 172END(ftrace_graph_caller) 173 174ENTRY(return_to_handler) 175 save_return_regs 176 mov a0, r8 177 jsri ftrace_return_to_handler 178 restore_return_regs 179 jmp lr 180END(return_to_handler) 181#endif 182 183#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 184ENTRY(ftrace_regs_caller) 185 mcount_enter_regs 186 187 lrw t1, PT_FRAME_SIZE 188 add t1, sp 189 190 ldw a0, (t1, 0) 191 subi a0, 4 192 ldw a1, (t1, 8) 193 lrw a2, function_trace_op 194 ldw a2, (a2, 0) 195 mov a3, sp 196 197 nop 198GLOBAL(ftrace_regs_call) 199 nop32_stub 200 201#ifdef CONFIG_FUNCTION_GRAPH_TRACER 202 nop 203GLOBAL(ftrace_graph_regs_call) 204 nop32_stub 205#endif 206 207 mcount_exit_regs 208ENDPROC(ftrace_regs_caller) 209#endif /* CONFIG_DYNAMIC_FTRACE */ 210