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