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