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