1/* SPDX-License-Identifier: BSD-2-Clause */ 2/* 3 * Copyright (c) 2016, Linaro Limited 4 */ 5 6#include <asm.S> 7 8#if defined(CFG_TA_GPROF_SUPPORT) || defined(CFG_FTRACE_SUPPORT) 9 10 .section .note.GNU-stack,"",%progbits 11 12/* 13 * Convert return address to call site address by subtracting the size of the 14 * mcount call instruction (blx __gnu_mcount_nc). 15 */ 16.macro mcount_adj_pc rd, rn 17 bic \rd, \rn, #1 /* Clear thumb bit if present */ 18 sub \rd, \rd, #4 19.endm 20 21/* 22 * With the -pg option, GCC (4.4+) inserts a call to __gnu_mcount_nc into 23 * every function prologue. 24 * The caller of the instrumented function can be determined from the lr value 25 * stored on the top of the stack. The callee, i.e. the instrumented function 26 * itself, is determined from the current value of lr. Then we call: 27 * void __mcount_internal(void *frompc, void *selfpc); 28 */ 29FUNC __gnu_mcount_nc, : 30UNWIND( .cantunwind) 31 stmdb sp!, {r0-r3, lr} 32#if defined(CFG_TA_GPROF_SUPPORT) && !defined(__KERNEL__) 33 ldr r0, [sp, #20] /* lr of instrumented func */ 34 mcount_adj_pc r0, r0 35 mcount_adj_pc r1, lr /* instrumented func */ 36 bl __mcount_internal 37#endif 38#ifdef CFG_FTRACE_SUPPORT 39 /* Get instrumented function's pc value */ 40 ldr r0, [sp, #16] 41 mcount_adj_pc r0, r0 42 /* Get instrumented function's lr address pointer */ 43 sub r1, fp, #4 44 bl ftrace_enter 45#endif 46 ldmia sp!, {r0-r3, ip, lr} 47 bx ip 48END_FUNC __gnu_mcount_nc 49 50#ifdef CFG_FTRACE_SUPPORT 51FUNC __ftrace_return, : 52 /* save return value regs */ 53 stmdb sp!, {r0-r3} 54 55 /* get return address of parent func */ 56 bl ftrace_return 57 mov lr, r0 58 59 /* restore return value regs */ 60 ldmia sp!, {r0-r3} 61 bx lr 62END_FUNC __ftrace_return 63#endif 64 65#endif /* CFG_TA_GPROF_SUPPORT || CFG_FTRACE_SUPPORT */ 66