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