1*e3dddf72SSumit Garg/* SPDX-License-Identifier: BSD-2-Clause */ 2*e3dddf72SSumit Garg/* 3*e3dddf72SSumit Garg * Copyright (c) 2016, Linaro Limited 4*e3dddf72SSumit Garg */ 5*e3dddf72SSumit Garg 6*e3dddf72SSumit Garg#include <asm.S> 7*e3dddf72SSumit Garg 8*e3dddf72SSumit Garg#if defined(CFG_TA_GPROF_SUPPORT) || defined(CFG_TA_FTRACE_SUPPORT) 9*e3dddf72SSumit Garg 10*e3dddf72SSumit Garg/* 11*e3dddf72SSumit Garg * Convert return address to call site address by subtracting the size of one 12*e3dddf72SSumit Garg * instruction. 13*e3dddf72SSumit Garg */ 14*e3dddf72SSumit Garg.macro adjust_pc rd, rn 15*e3dddf72SSumit Garg sub \rd, \rn, #4 16*e3dddf72SSumit Garg.endm 17*e3dddf72SSumit Garg 18*e3dddf72SSumit Garg/* Get instrumented function's pc value */ 19*e3dddf72SSumit Garg.macro get_pc reg 20*e3dddf72SSumit Garg ldr \reg, [x29, #8] 21*e3dddf72SSumit Garg sub \reg, \reg, #4 22*e3dddf72SSumit Garg.endm 23*e3dddf72SSumit Garg 24*e3dddf72SSumit Garg/* Get instrumented function's lr address pointer */ 25*e3dddf72SSumit Garg.macro get_lr_addr reg 26*e3dddf72SSumit Garg ldr \reg, [x29] 27*e3dddf72SSumit Garg add \reg, \reg, #8 28*e3dddf72SSumit Garg.endm 29*e3dddf72SSumit Garg 30*e3dddf72SSumit Garg/* 31*e3dddf72SSumit Garg * void _mcount(void *return_address) 32*e3dddf72SSumit Garg * @return_address: return address to instrumented function 33*e3dddf72SSumit Garg * 34*e3dddf72SSumit Garg * With the -pg option, the compiler inserts a call to _mcount into 35*e3dddf72SSumit Garg * every function prologue. 36*e3dddf72SSumit Garg * x0 contains the value of lr (x30) before the call, that is the return 37*e3dddf72SSumit Garg * address to the caller of the instrumented function. The callee, i.e. the 38*e3dddf72SSumit Garg * instrumented function itself, is determined from the current value of x30. 39*e3dddf72SSumit Garg * Then we call: 40*e3dddf72SSumit Garg * void __mcount_internal(void *frompc, void *selfpc); 41*e3dddf72SSumit Garg */ 42*e3dddf72SSumit GargFUNC _mcount, : 43*e3dddf72SSumit Garg stp x29, x30, [sp, #-16]! 44*e3dddf72SSumit Garg mov x29, sp 45*e3dddf72SSumit Garg#ifdef CFG_TA_GPROF_SUPPORT 46*e3dddf72SSumit Garg adjust_pc x0, x0 47*e3dddf72SSumit Garg adjust_pc x1, x30 48*e3dddf72SSumit Garg bl __mcount_internal 49*e3dddf72SSumit Garg#endif 50*e3dddf72SSumit Garg#ifdef CFG_TA_FTRACE_SUPPORT 51*e3dddf72SSumit Garg get_pc x0 52*e3dddf72SSumit Garg get_lr_addr x1 53*e3dddf72SSumit Garg bl ftrace_enter 54*e3dddf72SSumit Garg#endif 55*e3dddf72SSumit Garg ldp x29, x30, [sp], #16 56*e3dddf72SSumit Garg ret 57*e3dddf72SSumit GargEND_FUNC _mcount 58*e3dddf72SSumit Garg 59*e3dddf72SSumit Garg#ifdef CFG_TA_FTRACE_SUPPORT 60*e3dddf72SSumit GargFUNC __ftrace_return, : 61*e3dddf72SSumit Garg /* Save return value regs */ 62*e3dddf72SSumit Garg sub sp, sp, #64 63*e3dddf72SSumit Garg stp x0, x1, [sp] 64*e3dddf72SSumit Garg stp x2, x3, [sp, #16] 65*e3dddf72SSumit Garg stp x4, x5, [sp, #32] 66*e3dddf72SSumit Garg stp x6, x7, [sp, #48] 67*e3dddf72SSumit Garg 68*e3dddf72SSumit Garg /* Get return address of parent func */ 69*e3dddf72SSumit Garg bl ftrace_return 70*e3dddf72SSumit Garg mov x30, x0 71*e3dddf72SSumit Garg 72*e3dddf72SSumit Garg /* Restore return value regs */ 73*e3dddf72SSumit Garg ldp x0, x1, [sp] 74*e3dddf72SSumit Garg ldp x2, x3, [sp, #16] 75*e3dddf72SSumit Garg ldp x4, x5, [sp, #32] 76*e3dddf72SSumit Garg ldp x6, x7, [sp, #48] 77*e3dddf72SSumit Garg add sp, sp, #64 78*e3dddf72SSumit Garg 79*e3dddf72SSumit Garg ret 80*e3dddf72SSumit GargEND_FUNC __ftrace_return 81*e3dddf72SSumit Garg#endif 82*e3dddf72SSumit Garg 83*e3dddf72SSumit Garg#endif /* CFG_TA_GPROF_SUPPORT || CFG_TA_FTRACE_SUPPORT */ 84