xref: /optee_os/lib/libutils/ext/arch/arm/mcount_a64.S (revision 181f84921804f9b8e2d24027eca1d916d6e15a44)
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