Commit d65987a88dc8b182ef933edf93c23cf4233dd8d5

Authored by Michal Simek
1 parent f397c077e1

microblaze: ftrace: Pass the first calling instruction for dynamic ftrace

Selftest for dynamic ftrace requres to pass address of the first
calling instruction because hash function is calculated from it.

ftrace_update_ftrace_func setups pointer to function which is called
in _mcount function. trace_selftest is not aware about instruction
size (for microblaze 8 - imm and addik) and that's why we have
to pass in r5 address of imm not addik which is in r15.12

For more info look at ftrace_ops_list_func/ftrace.c.

Signed-off-by: Michal Simek <monstr@monstr.eu>

Showing 1 changed file with 1 additions and 1 deletions Inline Diff

arch/microblaze/kernel/mcount.S
1 /* 1 /*
2 * Low-level ftrace handling 2 * Low-level ftrace handling
3 * 3 *
4 * Copyright (C) 2009 Michal Simek <monstr@monstr.eu> 4 * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
5 * Copyright (C) 2009 PetaLogix 5 * Copyright (C) 2009 PetaLogix
6 * 6 *
7 * This file is subject to the terms and conditions of the GNU General 7 * This file is subject to the terms and conditions of the GNU General
8 * Public License. See the file COPYING in the main directory of this 8 * Public License. See the file COPYING in the main directory of this
9 * archive for more details. 9 * archive for more details.
10 */ 10 */
11 11
12 #include <linux/linkage.h> 12 #include <linux/linkage.h>
13 13
14 #define NOALIGN_ENTRY(name) .globl name; name: 14 #define NOALIGN_ENTRY(name) .globl name; name:
15 15
16 /* FIXME MS: I think that I don't need to save all regs */ 16 /* FIXME MS: I think that I don't need to save all regs */
17 #define SAVE_REGS \ 17 #define SAVE_REGS \
18 addik r1, r1, -120; \ 18 addik r1, r1, -120; \
19 swi r2, r1, 4; \ 19 swi r2, r1, 4; \
20 swi r3, r1, 8; \ 20 swi r3, r1, 8; \
21 swi r4, r1, 12; \ 21 swi r4, r1, 12; \
22 swi r5, r1, 116; \ 22 swi r5, r1, 116; \
23 swi r6, r1, 16; \ 23 swi r6, r1, 16; \
24 swi r7, r1, 20; \ 24 swi r7, r1, 20; \
25 swi r8, r1, 24; \ 25 swi r8, r1, 24; \
26 swi r9, r1, 28; \ 26 swi r9, r1, 28; \
27 swi r10, r1, 32; \ 27 swi r10, r1, 32; \
28 swi r11, r1, 36; \ 28 swi r11, r1, 36; \
29 swi r12, r1, 40; \ 29 swi r12, r1, 40; \
30 swi r13, r1, 44; \ 30 swi r13, r1, 44; \
31 swi r14, r1, 48; \ 31 swi r14, r1, 48; \
32 swi r16, r1, 52; \ 32 swi r16, r1, 52; \
33 swi r17, r1, 56; \ 33 swi r17, r1, 56; \
34 swi r18, r1, 60; \ 34 swi r18, r1, 60; \
35 swi r19, r1, 64; \ 35 swi r19, r1, 64; \
36 swi r20, r1, 68; \ 36 swi r20, r1, 68; \
37 swi r21, r1, 72; \ 37 swi r21, r1, 72; \
38 swi r22, r1, 76; \ 38 swi r22, r1, 76; \
39 swi r23, r1, 80; \ 39 swi r23, r1, 80; \
40 swi r24, r1, 84; \ 40 swi r24, r1, 84; \
41 swi r25, r1, 88; \ 41 swi r25, r1, 88; \
42 swi r26, r1, 92; \ 42 swi r26, r1, 92; \
43 swi r27, r1, 96; \ 43 swi r27, r1, 96; \
44 swi r28, r1, 100; \ 44 swi r28, r1, 100; \
45 swi r29, r1, 104; \ 45 swi r29, r1, 104; \
46 swi r30, r1, 108; \ 46 swi r30, r1, 108; \
47 swi r31, r1, 112; 47 swi r31, r1, 112;
48 48
49 #define RESTORE_REGS \ 49 #define RESTORE_REGS \
50 lwi r2, r1, 4; \ 50 lwi r2, r1, 4; \
51 lwi r3, r1, 8; \ 51 lwi r3, r1, 8; \
52 lwi r4, r1, 12; \ 52 lwi r4, r1, 12; \
53 lwi r5, r1, 116; \ 53 lwi r5, r1, 116; \
54 lwi r6, r1, 16; \ 54 lwi r6, r1, 16; \
55 lwi r7, r1, 20; \ 55 lwi r7, r1, 20; \
56 lwi r8, r1, 24; \ 56 lwi r8, r1, 24; \
57 lwi r9, r1, 28; \ 57 lwi r9, r1, 28; \
58 lwi r10, r1, 32; \ 58 lwi r10, r1, 32; \
59 lwi r11, r1, 36; \ 59 lwi r11, r1, 36; \
60 lwi r12, r1, 40; \ 60 lwi r12, r1, 40; \
61 lwi r13, r1, 44; \ 61 lwi r13, r1, 44; \
62 lwi r14, r1, 48; \ 62 lwi r14, r1, 48; \
63 lwi r16, r1, 52; \ 63 lwi r16, r1, 52; \
64 lwi r17, r1, 56; \ 64 lwi r17, r1, 56; \
65 lwi r18, r1, 60; \ 65 lwi r18, r1, 60; \
66 lwi r19, r1, 64; \ 66 lwi r19, r1, 64; \
67 lwi r20, r1, 68; \ 67 lwi r20, r1, 68; \
68 lwi r21, r1, 72; \ 68 lwi r21, r1, 72; \
69 lwi r22, r1, 76; \ 69 lwi r22, r1, 76; \
70 lwi r23, r1, 80; \ 70 lwi r23, r1, 80; \
71 lwi r24, r1, 84; \ 71 lwi r24, r1, 84; \
72 lwi r25, r1, 88; \ 72 lwi r25, r1, 88; \
73 lwi r26, r1, 92; \ 73 lwi r26, r1, 92; \
74 lwi r27, r1, 96; \ 74 lwi r27, r1, 96; \
75 lwi r28, r1, 100; \ 75 lwi r28, r1, 100; \
76 lwi r29, r1, 104; \ 76 lwi r29, r1, 104; \
77 lwi r30, r1, 108; \ 77 lwi r30, r1, 108; \
78 lwi r31, r1, 112; \ 78 lwi r31, r1, 112; \
79 addik r1, r1, 120; 79 addik r1, r1, 120;
80 80
81 ENTRY(ftrace_stub) 81 ENTRY(ftrace_stub)
82 rtsd r15, 8; 82 rtsd r15, 8;
83 nop; 83 nop;
84 84
85 ENTRY(_mcount) 85 ENTRY(_mcount)
86 #ifdef CONFIG_DYNAMIC_FTRACE 86 #ifdef CONFIG_DYNAMIC_FTRACE
87 ENTRY(ftrace_caller) 87 ENTRY(ftrace_caller)
88 /* MS: It is just barrier which is removed from C code */ 88 /* MS: It is just barrier which is removed from C code */
89 rtsd r15, 8 89 rtsd r15, 8
90 nop 90 nop
91 #endif /* CONFIG_DYNAMIC_FTRACE */ 91 #endif /* CONFIG_DYNAMIC_FTRACE */
92 SAVE_REGS 92 SAVE_REGS
93 swi r15, r1, 0; 93 swi r15, r1, 0;
94 /* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST begin of checking */ 94 /* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST begin of checking */
95 lwi r5, r0, function_trace_stop; 95 lwi r5, r0, function_trace_stop;
96 bneid r5, end; 96 bneid r5, end;
97 nop; 97 nop;
98 /* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST end of checking */ 98 /* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST end of checking */
99 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 99 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
100 #ifndef CONFIG_DYNAMIC_FTRACE 100 #ifndef CONFIG_DYNAMIC_FTRACE
101 lwi r5, r0, ftrace_graph_return; 101 lwi r5, r0, ftrace_graph_return;
102 addik r6, r0, ftrace_stub; /* asm implementation */ 102 addik r6, r0, ftrace_stub; /* asm implementation */
103 cmpu r5, r5, r6; /* ftrace_graph_return != ftrace_stub */ 103 cmpu r5, r5, r6; /* ftrace_graph_return != ftrace_stub */
104 beqid r5, end_graph_tracer; 104 beqid r5, end_graph_tracer;
105 nop; 105 nop;
106 106
107 lwi r6, r0, ftrace_graph_entry; 107 lwi r6, r0, ftrace_graph_entry;
108 addik r5, r0, ftrace_graph_entry_stub; /* implemented in C */ 108 addik r5, r0, ftrace_graph_entry_stub; /* implemented in C */
109 cmpu r5, r5, r6; /* ftrace_graph_entry != ftrace_graph_entry_stub */ 109 cmpu r5, r5, r6; /* ftrace_graph_entry != ftrace_graph_entry_stub */
110 beqid r5, end_graph_tracer; 110 beqid r5, end_graph_tracer;
111 nop; 111 nop;
112 #else /* CONFIG_DYNAMIC_FTRACE */ 112 #else /* CONFIG_DYNAMIC_FTRACE */
113 NOALIGN_ENTRY(ftrace_call_graph) 113 NOALIGN_ENTRY(ftrace_call_graph)
114 /* MS: jump over graph function - replaced from C code */ 114 /* MS: jump over graph function - replaced from C code */
115 bri end_graph_tracer 115 bri end_graph_tracer
116 #endif /* CONFIG_DYNAMIC_FTRACE */ 116 #endif /* CONFIG_DYNAMIC_FTRACE */
117 addik r5, r1, 120; /* MS: load parent addr */ 117 addik r5, r1, 120; /* MS: load parent addr */
118 addik r6, r15, 0; /* MS: load current function addr */ 118 addik r6, r15, 0; /* MS: load current function addr */
119 bralid r15, prepare_ftrace_return; 119 bralid r15, prepare_ftrace_return;
120 nop; 120 nop;
121 /* MS: graph was taken that's why - can jump over function trace */ 121 /* MS: graph was taken that's why - can jump over function trace */
122 brid end; 122 brid end;
123 nop; 123 nop;
124 end_graph_tracer: 124 end_graph_tracer:
125 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 125 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
126 #ifndef CONFIG_DYNAMIC_FTRACE 126 #ifndef CONFIG_DYNAMIC_FTRACE
127 /* MS: test function trace if is taken or not */ 127 /* MS: test function trace if is taken or not */
128 lwi r20, r0, ftrace_trace_function; 128 lwi r20, r0, ftrace_trace_function;
129 addik r6, r0, ftrace_stub; 129 addik r6, r0, ftrace_stub;
130 cmpu r5, r20, r6; /* ftrace_trace_function != ftrace_stub */ 130 cmpu r5, r20, r6; /* ftrace_trace_function != ftrace_stub */
131 beqid r5, end; /* MS: not taken -> jump over */ 131 beqid r5, end; /* MS: not taken -> jump over */
132 nop; 132 nop;
133 #else /* CONFIG_DYNAMIC_FTRACE */ 133 #else /* CONFIG_DYNAMIC_FTRACE */
134 NOALIGN_ENTRY(ftrace_call) 134 NOALIGN_ENTRY(ftrace_call)
135 /* instruction for setup imm FUNC_part1, addik r20, r0, FUNC_part2 */ 135 /* instruction for setup imm FUNC_part1, addik r20, r0, FUNC_part2 */
136 nop 136 nop
137 nop 137 nop
138 #endif /* CONFIG_DYNAMIC_FTRACE */ 138 #endif /* CONFIG_DYNAMIC_FTRACE */
139 /* static normal trace */ 139 /* static normal trace */
140 lwi r6, r1, 120; /* MS: load parent addr */ 140 lwi r6, r1, 120; /* MS: load parent addr */
141 addik r5, r15, 0; /* MS: load current function addr */ 141 addik r5, r15, -4; /* MS: load current function addr */
142 /* MS: here is dependency on previous code */ 142 /* MS: here is dependency on previous code */
143 brald r15, r20; /* MS: jump to ftrace handler */ 143 brald r15, r20; /* MS: jump to ftrace handler */
144 nop; 144 nop;
145 end: 145 end:
146 lwi r15, r1, 0; 146 lwi r15, r1, 0;
147 RESTORE_REGS 147 RESTORE_REGS
148 148
149 rtsd r15, 8; /* MS: jump back */ 149 rtsd r15, 8; /* MS: jump back */
150 nop; 150 nop;
151 151
152 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 152 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
153 ENTRY(return_to_handler) 153 ENTRY(return_to_handler)
154 nop; /* MS: just barrier for rtsd r15, 8 */ 154 nop; /* MS: just barrier for rtsd r15, 8 */
155 nop; 155 nop;
156 SAVE_REGS 156 SAVE_REGS
157 swi r15, r1, 0; 157 swi r15, r1, 0;
158 158
159 /* MS: find out returning address */ 159 /* MS: find out returning address */
160 bralid r15, ftrace_return_to_handler; 160 bralid r15, ftrace_return_to_handler;
161 nop; 161 nop;
162 162
163 /* MS: return value from ftrace_return_to_handler is my returning addr 163 /* MS: return value from ftrace_return_to_handler is my returning addr
164 * must be before restore regs because I have to restore r3 content */ 164 * must be before restore regs because I have to restore r3 content */
165 addik r15, r3, 0; 165 addik r15, r3, 0;
166 RESTORE_REGS 166 RESTORE_REGS
167 167
168 rtsd r15, 8; /* MS: jump back */ 168 rtsd r15, 8; /* MS: jump back */
169 nop; 169 nop;
170 #endif /* CONFIG_FUNCTION_TRACER */ 170 #endif /* CONFIG_FUNCTION_TRACER */
171 171