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