14 #include <asm/cacheflush.h>
17 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
22 void prepare_ftrace_return(
unsigned long *parent,
unsigned long self_addr)
27 unsigned long return_hooker = (
unsigned long)
38 asm volatile(
" 1: lwi %0, %2, 0; \
42 .section .fixup, \"ax\"; \
46 .section __ex_table,\"a\"; \
50 :
"=&r" (old),
"=r" (faulted)
51 :
"r" (parent),
"r" (return_hooker)
69 trace.func = self_addr;
71 if (!ftrace_graph_entry(&
trace)) {
78 #ifdef CONFIG_DYNAMIC_FTRACE
80 static int ftrace_modify_code(
unsigned long addr,
unsigned int value)
84 __asm__ __volatile__(
" 1: swi %2, %1, 0; \
87 .section .fixup, \"ax\"; \
91 .section __ex_table,\"a\"; \
95 :
"r" (addr),
"r" (value)
107 #define MICROBLAZE_NOP 0x80000000
108 #define MICROBLAZE_BRI 0xb800000C
110 static unsigned int recorded;
111 static unsigned int imm;
114 #undef USE_FTRACE_NOP
116 #ifdef USE_FTRACE_NOP
117 static unsigned int bralid;
121 struct dyn_ftrace *rec,
unsigned long addr)
143 imm = *(
unsigned int *)rec->ip;
144 pr_debug(
"%s: imm:0x%x\n", __func__, imm);
145 #ifdef USE_FTRACE_NOP
146 bralid = *(
unsigned int *)(rec->ip + 4);
147 pr_debug(
"%s: bralid 0x%x\n", __func__, bralid);
151 #ifdef USE_FTRACE_NOP
152 ret = ftrace_modify_code(rec->ip, MICROBLAZE_NOP);
153 ret += ftrace_modify_code(rec->ip + 4, MICROBLAZE_NOP);
155 ret = ftrace_modify_code(rec->ip, MICROBLAZE_BRI);
164 pr_debug(
"%s: addr:0x%x, rec->ip: 0x%x, imm:0x%x\n",
165 __func__, (
unsigned int)addr, (
unsigned int)rec->ip, imm);
166 ret = ftrace_modify_code(rec->ip, imm);
167 #ifdef USE_FTRACE_NOP
168 pr_debug(
"%s: bralid:0x%x\n", __func__, bralid);
169 ret += ftrace_modify_code(rec->ip + 4, bralid);
177 *(
unsigned long *)data = 0;
184 unsigned long ip = (
unsigned long)(&ftrace_call);
185 unsigned int upper = (
unsigned int)func;
186 unsigned int lower = (
unsigned int)func;
190 upper = 0xb0000000 + (upper >> 16);
191 lower = 0x32800000 + (lower & 0xFFFF);
193 pr_debug(
"%s: func=0x%x, ip=0x%x, upper=0x%x, lower=0x%x\n",
194 __func__, (
unsigned int)func, (
unsigned int)ip, upper, lower);
197 ret = ftrace_modify_code(ip, upper);
198 ret += ftrace_modify_code(ip + 4, lower);
201 ret += ftrace_modify_code((
unsigned long)&ftrace_caller,
207 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
208 unsigned int old_jump;
210 int ftrace_enable_ftrace_graph_caller(
void)
213 unsigned long ip = (
unsigned long)(&ftrace_call_graph);
215 old_jump = *(
unsigned int *)ip;
216 ret = ftrace_modify_code(ip, MICROBLAZE_NOP);
218 pr_debug(
"%s: Replace instruction: 0x%x\n", __func__, old_jump);
222 int ftrace_disable_ftrace_graph_caller(
void)
225 unsigned long ip = (
unsigned long)(&ftrace_call_graph);
227 ret = ftrace_modify_code(ip, old_jump);