sparc: Add kgdb support.

Current limitations:

1) On SMP single stepping has some fundamental issues,
   shared with other sw single-step architectures such
   as mips and arm.

2) On 32-bit sparc we don't support SMP kgdb yet.  That
   requires some reworking of the IPI mechanisms and
   infrastructure on that platform.

Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 49590f8..d211fdb 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -68,6 +68,7 @@
 	default y
 	select HAVE_IDE
 	select HAVE_OPROFILE
+	select HAVE_ARCH_KGDB if !SMP
 
 # Identify this as a Sparc32 build
 config SPARC32
diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig
index 6a2c57a..2e3a149 100644
--- a/arch/sparc/defconfig
+++ b/arch/sparc/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.25
-# Sun Apr 20 01:49:51 2008
+# Tue Apr 29 01:28:58 2008
 #
 CONFIG_MMU=y
 CONFIG_HIGHMEM=y
@@ -217,12 +217,7 @@
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
-CONFIG_IP_SCTP=m
-# CONFIG_SCTP_DBG_MSG is not set
-CONFIG_SCTP_DBG_OBJCNT=y
-# CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_IP_SCTP is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -245,9 +240,7 @@
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_AF_RXRPC=m
-# CONFIG_AF_RXRPC_DEBUG is not set
-# CONFIG_RXKAD is not set
+# CONFIG_AF_RXRPC is not set
 
 #
 # Wireless
@@ -390,7 +383,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
+# CONFIG_TUN is not set
 # CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
 # CONFIG_PHYLIB is not set
@@ -544,6 +537,7 @@
 # CONFIG_SERIAL_SUNSAB is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_CONSOLE_POLL=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
@@ -595,6 +589,7 @@
 # Multifunction device drivers
 #
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
 
 #
 # Multimedia devices
@@ -645,10 +640,6 @@
 # CONFIG_NEW_LEDS is not set
 # CONFIG_INFINIBAND is not set
 # CONFIG_RTC_CLASS is not set
-
-#
-# Userspace I/O
-#
 # CONFIG_UIO is not set
 
 #
@@ -680,16 +671,12 @@
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
-CONFIG_XFS_FS=m
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_POSIX_ACL=y
-CONFIG_XFS_RT=y
+# CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_QUOTACTL=y
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 # CONFIG_FUSE_FS is not set
@@ -725,11 +712,9 @@
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
-# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
-CONFIG_BEFS_FS=m
-# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
@@ -744,7 +729,6 @@
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
@@ -755,16 +739,10 @@
 CONFIG_RPCSEC_GSS_KRB5=m
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-# CONFIG_CIFS_WEAK_PW_HASH is not set
-# CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_DEBUG2 is not set
-# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
-CONFIG_AFS_FS=m
-# CONFIG_AFS_DEBUG is not set
+# CONFIG_AFS_FS is not set
 
 #
 # Partition Types
@@ -821,6 +799,7 @@
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_ENABLE_WARN_DEPRECATED is not set
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
@@ -842,70 +821,105 @@
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_SAMPLES is not set
+CONFIG_KGDB=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_KGDB_SERIAL_CONSOLE=y
+CONFIG_KGDB_TESTS=y
+# CONFIG_KGDB_TESTS_ON_BOOT is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 
 #
 # Security options
 #
-CONFIG_KEYS=y
-# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
-# CONFIG_CRYPTO_SEQIV is not set
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_XCBC is not set
-CONFIG_CRYPTO_NULL=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_SHA1=y
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_DES=y
-# CONFIG_CRYPTO_FCRYPT is not set
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
 CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+# CONFIG_CRYPTO_CAMELLIA is not set
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
 CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-CONFIG_CRYPTO_AUTHENC=y
 # CONFIG_CRYPTO_LZO is not set
 # CONFIG_CRYPTO_HW is not set
 
@@ -913,6 +927,7 @@
 # Library routines
 #
 CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_ITU_T is not set
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 59700aa..6e03a2a 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -25,3 +25,4 @@
 obj-$(CONFIG_SUN_PM) += apc.o pmc.o
 obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o
 obj-$(CONFIG_SPARC_LED) += led.o
+obj-$(CONFIG_KGDB) += kgdb.o
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 484c83d..57d1bbd 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -12,7 +12,6 @@
 #include <asm/head.h>
 #include <asm/asi.h>
 #include <asm/smp.h>
-#include <asm/kgdb.h>
 #include <asm/contregs.h>
 #include <asm/ptrace.h>
 #include <asm/asm-offsets.h>
@@ -45,91 +44,20 @@
 	_SV; _SV; _SV; _SV; _SV; _SV; _SV; \
 	_RS; _RS; _RS; _RS; _RS; _RS; _RS;
 
-/* First, KGDB low level things.  This is a rewrite
- * of the routines found in the sparc-stub.c asm() statement
- * from the gdb distribution.  This is also dual-purpose
- * as a software trap for userlevel programs.
- */
-	.data
-	.align	4
-
-in_trap_handler:
-	.word	0
-
 	.text
+
+#ifdef CONFIG_KGDB
 	.align	4
-
-#if 0 /* kgdb is dropped from 2.5.33 */
-! This function is called when any SPARC trap (except window overflow or
-! underflow) occurs.  It makes sure that the invalid register window is still
-! available before jumping into C code.  It will also restore the world if you
-! return from handle_exception.
-
-	.globl	trap_low
-trap_low:
-	rd	%wim, %l3
-	SAVE_ALL
-
-	sethi	%hi(in_trap_handler), %l4
-	ld	[%lo(in_trap_handler) + %l4], %l5
-	inc	%l5
-	st	%l5, [%lo(in_trap_handler) + %l4]
-
-	/* Make sure kgdb sees the same state we just saved. */
-	LOAD_PT_GLOBALS(sp)
-	LOAD_PT_INS(sp)
-	ld	[%sp + STACKFRAME_SZ + PT_Y], %l4
-	ld	[%sp + STACKFRAME_SZ + PT_WIM], %l3
-	ld	[%sp + STACKFRAME_SZ + PT_PSR], %l0
-	ld	[%sp + STACKFRAME_SZ + PT_PC], %l1
-	ld	[%sp + STACKFRAME_SZ + PT_NPC], %l2
-	rd	%tbr, %l5	/* Never changes... */
-
-	/* Make kgdb exception frame. */	
-	sub	%sp,(16+1+6+1+72)*4,%sp	! Make room for input & locals
- 					! + hidden arg + arg spill
-					! + doubleword alignment
-					! + registers[72] local var
-	SAVE_KGDB_GLOBALS(sp)
-	SAVE_KGDB_INS(sp)
-	SAVE_KGDB_SREGS(sp, l4, l0, l3, l5, l1, l2)
-
-	/* We are increasing PIL, so two writes. */
-	or	%l0, PSR_PIL, %l0
-	wr	%l0, 0, %psr
-	WRITE_PAUSE
-	wr	%l0, PSR_ET, %psr
-	WRITE_PAUSE
-
-	call	handle_exception
-	 add	%sp, STACKFRAME_SZ, %o0	! Pass address of registers
-
-	/* Load new kgdb register set. */
-	LOAD_KGDB_GLOBALS(sp)
-	LOAD_KGDB_INS(sp)
-	LOAD_KGDB_SREGS(sp, l4, l0, l3, l5, l1, l2)
-	wr      %l4, 0x0, %y
-
-	sethi	%hi(in_trap_handler), %l4
-	ld	[%lo(in_trap_handler) + %l4], %l5
-	dec	%l5
-	st	%l5, [%lo(in_trap_handler) + %l4]
-
-	add	%sp,(16+1+6+1+72)*4,%sp	! Undo the kgdb trap frame.
-
-	/* Now take what kgdb did and place it into the pt_regs
-	 * frame which SparcLinux RESTORE_ALL understands.,
-	 */
-	STORE_PT_INS(sp)
-	STORE_PT_GLOBALS(sp)
-	STORE_PT_YREG(sp, g2)
-	STORE_PT_PRIV(sp, l0, l1, l2)
-
-	RESTORE_ALL
+	.globl		arch_kgdb_breakpoint
+	.type		arch_kgdb_breakpoint,#function
+arch_kgdb_breakpoint:
+	ta		0x7d
+	retl
+	 nop
+	.size		arch_kgdb_breakpoint,.-arch_kgdb_breakpoint
 #endif
 
 #if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
-	.text
 	.align	4
 	.globl	floppy_hardint
 floppy_hardint:
@@ -1596,6 +1524,23 @@
 
 	RESTORE_ALL
 
+#ifdef CONFIG_KGDB
+	.align	4
+	.globl	kgdb_trap_low
+	.type	kgdb_trap_low,#function
+kgdb_trap_low:
+	rd	%wim,%l3
+	SAVE_ALL
+	wr 	%l0, PSR_ET, %psr
+	WRITE_PAUSE
+
+	call	kgdb_trap
+	 add	%sp, STACKFRAME_SZ, %o0
+
+	RESTORE_ALL
+	.size	kgdb_trap_low,.-kgdb_trap_low
+#endif
+
 	.align	4
 	.globl	__handle_exception, flush_patch_exception
 __handle_exception:
@@ -1698,4 +1643,22 @@
 
 #endif /* CONFIG_PCI */
 
+	.globl	flushw_all
+flushw_all:
+	save	%sp, -0x40, %sp
+	save	%sp, -0x40, %sp
+	save	%sp, -0x40, %sp
+	save	%sp, -0x40, %sp
+	save	%sp, -0x40, %sp
+	save	%sp, -0x40, %sp
+	save	%sp, -0x40, %sp
+	restore
+	restore
+	restore
+	restore
+	restore
+	restore
+	ret
+	 restore
+
 /* End of entry.S */
diff --git a/arch/sparc/kernel/head.S b/arch/sparc/kernel/head.S
index b7f1e81..8bec05f 100644
--- a/arch/sparc/kernel/head.S
+++ b/arch/sparc/kernel/head.S
@@ -191,7 +191,8 @@
 t_baded:BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1)
 t_badf2:BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6)
 t_badf7:BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb)
-t_badfc:BAD_TRAP(0xfc) BAD_TRAP(0xfd)
+t_badfc:BAD_TRAP(0xfc)
+t_kgdb:	KGDB_TRAP(0xfd)
 dbtrap:	BAD_TRAP(0xfe)                      /* Debugger/PROM breakpoint #1   */
 dbtrap2:BAD_TRAP(0xff)                      /* Debugger/PROM breakpoint #2   */	
 
@@ -267,7 +268,7 @@
 	BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1)
 	BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6)
 	BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb)
-	BAD_TRAP(0xfc) BAD_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff)
+	BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff)
 
 trapbase_cpu2:
 	BAD_TRAP(0x0) SRMMU_TFAULT TRAP_ENTRY(0x2, bad_instruction)
@@ -335,7 +336,7 @@
 	BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1)
 	BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6)
 	BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb)
-	BAD_TRAP(0xfc) BAD_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff)
+	BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff)
 
 trapbase_cpu3:
 	BAD_TRAP(0x0) SRMMU_TFAULT TRAP_ENTRY(0x2, bad_instruction)
@@ -403,7 +404,7 @@
 	BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1)
 	BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6)
 	BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb)
-	BAD_TRAP(0xfc) BAD_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff)
+	BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff)
 
 #endif
 	.align PAGE_SIZE
diff --git a/arch/sparc/kernel/kgdb.c b/arch/sparc/kernel/kgdb.c
new file mode 100644
index 0000000..757805c
--- /dev/null
+++ b/arch/sparc/kernel/kgdb.c
@@ -0,0 +1,164 @@
+/* kgdb.c: KGDB support for 32-bit sparc.
+ *
+ * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
+ */
+
+#include <linux/kgdb.h>
+#include <linux/kdebug.h>
+
+#include <asm/kdebug.h>
+#include <asm/ptrace.h>
+#include <asm/irq.h>
+
+extern unsigned long trapbase;
+
+void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+	struct reg_window *win;
+	int i;
+
+	gdb_regs[GDB_G0] = 0;
+	for (i = 0; i < 15; i++)
+		gdb_regs[GDB_G1 + i] = regs->u_regs[UREG_G1 + i];
+
+	win = (struct reg_window *) regs->u_regs[UREG_FP];
+	for (i = 0; i < 8; i++)
+		gdb_regs[GDB_L0 + i] = win->locals[i];
+	for (i = 0; i < 8; i++)
+		gdb_regs[GDB_I0 + i] = win->ins[i];
+
+	for (i = GDB_F0; i <= GDB_F31; i++)
+		gdb_regs[i] = 0;
+
+	gdb_regs[GDB_Y] = regs->y;
+	gdb_regs[GDB_PSR] = regs->psr;
+	gdb_regs[GDB_WIM] = 0;
+	gdb_regs[GDB_TBR] = (unsigned long) &trapbase;
+	gdb_regs[GDB_PC] = regs->pc;
+	gdb_regs[GDB_NPC] = regs->npc;
+	gdb_regs[GDB_FSR] = 0;
+	gdb_regs[GDB_CSR] = 0;
+}
+
+void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
+{
+	struct thread_info *t = task_thread_info(p);
+	struct reg_window *win;
+	int i;
+
+	for (i = GDB_G0; i < GDB_G6; i++)
+		gdb_regs[i] = 0;
+	gdb_regs[GDB_G6] = (unsigned long) t;
+	gdb_regs[GDB_G7] = 0;
+	for (i = GDB_O0; i < GDB_SP; i++)
+		gdb_regs[i] = 0;
+	gdb_regs[GDB_SP] = t->ksp;
+	gdb_regs[GDB_O7] = 0;
+
+	win = (struct reg_window *) t->ksp;
+	for (i = 0; i < 8; i++)
+		gdb_regs[GDB_L0 + i] = win->locals[i];
+	for (i = 0; i < 8; i++)
+		gdb_regs[GDB_I0 + i] = win->ins[i];
+
+	for (i = GDB_F0; i <= GDB_F31; i++)
+		gdb_regs[i] = 0;
+
+	gdb_regs[GDB_Y] = 0;
+
+	gdb_regs[GDB_PSR] = t->kpsr;
+	gdb_regs[GDB_WIM] = t->kwim;
+	gdb_regs[GDB_TBR] = (unsigned long) &trapbase;
+	gdb_regs[GDB_PC] = t->kpc;
+	gdb_regs[GDB_NPC] = t->kpc + 4;
+	gdb_regs[GDB_FSR] = 0;
+	gdb_regs[GDB_CSR] = 0;
+}
+
+void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+	struct reg_window *win;
+	int i;
+
+	for (i = 0; i < 15; i++)
+		regs->u_regs[UREG_G1 + i] = gdb_regs[GDB_G1 + i];
+
+	/* If the PSR register is changing, we have to preserve
+	 * the CWP field, otherwise window save/restore explodes.
+	 */
+	if (regs->psr != gdb_regs[GDB_PSR]) {
+		unsigned long cwp = regs->psr & PSR_CWP;
+
+		regs->psr = (gdb_regs[GDB_PSR] & ~PSR_CWP) | cwp;
+	}
+
+	regs->pc = gdb_regs[GDB_PC];
+	regs->npc = gdb_regs[GDB_NPC];
+	regs->y = gdb_regs[GDB_Y];
+
+	win = (struct reg_window *) regs->u_regs[UREG_FP];
+	for (i = 0; i < 8; i++)
+		win->locals[i] = gdb_regs[GDB_L0 + i];
+	for (i = 0; i < 8; i++)
+		win->ins[i] = gdb_regs[GDB_I0 + i];
+}
+
+int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
+			       char *remcomInBuffer, char *remcomOutBuffer,
+			       struct pt_regs *linux_regs)
+{
+	unsigned long addr;
+	char *ptr;
+
+	switch (remcomInBuffer[0]) {
+	case 'c':
+		/* try to read optional parameter, pc unchanged if no parm */
+		ptr = &remcomInBuffer[1];
+		if (kgdb_hex2long(&ptr, &addr)) {
+			linux_regs->pc = addr;
+			linux_regs->npc = addr + 4;
+		}
+		/* fallthru */
+
+	case 'D':
+	case 'k':
+		if (linux_regs->pc == (unsigned long) arch_kgdb_breakpoint) {
+			linux_regs->pc = linux_regs->npc;
+			linux_regs->npc += 4;
+		}
+		return 0;
+	}
+	return -1;
+}
+
+extern void do_hw_interrupt(struct pt_regs *regs, unsigned long type);
+
+asmlinkage void kgdb_trap(struct pt_regs *regs)
+{
+	unsigned long flags;
+
+	if (user_mode(regs)) {
+		do_hw_interrupt(regs, 0xfd);
+		return;
+	}
+
+	flushw_all();
+
+	local_irq_save(flags);
+	kgdb_handle_exception(0x172, SIGTRAP, 0, regs);
+	local_irq_restore(flags);
+}
+
+int kgdb_arch_init(void)
+{
+	return 0;
+}
+
+void kgdb_arch_exit(void)
+{
+}
+
+struct kgdb_arch arch_kgdb_ops = {
+	/* Breakpoint instruction: ta 0x7d */
+	.gdb_bpt_instr		= { 0x91, 0xd0, 0x20, 0x7d },
+};
diff --git a/arch/sparc/kernel/sparc-stub.c b/arch/sparc/kernel/sparc-stub.c
deleted file mode 100644
index e84f815..0000000
--- a/arch/sparc/kernel/sparc-stub.c
+++ /dev/null
@@ -1,724 +0,0 @@
-/* $Id: sparc-stub.c,v 1.28 2001/10/30 04:54:21 davem Exp $
- * sparc-stub.c:  KGDB support for the Linux kernel.
- *
- * Modifications to run under Linux
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- *
- * This file originally came from the gdb sources, and the
- * copyright notices have been retained below.
- */
-
-/****************************************************************************
-
-		THIS SOFTWARE IS NOT COPYRIGHTED
-
-   HP offers the following for use in the public domain.  HP makes no
-   warranty with regard to the software or its performance and the
-   user accepts the software "AS IS" with all faults.
-
-   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
-   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-****************************************************************************/
-
-/****************************************************************************
- *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
- *
- *  Module name: remcom.c $
- *  Revision: 1.34 $
- *  Date: 91/03/09 12:29:49 $
- *  Contributor:     Lake Stevens Instrument Division$
- *
- *  Description:     low level support for gdb debugger. $
- *
- *  Considerations:  only works on target hardware $
- *
- *  Written by:      Glenn Engel $
- *  ModuleState:     Experimental $
- *
- *  NOTES:           See Below $
- *
- *  Modified for SPARC by Stu Grossman, Cygnus Support.
- *
- *  This code has been extensively tested on the Fujitsu SPARClite demo board.
- *
- *  To enable debugger support, two things need to happen.  One, a
- *  call to set_debug_traps() is necessary in order to allow any breakpoints
- *  or error conditions to be properly intercepted and reported to gdb.
- *  Two, a breakpoint needs to be generated to begin communication.  This
- *  is most easily accomplished by a call to breakpoint().  Breakpoint()
- *  simulates a breakpoint by executing a trap #1.
- *
- *************
- *
- *    The following gdb commands are supported:
- *
- * command          function                               Return value
- *
- *    g             return the value of the CPU registers  hex data or ENN
- *    G             set the value of the CPU registers     OK or ENN
- *
- *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
- *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
- *
- *    c             Resume at current address              SNN   ( signal NN)
- *    cAA..AA       Continue at address AA..AA             SNN
- *
- *    s             Step one instruction                   SNN
- *    sAA..AA       Step one instruction from AA..AA       SNN
- *
- *    k             kill
- *
- *    ?             What was the last sigval ?             SNN   (signal NN)
- *
- *    bBB..BB	    Set baud rate to BB..BB		   OK or BNN, then sets
- *							   baud rate
- *
- * All commands and responses are sent with a packet which includes a
- * checksum.  A packet consists of
- *
- * $<packet info>#<checksum>.
- *
- * where
- * <packet info> :: <characters representing the command or response>
- * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
- *
- * When a packet is received, it is first acknowledged with either '+' or '-'.
- * '+' indicates a successful transfer.  '-' indicates a failed transfer.
- *
- * Example:
- *
- * Host:                  Reply:
- * $m0,10#2a               +$00010203040506070809101112131415#42
- *
- ****************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-
-#include <asm/system.h>
-#include <asm/signal.h>
-#include <asm/oplib.h>
-#include <asm/head.h>
-#include <asm/traps.h>
-#include <asm/vac-ops.h>
-#include <asm/kgdb.h>
-#include <asm/pgalloc.h>
-#include <asm/pgtable.h>
-#include <asm/cacheflush.h>
-
-/*
- *
- * external low-level support routines
- */
-
-extern void putDebugChar(char);   /* write a single character      */
-extern char getDebugChar(void);   /* read and return a single char */
-
-/*
- * BUFMAX defines the maximum number of characters in inbound/outbound buffers
- * at least NUMREGBYTES*2 are needed for register packets
- */
-#define BUFMAX 2048
-
-static int initialized;	/* !0 means we've been initialized */
-
-static const char hexchars[]="0123456789abcdef";
-
-#define NUMREGS 72
-
-/* Number of bytes of registers.  */
-#define NUMREGBYTES (NUMREGS * 4)
-enum regnames {G0, G1, G2, G3, G4, G5, G6, G7,
-		 O0, O1, O2, O3, O4, O5, SP, O7,
-		 L0, L1, L2, L3, L4, L5, L6, L7,
-		 I0, I1, I2, I3, I4, I5, FP, I7,
-
-		 F0, F1, F2, F3, F4, F5, F6, F7,
-		 F8, F9, F10, F11, F12, F13, F14, F15,
-		 F16, F17, F18, F19, F20, F21, F22, F23,
-		 F24, F25, F26, F27, F28, F29, F30, F31,
-		 Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR };
-
-
-extern void trap_low(void);  /* In arch/sparc/kernel/entry.S */
-
-unsigned long get_sun4cpte(unsigned long addr)
-{
-	unsigned long entry;
-
-	__asm__ __volatile__("\n\tlda [%1] %2, %0\n\t" : 
-			     "=r" (entry) :
-			     "r" (addr), "i" (ASI_PTE));
-	return entry;
-}
-
-unsigned long get_sun4csegmap(unsigned long addr)
-{
-	unsigned long entry;
-
-	__asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" : 
-			     "=r" (entry) :
-			     "r" (addr), "i" (ASI_SEGMAP));
-	return entry;
-}
-
-#if 0
-/* Have to sort this out. This cannot be done after initialization. */
-static void flush_cache_all_nop(void) {}
-#endif
-
-/* Place where we save old trap entries for restoration */
-struct tt_entry kgdb_savettable[256];
-typedef void (*trapfunc_t)(void);
-
-/* Helper routine for manipulation of kgdb_savettable */
-static inline void copy_ttentry(struct tt_entry *src, struct tt_entry *dest)
-{
-	dest->inst_one = src->inst_one;
-	dest->inst_two = src->inst_two;
-	dest->inst_three = src->inst_three;
-	dest->inst_four = src->inst_four;
-}
-
-/* Initialize the kgdb_savettable so that debugging can commence */
-static void eh_init(void)
-{
-	int i;
-
-	for(i=0; i < 256; i++)
-		copy_ttentry(&sparc_ttable[i], &kgdb_savettable[i]);
-}
-
-/* Install an exception handler for kgdb */
-static void exceptionHandler(int tnum, trapfunc_t trap_entry)
-{
-	unsigned long te_addr = (unsigned long) trap_entry;
-
-	/* Make new vector */
-	sparc_ttable[tnum].inst_one =
-		SPARC_BRANCH((unsigned long) te_addr,
-			     (unsigned long) &sparc_ttable[tnum].inst_one);
-	sparc_ttable[tnum].inst_two = SPARC_RD_PSR_L0;
-	sparc_ttable[tnum].inst_three = SPARC_NOP;
-	sparc_ttable[tnum].inst_four = SPARC_NOP;
-}
-
-/* Convert ch from a hex digit to an int */
-static int
-hex(unsigned char ch)
-{
-	if (ch >= 'a' && ch <= 'f')
-		return ch-'a'+10;
-	if (ch >= '0' && ch <= '9')
-		return ch-'0';
-	if (ch >= 'A' && ch <= 'F')
-		return ch-'A'+10;
-	return -1;
-}
-
-/* scan for the sequence $<data>#<checksum>     */
-static void
-getpacket(char *buffer)
-{
-	unsigned char checksum;
-	unsigned char xmitcsum;
-	int i;
-	int count;
-	unsigned char ch;
-
-	do {
-		/* wait around for the start character, ignore all other characters */
-		while ((ch = (getDebugChar() & 0x7f)) != '$') ;
-
-		checksum = 0;
-		xmitcsum = -1;
-
-		count = 0;
-
-		/* now, read until a # or end of buffer is found */
-		while (count < BUFMAX) {
-			ch = getDebugChar() & 0x7f;
-			if (ch == '#')
-				break;
-			checksum = checksum + ch;
-			buffer[count] = ch;
-			count = count + 1;
-		}
-
-		if (count >= BUFMAX)
-			continue;
-
-		buffer[count] = 0;
-
-		if (ch == '#') {
-			xmitcsum = hex(getDebugChar() & 0x7f) << 4;
-			xmitcsum |= hex(getDebugChar() & 0x7f);
-			if (checksum != xmitcsum)
-				putDebugChar('-');	/* failed checksum */
-			else {
-				putDebugChar('+'); /* successful transfer */
-				/* if a sequence char is present, reply the ID */
-				if (buffer[2] == ':') {
-					putDebugChar(buffer[0]);
-					putDebugChar(buffer[1]);
-					/* remove sequence chars from buffer */
-					count = strlen(buffer);
-					for (i=3; i <= count; i++)
-						buffer[i-3] = buffer[i];
-				}
-			}
-		}
-	} while (checksum != xmitcsum);
-}
-
-/* send the packet in buffer.  */
-
-static void
-putpacket(unsigned char *buffer)
-{
-	unsigned char checksum;
-	int count;
-	unsigned char ch, recv;
-
-	/*  $<packet info>#<checksum>. */
-	do {
-		putDebugChar('$');
-		checksum = 0;
-		count = 0;
-
-		while ((ch = buffer[count])) {
-			putDebugChar(ch);
-			checksum += ch;
-			count += 1;
-		}
-
-		putDebugChar('#');
-		putDebugChar(hexchars[checksum >> 4]);
-		putDebugChar(hexchars[checksum & 0xf]);
-		recv = getDebugChar();
-	} while ((recv & 0x7f) != '+');
-}
-
-static char remcomInBuffer[BUFMAX];
-static char remcomOutBuffer[BUFMAX];
-
-/* Convert the memory pointed to by mem into hex, placing result in buf.
- * Return a pointer to the last char put in buf (null), in case of mem fault,
- * return 0.
- */
-
-static unsigned char *
-mem2hex(char *mem, char *buf, int count)
-{
-	unsigned char ch;
-
-	while (count-- > 0) {
-		/* This assembler code is basically:  ch = *mem++;
-		 * except that we use the SPARC/Linux exception table
-		 * mechanism (see how "fixup" works in kernel_mna_trap_fault)
-		 * to arrange for a "return 0" upon a memory fault
-		 */
-		__asm__(
-			"\n1:\n\t"
-			"ldub [%0], %1\n\t"
-			"inc %0\n\t"
-			".section .fixup,#alloc,#execinstr\n\t"
-			".align 4\n"
-			"2:\n\t"
-			"retl\n\t"
-			" mov 0, %%o0\n\t"
-			".section __ex_table, #alloc\n\t"
-			".align 4\n\t"
-			".word 1b, 2b\n\t"
-			".text\n"
-			: "=r" (mem), "=r" (ch) : "0" (mem));
-		*buf++ = hexchars[ch >> 4];
-		*buf++ = hexchars[ch & 0xf];
-	}
-
-	*buf = 0;
-	return buf;
-}
-
-/* convert the hex array pointed to by buf into binary to be placed in mem
- * return a pointer to the character AFTER the last byte written.
-*/
-static char *
-hex2mem(char *buf, char *mem, int count)
-{
-	int i;
-	unsigned char ch;
-
-	for (i=0; i<count; i++) {
-
-		ch = hex(*buf++) << 4;
-		ch |= hex(*buf++);
-		/* Assembler code is   *mem++ = ch;   with return 0 on fault */
-		__asm__(
-			"\n1:\n\t"
-			"stb %1, [%0]\n\t"
-			"inc %0\n\t"
-			".section .fixup,#alloc,#execinstr\n\t"
-			".align 4\n"
-			"2:\n\t"
-			"retl\n\t"
-			" mov 0, %%o0\n\t"
-			".section __ex_table, #alloc\n\t"
-			".align 4\n\t"
-			".word 1b, 2b\n\t"
-			".text\n"
-			: "=r" (mem) : "r" (ch) , "0" (mem));
-	}
-	return mem;
-}
-
-/* This table contains the mapping between SPARC hardware trap types, and
-   signals, which are primarily what GDB understands.  It also indicates
-   which hardware traps we need to commandeer when initializing the stub. */
-
-static struct hard_trap_info
-{
-  unsigned char tt;		/* Trap type code for SPARC */
-  unsigned char signo;		/* Signal that we map this trap into */
-} hard_trap_info[] = {
-  {SP_TRAP_SBPT, SIGTRAP},      /* ta 1 - Linux/KGDB software breakpoint */
-  {0, 0}			/* Must be last */
-};
-
-/* Set up exception handlers for tracing and breakpoints */
-
-void
-set_debug_traps(void)
-{
-	struct hard_trap_info *ht;
-	unsigned long flags;
-
-	local_irq_save(flags);
-#if 0	
-/* Have to sort this out. This cannot be done after initialization. */
-	BTFIXUPSET_CALL(flush_cache_all, flush_cache_all_nop, BTFIXUPCALL_NOP);
-#endif
-
-	/* Initialize our copy of the Linux Sparc trap table */
-	eh_init();
-
-	for (ht = hard_trap_info; ht->tt && ht->signo; ht++) {
-		/* Only if it doesn't destroy our fault handlers */
-		if((ht->tt != SP_TRAP_TFLT) && 
-		   (ht->tt != SP_TRAP_DFLT))
-			exceptionHandler(ht->tt, trap_low);
-	}
-
-	/* In case GDB is started before us, ack any packets (presumably
-	 * "$?#xx") sitting there.
-	 *
-	 * I've found this code causes more problems than it solves,
-	 * so that's why it's commented out.  GDB seems to work fine
-	 * now starting either before or after the kernel   -bwb
-	 */
-#if 0
-	while((c = getDebugChar()) != '$');
-	while((c = getDebugChar()) != '#');
-	c = getDebugChar(); /* eat first csum byte */
-	c = getDebugChar(); /* eat second csum byte */
-	putDebugChar('+'); /* ack it */
-#endif
-
-	initialized = 1; /* connect! */
-	local_irq_restore(flags);
-}
-
-/* Convert the SPARC hardware trap type code to a unix signal number. */
-
-static int
-computeSignal(int tt)
-{
-	struct hard_trap_info *ht;
-
-	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
-		if (ht->tt == tt)
-			return ht->signo;
-
-	return SIGHUP;         /* default for things we don't know about */
-}
-
-/*
- * While we find nice hex chars, build an int.
- * Return number of chars processed.
- */
-
-static int
-hexToInt(char **ptr, int *intValue)
-{
-	int numChars = 0;
-	int hexValue;
-
-	*intValue = 0;
-
-	while (**ptr) {
-		hexValue = hex(**ptr);
-		if (hexValue < 0)
-			break;
-
-		*intValue = (*intValue << 4) | hexValue;
-		numChars ++;
-
-		(*ptr)++;
-	}
-
-	return (numChars);
-}
-
-/*
- * This function does all command processing for interfacing to gdb.  It
- * returns 1 if you should skip the instruction at the trap address, 0
- * otherwise.
- */
-
-extern void breakinst(void);
-
-void
-handle_exception (unsigned long *registers)
-{
-	int tt;       /* Trap type */
-	int sigval;
-	int addr;
-	int length;
-	char *ptr;
-	unsigned long *sp;
-
-	/* First, we must force all of the windows to be spilled out */
-
-	asm("save %sp, -64, %sp\n\t"
-	    "save %sp, -64, %sp\n\t"
-	    "save %sp, -64, %sp\n\t"
-	    "save %sp, -64, %sp\n\t"
-	    "save %sp, -64, %sp\n\t"
-	    "save %sp, -64, %sp\n\t"
-	    "save %sp, -64, %sp\n\t"
-	    "save %sp, -64, %sp\n\t"
-	    "restore\n\t"
-	    "restore\n\t"
-	    "restore\n\t"
-	    "restore\n\t"
-	    "restore\n\t"
-	    "restore\n\t"
-	    "restore\n\t"
-	    "restore\n\t");
-
-	lock_kernel();
-	if (registers[PC] == (unsigned long)breakinst) {
-		/* Skip over breakpoint trap insn */
-		registers[PC] = registers[NPC];
-		registers[NPC] += 4;
-	}
-
-	sp = (unsigned long *)registers[SP];
-
-	tt = (registers[TBR] >> 4) & 0xff;
-
-	/* reply to host that an exception has occurred */
-	sigval = computeSignal(tt);
-	ptr = remcomOutBuffer;
-
-	*ptr++ = 'T';
-	*ptr++ = hexchars[sigval >> 4];
-	*ptr++ = hexchars[sigval & 0xf];
-
-	*ptr++ = hexchars[PC >> 4];
-	*ptr++ = hexchars[PC & 0xf];
-	*ptr++ = ':';
-	ptr = mem2hex((char *)&registers[PC], ptr, 4);
-	*ptr++ = ';';
-
-	*ptr++ = hexchars[FP >> 4];
-	*ptr++ = hexchars[FP & 0xf];
-	*ptr++ = ':';
-	ptr = mem2hex((char *) (sp + 8 + 6), ptr, 4); /* FP */
-	*ptr++ = ';';
-
-	*ptr++ = hexchars[SP >> 4];
-	*ptr++ = hexchars[SP & 0xf];
-	*ptr++ = ':';
-	ptr = mem2hex((char *)&sp, ptr, 4);
-	*ptr++ = ';';
-
-	*ptr++ = hexchars[NPC >> 4];
-	*ptr++ = hexchars[NPC & 0xf];
-	*ptr++ = ':';
-	ptr = mem2hex((char *)&registers[NPC], ptr, 4);
-	*ptr++ = ';';
-
-	*ptr++ = hexchars[O7 >> 4];
-	*ptr++ = hexchars[O7 & 0xf];
-	*ptr++ = ':';
-	ptr = mem2hex((char *)&registers[O7], ptr, 4);
-	*ptr++ = ';';
-
-	*ptr++ = 0;
-
-	putpacket(remcomOutBuffer);
-
-	/* XXX We may want to add some features dealing with poking the
-	 * XXX page tables, the real ones on the srmmu, and what is currently
-	 * XXX loaded in the sun4/sun4c tlb at this point in time.  But this
-	 * XXX also required hacking to the gdb sources directly...
-	 */
-
-	while (1) {
-		remcomOutBuffer[0] = 0;
-
-		getpacket(remcomInBuffer);
-		switch (remcomInBuffer[0]) {
-		case '?':
-			remcomOutBuffer[0] = 'S';
-			remcomOutBuffer[1] = hexchars[sigval >> 4];
-			remcomOutBuffer[2] = hexchars[sigval & 0xf];
-			remcomOutBuffer[3] = 0;
-			break;
-
-		case 'd':
-			/* toggle debug flag */
-			break;
-
-		case 'g':		/* return the value of the CPU registers */
-		{
-			ptr = remcomOutBuffer;
-			/* G & O regs */
-			ptr = mem2hex((char *)registers, ptr, 16 * 4);
-			/* L & I regs */
-			ptr = mem2hex((char *) (sp + 0), ptr, 16 * 4);
-			/* Floating point */
-			memset(ptr, '0', 32 * 8);
-			/* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
-			mem2hex((char *)&registers[Y], (ptr + 32 * 4 * 2), (8 * 4));
-		}
-			break;
-
-		case 'G':	   /* set the value of the CPU registers - return OK */
-		{
-			unsigned long *newsp, psr;
-
-			psr = registers[PSR];
-
-			ptr = &remcomInBuffer[1];
-			/* G & O regs */
-			hex2mem(ptr, (char *)registers, 16 * 4);
-			/* L & I regs */
-			hex2mem(ptr + 16 * 4 * 2, (char *) (sp + 0), 16 * 4);
-			/* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
-			hex2mem(ptr + 64 * 4 * 2, (char *)&registers[Y], 8 * 4);
-
-			/* See if the stack pointer has moved.  If so,
-			 * then copy the saved locals and ins to the
-			 * new location.  This keeps the window
-			 * overflow and underflow routines happy.
-			 */
-
-			newsp = (unsigned long *)registers[SP];
-			if (sp != newsp)
-				sp = memcpy(newsp, sp, 16 * 4);
-
-			/* Don't allow CWP to be modified. */
-
-			if (psr != registers[PSR])
-				registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
-
-			strcpy(remcomOutBuffer,"OK");
-		}
-			break;
-
-		case 'm':	  /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
-			/* Try to read %x,%x.  */
-
-			ptr = &remcomInBuffer[1];
-
-			if (hexToInt(&ptr, &addr)
-			    && *ptr++ == ','
-			    && hexToInt(&ptr, &length))	{
-				if (mem2hex((char *)addr, remcomOutBuffer, length))
-					break;
-
-				strcpy (remcomOutBuffer, "E03");
-			} else {
-				strcpy(remcomOutBuffer,"E01");
-			}
-			break;
-
-		case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
-			/* Try to read '%x,%x:'.  */
-
-			ptr = &remcomInBuffer[1];
-
-			if (hexToInt(&ptr, &addr)
-			    && *ptr++ == ','
-			    && hexToInt(&ptr, &length)
-			    && *ptr++ == ':') {
-				if (hex2mem(ptr, (char *)addr, length)) {
-					strcpy(remcomOutBuffer, "OK");
-				} else {
-					strcpy(remcomOutBuffer, "E03");
-				}
-			} else {
-				strcpy(remcomOutBuffer, "E02");
-			}
-			break;
-
-		case 'c':    /* cAA..AA    Continue at address AA..AA(optional) */
-			/* try to read optional parameter, pc unchanged if no parm */
-
-			ptr = &remcomInBuffer[1];
-			if (hexToInt(&ptr, &addr)) {
-				registers[PC] = addr;
-				registers[NPC] = addr + 4;
-			}
-
-/* Need to flush the instruction cache here, as we may have deposited a
- * breakpoint, and the icache probably has no way of knowing that a data ref to
- * some location may have changed something that is in the instruction cache.
- */
-			flush_cache_all();
-			unlock_kernel();
-			return;
-
-			/* kill the program */
-		case 'k' :		/* do nothing */
-			break;
-		case 'r':		/* Reset */
-			asm ("call 0\n\t"
-			     "nop\n\t");
-			break;
-		}			/* switch */
-
-		/* reply to the request */
-		putpacket(remcomOutBuffer);
-	} /* while(1) */
-}
-
-/* This function will generate a breakpoint exception.  It is used at the
-   beginning of a program to sync up with a debugger and can be used
-   otherwise as a quick means to stop program execution and "break" into
-   the debugger. */
-
-void
-breakpoint(void)
-{
-	if (!initialized)
-		return;
-
-	/* Again, watch those c-prefixes for ELF kernels */
-#if defined(__svr4__) || defined(__ELF__)
-	asm(".globl breakinst\n"
-	    "breakinst:\n\t"
-	    "ta 1\n");
-#else
-	asm(".globl _breakinst\n"
-	    "_breakinst:\n\t"
-	    "ta 1\n");
-#endif
-}