summary refs log tree commit diff
path: root/arch/sh/lib
diff options
context:
space:
mode:
authorMatt Fleming <mjf@gentoo.org>2008-11-12 20:11:47 +0900
committerPaul Mundt <lethal@linux-sh.org>2008-12-22 18:42:52 +0900
commitfad57feba77d2e5b183e068cb6b90693e4567b40 (patch)
tree478788d5a05a30f638540d345e9d09c5733687da /arch/sh/lib
parentef6aff6884408db95ceb0f678f583536e0bd48f8 (diff)
downloadlinux-fad57feba77d2e5b183e068cb6b90693e4567b40.tar.gz
sh: dynamic ftrace support.
First cut at dynamic ftrace support.

Signed-off-by: Matt Fleming <mjf@gentoo.org>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/lib')
-rw-r--r--arch/sh/lib/Makefile1
-rw-r--r--arch/sh/lib/mcount.S90
2 files changed, 91 insertions, 0 deletions
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index 8596cc78e18d..596421821d08 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -11,6 +11,7 @@ memcpy-y			:= memcpy.o
 memcpy-$(CONFIG_CPU_SH4)	:= memcpy-sh4.o
 
 lib-$(CONFIG_MMU)		+= copy_page.o clear_page.o
+lib-$(CONFIG_FUNCTION_TRACER)	+= mcount.o
 lib-y				+= $(memcpy-y)
 
 EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S
new file mode 100644
index 000000000000..110fbfe1831f
--- /dev/null
+++ b/arch/sh/lib/mcount.S
@@ -0,0 +1,90 @@
+/*
+ * arch/sh/lib/mcount.S
+ *
+ *  Copyright (C) 2008  Paul Mundt
+ *  Copyright (C) 2008  Matt Fleming
+ *
+ * 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 <asm/ftrace.h>
+
+#define MCOUNT_ENTER()		\
+	mov.l	r4, @-r15;	\
+	mov.l	r5, @-r15;	\
+	mov.l	r6, @-r15;	\
+	mov.l	r7, @-r15;	\
+	sts.l	pr, @-r15;	\
+				\
+	mov.l	@(20,r15),r4;	\
+	sts	pr, r5
+
+#define MCOUNT_LEAVE()		\
+	lds.l	@r15+, pr;	\
+	mov.l	@r15+, r7;	\
+	mov.l	@r15+, r6;	\
+	mov.l	@r15+, r5;	\
+	rts;			\
+	 mov.l	@r15+, r4
+
+	.align 2
+	.globl	_mcount
+	.type	_mcount,@function
+	.globl	mcount
+	.type	mcount,@function
+_mcount:
+mcount:
+	MCOUNT_ENTER()
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+	.globl	mcount_call
+mcount_call:
+	mov.l	.Lftrace_stub, r6
+#else
+	mov.l	.Lftrace_trace_function, r6
+	mov.l	ftrace_stub, r7
+	cmp/eq	r6, r7
+	bt	skip_trace
+	mov.l	@r6, r6
+#endif
+
+	jsr	@r6
+	 nop
+
+skip_trace:
+	MCOUNT_LEAVE()
+
+	.align 2
+.Lftrace_trace_function:
+	.long	ftrace_trace_function
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+	.globl ftrace_caller
+ftrace_caller:
+	MCOUNT_ENTER()
+
+	.globl ftrace_call
+ftrace_call:
+	mov.l	.Lftrace_stub, r6
+	jsr	@r6
+	 nop
+
+	MCOUNT_LEAVE()
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+/*
+ * NOTE: From here on the locations of the .Lftrace_stub label and
+ * ftrace_stub itself are fixed. Adding additional data here will skew
+ * the displacement for the memory table and break the block replacement.
+ * Place new labels either after the ftrace_stub body, or before
+ * ftrace_caller. You have been warned.
+ */
+	.align 2
+.Lftrace_stub:
+	.long	ftrace_stub
+
+	.globl	ftrace_stub
+ftrace_stub:
+	rts
+	 nop