summaryrefslogtreecommitdiffstats
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)
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 8596cc78e18..596421821d0 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 00000000000..110fbfe1831
--- /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