165 lines · 4.0 KB · Assembly
RawDownload
/* * 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_FTRACEENTRY(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_TRACERENTRY(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 */