1/* SPDX-License-Identifier: BSD-2-Clause */ 2/* 3 * Copyright (c) 2023 Andes Technology Corporation 4 * Copyright (c) 2016, Linaro Limited 5 */ 6 7#include <asm.S> 8 9#if defined(CFG_FTRACE_SUPPORT) 10 11/* 12 * Convert return address to call site address by subtracting the size of one 13 * instruction. 14 */ 15.macro adjust_pc rd, rn 16 addi \rd, \rn, -4 17.endm 18 19#ifdef RV32 20 21/* Get instrumented function's pc value */ 22.macro get_pc reg 23 LDR \reg, REGOFF(3)(sp) 24 addi \reg, \reg, -4 25.endm 26 27/* Get instrumented function's ra address pointer */ 28.macro get_ra_addr reg 29 LDR \reg, REGOFF(2)(sp) 30 addi \reg, \reg, -4 31.endm 32 33#else /* RV64 */ 34 35/* Get instrumented function's pc value */ 36.macro get_pc reg 37 LDR \reg, REGOFF(1)(sp) 38 addi \reg, \reg, -4 39.endm 40 41/* Get instrumented function's ra address pointer */ 42.macro get_ra_addr reg 43 LDR \reg, REGOFF(0)(sp) 44 addi \reg, \reg, -8 45.endm 46 47#endif /* RV32 */ 48 49/* 50 * void _mcount(void *return_address) 51 * @return_address: return address to instrumented function 52 * 53 * With the -pg option, the compiler inserts a call to _mcount into 54 * every function prologue. 55 * a0 contains the value of ra before the call, that is the return 56 * address to the caller of the instrumented function. The callee, i.e. the 57 * instrumented function itself, is determined from the current value of ra. 58 * Then we call: 59 * void __mcount_internal(void *frompc, void *selfpc); 60 */ 61FUNC _mcount, : 62 addi sp, sp, -16 63 /* Save ra and s0(fp) onto stack */ 64#ifdef RV32 65 STR ra, REGOFF(3)(sp) 66 STR s0, REGOFF(2)(sp) 67#else 68 STR ra, REGOFF(1)(sp) 69 STR s0, REGOFF(0)(sp) 70#endif 71 /* Setup frame pointer */ 72 addi s0, sp, 16 73#ifdef CFG_FTRACE_SUPPORT 74 get_pc a0 75 get_ra_addr a1 76 call ftrace_enter 77#endif 78 /* Restore ra and s0(fp) from stack */ 79#ifdef RV32 80 LDR s0, REGOFF(2)(sp) 81 LDR ra, REGOFF(3)(sp) 82#else 83 LDR s0, REGOFF(0)(sp) 84 LDR ra, REGOFF(1)(sp) 85#endif 86 addi sp, sp, 16 87 ret 88END_FUNC _mcount 89 90#ifdef CFG_FTRACE_SUPPORT 91FUNC __ftrace_return, : 92 /* Save return value regs */ 93 addi sp, sp, -REGOFF(8) 94 STR a0, REGOFF(0)(sp) 95 STR a1, REGOFF(1)(sp) 96 STR a2, REGOFF(2)(sp) 97 STR a3, REGOFF(3)(sp) 98 STR a4, REGOFF(4)(sp) 99 STR a5, REGOFF(5)(sp) 100 STR a6, REGOFF(6)(sp) 101 STR a7, REGOFF(7)(sp) 102 103 /* Get return address of parent func */ 104 call ftrace_return 105 mv ra, a0 106 107 /* Restore return value regs */ 108 LDR a0, REGOFF(0)(sp) 109 LDR a1, REGOFF(1)(sp) 110 LDR a2, REGOFF(2)(sp) 111 LDR a3, REGOFF(3)(sp) 112 LDR a4, REGOFF(4)(sp) 113 LDR a5, REGOFF(5)(sp) 114 LDR a6, REGOFF(6)(sp) 115 LDR a7, REGOFF(7)(sp) 116 addi sp, sp, REGOFF(8) 117 118 ret 119END_FUNC __ftrace_return 120#endif 121 122#endif /* CFG_FTRACE_SUPPORT */ 123