1230c77a5SGuo Ren/* SPDX-License-Identifier: GPL-2.0 */ 2230c77a5SGuo Ren// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3230c77a5SGuo Ren 4230c77a5SGuo Ren#include <linux/linkage.h> 5d7950be1SGuo Ren#include <asm/ftrace.h> 6230c77a5SGuo Ren 7d7950be1SGuo Ren/* 8d7950be1SGuo Ren * csky-gcc with -pg will put the following asm after prologue: 9d7950be1SGuo Ren * push r15 10d7950be1SGuo Ren * jsri _mcount 11d7950be1SGuo Ren * 12d7950be1SGuo Ren * stack layout after mcount_enter in _mcount(): 13d7950be1SGuo Ren * 14d7950be1SGuo Ren * current sp => 0:+-------+ 15d7950be1SGuo Ren * | a0-a3 | -> must save all argument regs 16d7950be1SGuo Ren * +16:+-------+ 17d7950be1SGuo Ren * | lr | -> _mcount lr (instrumente function's pc) 18d7950be1SGuo Ren * +20:+-------+ 19d7950be1SGuo Ren * | fp=r8 | -> instrumented function fp 20d7950be1SGuo Ren * +24:+-------+ 21d7950be1SGuo Ren * | plr | -> instrumented function lr (parent's pc) 22d7950be1SGuo Ren * +-------+ 23d7950be1SGuo Ren */ 24d7950be1SGuo Ren 25d7950be1SGuo Ren.macro mcount_enter 26d7950be1SGuo Ren subi sp, 24 27230c77a5SGuo Ren stw a0, (sp, 0) 28230c77a5SGuo Ren stw a1, (sp, 4) 29230c77a5SGuo Ren stw a2, (sp, 8) 30230c77a5SGuo Ren stw a3, (sp, 12) 31230c77a5SGuo Ren stw lr, (sp, 16) 32d7950be1SGuo Ren stw r8, (sp, 20) 33d7950be1SGuo Ren.endm 34d7950be1SGuo Ren 35d7950be1SGuo Ren.macro mcount_exit 36230c77a5SGuo Ren ldw a0, (sp, 0) 37230c77a5SGuo Ren ldw a1, (sp, 4) 38230c77a5SGuo Ren ldw a2, (sp, 8) 39230c77a5SGuo Ren ldw a3, (sp, 12) 40230c77a5SGuo Ren ldw t1, (sp, 16) 41d7950be1SGuo Ren ldw r8, (sp, 20) 42d7950be1SGuo Ren ldw lr, (sp, 24) 43d7950be1SGuo Ren addi sp, 28 44230c77a5SGuo Ren jmp t1 45d7950be1SGuo Ren.endm 46d7950be1SGuo Ren 47d7950be1SGuo Ren.macro save_return_regs 48d7950be1SGuo Ren subi sp, 16 49d7950be1SGuo Ren stw a0, (sp, 0) 50d7950be1SGuo Ren stw a1, (sp, 4) 51d7950be1SGuo Ren stw a2, (sp, 8) 52d7950be1SGuo Ren stw a3, (sp, 12) 53d7950be1SGuo Ren.endm 54d7950be1SGuo Ren 55d7950be1SGuo Ren.macro restore_return_regs 56d7950be1SGuo Ren mov lr, a0 57d7950be1SGuo Ren ldw a0, (sp, 0) 58d7950be1SGuo Ren ldw a1, (sp, 4) 59d7950be1SGuo Ren ldw a2, (sp, 8) 60d7950be1SGuo Ren ldw a3, (sp, 12) 61d7950be1SGuo Ren addi sp, 16 62d7950be1SGuo Ren.endm 63d7950be1SGuo Ren 64*28bb030fSGuo Ren.macro nop32_stub 65*28bb030fSGuo Ren nop32 66*28bb030fSGuo Ren nop32 67*28bb030fSGuo Ren nop32 68*28bb030fSGuo Ren.endm 69*28bb030fSGuo Ren 70d7950be1SGuo RenENTRY(ftrace_stub) 71d7950be1SGuo Ren jmp lr 72d7950be1SGuo RenEND(ftrace_stub) 73d7950be1SGuo Ren 74*28bb030fSGuo Ren#ifndef CONFIG_DYNAMIC_FTRACE 75d7950be1SGuo RenENTRY(_mcount) 76d7950be1SGuo Ren mcount_enter 77d7950be1SGuo Ren 78d7950be1SGuo Ren /* r26 is link register, only used with jsri translation */ 79d7950be1SGuo Ren lrw r26, ftrace_trace_function 80d7950be1SGuo Ren ldw r26, (r26, 0) 81d7950be1SGuo Ren lrw a1, ftrace_stub 82d7950be1SGuo Ren cmpne r26, a1 83d7950be1SGuo Ren bf skip_ftrace 84d7950be1SGuo Ren 85d7950be1SGuo Ren mov a0, lr 86*28bb030fSGuo Ren subi a0, 4 87d7950be1SGuo Ren ldw a1, (sp, 24) 88d7950be1SGuo Ren 89d7950be1SGuo Ren jsr r26 90d7950be1SGuo Ren 91d7950be1SGuo Ren#ifndef CONFIG_FUNCTION_GRAPH_TRACER 92d7950be1SGuo Renskip_ftrace: 93d7950be1SGuo Ren mcount_exit 94d7950be1SGuo Ren#else 95d7950be1SGuo Renskip_ftrace: 96d7950be1SGuo Ren lrw a0, ftrace_graph_return 97d7950be1SGuo Ren ldw a0, (a0, 0) 98d7950be1SGuo Ren lrw a1, ftrace_stub 99d7950be1SGuo Ren cmpne a0, a1 100d7950be1SGuo Ren bt ftrace_graph_caller 101d7950be1SGuo Ren 102d7950be1SGuo Ren lrw a0, ftrace_graph_entry 103d7950be1SGuo Ren ldw a0, (a0, 0) 104d7950be1SGuo Ren lrw a1, ftrace_graph_entry_stub 105d7950be1SGuo Ren cmpne a0, a1 106d7950be1SGuo Ren bt ftrace_graph_caller 107d7950be1SGuo Ren 108d7950be1SGuo Ren mcount_exit 109d7950be1SGuo Ren#endif 110230c77a5SGuo RenEND(_mcount) 111*28bb030fSGuo Ren#else /* CONFIG_DYNAMIC_FTRACE */ 112*28bb030fSGuo RenENTRY(_mcount) 113*28bb030fSGuo Ren mov t1, lr 114*28bb030fSGuo Ren ldw lr, (sp, 0) 115*28bb030fSGuo Ren addi sp, 4 116*28bb030fSGuo Ren jmp t1 117*28bb030fSGuo RenENDPROC(_mcount) 118*28bb030fSGuo Ren 119*28bb030fSGuo RenENTRY(ftrace_caller) 120*28bb030fSGuo Ren mcount_enter 121*28bb030fSGuo Ren 122*28bb030fSGuo Ren ldw a0, (sp, 16) 123*28bb030fSGuo Ren subi a0, 4 124*28bb030fSGuo Ren ldw a1, (sp, 24) 125*28bb030fSGuo Ren 126*28bb030fSGuo Ren nop 127*28bb030fSGuo RenGLOBAL(ftrace_call) 128*28bb030fSGuo Ren nop32_stub 129*28bb030fSGuo Ren 130*28bb030fSGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER 131*28bb030fSGuo Ren nop 132*28bb030fSGuo RenGLOBAL(ftrace_graph_call) 133*28bb030fSGuo Ren nop32_stub 134*28bb030fSGuo Ren#endif 135*28bb030fSGuo Ren 136*28bb030fSGuo Ren mcount_exit 137*28bb030fSGuo RenENDPROC(ftrace_caller) 138*28bb030fSGuo Ren#endif /* CONFIG_DYNAMIC_FTRACE */ 139d7950be1SGuo Ren 140d7950be1SGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER 141d7950be1SGuo RenENTRY(ftrace_graph_caller) 142d7950be1SGuo Ren mov a0, sp 143d7950be1SGuo Ren addi a0, 24 144d7950be1SGuo Ren ldw a1, (sp, 16) 145*28bb030fSGuo Ren subi a1, 4 146d7950be1SGuo Ren mov a2, r8 147d7950be1SGuo Ren lrw r26, prepare_ftrace_return 148d7950be1SGuo Ren jsr r26 149d7950be1SGuo Ren mcount_exit 150d7950be1SGuo RenEND(ftrace_graph_caller) 151d7950be1SGuo Ren 152d7950be1SGuo RenENTRY(return_to_handler) 153d7950be1SGuo Ren save_return_regs 154d7950be1SGuo Ren mov a0, r8 155d7950be1SGuo Ren jsri ftrace_return_to_handler 156d7950be1SGuo Ren restore_return_regs 157d7950be1SGuo Ren jmp lr 158d7950be1SGuo RenEND(return_to_handler) 159d7950be1SGuo Ren#endif 160