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 107 jsr r26 108 109#ifndef CONFIG_FUNCTION_GRAPH_TRACER 110skip_ftrace: 111 mcount_exit 112#else 113skip_ftrace: 114 lrw a0, ftrace_graph_return 115 ldw a0, (a0, 0) 116 lrw a1, ftrace_stub 117 cmpne a0, a1 118 bt ftrace_graph_caller 119 120 lrw a0, ftrace_graph_entry 121 ldw a0, (a0, 0) 122 lrw a1, ftrace_graph_entry_stub 123 cmpne a0, a1 124 bt ftrace_graph_caller 125 126 mcount_exit 127#endif 128END(_mcount) 129#else /* CONFIG_DYNAMIC_FTRACE */ 130ENTRY(_mcount) 131 mov t1, lr 132 ldw lr, (sp, 0) 133 addi sp, 4 134 jmp t1 135ENDPROC(_mcount) 136 137ENTRY(ftrace_caller) 138 mcount_enter 139 140 ldw a0, (sp, 16) 141 subi a0, 4 142 ldw a1, (sp, 24) 143 lrw a2, function_trace_op 144 ldw a2, (a2, 0) 145 146 nop 147GLOBAL(ftrace_call) 148 nop32_stub 149 150#ifdef CONFIG_FUNCTION_GRAPH_TRACER 151 nop 152GLOBAL(ftrace_graph_call) 153 nop32_stub 154#endif 155 156 mcount_exit 157ENDPROC(ftrace_caller) 158#endif /* CONFIG_DYNAMIC_FTRACE */ 159 160#ifdef CONFIG_FUNCTION_GRAPH_TRACER 161ENTRY(ftrace_graph_caller) 162 mov a0, sp 163 addi a0, 24 164 ldw a1, (sp, 16) 165 subi a1, 4 166 mov a2, r8 167 lrw r26, prepare_ftrace_return 168 jsr r26 169 mcount_exit 170END(ftrace_graph_caller) 171 172ENTRY(return_to_handler) 173 save_return_regs 174 mov a0, r8 175 jsri ftrace_return_to_handler 176 restore_return_regs 177 jmp lr 178END(return_to_handler) 179#endif 180 181#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 182ENTRY(ftrace_regs_caller) 183 mcount_enter_regs 184 185 lrw t1, PT_FRAME_SIZE 186 add t1, sp 187 188 ldw a0, (t1, 0) 189 subi a0, 4 190 ldw a1, (t1, 8) 191 lrw a2, function_trace_op 192 ldw a2, (a2, 0) 193 mov a3, sp 194 195 nop 196GLOBAL(ftrace_regs_call) 197 nop32_stub 198 199#ifdef CONFIG_FUNCTION_GRAPH_TRACER 200 nop 201GLOBAL(ftrace_graph_regs_call) 202 nop32_stub 203#endif 204 205 mcount_exit_regs 206ENDPROC(ftrace_regs_caller) 207#endif /* CONFIG_DYNAMIC_FTRACE */ 208