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