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 subi sp, 152 59 ldw t1, (sp, 4) 60 addi sp, 152 61 ldw r8, (sp, 4) 62 ldw lr, (sp, 8) 63 addi sp, 12 64 jmp t1 65.endm 66 67.macro save_return_regs 68 subi sp, 16 69 stw a0, (sp, 0) 70 stw a1, (sp, 4) 71 stw a2, (sp, 8) 72 stw a3, (sp, 12) 73.endm 74 75.macro restore_return_regs 76 mov lr, a0 77 ldw a0, (sp, 0) 78 ldw a1, (sp, 4) 79 ldw a2, (sp, 8) 80 ldw a3, (sp, 12) 81 addi sp, 16 82.endm 83 84.macro nop32_stub 85 nop32 86 nop32 87 nop32 88.endm 89 90ENTRY(ftrace_stub) 91 jmp lr 92END(ftrace_stub) 93 94#ifndef CONFIG_DYNAMIC_FTRACE 95ENTRY(_mcount) 96 mcount_enter 97 98 /* r26 is link register, only used with jsri translation */ 99 lrw r26, ftrace_trace_function 100 ldw r26, (r26, 0) 101 lrw a1, ftrace_stub 102 cmpne r26, a1 103 bf skip_ftrace 104 105 mov a0, lr 106 subi a0, 4 107 ldw a1, (sp, 24) 108 lrw a2, function_trace_op 109 ldw a2, (a2, 0) 110 111 jsr r26 112 113#ifndef CONFIG_FUNCTION_GRAPH_TRACER 114skip_ftrace: 115 mcount_exit 116#else 117skip_ftrace: 118 lrw a0, ftrace_graph_return 119 ldw a0, (a0, 0) 120 lrw a1, ftrace_stub 121 cmpne a0, a1 122 bt ftrace_graph_caller 123 124 lrw a0, ftrace_graph_entry 125 ldw a0, (a0, 0) 126 lrw a1, ftrace_graph_entry_stub 127 cmpne a0, a1 128 bt ftrace_graph_caller 129 130 mcount_exit 131#endif 132END(_mcount) 133#else /* CONFIG_DYNAMIC_FTRACE */ 134ENTRY(_mcount) 135 mov t1, lr 136 ldw lr, (sp, 0) 137 addi sp, 4 138 jmp t1 139ENDPROC(_mcount) 140 141ENTRY(ftrace_caller) 142 mcount_enter 143 144 ldw a0, (sp, 16) 145 subi a0, 4 146 ldw a1, (sp, 24) 147 lrw a2, function_trace_op 148 ldw a2, (a2, 0) 149 150 nop 151GLOBAL(ftrace_call) 152 nop32_stub 153 154#ifdef CONFIG_FUNCTION_GRAPH_TRACER 155 nop 156GLOBAL(ftrace_graph_call) 157 nop32_stub 158#endif 159 160 mcount_exit 161ENDPROC(ftrace_caller) 162#endif /* CONFIG_DYNAMIC_FTRACE */ 163 164#ifdef CONFIG_FUNCTION_GRAPH_TRACER 165ENTRY(ftrace_graph_caller) 166 mov a0, sp 167 addi a0, 24 168 ldw a1, (sp, 16) 169 subi a1, 4 170 mov a2, r8 171 lrw r26, prepare_ftrace_return 172 jsr r26 173 mcount_exit 174END(ftrace_graph_caller) 175 176ENTRY(return_to_handler) 177 save_return_regs 178 mov a0, r8 179 jsri ftrace_return_to_handler 180 restore_return_regs 181 jmp lr 182END(return_to_handler) 183#endif 184 185#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 186ENTRY(ftrace_regs_caller) 187 mcount_enter_regs 188 189 lrw t1, PT_FRAME_SIZE 190 add t1, sp 191 192 ldw a0, (t1, 0) 193 subi a0, 4 194 ldw a1, (t1, 8) 195 lrw a2, function_trace_op 196 ldw a2, (a2, 0) 197 mov a3, sp 198 199 nop 200GLOBAL(ftrace_regs_call) 201 nop32_stub 202 203#ifdef CONFIG_FUNCTION_GRAPH_TRACER 204 nop 205GLOBAL(ftrace_graph_regs_call) 206 nop32_stub 207#endif 208 209 mcount_exit_regs 210ENDPROC(ftrace_regs_caller) 211#endif /* CONFIG_DYNAMIC_FTRACE */ 212