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 .macro SAVE_ABI_STATE 17 addi sp, sp, -16 18 sd s0, 0(sp) 19 sd ra, 8(sp) 20 addi s0, sp, 16 21 .endm 22 23 /* 24 * The call to ftrace_return_to_handler would overwrite the return 25 * register if a0 was not saved. 26 */ 27 .macro SAVE_RET_ABI_STATE 28 addi sp, sp, -32 29 sd s0, 16(sp) 30 sd ra, 24(sp) 31 sd a0, 8(sp) 32 addi s0, sp, 32 33 .endm 34 35 .macro RESTORE_ABI_STATE 36 ld ra, 8(sp) 37 ld s0, 0(sp) 38 addi sp, sp, 16 39 .endm 40 41 .macro RESTORE_RET_ABI_STATE 42 ld ra, 24(sp) 43 ld s0, 16(sp) 44 ld a0, 8(sp) 45 addi sp, sp, 32 46 .endm 47 48ENTRY(ftrace_stub) 49#ifdef CONFIG_DYNAMIC_FTRACE 50 .global MCOUNT_NAME 51 .set MCOUNT_NAME, ftrace_stub 52#endif 53 ret 54ENDPROC(ftrace_stub) 55 56#ifdef CONFIG_FUNCTION_GRAPH_TRACER 57ENTRY(return_to_handler) 58/* 59 * On implementing the frame point test, the ideal way is to compare the 60 * s0 (frame pointer, if enabled) on entry and the sp (stack pointer) on return. 61 * However, the psABI of variable-length-argument functions does not allow this. 62 * 63 * So alternatively we check the *old* frame pointer position, that is, the 64 * value stored in -16(s0) on entry, and the s0 on return. 65 */ 66#ifdef HAVE_FUNCTION_GRAPH_FP_TEST 67 mv t6, s0 68#endif 69 SAVE_RET_ABI_STATE 70#ifdef HAVE_FUNCTION_GRAPH_FP_TEST 71 mv a0, t6 72#endif 73 call ftrace_return_to_handler 74 mv a1, a0 75 RESTORE_RET_ABI_STATE 76 jalr a1 77ENDPROC(return_to_handler) 78#endif 79 80#ifndef CONFIG_DYNAMIC_FTRACE 81ENTRY(MCOUNT_NAME) 82 la t4, ftrace_stub 83#ifdef CONFIG_FUNCTION_GRAPH_TRACER 84 la t0, ftrace_graph_return 85 ld t1, 0(t0) 86 bne t1, t4, do_ftrace_graph_caller 87 88 la t3, ftrace_graph_entry 89 ld t2, 0(t3) 90 la t6, ftrace_graph_entry_stub 91 bne t2, t6, do_ftrace_graph_caller 92#endif 93 la t3, ftrace_trace_function 94 ld t5, 0(t3) 95 bne t5, t4, do_trace 96 ret 97 98#ifdef CONFIG_FUNCTION_GRAPH_TRACER 99/* 100 * A pseudo representation for the function graph tracer: 101 * prepare_to_return(&ra_to_caller_of_caller, ra_to_caller) 102 */ 103do_ftrace_graph_caller: 104 addi a0, s0, -8 105 mv a1, ra 106#ifdef HAVE_FUNCTION_GRAPH_FP_TEST 107 ld a2, -16(s0) 108#endif 109 SAVE_ABI_STATE 110 call prepare_ftrace_return 111 RESTORE_ABI_STATE 112 ret 113#endif 114 115/* 116 * A pseudo representation for the function tracer: 117 * (*ftrace_trace_function)(ra_to_caller, ra_to_caller_of_caller) 118 */ 119do_trace: 120 ld a1, -8(s0) 121 mv a0, ra 122 123 SAVE_ABI_STATE 124 jalr t5 125 RESTORE_ABI_STATE 126 ret 127ENDPROC(MCOUNT_NAME) 128#endif 129EXPORT_SYMBOL(MCOUNT_NAME) 130