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