Skip to contentSkip to conversation

KGDB: This adds basic support for KGDB on SuperH

PATCH In review Jason Wessel 1 participant 1 message Oct 15, 2007

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 13/21 KGDB: This adds basic support for KGDB on SuperH

sh-lite.patch

From: Jason Wessel <[email protected]>
CC: [email protected]
Subject: [PATCH] This adds basic support for KGDB on SuperH

This patch originally came from Tom Rini. It adds the unified kgdb support to the sh architechure covering sh3 and sh4. This patch also adds some architecture specific notes to the DocBook file and converting the 7751 to use this.

---
 Documentation/DocBook/kgdb.tmpl |   16 
 arch/sh/Kconfig.debug           |   79 --
 arch/sh/kernel/Makefile         |    2 
 arch/sh/kernel/kgdb-jmp.S       |   32 +
 arch/sh/kernel/kgdb.c           |  366 +++++++++++++
 arch/sh/kernel/kgdb_jmp.S       |   33 -
 arch/sh/kernel/kgdb_stub.c      | 1054 ----------------------------------------
 arch/sh/kernel/time.c           |    7 
 arch/sh/kernel/traps.c          |   24 
 arch/sh/mm/extable.c            |    7 
 arch/sh/mm/fault.c              |   12 
 drivers/serial/sh-sci.c         |   14 
 include/asm-sh/kgdb.h           |   95 +--
 lib/Kconfig.kgdb                |   11 
 14 files changed, 479 insertions(+), 1273 deletions(-)
 create mode 100644 arch/sh/kernel/kgdb-jmp.S
 create mode 100644 arch/sh/kernel/kgdb.c
 delete mode 100644 arch/sh/kernel/kgdb_jmp.S
 delete mode 100644 arch/sh/kernel/kgdb_stub.c
Documentation/DocBook/kgdb.tmpl +16 -0
@@ -124,6 +124,10 @@
     serial driver, pass in: <constant>kgdbwait</constant>.
     </para>
     <para>
+    To specify the values of the SH SCI(F) serial port at boot:
+    <constant>kgdbsci=0,115200</constant>.
+    </para>
+    <para>
     To specify the values of the serial port at boot:
     <constant>kgdb8250=io,3f8,115200,3</constant>.
     On IA64 this could also be:
@@ -181,6 +185,18 @@
     application program.
     </para>
   </chapter>
+  <chapter id="ArchitectureNotes">
+    <title>Architecture specific notes</title>
+      <para>
+      SuperH: The NMI switch found on some boards can be used to trigger an
+      initial breakpoint.  Subsequent triggers do nothing.  If console
+      is enabled on the SCI(F) serial port, and that is the port being used
+      for KGDB, then you must trigger a breakpoint via sysrq, NMI, or
+      some other method prior to connecting, or echo a control-c to the
+      serial port.  Also, to use the SCI(F) port for KGDB, the
+      <symbol>CONFIG_SERIAL_SH_SCI</symbol> driver must be enabled.
+      </para>
+  </chapter>
   <chapter id="CommonBackEndReq">
     <title>The common backend (required)</title>
       <para>
arch/sh/Kconfig.debug +0 -79

83 lines not on this page · raw message

arch/sh/kernel/Makefile +1 -1
@@ -14,7 +14,7 @@ obj-$(CONFIG_VSYSCALL)		+= vsyscall/
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_CF_ENABLER)	+= cf-enabler.o
 obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o
-obj-$(CONFIG_SH_KGDB)		+= kgdb_stub.o kgdb_jmp.o
+obj-$(CONFIG_KGDB)		+= kgdb.o kgdb-jmp.o
 obj-$(CONFIG_SH_CPU_FREQ)	+= cpufreq.o
 obj-$(CONFIG_MODULES)		+= sh_ksyms.o module.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
arch/sh/kernel/kgdb-jmp.S new file +32 -0
@@ -0,0 +1,32 @@
+#include <linux/linkage.h>
+
+ENTRY(kgdb_fault_setjmp)
+	add	#(9*4), r4
+	sts.l	pr, @-r4
+	mov.l	r15, @-r4
+	mov.l	r14, @-r4
+	mov.l	r13, @-r4
+	mov.l	r12, @-r4
+	mov.l	r11, @-r4
+	mov.l	r10, @-r4
+	mov.l	r9, @-r4
+	mov.l	r8, @-r4
+	rts
+	 mov	#0, r0
+
+ENTRY(kgdb_fault_longjmp)
+	mov.l	@r4+, r8
+	mov.l	@r4+, r9
+	mov.l	@r4+, r10
+	mov.l	@r4+, r11
+	mov.l	@r4+, r12
+	mov.l	@r4+, r13
+	mov.l	@r4+, r14
+	mov.l	@r4+, r15
+	lds.l	@r4+, pr
+	mov	r5, r0
+	tst	r0, r0
+	bf	1f
+	mov	#1, r0
+1:	rts
+	 nop
arch/sh/kernel/kgdb.c new file +366 -0

366 lines not on this page · raw message

arch/sh/kernel/kgdb_jmp.S deleted +0 -33
@@ -1,33 +0,0 @@
-#include <linux/linkage.h>
-
-ENTRY(setjmp)
-	add	#(9*4), r4
-	sts.l	pr, @-r4
-	mov.l	r15, @-r4
-	mov.l	r14, @-r4
-	mov.l	r13, @-r4
-	mov.l	r12, @-r4
-	mov.l	r11, @-r4
-	mov.l	r10, @-r4
-	mov.l	r9, @-r4
-	mov.l	r8, @-r4
-	rts
-	 mov	#0, r0
-
-ENTRY(longjmp)
-	mov.l	@r4+, r8
-	mov.l	@r4+, r9
-	mov.l	@r4+, r10
-	mov.l	@r4+, r11
-	mov.l	@r4+, r12
-	mov.l	@r4+, r13
-	mov.l	@r4+, r14
-	mov.l	@r4+, r15
-	lds.l	@r4+, pr
-	mov	r5, r0
-	tst	r0, r0
-	bf	1f
-	mov	#1, r0	! in case val==0
-1:	rts
-	 nop
-
arch/sh/kernel/kgdb_stub.c deleted +0 -1054

1,054 lines not on this page · raw message

arch/sh/kernel/time.c +0 -7
@@ -259,11 +259,4 @@ void __init time_init(void)
 		       ((sh_hpt_frequency + 500) / 1000) / 1000,
 		       ((sh_hpt_frequency + 500) / 1000) % 1000);
 
-#if defined(CONFIG_SH_KGDB)
-	/*
-	 * Set up kgdb as requested. We do it here because the serial
-	 * init uses the timer vars we just set up for figuring baud.
-	 */
-	kgdb_init();
-#endif
 }
arch/sh/kernel/traps.c +12 -12
@@ -25,16 +25,10 @@
 #include <linux/limits.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <linux/kgdb.h>
 
-#ifdef CONFIG_SH_KGDB
-#include <asm/kgdb.h>
-#define CHK_REMOTE_DEBUG(regs)			\
-{						\
-	if (kgdb_debug_hook && !user_mode(regs))\
-		(*kgdb_debug_hook)(regs);       \
-}
-#else
-#define CHK_REMOTE_DEBUG(regs)
+#ifndef CONFIG_KGDB
+#define kgdb_handle_exception(t, s, e, r)
 #endif
 
 #ifdef CONFIG_CPU_SH2
@@ -91,7 +85,9 @@ void die(const char * str, struct pt_reg
 
 	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
 
-	CHK_REMOTE_DEBUG(regs);
+#ifdef CONFIG_KGDB
+	kgdb_handle_exception(1, SIGTRAP, err, regs);
+#endif
 	print_modules();
 	show_regs(regs);
 
@@ -700,7 +696,9 @@ asmlinkage void do_reserved_inst(unsigne
 	lookup_exception_vector(error_code);
 
 	local_irq_enable();
-	CHK_REMOTE_DEBUG(regs);
+#ifdef CONFIG_KGDB
+	kgdb_handle_exception(1, SIGILL, error_code, regs);
+#endif
 	force_sig(SIGILL, tsk);
 	die_if_no_fixup("reserved instruction", regs, error_code);
 }
@@ -771,7 +769,9 @@ asmlinkage void do_illegal_slot_inst(uns
 	lookup_exception_vector(error_code);
 
 	local_irq_enable();
-	CHK_REMOTE_DEBUG(regs);
+#ifdef CONFIG_KGDB
+	kgdb_handle_exception(1, SIGILL, error_code, regs);
+#endif
 	force_sig(SIGILL, tsk);
 	die_if_no_fixup("illegal slot instruction", regs, error_code);
 }
arch/sh/mm/extable.c +7 -0
@@ -5,6 +5,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/kgdb.h>
 #include <asm/uaccess.h>
 
 int fixup_exception(struct pt_regs *regs)
@@ -16,6 +17,12 @@ int fixup_exception(struct pt_regs *regs
 		regs->pc = fixup->fixup;
 		return 1;
 	}
+#ifdef CONFIG_KGDB
+	if (atomic_read(&debugger_active) && kgdb_may_fault)
+		/* Restore our previous state. */
+		kgdb_fault_longjmp(kgdb_fault_jmp_regs);
+		/* Never reached. */
+#endif
 
 	return 0;
 }
arch/sh/mm/fault.c +1 -11
@@ -18,7 +18,6 @@
 #include <asm/system.h>
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
-#include <asm/kgdb.h>
 
 /*
  * This routine handles page faults.  It determines the address,
@@ -39,11 +38,6 @@ asmlinkage void __kprobes do_page_fault(
 	trace_hardirqs_on();
 	local_irq_enable();
 
-#ifdef CONFIG_SH_KGDB
-	if (kgdb_nofault && kgdb_bus_err_hook)
-		kgdb_bus_err_hook();
-#endif
-
 	tsk = current;
 	mm = tsk->mm;
 	si_code = SEGV_MAPERR;
@@ -200,6 +194,7 @@ no_context:
 	die("Oops", regs, writeaccess);
 	bust_spinlocks(0);
 	do_exit(SIGKILL);
+	dump_stack();
 
 /*
  * We ran out of memory, or some other thing happened to us that made
@@ -262,11 +257,6 @@ asmlinkage int __kprobes __do_page_fault
 	spinlock_t *ptl = NULL;
 	int ret = 1;
 
-#ifdef CONFIG_SH_KGDB
-	if (kgdb_nofault && kgdb_bus_err_hook)
-		kgdb_bus_err_hook();
-#endif
-
 	/*
 	 * We don't take page faults for P1, P2, and parts of P4, these
 	 * are always mapped, whether it be due to legacy behaviour in
drivers/serial/sh-sci.c +8 -6
@@ -120,7 +120,8 @@ static int get_char(struct uart_port *po
 	do {
 		status = sci_in(port, SCxSR);
 		if (status & SCxSR_ERRORS(port)) {
-			handle_error(port);
+			/* Clear error flags. */
+			sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
 			continue;
 		}
 	} while (!(status & SCxSR_RDxF(port)));
@@ -162,6 +163,7 @@ static void put_string(struct sci_port *
 
 #if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
 	int checksum;
+	const char hexchars[] = "0123456789abcdef";
 	int usegdb=0;
 
 #ifdef CONFIG_SH_STANDARD_BIOS
@@ -186,18 +188,18 @@ static void put_string(struct sci_port *
 			int h, l;
 
 			c = *p++;
-			h = highhex(c);
-			l = lowhex(c);
+			h = hexchars[c >> 4];
+			l = hexchars[c % 16];
 			put_char(port, h);
 			put_char(port, l);
 			checksum += h + l;
 		}
 		put_char(port, '#');
-		put_char(port, highhex(checksum));
-		put_char(port, lowhex(checksum));
+		put_char(port, hexchars[checksum >> 4]);
+		put_char(port, hexchars[checksum & 16]);
 	    } while  (get_char(port) != '+');
 	} else
-#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
+#endif /* CONFIG_SH_STANDARD_BIOS */
 	for (i=0; i<count; i++) {
 		if (*p == 10)
 			put_char(port, '\r');
include/asm-sh/kgdb.h +27 -68

109 lines not on this page · raw message

lib/Kconfig.kgdb +9 -2
@@ -3,7 +3,7 @@ config WANT_EXTRA_DEBUG_INFORMATION
 	bool
 	select DEBUG_INFO
 	select UNWIND_INFO
-	select FRAME_POINTER if X86
+	select FRAME_POINTER if X86 || SUPERH
 	default n
 
 config UNWIND_INFO
@@ -14,7 +14,7 @@ config KGDB
 	bool "KGDB: kernel debugging with remote gdb"
 	select WANT_EXTRA_DEBUG_INFORMATION
 	select KGDB_ARCH_HAS_SHADOW_INFO if X86_64
-	depends on DEBUG_KERNEL && (X86 || MIPS || IA64 || PPC)
+	depends on DEBUG_KERNEL && (X86 || MIPS || (SUPERH && !SUPERH64) || IA64 || PPC)
 	help
 	  If you say Y here, it will be possible to remotely debug the
 	  kernel using gdb.  Documentation of kernel debugger is available
@@ -44,6 +44,7 @@ choice
 	default KGDB_CPM_UART if (CPM2 || 8xx)
 	default KGDB_SIBYTE if SIBYTE_SB1xxx_SOC
  	default KGDB_TXX9 if CPU_TX49XX
+	default KGDB_SH_SCI if SERIAL_SH_SCI
 	default KGDB_8250_NOMODULE
 	help
 	  There are a number of different ways in which you can communicate
@@ -104,6 +105,12 @@ config KGDB_TXX9
 	depends on MIPS && CPU_TX49XX
 	help
 	  Uses TX49xx serial port to communicate with the host GDB.
+
+config KGDB_SH_SCI
+	bool "KGDB: On SH SCI(F) serial port"
+	depends on SUPERH && SERIAL_SH_SCI
+	help
+	  Uses the SH SCI(F) serial port to communicate with the host GDB.
 endchoice
 
 choice