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, : 28UNWIND( .cantunwind) 29 stmdb sp!, {r0-r3, lr} 30#if defined(CFG_TA_GPROF_SUPPORT) && !defined(__KERNEL__) 31 ldr r0, [sp, #20] /* lr of instrumented func */ 32 mcount_adj_pc r0, r0 33 mcount_adj_pc r1, lr /* instrumented func */ 34 bl __mcount_internal 35#endif 36#ifdef CFG_FTRACE_SUPPORT 37 /* Get instrumented function's pc value */ 38 ldr r0, [sp, #16] 39 mcount_adj_pc r0, r0 40 /* Get instrumented function's lr address pointer */ 41 sub r1, fp, #4 42 bl ftrace_enter 43#endif 44 ldmia sp!, {r0-r3, ip, lr} 45 bx ip 46END_FUNC __gnu_mcount_nc 47 48#ifdef CFG_FTRACE_SUPPORT 49FUNC __ftrace_return, : 50 /* save return value regs */ 51 stmdb sp!, {r0-r3} 52 53 /* get return address of parent func */ 54 bl ftrace_return 55 mov lr, r0 56 57 /* restore return value regs */ 58 ldmia sp!, {r0-r3} 59 bx lr 60END_FUNC __ftrace_return 61#endif 62 63#endif /* CFG_TA_GPROF_SUPPORT || CFG_FTRACE_SUPPORT */ 64