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> 689a3927aSGuo Ren#include <abi/entry.h> 789a3927aSGuo Ren#include <asm/asm-offsets.h> 8230c77a5SGuo Ren 9d7950be1SGuo Ren/* 10d7950be1SGuo Ren * csky-gcc with -pg will put the following asm after prologue: 11d7950be1SGuo Ren * push r15 12d7950be1SGuo Ren * jsri _mcount 13d7950be1SGuo Ren * 14d7950be1SGuo Ren * stack layout after mcount_enter in _mcount(): 15d7950be1SGuo Ren * 16d7950be1SGuo Ren * current sp => 0:+-------+ 17d7950be1SGuo Ren * | a0-a3 | -> must save all argument regs 18d7950be1SGuo Ren * +16:+-------+ 19d7950be1SGuo Ren * | lr | -> _mcount lr (instrumente function's pc) 20d7950be1SGuo Ren * +20:+-------+ 21d7950be1SGuo Ren * | fp=r8 | -> instrumented function fp 22d7950be1SGuo Ren * +24:+-------+ 23d7950be1SGuo Ren * | plr | -> instrumented function lr (parent's pc) 24d7950be1SGuo Ren * +-------+ 25d7950be1SGuo Ren */ 26d7950be1SGuo Ren 27d7950be1SGuo Ren.macro mcount_enter 28d7950be1SGuo Ren subi sp, 24 29230c77a5SGuo Ren stw a0, (sp, 0) 30230c77a5SGuo Ren stw a1, (sp, 4) 31230c77a5SGuo Ren stw a2, (sp, 8) 32230c77a5SGuo Ren stw a3, (sp, 12) 33230c77a5SGuo Ren stw lr, (sp, 16) 34d7950be1SGuo Ren stw r8, (sp, 20) 35d7950be1SGuo Ren.endm 36d7950be1SGuo Ren 37d7950be1SGuo Ren.macro mcount_exit 38230c77a5SGuo Ren ldw a0, (sp, 0) 39230c77a5SGuo Ren ldw a1, (sp, 4) 40230c77a5SGuo Ren ldw a2, (sp, 8) 41230c77a5SGuo Ren ldw a3, (sp, 12) 42230c77a5SGuo Ren ldw t1, (sp, 16) 43d7950be1SGuo Ren ldw r8, (sp, 20) 44d7950be1SGuo Ren ldw lr, (sp, 24) 45d7950be1SGuo Ren addi sp, 28 46230c77a5SGuo Ren jmp t1 47d7950be1SGuo Ren.endm 48d7950be1SGuo Ren 4989a3927aSGuo Ren.macro mcount_enter_regs 5089a3927aSGuo Ren subi sp, 8 5189a3927aSGuo Ren stw lr, (sp, 0) 5289a3927aSGuo Ren stw r8, (sp, 4) 5389a3927aSGuo Ren SAVE_REGS_FTRACE 5489a3927aSGuo Ren.endm 5589a3927aSGuo Ren 5689a3927aSGuo Ren.macro mcount_exit_regs 5789a3927aSGuo Ren RESTORE_REGS_FTRACE 58*a5447fb9SGuo Ren subi sp, 152 59*a5447fb9SGuo Ren ldw t1, (sp, 4) 60*a5447fb9SGuo Ren addi sp, 152 6189a3927aSGuo Ren ldw r8, (sp, 4) 6289a3927aSGuo Ren ldw lr, (sp, 8) 6389a3927aSGuo Ren addi sp, 12 6489a3927aSGuo Ren jmp t1 6589a3927aSGuo Ren.endm 6689a3927aSGuo Ren 67d7950be1SGuo Ren.macro save_return_regs 68d7950be1SGuo Ren subi sp, 16 69d7950be1SGuo Ren stw a0, (sp, 0) 70d7950be1SGuo Ren stw a1, (sp, 4) 71d7950be1SGuo Ren stw a2, (sp, 8) 72d7950be1SGuo Ren stw a3, (sp, 12) 73d7950be1SGuo Ren.endm 74d7950be1SGuo Ren 75d7950be1SGuo Ren.macro restore_return_regs 76d7950be1SGuo Ren mov lr, a0 77d7950be1SGuo Ren ldw a0, (sp, 0) 78d7950be1SGuo Ren ldw a1, (sp, 4) 79d7950be1SGuo Ren ldw a2, (sp, 8) 80d7950be1SGuo Ren ldw a3, (sp, 12) 81d7950be1SGuo Ren addi sp, 16 82d7950be1SGuo Ren.endm 83d7950be1SGuo Ren 8428bb030fSGuo Ren.macro nop32_stub 8528bb030fSGuo Ren nop32 8628bb030fSGuo Ren nop32 8728bb030fSGuo Ren nop32 8828bb030fSGuo Ren.endm 8928bb030fSGuo Ren 90d7950be1SGuo RenENTRY(ftrace_stub) 91d7950be1SGuo Ren jmp lr 92d7950be1SGuo RenEND(ftrace_stub) 93d7950be1SGuo Ren 9428bb030fSGuo Ren#ifndef CONFIG_DYNAMIC_FTRACE 95d7950be1SGuo RenENTRY(_mcount) 96d7950be1SGuo Ren mcount_enter 97d7950be1SGuo Ren 98d7950be1SGuo Ren /* r26 is link register, only used with jsri translation */ 99d7950be1SGuo Ren lrw r26, ftrace_trace_function 100d7950be1SGuo Ren ldw r26, (r26, 0) 101d7950be1SGuo Ren lrw a1, ftrace_stub 102d7950be1SGuo Ren cmpne r26, a1 103d7950be1SGuo Ren bf skip_ftrace 104d7950be1SGuo Ren 105d7950be1SGuo Ren mov a0, lr 10628bb030fSGuo Ren subi a0, 4 107d7950be1SGuo Ren ldw a1, (sp, 24) 108a13d5887SGuo Ren lrw a2, function_trace_op 109a13d5887SGuo Ren ldw a2, (a2, 0) 110d7950be1SGuo Ren 111d7950be1SGuo Ren jsr r26 112d7950be1SGuo Ren 113d7950be1SGuo Ren#ifndef CONFIG_FUNCTION_GRAPH_TRACER 114d7950be1SGuo Renskip_ftrace: 115d7950be1SGuo Ren mcount_exit 116d7950be1SGuo Ren#else 117d7950be1SGuo Renskip_ftrace: 118d7950be1SGuo Ren lrw a0, ftrace_graph_return 119d7950be1SGuo Ren ldw a0, (a0, 0) 120d7950be1SGuo Ren lrw a1, ftrace_stub 121d7950be1SGuo Ren cmpne a0, a1 122d7950be1SGuo Ren bt ftrace_graph_caller 123d7950be1SGuo Ren 124d7950be1SGuo Ren lrw a0, ftrace_graph_entry 125d7950be1SGuo Ren ldw a0, (a0, 0) 126d7950be1SGuo Ren lrw a1, ftrace_graph_entry_stub 127d7950be1SGuo Ren cmpne a0, a1 128d7950be1SGuo Ren bt ftrace_graph_caller 129d7950be1SGuo Ren 130d7950be1SGuo Ren mcount_exit 131d7950be1SGuo Ren#endif 132230c77a5SGuo RenEND(_mcount) 13328bb030fSGuo Ren#else /* CONFIG_DYNAMIC_FTRACE */ 13428bb030fSGuo RenENTRY(_mcount) 13528bb030fSGuo Ren mov t1, lr 13628bb030fSGuo Ren ldw lr, (sp, 0) 13728bb030fSGuo Ren addi sp, 4 13828bb030fSGuo Ren jmp t1 13928bb030fSGuo RenENDPROC(_mcount) 14028bb030fSGuo Ren 14128bb030fSGuo RenENTRY(ftrace_caller) 14228bb030fSGuo Ren mcount_enter 14328bb030fSGuo Ren 14428bb030fSGuo Ren ldw a0, (sp, 16) 14528bb030fSGuo Ren subi a0, 4 14628bb030fSGuo Ren ldw a1, (sp, 24) 14789a3927aSGuo Ren lrw a2, function_trace_op 14889a3927aSGuo Ren ldw a2, (a2, 0) 14928bb030fSGuo Ren 15028bb030fSGuo Ren nop 15128bb030fSGuo RenGLOBAL(ftrace_call) 15228bb030fSGuo Ren nop32_stub 15328bb030fSGuo Ren 15428bb030fSGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER 15528bb030fSGuo Ren nop 15628bb030fSGuo RenGLOBAL(ftrace_graph_call) 15728bb030fSGuo Ren nop32_stub 15828bb030fSGuo Ren#endif 15928bb030fSGuo Ren 16028bb030fSGuo Ren mcount_exit 16128bb030fSGuo RenENDPROC(ftrace_caller) 16228bb030fSGuo Ren#endif /* CONFIG_DYNAMIC_FTRACE */ 163d7950be1SGuo Ren 164d7950be1SGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER 165d7950be1SGuo RenENTRY(ftrace_graph_caller) 166d7950be1SGuo Ren mov a0, sp 167d7950be1SGuo Ren addi a0, 24 168d7950be1SGuo Ren ldw a1, (sp, 16) 16928bb030fSGuo Ren subi a1, 4 170d7950be1SGuo Ren mov a2, r8 171d7950be1SGuo Ren lrw r26, prepare_ftrace_return 172d7950be1SGuo Ren jsr r26 173d7950be1SGuo Ren mcount_exit 174d7950be1SGuo RenEND(ftrace_graph_caller) 175d7950be1SGuo Ren 176d7950be1SGuo RenENTRY(return_to_handler) 177d7950be1SGuo Ren save_return_regs 178d7950be1SGuo Ren mov a0, r8 179d7950be1SGuo Ren jsri ftrace_return_to_handler 180d7950be1SGuo Ren restore_return_regs 181d7950be1SGuo Ren jmp lr 182d7950be1SGuo RenEND(return_to_handler) 183d7950be1SGuo Ren#endif 18489a3927aSGuo Ren 18589a3927aSGuo Ren#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 18689a3927aSGuo RenENTRY(ftrace_regs_caller) 18789a3927aSGuo Ren mcount_enter_regs 18889a3927aSGuo Ren 18989a3927aSGuo Ren lrw t1, PT_FRAME_SIZE 19089a3927aSGuo Ren add t1, sp 19189a3927aSGuo Ren 19289a3927aSGuo Ren ldw a0, (t1, 0) 19389a3927aSGuo Ren subi a0, 4 19489a3927aSGuo Ren ldw a1, (t1, 8) 19589a3927aSGuo Ren lrw a2, function_trace_op 19689a3927aSGuo Ren ldw a2, (a2, 0) 19789a3927aSGuo Ren mov a3, sp 19889a3927aSGuo Ren 19989a3927aSGuo Ren nop 20089a3927aSGuo RenGLOBAL(ftrace_regs_call) 20189a3927aSGuo Ren nop32_stub 20289a3927aSGuo Ren 20389a3927aSGuo Ren#ifdef CONFIG_FUNCTION_GRAPH_TRACER 20489a3927aSGuo Ren nop 20589a3927aSGuo RenGLOBAL(ftrace_graph_regs_call) 20689a3927aSGuo Ren nop32_stub 20789a3927aSGuo Ren#endif 20889a3927aSGuo Ren 20989a3927aSGuo Ren mcount_exit_regs 21089a3927aSGuo RenENDPROC(ftrace_regs_caller) 21189a3927aSGuo Ren#endif /* CONFIG_DYNAMIC_FTRACE */ 212