sh: stacktrace/lockdep/irqflags tracing support.

Wire up all of the essentials for lockdep..

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 50d54c2..99c7e52 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -21,3 +21,4 @@
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
 obj-$(CONFIG_APM)		+= apm.o
 obj-$(CONFIG_PM)		+= pm.o
+obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S
index 298d919..34d51b3 100644
--- a/arch/sh/kernel/cpu/sh2/entry.S
+++ b/arch/sh/kernel/cpu/sh2/entry.S
@@ -184,6 +184,11 @@
 	add	r15,r8
 	mov.l	r9,@r8
 	mov	r9,r8
+#ifdef CONFIG_TRACE_IRQFLAGS
+	mov.l	5f, r9
+	jsr	@r9
+	 nop
+#endif
 	sti
 	bra	system_call
 	 nop
@@ -193,6 +198,9 @@
 2:	.long	break_point_trap_software
 3:	.long	NR_syscalls
 4:	.long	sys_call_table
+#ifdef CONFIG_TRACE_IRQFLAGS
+5:	.long	trace_hardirqs_on
+#endif
 
 #if defined(CONFIG_SH_STANDARD_BIOS)
 	/* Unwind the stack and jmp to the debug entry */
@@ -255,6 +263,11 @@
 
 restore_all:
 	cli
+#ifdef CONFIG_TRACE_IRQFLAGS
+	mov.l	3f, r0
+	jsr	@r0
+	 nop
+#endif
 	mov	r15,r0
 	mov.l	$cpu_mode,r2
 	mov	#OFF_SR,r3
@@ -307,6 +320,9 @@
 	.long	__current_thread_info
 $cpu_mode:	
 	.long	__cpu_mode
+#ifdef CONFIG_TRACE_IRQFLAGS
+3:	.long	trace_hardirqs_off
+#endif
 		
 ! common exception handler
 #include "../../entry-common.S"
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 7ba3dcb..8c0dc27 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -140,7 +140,7 @@
 	mov.l	1f, r0
  	mov.l	@r0, r6		! address
 	mov.l	3f, r0
-	sti
+
 	jmp	@r0
  	 mov	r15, r4		! regs
 
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 8f96d21..29136a3 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -100,6 +100,11 @@
 	.align	2
 ENTRY(exception_error)
 	!
+#ifdef CONFIG_TRACE_IRQFLAGS
+	mov.l	3f, r0
+	jsr	@r0
+	 nop
+#endif
 	sti
 	mov.l	2f, r0
 	jmp	@r0
@@ -109,10 +114,18 @@
 	.align	2
 1:	.long	break_point_trap_software
 2:	.long	do_exception_error
+#ifdef CONFIG_TRACE_IRQFLAGS
+3:	.long	trace_hardirqs_on
+#endif
 
 	.align	2
 ret_from_exception:
 	preempt_stop()
+#ifdef CONFIG_TRACE_IRQFLAGS
+	mov.l	4f, r0
+	jsr	@r0
+	 nop
+#endif
 ENTRY(ret_from_irq)
 	!
 	mov	#OFF_SR, r0
@@ -143,6 +156,11 @@
 	mov.l	1f, r0
 	mov.l	r0, @(TI_PRE_COUNT,r8)
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+	mov.l	3f, r0
+	jsr	@r0
+	 nop
+#endif
 	sti
 	mov.l	2f, r0
 	jsr	@r0
@@ -150,9 +168,15 @@
 	mov	#0, r0
 	mov.l	r0, @(TI_PRE_COUNT,r8)
 	cli
+#ifdef CONFIG_TRACE_IRQFLAGS
+	mov.l	4f, r0
+	jsr	@r0
+	 nop
+#endif
 
 	bra	need_resched
 	 nop
+
 noresched:
 	bra	__restore_all
 	 nop
@@ -160,11 +184,20 @@
 	.align 2
 1:	.long	PREEMPT_ACTIVE
 2:	.long	schedule
+#ifdef CONFIG_TRACE_IRQFLAGS
+3:	.long	trace_hardirqs_on
+4:	.long	trace_hardirqs_off
+#endif
 #endif
 
 ENTRY(resume_userspace)
 	! r8: current_thread_info
 	cli
+#ifdef CONFIG_TRACE_IRQFLAGS
+	mov.l	5f, r0
+	jsr	@r0
+	 nop
+#endif
 	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
 	tst	#_TIF_WORK_MASK, r0
 	bt/s	__restore_all
@@ -210,6 +243,11 @@
 	jsr	@r1				! schedule
 	 nop
 	cli
+#ifdef CONFIG_TRACE_IRQFLAGS
+	mov.l	5f, r0
+	jsr	@r0
+	 nop
+#endif
 	!
 	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
 	tst	#_TIF_WORK_MASK, r0
@@ -221,6 +259,10 @@
 1:	.long	schedule
 2:	.long	do_notify_resume
 3:	.long	restore_all
+#ifdef CONFIG_TRACE_IRQFLAGS
+4:	.long	trace_hardirqs_on
+5:	.long	trace_hardirqs_off
+#endif
 
 	.align	2
 syscall_exit_work:
@@ -229,6 +271,11 @@
 	tst	#_TIF_SYSCALL_TRACE, r0
 	bt/s	work_pending
 	 tst	#_TIF_NEED_RESCHED, r0
+#ifdef CONFIG_TRACE_IRQFLAGS
+	mov.l	5f, r0
+	jsr	@r0
+	 nop
+#endif
 	sti
 	! XXX setup arguments...
 	mov.l	4f, r0			! do_syscall_trace
@@ -265,7 +312,7 @@
 	 mov.l	r0, @(OFF_R0,r15)	! Return value
 
 __restore_all:
-	mov.l	1f,r0
+	mov.l	1f, r0
 	jmp	@r0
 	 nop
 
@@ -331,7 +378,13 @@
 	 mov	#OFF_TRA, r9
 	add	r15, r9
 	mov.l	r8, @r9			! set TRA value to tra
+#ifdef CONFIG_TRACE_IRQFLAGS
+	mov.l	5f, r10
+	jsr	@r10
+	 nop
+#endif
 	sti
+
 	!
 	get_current_thread_info r8, r10
 	mov.l	@(TI_FLAGS,r8), r8
@@ -355,6 +408,11 @@
 	!
 syscall_exit:
 	cli
+#ifdef CONFIG_TRACE_IRQFLAGS
+	mov.l	6f, r0
+	jsr	@r0
+	 nop
+#endif
 	!
 	get_current_thread_info r8, r0
 	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
@@ -369,3 +427,7 @@
 2:	.long	NR_syscalls
 3:	.long	sys_call_table
 4:	.long	do_syscall_trace
+#ifdef CONFIG_TRACE_IRQFLAGS
+5:	.long	trace_hardirqs_on
+6:	.long	trace_hardirqs_off
+#endif
diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c
new file mode 100644
index 0000000..0d5268a
--- /dev/null
+++ b/arch/sh/kernel/stacktrace.c
@@ -0,0 +1,43 @@
+/*
+ * arch/sh/kernel/stacktrace.c
+ *
+ * Stack trace management functions
+ *
+ *  Copyright (C) 2006  Paul Mundt
+ *
+ * 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 <asm/ptrace.h>
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ */
+void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+{
+	unsigned long *sp;
+
+	if (!task)
+		task = current;
+	if (task == current)
+		sp = (unsigned long *)current_stack_pointer;
+	else
+		sp = (unsigned long *)task->thread.sp;
+
+	while (!kstack_end(sp)) {
+		unsigned long 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;
+		}
+	}
+}