/*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/* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST begin of checking */94lwi r5, r0, function_trace_stop;95bneid r5, end;96nop;97/* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST end of checking */98#ifdef CONFIG_FUNCTION_GRAPH_TRACER99#ifndef CONFIG_DYNAMIC_FTRACE100lwi r5, r0, ftrace_graph_return;101addik r6, r0, ftrace_stub; /* asm implementation */102cmpu r5, r5, r6; /* ftrace_graph_return != ftrace_stub */103beqid r5, end_graph_tracer;104nop;105106lwi r6, r0, ftrace_graph_entry;107addik r5, r0, ftrace_graph_entry_stub; /* implemented in C */108cmpu r5, r5, r6; /* ftrace_graph_entry != ftrace_graph_entry_stub */109beqid r5, end_graph_tracer;110nop;111#else /* CONFIG_DYNAMIC_FTRACE */112NOALIGN_ENTRY(ftrace_call_graph)113/* MS: jump over graph function - replaced from C code */114bri end_graph_tracer115#endif /* CONFIG_DYNAMIC_FTRACE */116addik r5, r1, 120; /* MS: load parent addr */117addik r6, r15, 0; /* MS: load current function addr */118bralid r15, prepare_ftrace_return;119nop;120/* MS: graph was taken that's why - can jump over function trace */121brid end;122nop;123end_graph_tracer:124#endif /* CONFIG_FUNCTION_GRAPH_TRACER */125#ifndef CONFIG_DYNAMIC_FTRACE126/* MS: test function trace if is taken or not */127lwi r20, r0, ftrace_trace_function;128addik r6, r0, ftrace_stub;129cmpu r5, r20, r6; /* ftrace_trace_function != ftrace_stub */130beqid r5, end; /* MS: not taken -> jump over */131nop;132#else /* CONFIG_DYNAMIC_FTRACE */133NOALIGN_ENTRY(ftrace_call)134/* instruction for setup imm FUNC_part1, addik r20, r0, FUNC_part2 */135nop136nop137#endif /* CONFIG_DYNAMIC_FTRACE */138/* static normal trace */139lwi r6, r1, 120; /* MS: load parent addr */140addik r5, r15, 0; /* MS: load current function addr */141/* MS: here is dependency on previous code */142brald r15, r20; /* MS: jump to ftrace handler */143nop;144end:145lwi r15, r1, 0;146RESTORE_REGS147148rtsd r15, 8; /* MS: jump back */149nop;150151#ifdef CONFIG_FUNCTION_GRAPH_TRACER152ENTRY(return_to_handler)153nop; /* MS: just barrier for rtsd r15, 8 */154nop;155SAVE_REGS156swi r15, r1, 0;157158/* MS: find out returning address */159bralid r15, ftrace_return_to_handler;160nop;161162/* MS: return value from ftrace_return_to_handler is my returning addr163* must be before restore regs because I have to restore r3 content */164addik r15, r3, 0;165RESTORE_REGS166167rtsd r15, 8; /* MS: jump back */168nop;169#endif /* CONFIG_FUNCTION_TRACER */170171172