microblaze: Stack trace support
authorMichal Simek <monstr@monstr.eu>
Tue, 10 Nov 2009 14:57:01 +0000 (15:57 +0100)
committerMichal Simek <monstr@monstr.eu>
Mon, 14 Dec 2009 07:40:09 +0000 (08:40 +0100)
This is working implemetation but the problem is that
Microblaze misses frame pointer that's why is there
big loop which trace and show all addresses which are in text.
It shows addresses which are in registers, etc.

This is problem and this is the reason why all Microblaze
traces are wrong. There is an option to do hacks and trace
the kernel code but this is too complicated.

Signed-off-by: Michal Simek <monstr@monstr.eu>
arch/microblaze/Kconfig
arch/microblaze/kernel/Makefile
arch/microblaze/kernel/stacktrace.c [new file with mode: 0644]

index bbd8327f18901d80d5eefe3e27015f65993a099f..8e1c4f7d3e6ec45e201c1ad74d123b1c0a6e8516 100644 (file)
@@ -57,6 +57,9 @@ config GENERIC_GPIO
 config GENERIC_CSUM
        def_bool y
 
+config STACKTRACE_SUPPORT
+       def_bool y
+
 config PCI
        def_bool n
 
index fddd0c403d405d9cda203d001b2cf7e7da5ed060..c465a5c4669c1a0a5af10ce1371f54e6e674ee27 100644 (file)
@@ -16,5 +16,6 @@ obj-$(CONFIG_SELFMOD)         += selfmod.o
 obj-$(CONFIG_HEART_BEAT)       += heartbeat.o
 obj-$(CONFIG_MODULES)          += microblaze_ksyms.o module.o
 obj-$(CONFIG_MMU)              += misc.o
+obj-$(CONFIG_STACKTRACE)       += stacktrace.o
 
 obj-y  += entry$(MMU).o
diff --git a/arch/microblaze/kernel/stacktrace.c b/arch/microblaze/kernel/stacktrace.c
new file mode 100644 (file)
index 0000000..123692f
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Stack trace support for Microblaze.
+ *
+ * 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/sched.h>
+#include <linux/stacktrace.h>
+#include <linux/thread_info.h>
+#include <linux/ptrace.h>
+#include <linux/module.h>
+
+/* FIXME initial support */
+void save_stack_trace(struct stack_trace *trace)
+{
+       unsigned long *sp;
+       unsigned long addr;
+       asm("addik %0, r1, 0" : "=r" (sp));
+
+       while (!kstack_end(sp)) {
+               addr = *sp++;
+               if (__kernel_text_address(addr)) {
+                       if (trace->skip > 0)
+                               trace->skip--;
+                       else
+                               trace->entries[trace->nr_entries++] = addr;
+
+                       if (trace->nr_entries >= trace->max_entries)
+                               break;
+               }
+       }
+}
+EXPORT_SYMBOL_GPL(save_stack_trace);
+
+void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
+{
+       unsigned int *sp;
+       unsigned long addr;
+
+       struct thread_info *ti = task_thread_info(tsk);
+
+       if (tsk == current)
+               asm("addik %0, r1, 0" : "=r" (sp));
+       else
+               sp = (unsigned int *)ti->cpu_context.r1;
+
+       while (!kstack_end(sp)) {
+               addr = *sp++;
+               if (__kernel_text_address(addr)) {
+                       if (trace->skip > 0)
+                               trace->skip--;
+                       else
+                               trace->entries[trace->nr_entries++] = addr;
+
+                       if (trace->nr_entries >= trace->max_entries)
+                               break;
+               }
+       }
+}
+EXPORT_SYMBOL_GPL(save_stack_trace_tsk);