Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/riscv/kernel/mcount.S
26424 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
/* Copyright (C) 2017 Andes Technology Corporation */
3
4
#include <linux/init.h>
5
#include <linux/linkage.h>
6
#include <linux/cfi_types.h>
7
#include <linux/export.h>
8
#include <asm/asm.h>
9
#include <asm/csr.h>
10
#include <asm/unistd.h>
11
#include <asm/thread_info.h>
12
#include <asm/asm-offsets.h>
13
#include <asm/ftrace.h>
14
15
.text
16
17
.macro SAVE_ABI_STATE
18
addi sp, sp, -16
19
REG_S s0, 0*SZREG(sp)
20
REG_S ra, 1*SZREG(sp)
21
addi s0, sp, 16
22
.endm
23
24
/*
25
* The call to ftrace_return_to_handler would overwrite the return
26
* register if a0 was not saved.
27
*/
28
.macro SAVE_RET_ABI_STATE
29
addi sp, sp, -FREGS_SIZE_ON_STACK
30
REG_S ra, FREGS_RA(sp)
31
REG_S s0, FREGS_S0(sp)
32
REG_S a0, FREGS_A0(sp)
33
REG_S a1, FREGS_A1(sp)
34
addi s0, sp, FREGS_SIZE_ON_STACK
35
.endm
36
37
.macro RESTORE_ABI_STATE
38
REG_L ra, 1*SZREG(sp)
39
REG_L s0, 0*SZREG(sp)
40
addi sp, sp, 16
41
.endm
42
43
.macro RESTORE_RET_ABI_STATE
44
REG_L ra, FREGS_RA(sp)
45
REG_L s0, FREGS_S0(sp)
46
REG_L a0, FREGS_A0(sp)
47
REG_L a1, FREGS_A1(sp)
48
addi sp, sp, FREGS_SIZE_ON_STACK
49
.endm
50
51
SYM_TYPED_FUNC_START(ftrace_stub)
52
#ifdef CONFIG_DYNAMIC_FTRACE
53
.global _mcount
54
.set _mcount, ftrace_stub
55
#endif
56
ret
57
SYM_FUNC_END(ftrace_stub)
58
59
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
60
SYM_TYPED_FUNC_START(ftrace_stub_graph)
61
ret
62
SYM_FUNC_END(ftrace_stub_graph)
63
64
SYM_FUNC_START(return_to_handler)
65
/*
66
* On implementing the frame point test, the ideal way is to compare the
67
* s0 (frame pointer, if enabled) on entry and the sp (stack pointer) on return.
68
* However, the psABI of variable-length-argument functions does not allow this.
69
*
70
* So alternatively we check the *old* frame pointer position, that is, the
71
* value stored in -16(s0) on entry, and the s0 on return.
72
*/
73
SAVE_RET_ABI_STATE
74
mv a0, sp
75
call ftrace_return_to_handler
76
mv a2, a0
77
RESTORE_RET_ABI_STATE
78
jalr a2
79
SYM_FUNC_END(return_to_handler)
80
#endif
81
82
#ifndef CONFIG_DYNAMIC_FTRACE
83
SYM_FUNC_START(_mcount)
84
la t4, ftrace_stub
85
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
86
la t0, ftrace_graph_return
87
REG_L t1, 0(t0)
88
bne t1, t4, .Ldo_ftrace_graph_caller
89
90
la t3, ftrace_graph_entry
91
REG_L t2, 0(t3)
92
la t6, ftrace_graph_entry_stub
93
bne t2, t6, .Ldo_ftrace_graph_caller
94
#endif
95
la t3, ftrace_trace_function
96
REG_L t5, 0(t3)
97
bne t5, t4, .Ldo_trace
98
ret
99
100
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
101
/*
102
* A pseudo representation for the function graph tracer:
103
* prepare_to_return(&ra_to_caller_of_caller, ra_to_caller)
104
*/
105
.Ldo_ftrace_graph_caller:
106
addi a0, s0, -SZREG
107
mv a1, ra
108
#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
109
REG_L a2, -2*SZREG(s0)
110
#endif
111
SAVE_ABI_STATE
112
call prepare_ftrace_return
113
RESTORE_ABI_STATE
114
ret
115
#endif
116
117
/*
118
* A pseudo representation for the function tracer:
119
* (*ftrace_trace_function)(ra_to_caller, ra_to_caller_of_caller)
120
*/
121
.Ldo_trace:
122
REG_L a1, -SZREG(s0)
123
mv a0, ra
124
125
SAVE_ABI_STATE
126
jalr t5
127
RESTORE_ABI_STATE
128
ret
129
SYM_FUNC_END(_mcount)
130
#endif
131
EXPORT_SYMBOL(_mcount)
132
133