xref: /openbmc/linux/arch/loongarch/kernel/mcount.S (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1dbe3ba30SQing Zhang/* SPDX-License-Identifier: GPL-2.0 */
2dbe3ba30SQing Zhang/*
3dbe3ba30SQing Zhang * LoongArch specific _mcount support
4dbe3ba30SQing Zhang *
5dbe3ba30SQing Zhang * Copyright (C) 2022 Loongson Technology Corporation Limited
6dbe3ba30SQing Zhang */
7dbe3ba30SQing Zhang
8*55b46ff9SMasahiro Yamada#include <linux/export.h>
9dbe3ba30SQing Zhang#include <asm/ftrace.h>
10dbe3ba30SQing Zhang#include <asm/regdef.h>
11dbe3ba30SQing Zhang#include <asm/stackframe.h>
12dbe3ba30SQing Zhang
13dbe3ba30SQing Zhang	.text
14dbe3ba30SQing Zhang
15dbe3ba30SQing Zhang#define MCOUNT_S0_OFFSET	(0)
16dbe3ba30SQing Zhang#define MCOUNT_RA_OFFSET	(SZREG)
17dbe3ba30SQing Zhang#define MCOUNT_STACK_SIZE	(2 * SZREG)
18dbe3ba30SQing Zhang
19dbe3ba30SQing Zhang	.macro MCOUNT_SAVE_REGS
20dbe3ba30SQing Zhang	PTR_ADDI	sp, sp, -MCOUNT_STACK_SIZE
21dbe3ba30SQing Zhang	PTR_S		s0, sp, MCOUNT_S0_OFFSET
22dbe3ba30SQing Zhang	PTR_S		ra, sp, MCOUNT_RA_OFFSET
23dbe3ba30SQing Zhang	move		s0, a0
24dbe3ba30SQing Zhang	.endm
25dbe3ba30SQing Zhang
26dbe3ba30SQing Zhang	.macro MCOUNT_RESTORE_REGS
27dbe3ba30SQing Zhang	move		a0, s0
28dbe3ba30SQing Zhang	PTR_L		ra, sp, MCOUNT_RA_OFFSET
29dbe3ba30SQing Zhang	PTR_L		s0, sp, MCOUNT_S0_OFFSET
30dbe3ba30SQing Zhang	PTR_ADDI	sp, sp, MCOUNT_STACK_SIZE
31dbe3ba30SQing Zhang	.endm
32dbe3ba30SQing Zhang
33dbe3ba30SQing ZhangSYM_FUNC_START(_mcount)
34dbe3ba30SQing Zhang	la.pcrel	t1, ftrace_stub
35dbe3ba30SQing Zhang	la.pcrel	t2, ftrace_trace_function	/* Prepare t2 for (1) */
36dbe3ba30SQing Zhang	PTR_L		t2, t2, 0
37dbe3ba30SQing Zhang	beq		t1, t2, fgraph_trace
38dbe3ba30SQing Zhang
39dbe3ba30SQing Zhang	MCOUNT_SAVE_REGS
40dbe3ba30SQing Zhang
41dbe3ba30SQing Zhang	move		a0, ra				/* arg0: self return address */
42dbe3ba30SQing Zhang	move		a1, s0				/* arg1: parent's return address */
43dbe3ba30SQing Zhang	jirl		ra, t2, 0			/* (1) call *ftrace_trace_function */
44dbe3ba30SQing Zhang
45dbe3ba30SQing Zhang	MCOUNT_RESTORE_REGS
46dbe3ba30SQing Zhang
47dbe3ba30SQing Zhangfgraph_trace:
48dbe3ba30SQing Zhang#ifdef CONFIG_FUNCTION_GRAPH_TRACER
49dbe3ba30SQing Zhang	la.pcrel	t1, ftrace_stub
50dbe3ba30SQing Zhang	la.pcrel	t3, ftrace_graph_return
51dbe3ba30SQing Zhang	PTR_L		t3, t3, 0
52dbe3ba30SQing Zhang	bne		t1, t3, ftrace_graph_caller
53dbe3ba30SQing Zhang	la.pcrel	t1, ftrace_graph_entry_stub
54dbe3ba30SQing Zhang	la.pcrel	t3, ftrace_graph_entry
55dbe3ba30SQing Zhang	PTR_L		t3, t3, 0
56dbe3ba30SQing Zhang	bne		t1, t3, ftrace_graph_caller
57dbe3ba30SQing Zhang#endif
58dbe3ba30SQing Zhang
59dbe3ba30SQing ZhangSYM_INNER_LABEL(ftrace_stub, SYM_L_GLOBAL)
60dbe3ba30SQing Zhang	jr		ra
61dbe3ba30SQing Zhang#ifdef CONFIG_FUNCTION_GRAPH_TRACER
62dbe3ba30SQing ZhangSYM_INNER_LABEL(ftrace_graph_func, SYM_L_GLOBAL)
63dbe3ba30SQing Zhang	bl		ftrace_stub
64dbe3ba30SQing Zhang#endif
65dbe3ba30SQing ZhangSYM_FUNC_END(_mcount)
66dbe3ba30SQing ZhangEXPORT_SYMBOL(_mcount)
67dbe3ba30SQing Zhang
68dbe3ba30SQing Zhang#ifdef CONFIG_FUNCTION_GRAPH_TRACER
69dbe3ba30SQing ZhangSYM_FUNC_START(ftrace_graph_caller)
70dbe3ba30SQing Zhang	MCOUNT_SAVE_REGS
71dbe3ba30SQing Zhang
72dbe3ba30SQing Zhang	PTR_ADDI	a0, ra, -4			/* arg0: Callsite self return addr */
73dbe3ba30SQing Zhang	PTR_ADDI	a1, sp, MCOUNT_STACK_SIZE	/* arg1: Callsite sp */
74dbe3ba30SQing Zhang	move		a2, s0				/* arg2: Callsite parent ra */
75dbe3ba30SQing Zhang	bl		prepare_ftrace_return
76dbe3ba30SQing Zhang
77dbe3ba30SQing Zhang	MCOUNT_RESTORE_REGS
78dbe3ba30SQing Zhang	jr		ra
79dbe3ba30SQing ZhangSYM_FUNC_END(ftrace_graph_caller)
80dbe3ba30SQing Zhang
81dbe3ba30SQing ZhangSYM_FUNC_START(return_to_handler)
825779e3c0SDonglin Peng	PTR_ADDI	sp, sp, -FGRET_REGS_SIZE
835779e3c0SDonglin Peng	PTR_S		a0, sp, FGRET_REGS_A0
845779e3c0SDonglin Peng	PTR_S		a1, sp, FGRET_REGS_A1
855779e3c0SDonglin Peng	PTR_S		zero, sp, FGRET_REGS_FP
86dbe3ba30SQing Zhang
875779e3c0SDonglin Peng	move		a0, sp
88dbe3ba30SQing Zhang	bl		ftrace_return_to_handler
89dbe3ba30SQing Zhang
90dbe3ba30SQing Zhang	/* Restore the real parent address: a0 -> ra */
91dbe3ba30SQing Zhang	move		ra, a0
92dbe3ba30SQing Zhang
935779e3c0SDonglin Peng	PTR_L		a0, sp, FGRET_REGS_A0
945779e3c0SDonglin Peng	PTR_L		a1, sp, FGRET_REGS_A1
955779e3c0SDonglin Peng	PTR_ADDI	sp, sp, FGRET_REGS_SIZE
96dbe3ba30SQing Zhang	jr		ra
97dbe3ba30SQing ZhangSYM_FUNC_END(return_to_handler)
98dbe3ba30SQing Zhang#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
99