1/* SPDX-License-Identifier: GPL-2.0 */ 2/* Copyright (C) 2017 Andes Technology Corporation */ 3 4#include <linux/init.h> 5#include <linux/linkage.h> 6#include <asm/asm.h> 7#include <asm/csr.h> 8#include <asm/unistd.h> 9#include <asm/thread_info.h> 10#include <asm/asm-offsets.h> 11#include <asm-generic/export.h> 12#include <asm/ftrace.h> 13 14 .text 15 16#define FENTRY_RA_OFFSET 8 17#define ABI_SIZE_ON_STACK 80 18#define ABI_A0 0 19#define ABI_A1 8 20#define ABI_A2 16 21#define ABI_A3 24 22#define ABI_A4 32 23#define ABI_A5 40 24#define ABI_A6 48 25#define ABI_A7 56 26#define ABI_T0 64 27#define ABI_RA 72 28 29 .macro SAVE_ABI 30 addi sp, sp, -ABI_SIZE_ON_STACK 31 32 REG_S a0, ABI_A0(sp) 33 REG_S a1, ABI_A1(sp) 34 REG_S a2, ABI_A2(sp) 35 REG_S a3, ABI_A3(sp) 36 REG_S a4, ABI_A4(sp) 37 REG_S a5, ABI_A5(sp) 38 REG_S a6, ABI_A6(sp) 39 REG_S a7, ABI_A7(sp) 40 REG_S t0, ABI_T0(sp) 41 REG_S ra, ABI_RA(sp) 42 .endm 43 44 .macro RESTORE_ABI 45 REG_L a0, ABI_A0(sp) 46 REG_L a1, ABI_A1(sp) 47 REG_L a2, ABI_A2(sp) 48 REG_L a3, ABI_A3(sp) 49 REG_L a4, ABI_A4(sp) 50 REG_L a5, ABI_A5(sp) 51 REG_L a6, ABI_A6(sp) 52 REG_L a7, ABI_A7(sp) 53 REG_L t0, ABI_T0(sp) 54 REG_L ra, ABI_RA(sp) 55 56 addi sp, sp, ABI_SIZE_ON_STACK 57 .endm 58 59#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 60 .macro SAVE_ALL 61 addi sp, sp, -PT_SIZE_ON_STACK 62 63 REG_S t0, PT_EPC(sp) 64 REG_S x1, PT_RA(sp) 65 REG_S x2, PT_SP(sp) 66 REG_S x3, PT_GP(sp) 67 REG_S x4, PT_TP(sp) 68 REG_S x5, PT_T0(sp) 69 save_from_x6_to_x31 70 .endm 71 72 .macro RESTORE_ALL 73 REG_L x1, PT_RA(sp) 74 REG_L x2, PT_SP(sp) 75 REG_L x3, PT_GP(sp) 76 REG_L x4, PT_TP(sp) 77 /* Restore t0 with PT_EPC */ 78 REG_L x5, PT_EPC(sp) 79 restore_from_x6_to_x31 80 81 addi sp, sp, PT_SIZE_ON_STACK 82 .endm 83#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ 84 85SYM_FUNC_START(ftrace_caller) 86 SAVE_ABI 87 88 addi a0, t0, -FENTRY_RA_OFFSET 89 la a1, function_trace_op 90 REG_L a2, 0(a1) 91 mv a1, ra 92 mv a3, sp 93 94SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL) 95 call ftrace_stub 96 97#ifdef CONFIG_FUNCTION_GRAPH_TRACER 98 addi a0, sp, ABI_RA 99 REG_L a1, ABI_T0(sp) 100 addi a1, a1, -FENTRY_RA_OFFSET 101#ifdef HAVE_FUNCTION_GRAPH_FP_TEST 102 mv a2, s0 103#endif 104SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL) 105 call ftrace_stub 106#endif 107 RESTORE_ABI 108 jr t0 109SYM_FUNC_END(ftrace_caller) 110 111#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 112SYM_FUNC_START(ftrace_regs_caller) 113 SAVE_ALL 114 115 addi a0, t0, -FENTRY_RA_OFFSET 116 la a1, function_trace_op 117 REG_L a2, 0(a1) 118 mv a1, ra 119 mv a3, sp 120 121SYM_INNER_LABEL(ftrace_regs_call, SYM_L_GLOBAL) 122 call ftrace_stub 123 124#ifdef CONFIG_FUNCTION_GRAPH_TRACER 125 addi a0, sp, PT_RA 126 REG_L a1, PT_EPC(sp) 127 addi a1, a1, -FENTRY_RA_OFFSET 128#ifdef HAVE_FUNCTION_GRAPH_FP_TEST 129 mv a2, s0 130#endif 131SYM_INNER_LABEL(ftrace_graph_regs_call, SYM_L_GLOBAL) 132 call ftrace_stub 133#endif 134 135 RESTORE_ALL 136 jr t0 137SYM_FUNC_END(ftrace_regs_caller) 138#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ 139