[PATCH 9/21] KGDB: This adds basic support to the MIPS architecture

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Jason Wessel <[email protected]>
mips-lite.patch

From: Jason Wessel <[email protected]>
CC: [email protected]
Subject: [PATCH] This adds basic support to the MIPS architecture

This patch also adds support for the rs232 early kgdb access for MIPS
Malta (via 8250), SiByte 1250-SWARM (32 and 64bit, custom UART), all
from Manish Lachwani, and Toshiba TX493x platforms from Sergei
Shtylyov.

Signed-off-by: Vitaly Wool <[email protected]>
Signed-off-by: Geoff Levand <[email protected]>
Signed-off-by: Sergei Shtylyov <[email protected]>
Signed-off-by: Tom Rini <[email protected]>
Signed-off-by: Jason Wessel <[email protected]>

---
 arch/mips/Kconfig                                          |    8 
 arch/mips/Kconfig.debug                                    |   22 
 arch/mips/au1000/common/Makefile                           |    1 
 arch/mips/au1000/common/dbg_io.c                           |  121 -
 arch/mips/basler/excite/Makefile                           |    1 
 arch/mips/basler/excite/excite_dbg_io.c                    |  121 -
 arch/mips/basler/excite/excite_irq.c                       |    7 
 arch/mips/basler/excite/excite_setup.c                     |    4 
 arch/mips/jmr3927/rbhma3100/Makefile                       |    1 
 arch/mips/jmr3927/rbhma3100/kgdb_io.c                      |  105 -
 arch/mips/kernel/Makefile                                  |    3 
 arch/mips/kernel/gdb-low.S                                 |  394 ----
 arch/mips/kernel/gdb-stub.c                                | 1154 -------------
 arch/mips/kernel/irq.c                                     |   33 
 arch/mips/kernel/kgdb-jmp.c                                |  112 +
 arch/mips/kernel/kgdb-setjmp.S                             |   28 
 arch/mips/kernel/kgdb.c                                    |  293 +++
 arch/mips/kernel/kgdb_handler.S                            |  339 +++
 arch/mips/kernel/traps.c                                   |   13 
 arch/mips/mips-boards/atlas/Makefile                       |    1 
 arch/mips/mips-boards/atlas/atlas_gdb.c                    |   97 -
 arch/mips/mips-boards/atlas/atlas_setup.c                  |    7 
 arch/mips/mips-boards/generic/Makefile                     |    1 
 arch/mips/mips-boards/generic/gdb_hook.c                   |  133 -
 arch/mips/mips-boards/generic/init.c                       |   62 
 arch/mips/mips-boards/malta/malta_setup.c                  |    8 
 arch/mips/mm/extable.c                                     |    7 
 arch/mips/pci/fixup-atlas.c                                |   21 
 arch/mips/philips/pnx8550/common/Makefile                  |    1 
 arch/mips/philips/pnx8550/common/gdb_hook.c                |  109 -
 arch/mips/philips/pnx8550/common/setup.c                   |   11 
 arch/mips/pmc-sierra/yosemite/Makefile                     |    1 
 arch/mips/pmc-sierra/yosemite/dbg_io.c                     |  180 --
 arch/mips/pmc-sierra/yosemite/irq.c                        |    9 
 arch/mips/sgi-ip22/ip22-setup.c                            |   24 
 arch/mips/sgi-ip27/Makefile                                |    1 
 arch/mips/sgi-ip27/ip27-dbgio.c                            |   60 
 arch/mips/sibyte/bcm1480/irq.c                             |   81 
 arch/mips/sibyte/cfe/setup.c                               |   14 
 arch/mips/sibyte/sb1250/irq.c                              |   64 
 arch/mips/sibyte/sb1250/kgdb_sibyte.c                      |  145 +
 arch/mips/sibyte/swarm/Makefile                            |    2 
 arch/mips/sibyte/swarm/dbg_io.c                            |   76 
 arch/mips/tx4927/common/Makefile                           |    1 
 arch/mips/tx4927/common/tx4927_dbgio.c                     |   46 
 arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c |   12 
 arch/mips/tx4938/common/Makefile                           |    1 
 arch/mips/tx4938/common/dbgio.c                            |   50 
 arch/mips/tx4938/toshiba_rbtx4938/setup.c                  |   10 
 drivers/serial/Makefile                                    |    1 
 drivers/serial/serial_txx9.c                               |   13 
 drivers/serial/serial_txx9_kgdb.c                          |  152 +
 include/asm-mips/asmmacro-32.h                             |   43 
 include/asm-mips/asmmacro-64.h                             |   99 +
 include/asm-mips/kdebug.h                                  |   30 
 include/asm-mips/kgdb.h                                    |   48 
 lib/Kconfig.kgdb                                           |   19 
 57 files changed, 1384 insertions(+), 3016 deletions(-)

--- a/arch/mips/Kconfig.debug
+++ b/arch/mips/Kconfig.debug
@@ -46,28 +46,6 @@ config SMTC_IDLE_HOOK_DEBUG
 	  arch/mips/kernel/smtc.c.  This debugging option result in significant
 	  overhead so should be disabled in production kernels.
 
-config KGDB
-	bool "Remote GDB kernel debugging"
-	depends on DEBUG_KERNEL && SYS_SUPPORTS_KGDB
-	select DEBUG_INFO
-	help
-	  If you say Y here, it will be possible to remotely debug the MIPS
-	  kernel using gdb. This enlarges your kernel image disk size by
-	  several megabytes and requires a machine with more than 16 MB,
-	  better 32 MB RAM to avoid excessive linking time. This is only
-	  useful for kernel hackers. If unsure, say N.
-
-config SYS_SUPPORTS_KGDB
-	bool
-
-config GDB_CONSOLE
-	bool "Console output to GDB"
-	depends on KGDB
-	help
-	  If you are using GDB for remote debugging over a serial port and
-	  would like kernel messages to be formatted into GDB $O packets so
-	  that GDB prints them as program output, say 'Y'.
-
 config SB1XXX_CORELIS
 	bool "Corelis Debugger"
 	depends on SIBYTE_SB1xxx_SOC
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -60,7 +60,8 @@ obj-$(CONFIG_MIPS32_COMPAT)	+= linux32.o
 obj-$(CONFIG_MIPS32_N32)	+= binfmt_elfn32.o scall64-n32.o signal_n32.o
 obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o
 
-obj-$(CONFIG_KGDB)		+= gdb-low.o gdb-stub.o
+obj-$(CONFIG_KGDB)		+= kgdb_handler.o kgdb.o kgdb-jmp.o	\
+					kgdb-setjmp.o
 obj-$(CONFIG_PROC_FS)		+= proc.o
 
 obj-$(CONFIG_64BIT)		+= cpu-bugs64.o
--- a/arch/mips/kernel/gdb-stub.c
+++ /dev/null
@@ -1,1154 +0,0 @@
-/*
- *  arch/mips/kernel/gdb-stub.c
- *
- *  Originally written by Glenn Engel, Lake Stevens Instrument Division
- *
- *  Contributed by HP Systems
- *
- *  Modified for SPARC by Stu Grossman, Cygnus Support.
- *
- *  Modified for Linux/MIPS (and MIPS in general) by Andreas Busse
- *  Send complaints, suggestions etc. to <[email protected]>
- *
- *  Copyright (C) 1995 Andreas Busse
- *
- *  Copyright (C) 2003 MontaVista Software Inc.
- *  Author: Jun Sun, [email protected] or [email protected]
- */
-
-/*
- *  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 BREAK instruction.
- *
- *
- *    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
- *
- *
- *  ==============
- *  MORE EXAMPLES:
- *  ==============
- *
- *  For reference -- the following are the steps that one
- *  company took (RidgeRun Inc) to get remote gdb debugging
- *  going. In this scenario the host machine was a PC and the
- *  target platform was a Galileo EVB64120A MIPS evaluation
- *  board.
- *
- *  Step 1:
- *  First download gdb-5.0.tar.gz from the internet.
- *  and then build/install the package.
- *
- *  Example:
- *    $ tar zxf gdb-5.0.tar.gz
- *    $ cd gdb-5.0
- *    $ ./configure --target=mips-linux-elf
- *    $ make
- *    $ install
- *    $ which mips-linux-elf-gdb
- *    /usr/local/bin/mips-linux-elf-gdb
- *
- *  Step 2:
- *  Configure linux for remote debugging and build it.
- *
- *  Example:
- *    $ cd ~/linux
- *    $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging>
- *    $ make
- *
- *  Step 3:
- *  Download the kernel to the remote target and start
- *  the kernel running. It will promptly halt and wait
- *  for the host gdb session to connect. It does this
- *  since the "Kernel Hacking" option has defined
- *  CONFIG_KGDB which in turn enables your calls
- *  to:
- *     set_debug_traps();
- *     breakpoint();
- *
- *  Step 4:
- *  Start the gdb session on the host.
- *
- *  Example:
- *    $ mips-linux-elf-gdb vmlinux
- *    (gdb) set remotebaud 115200
- *    (gdb) target remote /dev/ttyS1
- *    ...at this point you are connected to
- *       the remote target and can use gdb
- *       in the normal fasion. Setting
- *       breakpoints, single stepping,
- *       printing variables, etc.
- */
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/console.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/reboot.h>
-
-#include <asm/asm.h>
-#include <asm/cacheflush.h>
-#include <asm/mipsregs.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/gdb-stub.h>
-#include <asm/inst.h>
-#include <asm/smp.h>
-
-/*
- * external low-level support routines
- */
-
-extern int putDebugChar(char c);    /* write a single character      */
-extern char getDebugChar(void);     /* read and return a single char */
-extern void trap_low(void);
-
-/*
- * breakpoint and test functions
- */
-extern void breakpoint(void);
-extern void breakinst(void);
-extern void async_breakpoint(void);
-extern void async_breakinst(void);
-extern void adel(void);
-
-/*
- * local prototypes
- */
-
-static void getpacket(char *buffer);
-static void putpacket(char *buffer);
-static int computeSignal(int tt);
-static int hex(unsigned char ch);
-static int hexToInt(char **ptr, int *intValue);
-static int hexToLong(char **ptr, long *longValue);
-static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault);
-void handle_exception(struct gdb_regs *regs);
-
-int kgdb_enabled;
-
-/*
- * spin locks for smp case
- */
-static DEFINE_SPINLOCK(kgdb_lock);
-static raw_spinlock_t kgdb_cpulock[NR_CPUS] = {
-	[0 ... NR_CPUS-1] = __RAW_SPIN_LOCK_UNLOCKED,
-};
-
-/*
- * BUFMAX defines the maximum number of characters in inbound/outbound buffers
- * at least NUMREGBYTES*2 are needed for register packets
- */
-#define BUFMAX 2048
-
-static char input_buffer[BUFMAX];
-static char output_buffer[BUFMAX];
-static int initialized;	/* !0 means we've been initialized */
-static int kgdb_started;
-static const char hexchars[]="0123456789abcdef";
-
-/* Used to prevent crashes in memory access.  Note that they'll crash anyway if
-   we haven't set up fault handlers yet... */
-int kgdb_read_byte(unsigned char *address, unsigned char *dest);
-int kgdb_write_byte(unsigned char val, unsigned char *dest);
-
-/*
- * 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();
-			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 sequence 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(char *buffer)
-{
-	unsigned char checksum;
-	int count;
-	unsigned char ch;
-
-	/*
-	 * $<packet info>#<checksum>.
-	 */
-
-	do {
-		putDebugChar('$');
-		checksum = 0;
-		count = 0;
-
-		while ((ch = buffer[count]) != 0) {
-			if (!(putDebugChar(ch)))
-				return;
-			checksum += ch;
-			count += 1;
-		}
-
-		putDebugChar('#');
-		putDebugChar(hexchars[checksum >> 4]);
-		putDebugChar(hexchars[checksum & 0xf]);
-
-	}
-	while ((getDebugChar() & 0x7f) != '+');
-}
-
-
-/*
- * 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.
- * may_fault is non-zero if we are reading from arbitrary memory, but is currently
- * not used.
- */
-static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault)
-{
-	unsigned char ch;
-
-	while (count-- > 0) {
-		if (kgdb_read_byte(mem++, &ch) != 0)
-			return 0;
-		*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
- * may_fault is non-zero if we are reading from arbitrary memory, but is currently
- * not used.
- */
-static char *hex2mem(char *buf, char *mem, int count, int binary, int may_fault)
-{
-	int i;
-	unsigned char ch;
-
-	for (i=0; i<count; i++)
-	{
-		if (binary) {
-			ch = *buf++;
-			if (ch == 0x7d)
-				ch = 0x20 ^ *buf++;
-		}
-		else {
-			ch = hex(*buf++) << 4;
-			ch |= hex(*buf++);
-		}
-		if (kgdb_write_byte(ch, mem++) != 0)
-			return 0;
-	}
-
-	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 MIPS R3xxx and R4xxx */
-	unsigned char signo;		/* Signal that we map this trap into */
-} hard_trap_info[] = {
-	{ 6, SIGBUS },			/* instruction bus error */
-	{ 7, SIGBUS },			/* data bus error */
-	{ 9, SIGTRAP },			/* break */
-	{ 10, SIGILL },			/* reserved instruction */
-/*	{ 11, SIGILL },		*/	/* CPU unusable */
-	{ 12, SIGFPE },			/* overflow */
-	{ 13, SIGTRAP },		/* trap */
-	{ 14, SIGSEGV },		/* virtual instruction cache coherency */
-	{ 15, SIGFPE },			/* floating point exception */
-	{ 23, SIGSEGV },		/* watch */
-	{ 31, SIGSEGV },		/* virtual data cache coherency */
-	{ 0, 0}				/* Must be last */
-};
-
-/* Save the normal trap handlers for user-mode traps. */
-void *saved_vectors[32];
-
-/*
- * Set up exception handlers for tracing and breakpoints
- */
-void set_debug_traps(void)
-{
-	struct hard_trap_info *ht;
-	unsigned long flags;
-	unsigned char c;
-
-	local_irq_save(flags);
-	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
-		saved_vectors[ht->tt] = set_except_vector(ht->tt, trap_low);
-
-	putDebugChar('+'); /* 'hello world' */
-	/*
-	 * In case GDB is started before us, ack any packets
-	 * (presumably "$?#xx") sitting there.
-	 */
-	while((c = getDebugChar()) != '$');
-	while((c = getDebugChar()) != '#');
-	c = getDebugChar(); /* eat first csum byte */
-	c = getDebugChar(); /* eat second csum byte */
-	putDebugChar('+'); /* ack it */
-
-	initialized = 1;
-	local_irq_restore(flags);
-}
-
-void restore_debug_traps(void)
-{
-	struct hard_trap_info *ht;
-	unsigned long flags;
-
-	local_irq_save(flags);
-	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
-		set_except_vector(ht->tt, saved_vectors[ht->tt]);
-	local_irq_restore(flags);
-}
-
-/*
- * Convert the MIPS 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);
-}
-
-static int hexToLong(char **ptr, long *longValue)
-{
-	int numChars = 0;
-	int hexValue;
-
-	*longValue = 0;
-
-	while (**ptr) {
-		hexValue = hex(**ptr);
-		if (hexValue < 0)
-			break;
-
-		*longValue = (*longValue << 4) | hexValue;
-		numChars ++;
-
-		(*ptr)++;
-	}
-
-	return numChars;
-}
-
-
-#if 0
-/*
- * Print registers (on target console)
- * Used only to debug the stub...
- */
-void show_gdbregs(struct gdb_regs * regs)
-{
-	/*
-	 * Saved main processor registers
-	 */
-	printk("$0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-	       regs->reg0, regs->reg1, regs->reg2, regs->reg3,
-	       regs->reg4, regs->reg5, regs->reg6, regs->reg7);
-	printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-	       regs->reg8, regs->reg9, regs->reg10, regs->reg11,
-	       regs->reg12, regs->reg13, regs->reg14, regs->reg15);
-	printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-	       regs->reg16, regs->reg17, regs->reg18, regs->reg19,
-	       regs->reg20, regs->reg21, regs->reg22, regs->reg23);
-	printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-	       regs->reg24, regs->reg25, regs->reg26, regs->reg27,
-	       regs->reg28, regs->reg29, regs->reg30, regs->reg31);
-
-	/*
-	 * Saved cp0 registers
-	 */
-	printk("epc  : %08lx\nStatus: %08lx\nCause : %08lx\n",
-	       regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
-}
-#endif /* dead code */
-
-/*
- * We single-step by setting breakpoints. When an exception
- * is handled, we need to restore the instructions hoisted
- * when the breakpoints were set.
- *
- * This is where we save the original instructions.
- */
-static struct gdb_bp_save {
-	unsigned long addr;
-	unsigned int val;
-} step_bp[2];
-
-#define BP 0x0000000d  /* break opcode */
-
-/*
- * Set breakpoint instructions for single stepping.
- */
-static void single_step(struct gdb_regs *regs)
-{
-	union mips_instruction insn;
-	unsigned long targ;
-	int is_branch, is_cond, i;
-
-	targ = regs->cp0_epc;
-	insn.word = *(unsigned int *)targ;
-	is_branch = is_cond = 0;
-
-	switch (insn.i_format.opcode) {
-	/*
-	 * jr and jalr are in r_format format.
-	 */
-	case spec_op:
-		switch (insn.r_format.func) {
-		case jalr_op:
-		case jr_op:
-			targ = *(&regs->reg0 + insn.r_format.rs);
-			is_branch = 1;
-			break;
-		}
-		break;
-
-	/*
-	 * This group contains:
-	 * bltz_op, bgez_op, bltzl_op, bgezl_op,
-	 * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
-	 */
-	case bcond_op:
-		is_branch = is_cond = 1;
-		targ += 4 + (insn.i_format.simmediate << 2);
-		break;
-
-	/*
-	 * These are unconditional and in j_format.
-	 */
-	case jal_op:
-	case j_op:
-		is_branch = 1;
-		targ += 4;
-		targ >>= 28;
-		targ <<= 28;
-		targ |= (insn.j_format.target << 2);
-		break;
-
-	/*
-	 * These are conditional.
-	 */
-	case beq_op:
-	case beql_op:
-	case bne_op:
-	case bnel_op:
-	case blez_op:
-	case blezl_op:
-	case bgtz_op:
-	case bgtzl_op:
-	case cop0_op:
-	case cop1_op:
-	case cop2_op:
-	case cop1x_op:
-		is_branch = is_cond = 1;
-		targ += 4 + (insn.i_format.simmediate << 2);
-		break;
-	}
-
-	if (is_branch) {
-		i = 0;
-		if (is_cond && targ != (regs->cp0_epc + 8)) {
-			step_bp[i].addr = regs->cp0_epc + 8;
-			step_bp[i++].val = *(unsigned *)(regs->cp0_epc + 8);
-			*(unsigned *)(regs->cp0_epc + 8) = BP;
-		}
-		step_bp[i].addr = targ;
-		step_bp[i].val  = *(unsigned *)targ;
-		*(unsigned *)targ = BP;
-	} else {
-		step_bp[0].addr = regs->cp0_epc + 4;
-		step_bp[0].val  = *(unsigned *)(regs->cp0_epc + 4);
-		*(unsigned *)(regs->cp0_epc + 4) = BP;
-	}
-}
-
-/*
- *  If asynchronously interrupted by gdb, then we need to set a breakpoint
- *  at the interrupted instruction so that we wind up stopped with a
- *  reasonable stack frame.
- */
-static struct gdb_bp_save async_bp;
-
-/*
- * Swap the interrupted EPC with our asynchronous breakpoint routine.
- * This is safer than stuffing the breakpoint in-place, since no cache
- * flushes (or resulting smp_call_functions) are required.  The
- * assumption is that only one CPU will be handling asynchronous bp's,
- * and only one can be active at a time.
- */
-extern spinlock_t smp_call_lock;
-
-void set_async_breakpoint(unsigned long *epc)
-{
-	/* skip breaking into userland */
-	if ((*epc & 0x80000000) == 0)
-		return;
-
-#ifdef CONFIG_SMP
-	/* avoid deadlock if someone is make IPC */
-	if (spin_is_locked(&smp_call_lock))
-		return;
-#endif
-
-	async_bp.addr = *epc;
-	*epc = (unsigned long)async_breakpoint;
-}
-
-static void kgdb_wait(void *arg)
-{
-	unsigned flags;
-	int cpu = smp_processor_id();
-
-	local_irq_save(flags);
-
-	__raw_spin_lock(&kgdb_cpulock[cpu]);
-	__raw_spin_unlock(&kgdb_cpulock[cpu]);
-
-	local_irq_restore(flags);
-}
-
-/*
- * GDB stub needs to call kgdb_wait on all processor with interrupts
- * disabled, so it uses it's own special variant.
- */
-static int kgdb_smp_call_kgdb_wait(void)
-{
-#ifdef CONFIG_SMP
-	cpumask_t mask = cpu_online_map;
-	struct call_data_struct data;
-	int cpu = smp_processor_id();
-	int cpus;
-
-	/*
-	 * Can die spectacularly if this CPU isn't yet marked online
-	 */
-	BUG_ON(!cpu_online(cpu));
-
-	cpu_clear(cpu, mask);
-	cpus = cpus_weight(mask);
-	if (!cpus)
-		return 0;
-
-	if (spin_is_locked(&smp_call_lock)) {
-		/*
-		 * Some other processor is trying to make us do something
-		 * but we're not going to respond... give up
-		 */
-		return -1;
-		}
-
-	/*
-	 * We will continue here, accepting the fact that
-	 * the kernel may deadlock if another CPU attempts
-	 * to call smp_call_function now...
-	 */
-
-	data.func = kgdb_wait;
-	data.info = NULL;
-	atomic_set(&data.started, 0);
-	data.wait = 0;
-
-	spin_lock(&smp_call_lock);
-	call_data = &data;
-	mb();
-
-	core_send_ipi_mask(mask, SMP_CALL_FUNCTION);
-
-	/* Wait for response */
-	/* FIXME: lock-up detection, backtrace on lock-up */
-	while (atomic_read(&data.started) != cpus)
-		barrier();
-
-	call_data = NULL;
-	spin_unlock(&smp_call_lock);
-#endif
-
-	return 0;
-}
-
-/*
- * 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.
- */
-void handle_exception(struct gdb_regs *regs)
-{
-	int trap;			/* Trap type */
-	int sigval;
-	long addr;
-	int length;
-	char *ptr;
-	unsigned long *stack;
-	int i;
-	int bflag = 0;
-
-	kgdb_started = 1;
-
-	/*
-	 * acquire the big kgdb spinlock
-	 */
-	if (!spin_trylock(&kgdb_lock)) {
-		/*
-		 * some other CPU has the lock, we should go back to
-		 * receive the gdb_wait IPC
-		 */
-		return;
-	}
-
-	/*
-	 * If we're in async_breakpoint(), restore the real EPC from
-	 * the breakpoint.
-	 */
-	if (regs->cp0_epc == (unsigned long)async_breakinst) {
-		regs->cp0_epc = async_bp.addr;
-		async_bp.addr = 0;
-	}
-
-	/*
-	 * acquire the CPU spinlocks
-	 */
-	for_each_online_cpu(i)
-		if (__raw_spin_trylock(&kgdb_cpulock[i]) == 0)
-			panic("kgdb: couldn't get cpulock %d\n", i);
-
-	/*
-	 * force other cpus to enter kgdb
-	 */
-	kgdb_smp_call_kgdb_wait();
-
-	/*
-	 * If we're in breakpoint() increment the PC
-	 */
-	trap = (regs->cp0_cause & 0x7c) >> 2;
-	if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst)
-		regs->cp0_epc += 4;
-
-	/*
-	 * If we were single_stepping, restore the opcodes hoisted
-	 * for the breakpoint[s].
-	 */
-	if (step_bp[0].addr) {
-		*(unsigned *)step_bp[0].addr = step_bp[0].val;
-		step_bp[0].addr = 0;
-
-		if (step_bp[1].addr) {
-			*(unsigned *)step_bp[1].addr = step_bp[1].val;
-			step_bp[1].addr = 0;
-		}
-	}
-
-	stack = (long *)regs->reg29;			/* stack ptr */
-	sigval = computeSignal(trap);
-
-	/*
-	 * reply to host that an exception has occurred
-	 */
-	ptr = output_buffer;
-
-	/*
-	 * Send trap type (converted to signal)
-	 */
-	*ptr++ = 'T';
-	*ptr++ = hexchars[sigval >> 4];
-	*ptr++ = hexchars[sigval & 0xf];
-
-	/*
-	 * Send Error PC
-	 */
-	*ptr++ = hexchars[REG_EPC >> 4];
-	*ptr++ = hexchars[REG_EPC & 0xf];
-	*ptr++ = ':';
-	ptr = mem2hex((char *)&regs->cp0_epc, ptr, sizeof(long), 0);
-	*ptr++ = ';';
-
-	/*
-	 * Send frame pointer
-	 */
-	*ptr++ = hexchars[REG_FP >> 4];
-	*ptr++ = hexchars[REG_FP & 0xf];
-	*ptr++ = ':';
-	ptr = mem2hex((char *)&regs->reg30, ptr, sizeof(long), 0);
-	*ptr++ = ';';
-
-	/*
-	 * Send stack pointer
-	 */
-	*ptr++ = hexchars[REG_SP >> 4];
-	*ptr++ = hexchars[REG_SP & 0xf];
-	*ptr++ = ':';
-	ptr = mem2hex((char *)&regs->reg29, ptr, sizeof(long), 0);
-	*ptr++ = ';';
-
-	*ptr++ = 0;
-	putpacket(output_buffer);	/* send it off... */
-
-	/*
-	 * Wait for input from remote GDB
-	 */
-	while (1) {
-		output_buffer[0] = 0;
-		getpacket(input_buffer);
-
-		switch (input_buffer[0])
-		{
-		case '?':
-			output_buffer[0] = 'S';
-			output_buffer[1] = hexchars[sigval >> 4];
-			output_buffer[2] = hexchars[sigval & 0xf];
-			output_buffer[3] = 0;
-			break;
-
-		/*
-		 * Detach debugger; let CPU run
-		 */
-		case 'D':
-			putpacket(output_buffer);
-			goto finish_kgdb;
-			break;
-
-		case 'd':
-			/* toggle debug flag */
-			break;
-
-		/*
-		 * Return the value of the CPU registers
-		 */
-		case 'g':
-			ptr = output_buffer;
-			ptr = mem2hex((char *)&regs->reg0, ptr, 32*sizeof(long), 0); /* r0...r31 */
-			ptr = mem2hex((char *)&regs->cp0_status, ptr, 6*sizeof(long), 0); /* cp0 */
-			ptr = mem2hex((char *)&regs->fpr0, ptr, 32*sizeof(long), 0); /* f0...31 */
-			ptr = mem2hex((char *)&regs->cp1_fsr, ptr, 2*sizeof(long), 0); /* cp1 */
-			ptr = mem2hex((char *)&regs->frame_ptr, ptr, 2*sizeof(long), 0); /* frp */
-			ptr = mem2hex((char *)&regs->cp0_index, ptr, 16*sizeof(long), 0); /* cp0 */
-			break;
-
-		/*
-		 * set the value of the CPU registers - return OK
-		 */
-		case 'G':
-		{
-			ptr = &input_buffer[1];
-			hex2mem(ptr, (char *)&regs->reg0, 32*sizeof(long), 0, 0);
-			ptr += 32*(2*sizeof(long));
-			hex2mem(ptr, (char *)&regs->cp0_status, 6*sizeof(long), 0, 0);
-			ptr += 6*(2*sizeof(long));
-			hex2mem(ptr, (char *)&regs->fpr0, 32*sizeof(long), 0, 0);
-			ptr += 32*(2*sizeof(long));
-			hex2mem(ptr, (char *)&regs->cp1_fsr, 2*sizeof(long), 0, 0);
-			ptr += 2*(2*sizeof(long));
-			hex2mem(ptr, (char *)&regs->frame_ptr, 2*sizeof(long), 0, 0);
-			ptr += 2*(2*sizeof(long));
-			hex2mem(ptr, (char *)&regs->cp0_index, 16*sizeof(long), 0, 0);
-			strcpy(output_buffer, "OK");
-		 }
-		break;
-
-		/*
-		 * mAA..AA,LLLL  Read LLLL bytes at address AA..AA
-		 */
-		case 'm':
-			ptr = &input_buffer[1];
-
-			if (hexToLong(&ptr, &addr)
-				&& *ptr++ == ','
-				&& hexToInt(&ptr, &length)) {
-				if (mem2hex((char *)addr, output_buffer, length, 1))
-					break;
-				strcpy(output_buffer, "E03");
-			} else
-				strcpy(output_buffer, "E01");
-			break;
-
-		/*
-		 * XAA..AA,LLLL: Write LLLL escaped binary bytes at address AA.AA
-		 */
-		case 'X':
-			bflag = 1;
-			/* fall through */
-
-		/*
-		 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK
-		 */
-		case 'M':
-			ptr = &input_buffer[1];
-
-			if (hexToLong(&ptr, &addr)
-				&& *ptr++ == ','
-				&& hexToInt(&ptr, &length)
-				&& *ptr++ == ':') {
-				if (hex2mem(ptr, (char *)addr, length, bflag, 1))
-					strcpy(output_buffer, "OK");
-				else
-					strcpy(output_buffer, "E03");
-			}
-			else
-				strcpy(output_buffer, "E02");
-			break;
-
-		/*
-		 * cAA..AA    Continue at address AA..AA(optional)
-		 */
-		case 'c':
-			/* try to read optional parameter, pc unchanged if no parm */
-
-			ptr = &input_buffer[1];
-			if (hexToLong(&ptr, &addr))
-				regs->cp0_epc = addr;
-
-			goto exit_kgdb_exception;
-			break;
-
-		/*
-		 * kill the program; let us try to restart the machine
-		 * Reset the whole machine.
-		 */
-		case 'k':
-		case 'r':
-			machine_restart("kgdb restarts machine");
-			break;
-
-		/*
-		 * Step to next instruction
-		 */
-		case 's':
-			/*
-			 * There is no single step insn in the MIPS ISA, so we
-			 * use breakpoints and continue, instead.
-			 */
-			single_step(regs);
-			goto exit_kgdb_exception;
-			/* NOTREACHED */
-			break;
-
-		/*
-		 * Set baud rate (bBB)
-		 * FIXME: Needs to be written
-		 */
-		case 'b':
-		{
-#if 0
-			int baudrate;
-			extern void set_timer_3();
-
-			ptr = &input_buffer[1];
-			if (!hexToInt(&ptr, &baudrate))
-			{
-				strcpy(output_buffer, "B01");
-				break;
-			}
-
-			/* Convert baud rate to uart clock divider */
-
-			switch (baudrate)
-			{
-				case 38400:
-					baudrate = 16;
-					break;
-				case 19200:
-					baudrate = 33;
-					break;
-				case 9600:
-					baudrate = 65;
-					break;
-				default:
-					baudrate = 0;
-					strcpy(output_buffer, "B02");
-					goto x1;
-			}
-
-			if (baudrate) {
-				putpacket("OK");	/* Ack before changing speed */
-				set_timer_3(baudrate); /* Set it */
-			}
-#endif
-		}
-		break;
-
-		}			/* switch */
-
-		/*
-		 * reply to the request
-		 */
-
-		putpacket(output_buffer);
-
-	} /* while */
-
-	return;
-
-finish_kgdb:
-	restore_debug_traps();
-
-exit_kgdb_exception:
-	/* release locks so other CPUs can go */
-	for_each_online_cpu(i)
-		__raw_spin_unlock(&kgdb_cpulock[i]);
-	spin_unlock(&kgdb_lock);
-
-	__flush_cache_all();
-	return;
-}
-
-/*
- * 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;
-
-	__asm__ __volatile__(
-			".globl	breakinst\n\t"
-			".set\tnoreorder\n\t"
-			"nop\n"
-			"breakinst:\tbreak\n\t"
-			"nop\n\t"
-			".set\treorder"
-			);
-}
-
-/* Nothing but the break; don't pollute any registers */
-void async_breakpoint(void)
-{
-	__asm__ __volatile__(
-			".globl	async_breakinst\n\t"
-			".set\tnoreorder\n\t"
-			"nop\n"
-			"async_breakinst:\tbreak\n\t"
-			"nop\n\t"
-			".set\treorder"
-			);
-}
-
-void adel(void)
-{
-	__asm__ __volatile__(
-			".globl\tadel\n\t"
-			"lui\t$8,0x8000\n\t"
-			"lw\t$9,1($8)\n\t"
-			);
-}
-
-/*
- * malloc is needed by gdb client in "call func()", even a private one
- * will make gdb happy
- */
-static void __used *malloc(size_t size)
-{
-	return kmalloc(size, GFP_ATOMIC);
-}
-
-static void __used free(void *where)
-{
-	kfree(where);
-}
-
-#ifdef CONFIG_GDB_CONSOLE
-
-void gdb_putsn(const char *str, int l)
-{
-	char outbuf[18];
-
-	if (!kgdb_started)
-		return;
-
-	outbuf[0]='O';
-
-	while(l) {
-		int i = (l>8)?8:l;
-		mem2hex((char *)str, &outbuf[1], i, 0);
-		outbuf[(i*2)+1]=0;
-		putpacket(outbuf);
-		str += i;
-		l -= i;
-	}
-}
-
-static void gdb_console_write(struct console *con, const char *s, unsigned n)
-{
-	gdb_putsn(s, n);
-}
-
-static struct console gdb_console = {
-	.name	= "gdb",
-	.write	= gdb_console_write,
-	.flags	= CON_PRINTBUFFER,
-	.index	= -1
-};
-
-static int __init register_gdb_console(void)
-{
-	register_console(&gdb_console);
-
-	return 0;
-}
-
-console_initcall(register_gdb_console);
-
-#endif
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -21,11 +21,15 @@
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/kallsyms.h>
+#include <linux/kgdb.h>
 
 #include <asm/atomic.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
+/* Keep track of if we've done certain initialization already or not. */
+int kgdb_early_setup;
+
 static unsigned long irq_map[NR_IRQS / BITS_PER_LONG];
 
 int allocate_irqno(void)
@@ -130,28 +134,23 @@ asmlinkage void spurious_interrupt(void)
 	atomic_inc(&irq_err_count);
 }
 
-#ifdef CONFIG_KGDB
-extern void breakpoint(void);
-extern void set_debug_traps(void);
-
-static int kgdb_flag = 1;
-static int __init nokgdb(char *str)
+void __init init_IRQ(void)
 {
-	kgdb_flag = 0;
-	return 1;
-}
-__setup("nokgdb", nokgdb);
+
+#ifdef CONFIG_KGDB
+	if (kgdb_early_setup)
+		return;
 #endif
 
-void __init init_IRQ(void)
-{
 	arch_init_irq();
 
+
 #ifdef CONFIG_KGDB
-	if (kgdb_flag) {
-		printk("Wait for gdb client connection ...\n");
-		set_debug_traps();
-		breakpoint();
-	}
+	/*
+	 * We have been called before kgdb_arch_init(). Hence,
+	 * we dont want the traps to be reinitialized
+	 */
+	if (kgdb_early_setup == 0)
+		kgdb_early_setup = 1;
 #endif
 }
--- /dev/null
+++ b/arch/mips/kernel/kgdb-jmp.c
@@ -0,0 +1,112 @@
+/*
+ * arch/mips/kernel/kgdb-jmp.c
+ *
+ * Save and restore system registers so that within a limited frame we
+ * may have a fault and "jump back" to a known safe location.
+ *
+ * Author: Tom Rini <[email protected]>
+ * Author: Manish Lachwani <[email protected]>
+ *
+ * Cribbed from glibc, which carries the following:
+ * Copyright (C) 1996, 1997, 2000, 2002, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2005-2006 by MontaVista Software.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program as licensed "as is" without any warranty of
+ * any kind, whether express or implied.
+ */
+
+#include <linux/kgdb.h>
+
+#ifdef CONFIG_64BIT
+/*
+ * MIPS 64-bit
+ */
+
+int kgdb_fault_setjmp_aux(unsigned long *curr_context, unsigned long sp,
+	unsigned long fp)
+{
+	__asm__ __volatile__ ("sd $gp, %0" : : "m" (curr_context[0]));
+	__asm__ __volatile__ ("sd $16, %0" : : "m" (curr_context[1]));
+	__asm__ __volatile__ ("sd $17, %0" : : "m" (curr_context[2]));
+	__asm__ __volatile__ ("sd $18, %0" : : "m" (curr_context[3]));
+	__asm__ __volatile__ ("sd $19, %0" : : "m" (curr_context[4]));
+	__asm__ __volatile__ ("sd $20, %0" : : "m" (curr_context[5]));
+	__asm__ __volatile__ ("sd $21, %0" : : "m" (curr_context[6]));
+	__asm__ __volatile__ ("sd $22, %0" : : "m" (curr_context[7]));
+	__asm__ __volatile__ ("sd $23, %0" : : "m" (curr_context[8]));
+	__asm__ __volatile__ ("sd $31, %0" : : "m" (curr_context[9]));
+	curr_context[10] = sp;
+	curr_context[11] = fp;
+
+	return 0;
+}
+
+void kgdb_fault_longjmp(unsigned long *curr_context)
+{
+	__asm__ __volatile__ ("ld $gp, %0" : : "m" (curr_context[0]));
+	__asm__ __volatile__ ("ld $16, %0" : : "m" (curr_context[1]));
+	__asm__ __volatile__ ("ld $17, %0" : : "m" (curr_context[2]));
+	__asm__ __volatile__ ("ld $18, %0" : : "m" (curr_context[3]));
+	__asm__ __volatile__ ("ld $19, %0" : : "m" (curr_context[4]));
+	__asm__ __volatile__ ("ld $20, %0" : : "m" (curr_context[5]));
+	__asm__ __volatile__ ("ld $21, %0" : : "m" (curr_context[6]));
+	__asm__ __volatile__ ("ld $22, %0" : : "m" (curr_context[7]));
+	__asm__ __volatile__ ("ld $23, %0" : : "m" (curr_context[8]));
+	__asm__ __volatile__ ("ld $25, %0" : : "m" (curr_context[9]));
+	__asm__ __volatile__ ("ld $29, %0\n\t"
+			      "ld $30, %1\n\t" : :
+			      "m" (curr_context[10]), "m" (curr_context[11]));
+
+	__asm__ __volatile__ ("dli $2, 1");
+	__asm__ __volatile__ ("j $25");
+
+	for (;;);
+}
+#else
+/*
+ * MIPS 32-bit
+ */
+
+int kgdb_fault_setjmp_aux(unsigned long *curr_context, unsigned long sp,
+	unsigned long fp)
+{
+	__asm__ __volatile__("sw $gp, %0" : : "m" (curr_context[0]));
+	__asm__ __volatile__("sw $16, %0" : : "m" (curr_context[1]));
+	__asm__ __volatile__("sw $17, %0" : : "m" (curr_context[2]));
+	__asm__ __volatile__("sw $18, %0" : : "m" (curr_context[3]));
+	__asm__ __volatile__("sw $19, %0" : : "m" (curr_context[4]));
+	__asm__ __volatile__("sw $20, %0" : : "m" (curr_context[5]));
+	__asm__ __volatile__("sw $21, %0" : : "m" (curr_context[6]));
+	__asm__ __volatile__("sw $22, %0" : : "m" (curr_context[7]));
+	__asm__ __volatile__("sw $23, %0" : : "m" (curr_context[8]));
+	__asm__ __volatile__("sw $31, %0" : : "m" (curr_context[9]));
+	curr_context[10] = sp;
+	curr_context[11] = fp;
+
+	return 0;
+}
+
+void kgdb_fault_longjmp(unsigned long *curr_context)
+{
+	__asm__ __volatile__("lw $gp, %0" : : "m" (curr_context[0]));
+	__asm__ __volatile__("lw $16, %0" : : "m" (curr_context[1]));
+	__asm__ __volatile__("lw $17, %0" : : "m" (curr_context[2]));
+	__asm__ __volatile__("lw $18, %0" : : "m" (curr_context[3]));
+	__asm__ __volatile__("lw $19, %0" : : "m" (curr_context[4]));
+	__asm__ __volatile__("lw $20, %0" : : "m" (curr_context[5]));
+	__asm__ __volatile__("lw $21, %0" : : "m" (curr_context[6]));
+	__asm__ __volatile__("lw $22, %0" : : "m" (curr_context[7]));
+	__asm__ __volatile__("lw $23, %0" : : "m" (curr_context[8]));
+	__asm__ __volatile__("lw $25, %0" : : "m" (curr_context[9]));
+
+	__asm__ __volatile__("lw $29, %0\n\t"
+			     "lw $30, %1\n\t" : :
+			     "m" (curr_context[10]), "m" (curr_context[11]));
+
+	__asm__ __volatile__("li $2, 1");
+	__asm__ __volatile__("jr $25");
+
+	for (;;);
+}
+#endif
--- /dev/null
+++ b/arch/mips/kernel/kgdb-setjmp.S
@@ -0,0 +1,28 @@
+/*
+ * arch/mips/kernel/kgdb-jmp.c
+ *
+ * Save and restore system registers so that within a limited frame we
+ * may have a fault and "jump back" to a known safe location.
+ *
+ * Copyright (C) 2005 by MontaVista Software.
+ * Author: Manish Lachwani ([email protected])
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program as licensed "as is" without any warranty of
+ * any kind, whether express or implied.
+ */
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.ent	kgdb_fault_setjmp,0
+ENTRY (kgdb_fault_setjmp)
+	move    a1, sp
+	move	a2, fp
+#ifdef CONFIG_64BIT
+	nop
+#endif
+	j	kgdb_fault_setjmp_aux
+	.end	kgdb_fault_setjmp
--- /dev/null
+++ b/arch/mips/kernel/kgdb.c
@@ -0,0 +1,293 @@
+/*
+ * arch/mips/kernel/kgdb.c
+ *
+ *  Originally written by Glenn Engel, Lake Stevens Instrument Division
+ *
+ *  Contributed by HP Systems
+ *
+ *  Modified for SPARC by Stu Grossman, Cygnus Support.
+ *
+ *  Modified for Linux/MIPS (and MIPS in general) by Andreas Busse
+ *  Send complaints, suggestions etc. to <[email protected]>
+ *
+ *  Copyright (C) 1995 Andreas Busse
+ *
+ *  Copyright (C) 2003 MontaVista Software Inc.
+ *  Author: Jun Sun, [email protected] or [email protected]
+ *
+ *  Copyright (C) 2004-2005 MontaVista Software Inc.
+ *  Author: Manish Lachwani, [email protected] or [email protected]
+ *
+ *  This file is licensed under the terms of the GNU General Public License
+ *  version 2. This program is licensed "as is" without any warranty of any
+ *  kind, whether express or implied.
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/ptrace.h>		/* for linux pt_regs struct */
+#include <asm/system.h>
+#include <linux/kgdb.h>
+#include <linux/init.h>
+#include <linux/kdebug.h>
+#include <asm/inst.h>
+#include <asm/gdb-stub.h>
+#include <asm/cacheflush.h>
+
+static struct hard_trap_info {
+	unsigned char tt;	/* Trap type code for MIPS R3xxx and R4xxx */
+	unsigned char signo;	/* Signal that we map this trap into */
+} hard_trap_info[] = {
+	{ 6, SIGBUS },		/* instruction bus error */
+	{ 7, SIGBUS },		/* data bus error */
+	{ 9, SIGTRAP },		/* break */
+/*	{ 11, SIGILL },	*/	/* CPU unusable */
+	{ 12, SIGFPE },		/* overflow */
+	{ 13, SIGTRAP },	/* trap */
+	{ 14, SIGSEGV },	/* virtual instruction cache coherency */
+	{ 15, SIGFPE },		/* floating point exception */
+	{ 23, SIGSEGV },	/* watch */
+	{ 31, SIGSEGV },	/* virtual data cache coherency */
+	{ 0, 0}			/* Must be last */
+};
+
+/* Save the normal trap handlers for user-mode traps. */
+void *saved_vectors[32];
+
+extern void trap_low(void);
+extern void breakinst(void);
+extern void init_IRQ(void);
+
+void kgdb_call_nmi_hook(void *ignored)
+{
+	kgdb_nmihook(smp_processor_id(), (void *)0);
+}
+
+void kgdb_roundup_cpus(unsigned long flags)
+{
+	local_irq_enable();
+	smp_call_function(kgdb_call_nmi_hook, 0, 0, 0);
+	local_irq_disable();
+}
+
+static int compute_signal(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 */
+}
+
+/*
+ * Set up exception handlers for tracing and breakpoints
+ */
+void handle_exception(struct pt_regs *regs)
+{
+	int trap = (regs->cp0_cause & 0x7c) >> 2;
+
+	if (fixup_exception(regs))
+		return;
+
+	if (atomic_read(&debugger_active))
+		kgdb_nmihook(smp_processor_id(), regs);
+
+	if (atomic_read(&kgdb_setting_breakpoint))
+		if ((trap == 9) && (regs->cp0_epc == (unsigned long)breakinst))
+			regs->cp0_epc += 4;
+
+	kgdb_handle_exception(0, compute_signal(trap), 0, regs);
+
+	/* In SMP mode, __flush_cache_all does IPI */
+	local_irq_enable();
+	__flush_cache_all();
+}
+
+void set_debug_traps(void)
+{
+	struct hard_trap_info *ht;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+		saved_vectors[ht->tt] = set_except_vector(ht->tt, trap_low);
+
+	local_irq_restore(flags);
+}
+
+void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+	int reg;
+#if (KGDB_GDB_REG_SIZE == 32)
+	u32 *ptr = (u32 *)gdb_regs;
+#else
+	u64 *ptr = (u64 *)gdb_regs;
+#endif
+
+	for (reg = 0; reg < 32; reg++)
+		*(ptr++) = regs->regs[reg];
+
+	*(ptr++) = regs->cp0_status;
+	*(ptr++) = regs->lo;
+	*(ptr++) = regs->hi;
+	*(ptr++) = regs->cp0_badvaddr;
+	*(ptr++) = regs->cp0_cause;
+	*(ptr++) = regs->cp0_epc;
+
+	return;
+}
+
+void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+
+	int reg;
+#if (KGDB_GDB_REG_SIZE == 32)
+	const u32 *ptr = (u32 *)gdb_regs;
+#else
+	const u64 *ptr = (u64 *)gdb_regs;
+#endif
+
+	for (reg = 0; reg < 32; reg++)
+		regs->regs[reg] = *(ptr++);
+
+	regs->cp0_status = *(ptr++);
+	regs->lo = *(ptr++);
+	regs->hi = *(ptr++);
+	regs->cp0_badvaddr = *(ptr++);
+	regs->cp0_cause = *(ptr++);
+	regs->cp0_epc = *(ptr++);
+
+	return;
+}
+
+/*
+ * Similar to regs_to_gdb_regs() except that process is sleeping and so
+ * we may not be able to get all the info.
+ */
+void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
+{
+	int reg;
+	struct thread_info *ti = task_thread_info(p);
+	unsigned long ksp = (unsigned long)ti + THREAD_SIZE - 32;
+	struct pt_regs *regs = (struct pt_regs *)ksp - 1;
+#if (KGDB_GDB_REG_SIZE == 32)
+	u32 *ptr = (u32 *)gdb_regs;
+#else
+	u64 *ptr = (u64 *)gdb_regs;
+#endif
+
+	for (reg = 0; reg < 16; reg++)
+		*(ptr++) = regs->regs[reg];
+
+	/* S0 - S7 */
+	for (reg = 16; reg < 24; reg++)
+		*(ptr++) = regs->regs[reg];
+
+	for (reg = 24; reg < 28; reg++)
+		*(ptr++) = 0;
+
+	/* GP, SP, FP, RA */
+	for (reg = 28; reg < 32; reg++)
+		*(ptr++) = regs->regs[reg];
+
+	*(ptr++) = regs->cp0_status;
+	*(ptr++) = regs->lo;
+	*(ptr++) = regs->hi;
+	*(ptr++) = regs->cp0_badvaddr;
+	*(ptr++) = regs->cp0_cause;
+	*(ptr++) = regs->cp0_epc;
+
+	return;
+}
+
+/*
+ * Calls linux_debug_hook before the kernel dies. If KGDB is enabled,
+ * then try to fall into the debugger
+ */
+static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
+			    void *ptr)
+{
+	struct die_args *args = (struct die_args *)ptr;
+	struct pt_regs *regs = args->regs;
+	int trap = (regs->cp0_cause & 0x7c) >> 2;
+
+	/* See if KGDB is interested. */
+	if (user_mode(regs))
+		/* Userpace events, ignore. */
+		return NOTIFY_DONE;
+
+	kgdb_handle_exception(trap, compute_signal(trap), 0, regs);
+	return NOTIFY_OK;
+}
+
+static struct notifier_block kgdb_notifier = {
+	.notifier_call = kgdb_mips_notify,
+};
+
+/*
+ * Handle the 's' and 'c' commands
+ */
+int kgdb_arch_handle_exception(int vector, int signo, int err_code,
+			       char *remcom_in_buffer, char *remcom_out_buffer,
+			       struct pt_regs *regs)
+{
+	char *ptr;
+	unsigned long address;
+	int cpu = smp_processor_id();
+
+	switch (remcom_in_buffer[0]) {
+	case 's':
+	case 'c':
+		/* handle the optional parameter */
+		ptr = &remcom_in_buffer[1];
+		if (kgdb_hex2long(&ptr, &address))
+			regs->cp0_epc = address;
+
+		atomic_set(&cpu_doing_single_step, -1);
+		if (remcom_in_buffer[0] == 's')
+			if (kgdb_contthread)
+				atomic_set(&cpu_doing_single_step, cpu);
+
+		return 0;
+	}
+
+	return -1;
+}
+
+struct kgdb_arch arch_kgdb_ops = {
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+	.gdb_bpt_instr = {0xd},
+#else /* ! CONFIG_CPU_LITTLE_ENDIAN */
+	.gdb_bpt_instr = {0x00, 0x00, 0x00, 0x0d},
+#endif
+};
+
+/*
+ * We use kgdb_early_setup so that functions we need to call now don't
+ * cause trouble when called again later.
+ */
+__init int kgdb_arch_init(void)
+{
+	/* Board-specifics. */
+	/* Force some calls to happen earlier. */
+	if (kgdb_early_setup == 0) {
+		trap_init();
+		init_IRQ();
+		kgdb_early_setup = 1;
+	}
+
+	/* Set our traps. */
+	/* This needs to be done more finely grained again, paired in
+	 * a before/after in kgdb_handle_exception(...) -- Tom */
+	set_debug_traps();
+	register_die_notifier(&kgdb_notifier);
+
+	return 0;
+}
--- /dev/null
+++ b/arch/mips/kernel/kgdb_handler.S
@@ -0,0 +1,339 @@
+/*
+ * arch/mips/kernel/kgdb_handler.S
+ *
+ * Copyright (C) 2007 Wind River Systems, Inc
+ *
+ * Copyright (C) 2004-2005 MontaVista Software Inc.
+ * Author: Manish Lachwani, [email protected] or [email protected]
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/*
+ * Trap Handler for the new KGDB framework. The main KGDB handler is
+ * handle_exception that will be called from here
+ *
+ */
+
+#include <linux/sys.h>
+
+#include <asm/asm.h>
+#include <asm/errno.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/gdb-stub.h>
+
+#ifdef CONFIG_32BIT
+#define DMFC0	mfc0
+#define DMTC0	mtc0
+#define LDC1	lwc1
+#define SDC1	swc1
+#endif
+#ifdef CONFIG_64BIT
+#define DMFC0	dmfc0
+#define DMTC0	dmtc0
+#define LDC1	ldc1
+#define SDC1	sdc1
+#endif
+
+#include <asm/asmmacro.h>
+
+/*
+ * [jsun] We reserves about 2x GDB_FR_SIZE in stack.  The lower (addressed)
+ * part is used to store registers and passed to exception handler.
+ * The upper part is reserved for "call func" feature where gdb client
+ * saves some of the regs, setups call frame and passes args.
+ *
+ * A trace shows about 200 bytes are used to store about half of all regs.
+ * The rest should be big enough for frame setup and passing args.
+ */
+
+/*
+ * The low level trap handler
+ */
+		.align 	5
+		NESTED(trap_low, GDB_FR_SIZE, sp)
+ 		.set	noat
+		.set 	noreorder
+
+		mfc0	k0, CP0_STATUS
+		sll	k0, 3     		/* extract cu0 bit */
+		bltz	k0, 1f
+		move	k1, sp
+
+		/*
+		 * Called from user mode, go somewhere else.
+		 */
+#if defined(CONFIG_32BIT)
+		lui	k1, %hi(saved_vectors)
+		mfc0	k0, CP0_CAUSE
+		andi	k0, k0, 0x7c
+		add	k1, k1, k0
+		lw	k0, %lo(saved_vectors)(k1)
+#elif defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
+		DMFC0	k0, CP0_CAUSE
+		lui	k1, %highest(saved_vectors)
+                andi    k0, k0, 0x7c           /* mask exception type */
+                dsll    k0, 1                  /* turn into byte offset */
+		daddiu	k1, %higher(saved_vectors)
+		dsll	k1, k1, 16
+		daddiu	k1, %hi(saved_vectors)
+		dsll	k1, k1, 16
+		daddu	k1, k1, k0
+		LONG_L	k0, %lo(saved_vectors)(k1)
+#else
+#error "MIPS configuration is unsupported for kgdb!!"
+#endif
+		jr	k0
+		nop
+1:
+		move	k0, sp
+		PTR_SUBU sp, k1, GDB_FR_SIZE*2	# see comment above
+		LONG_S	k0, GDB_FR_REG29(sp)
+		LONG_S	$2, GDB_FR_REG2(sp)
+
+/*
+ * First save the CP0 and special registers
+ */
+
+		mfc0	v0, CP0_STATUS
+		LONG_S	v0, GDB_FR_STATUS(sp)
+		mfc0	v0, CP0_CAUSE
+		LONG_S	v0, GDB_FR_CAUSE(sp)
+		DMFC0	v0, CP0_EPC
+		LONG_S	v0, GDB_FR_EPC(sp)
+		DMFC0	v0, CP0_BADVADDR
+		LONG_S	v0, GDB_FR_BADVADDR(sp)
+		mfhi	v0
+		LONG_S	v0, GDB_FR_HI(sp)
+		mflo	v0
+		LONG_S	v0, GDB_FR_LO(sp)
+
+/*
+ * Now the integer registers
+ */
+
+		LONG_S	zero, GDB_FR_REG0(sp)		/* I know... */
+		LONG_S	$1, GDB_FR_REG1(sp)
+		/* v0 already saved */
+		LONG_S	$3, GDB_FR_REG3(sp)
+		LONG_S	$4, GDB_FR_REG4(sp)
+		LONG_S	$5, GDB_FR_REG5(sp)
+		LONG_S	$6, GDB_FR_REG6(sp)
+		LONG_S	$7, GDB_FR_REG7(sp)
+		LONG_S	$8, GDB_FR_REG8(sp)
+		LONG_S	$9, GDB_FR_REG9(sp)
+		LONG_S	$10, GDB_FR_REG10(sp)
+		LONG_S	$11, GDB_FR_REG11(sp)
+		LONG_S	$12, GDB_FR_REG12(sp)
+		LONG_S	$13, GDB_FR_REG13(sp)
+		LONG_S	$14, GDB_FR_REG14(sp)
+		LONG_S	$15, GDB_FR_REG15(sp)
+		LONG_S	$16, GDB_FR_REG16(sp)
+		LONG_S	$17, GDB_FR_REG17(sp)
+		LONG_S	$18, GDB_FR_REG18(sp)
+		LONG_S	$19, GDB_FR_REG19(sp)
+		LONG_S	$20, GDB_FR_REG20(sp)
+		LONG_S	$21, GDB_FR_REG21(sp)
+		LONG_S	$22, GDB_FR_REG22(sp)
+		LONG_S	$23, GDB_FR_REG23(sp)
+		LONG_S	$24, GDB_FR_REG24(sp)
+		LONG_S	$25, GDB_FR_REG25(sp)
+		LONG_S	$26, GDB_FR_REG26(sp)
+		LONG_S	$27, GDB_FR_REG27(sp)
+		LONG_S	$28, GDB_FR_REG28(sp)
+		/* sp already saved */
+		LONG_S	$30, GDB_FR_REG30(sp)
+		LONG_S	$31, GDB_FR_REG31(sp)
+
+		CLI				/* disable interrupts */
+
+/*
+ * Followed by the floating point registers
+ */
+		mfc0	v0, CP0_STATUS		/* FPU enabled? */
+		srl	v0, v0, 16
+		andi	v0, v0, (ST0_CU1 >> 16)
+
+		beqz	v0,3f			/* disabled, skip */
+		 nop
+
+		li	t0, 0
+#ifdef CONFIG_64BIT
+		mfc0	t0, CP0_STATUS
+#endif
+		fpu_save_double_kgdb sp t0 t1	# clobbers t1
+
+
+/*
+ * Current stack frame ptr
+ */
+
+3:
+		LONG_S	sp, GDB_FR_FRP(sp)
+
+/*
+ * CP0 registers (R4000/R4400 unused registers skipped)
+ */
+
+		mfc0	v0, CP0_INDEX
+		LONG_S	v0, GDB_FR_CP0_INDEX(sp)
+		mfc0	v0, CP0_RANDOM
+		LONG_S	v0, GDB_FR_CP0_RANDOM(sp)
+		DMFC0	v0, CP0_ENTRYLO0
+		LONG_S	v0, GDB_FR_CP0_ENTRYLO0(sp)
+		DMFC0	v0, CP0_ENTRYLO1
+		LONG_S	v0, GDB_FR_CP0_ENTRYLO1(sp)
+		DMFC0	v0, CP0_CONTEXT
+		LONG_S	v0, GDB_FR_CP0_CONTEXT(sp)
+		mfc0	v0, CP0_PAGEMASK
+		LONG_S	v0, GDB_FR_CP0_PAGEMASK(sp)
+		mfc0	v0, CP0_WIRED
+		LONG_S	v0, GDB_FR_CP0_WIRED(sp)
+		DMFC0	v0, CP0_ENTRYHI
+		LONG_S	v0, GDB_FR_CP0_ENTRYHI(sp)
+		mfc0	v0, CP0_PRID
+		LONG_S	v0, GDB_FR_CP0_PRID(sp)
+
+		.set	at
+
+/*
+ * Continue with the higher level handler
+ */
+
+		move	a0,sp
+
+		jal	handle_exception
+		 nop
+
+/*
+ * Restore all writable registers, in reverse order
+ */
+
+		.set	noat
+
+		LONG_L	v0, GDB_FR_CP0_ENTRYHI(sp)
+		LONG_L	v1, GDB_FR_CP0_WIRED(sp)
+		DMTC0	v0, CP0_ENTRYHI
+		mtc0	v1, CP0_WIRED
+		LONG_L	v0, GDB_FR_CP0_PAGEMASK(sp)
+		LONG_L	v1, GDB_FR_CP0_ENTRYLO1(sp)
+		mtc0	v0, CP0_PAGEMASK
+		DMTC0	v1, CP0_ENTRYLO1
+		LONG_L	v0, GDB_FR_CP0_ENTRYLO0(sp)
+		LONG_L	v1, GDB_FR_CP0_INDEX(sp)
+		DMTC0	v0, CP0_ENTRYLO0
+		LONG_L	v0, GDB_FR_CP0_CONTEXT(sp)
+		mtc0	v1, CP0_INDEX
+		DMTC0	v0, CP0_CONTEXT
+
+
+/*
+ * Next, the floating point registers
+ */
+		mfc0	v0, CP0_STATUS		/* check if FPU is enabled */
+		srl	v0, v0, 16
+		andi	v0, v0, (ST0_CU1 >> 16)
+
+		beqz	v0, 3f			/* disabled, skip */
+		 nop
+
+		li	t0, 0
+#ifdef CONFIG_64BIT
+		mfc0	t0, CP0_STATUS
+#endif
+		fpu_restore_double_kgdb sp t0 t1 # clobbers t1
+
+
+/*
+ * Now the CP0 and integer registers
+ */
+
+3:
+		mfc0	t0, CP0_STATUS
+		ori	t0, 0x1f
+		xori	t0, 0x1f
+		mtc0	t0, CP0_STATUS
+
+		LONG_L	v0, GDB_FR_STATUS(sp)
+		LONG_L	v1, GDB_FR_EPC(sp)
+		mtc0	v0, CP0_STATUS
+		DMTC0	v1, CP0_EPC
+		LONG_L	v0, GDB_FR_HI(sp)
+		LONG_L	v1, GDB_FR_LO(sp)
+		mthi	v0
+		mtlo	v1
+		LONG_L	$31, GDB_FR_REG31(sp)
+		LONG_L	$30, GDB_FR_REG30(sp)
+		LONG_L	$28, GDB_FR_REG28(sp)
+		LONG_L	$27, GDB_FR_REG27(sp)
+		LONG_L	$26, GDB_FR_REG26(sp)
+		LONG_L	$25, GDB_FR_REG25(sp)
+		LONG_L	$24, GDB_FR_REG24(sp)
+		LONG_L	$23, GDB_FR_REG23(sp)
+		LONG_L	$22, GDB_FR_REG22(sp)
+		LONG_L	$21, GDB_FR_REG21(sp)
+		LONG_L	$20, GDB_FR_REG20(sp)
+		LONG_L	$19, GDB_FR_REG19(sp)
+		LONG_L	$18, GDB_FR_REG18(sp)
+		LONG_L	$17, GDB_FR_REG17(sp)
+		LONG_L	$16, GDB_FR_REG16(sp)
+		LONG_L	$15, GDB_FR_REG15(sp)
+		LONG_L	$14, GDB_FR_REG14(sp)
+		LONG_L	$13, GDB_FR_REG13(sp)
+		LONG_L	$12, GDB_FR_REG12(sp)
+		LONG_L	$11, GDB_FR_REG11(sp)
+		LONG_L	$10, GDB_FR_REG10(sp)
+		LONG_L	$9, GDB_FR_REG9(sp)
+		LONG_L	$8, GDB_FR_REG8(sp)
+		LONG_L	$7, GDB_FR_REG7(sp)
+		LONG_L	$6, GDB_FR_REG6(sp)
+		LONG_L	$5, GDB_FR_REG5(sp)
+		LONG_L	$4, GDB_FR_REG4(sp)
+		LONG_L	$3, GDB_FR_REG3(sp)
+		LONG_L	$2, GDB_FR_REG2(sp)
+		LONG_L	$1, GDB_FR_REG1(sp)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+		LONG_L	k0, GDB_FR_EPC(sp)
+		LONG_L	$29, GDB_FR_REG29(sp)		/* Deallocate stack */
+		jr	k0
+		rfe
+#else
+		LONG_L	sp, GDB_FR_REG29(sp)		/* Deallocate stack */
+
+		.set	mips3
+		eret
+		.set	mips0
+#endif
+		.set	at
+		.set	reorder
+		END(trap_low)
+
+LEAF(kgdb_read_byte)
+4:		lb	t0, (a0)
+		sb	t0, (a1)
+		li	v0, 0
+		jr	ra
+		.section __ex_table,"a"
+		PTR	4b, kgdbfault
+		.previous
+		END(kgdb_read_byte)
+
+LEAF(kgdb_write_byte)
+5:		sb	a0, (a1)
+		li	v0, 0
+		jr	ra
+		.section __ex_table,"a"
+		PTR	5b, kgdbfault
+		.previous
+		END(kgdb_write_byte)
+
+		.type	kgdbfault@function
+		.ent	kgdbfault
+
+kgdbfault:	li	v0, -EFAULT
+		jr	ra
+		.end	kgdbfault
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -10,6 +10,8 @@
  * Kevin D. Kissell, [email protected] and Carsten Langgaard, [email protected]
  * Copyright (C) 2000, 01 MIPS Technologies, Inc.
  * Copyright (C) 2002, 2003, 2004, 2005  Maciej W. Rozycki
+ *
+ * KGDB specific changes - Manish Lachwani ([email protected])
  */
 #include <linux/bug.h>
 #include <linux/init.h>
@@ -21,6 +23,8 @@
 #include <linux/kallsyms.h>
 #include <linux/bootmem.h>
 #include <linux/interrupt.h>
+#include <linux/kgdb.h>
+#include <linux/kdebug.h>
 
 #include <asm/bootinfo.h>
 #include <asm/branch.h>
@@ -319,6 +323,10 @@ void __noreturn die(const char * str, st
 	unsigned long dvpret = dvpe();
 #endif /* CONFIG_MIPS_MT_SMTC */
 
+#ifdef CONFIG_KGDB
+	if (kgdb_may_fault)
+		kgdb_fault_longjmp(kgdb_fault_jmp_regs);
+#endif
 	console_verbose();
 	spin_lock_irq(&die_lock);
 	bust_spinlocks(1);
@@ -1470,6 +1478,11 @@ void __init trap_init(void)
 	extern char except_vec4;
 	unsigned long i;
 
+#if defined(CONFIG_KGDB)
+	if (kgdb_early_setup)
+		return;	/* Already done */
+#endif
+
 	if (cpu_has_veic || cpu_has_vint)
 		ebase = (unsigned long) alloc_bootmem_low_pages(0x200 + VECTORSPACING*64);
 	else
--- a/arch/mips/mips-boards/generic/Makefile
+++ b/arch/mips/mips-boards/generic/Makefile
@@ -23,6 +23,5 @@ obj-y				:= reset.o display.o init.o mem
 
 obj-$(CONFIG_EARLY_PRINTK)	+= console.o
 obj-$(CONFIG_PCI)		+= pci.o
-obj-$(CONFIG_KGDB)		+= gdb_hook.o
 
 EXTRA_CFLAGS += -Werror
--- a/arch/mips/mips-boards/generic/init.c
+++ b/arch/mips/mips-boards/generic/init.c
@@ -37,15 +37,6 @@
 
 #include <asm/mips-boards/malta.h>
 
-#ifdef CONFIG_KGDB
-extern int rs_kgdb_hook(int, int);
-extern int rs_putDebugChar(char);
-extern char rs_getDebugChar(void);
-extern int saa9730_kgdb_hook(int);
-extern int saa9730_putDebugChar(char);
-extern char saa9730_getDebugChar(void);
-#endif
-
 int prom_argc;
 int *_prom_argv, *_prom_envp;
 
@@ -173,59 +164,6 @@ static void __init console_config(void)
 }
 #endif
 
-#ifdef CONFIG_KGDB
-void __init kgdb_config(void)
-{
-	extern int (*generic_putDebugChar)(char);
-	extern char (*generic_getDebugChar)(void);
-	char *argptr;
-	int line, speed;
-
-	argptr = prom_getcmdline();
-	if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) {
-		argptr += strlen("kgdb=ttyS");
-		if (*argptr != '0' && *argptr != '1')
-			printk("KGDB: Unknown serial line /dev/ttyS%c, "
-			       "falling back to /dev/ttyS1\n", *argptr);
-		line = *argptr == '0' ? 0 : 1;
-		printk("KGDB: Using serial line /dev/ttyS%d for session\n", line);
-
-		speed = 0;
-		if (*++argptr == ',')
-		{
-			int c;
-			while ((c = *++argptr) && ('0' <= c && c <= '9'))
-				speed = speed * 10 + c - '0';
-		}
-#ifdef CONFIG_MIPS_ATLAS
-		if (line == 1) {
-			speed = saa9730_kgdb_hook(speed);
-			generic_putDebugChar = saa9730_putDebugChar;
-			generic_getDebugChar = saa9730_getDebugChar;
-		}
-		else
-#endif
-		{
-			speed = rs_kgdb_hook(line, speed);
-			generic_putDebugChar = rs_putDebugChar;
-			generic_getDebugChar = rs_getDebugChar;
-		}
-
-		pr_info("KGDB: Using serial line /dev/ttyS%d at %d for "
-		        "session, please connect your debugger\n",
-		        line ? 1 : 0, speed);
-
-		{
-			char *s;
-			for (s = "Please connect GDB to this port\r\n"; *s; )
-				generic_putDebugChar(*s++);
-		}
-
-		/* Breakpoint is invoked after interrupts are initialised */
-	}
-}
-#endif
-
 void __init mips_nmi_setup(void)
 {
 	void *base;
--- a/arch/mips/mips-boards/malta/malta_setup.c
+++ b/arch/mips/mips-boards/malta/malta_setup.c
@@ -38,10 +38,6 @@
 extern void mips_reboot_setup(void);
 extern unsigned long mips_rtc_get_time(void);
 
-#ifdef CONFIG_KGDB
-extern void kgdb_config(void);
-#endif
-
 struct resource standard_io_resources[] = {
 	{ .name = "dma1", .start = 0x00, .end = 0x1f, .flags = IORESOURCE_BUSY },
 	{ .name = "timer", .start = 0x40, .end = 0x5f, .flags = IORESOURCE_BUSY },
@@ -98,10 +94,6 @@ void __init plat_mem_setup(void)
 	 */
 	enable_dma(4);
 
-#ifdef CONFIG_KGDB
-	kgdb_config();
-#endif
-
 	if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO) {
 		char *argptr;
 
--- a/arch/mips/mm/extable.c
+++ b/arch/mips/mm/extable.c
@@ -3,6 +3,7 @@
  */
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/kgdb.h>
 #include <asm/branch.h>
 #include <asm/uaccess.h>
 
@@ -16,6 +17,12 @@ int fixup_exception(struct pt_regs *regs
 
 		return 1;
 	}
+#ifdef CONFIG_KGDB
+	if (atomic_read(&debugger_active) && kgdb_may_fault)
+		/* Restore our previous state. */
+		kgdb_fault_longjmp(kgdb_fault_jmp_regs);
+		/* Not reached. */
+#endif
 
 	return 0;
 }
--- a/arch/mips/sibyte/cfe/setup.c
+++ b/arch/mips/sibyte/cfe/setup.c
@@ -58,10 +58,6 @@ int cfe_cons_handle;
 extern unsigned long initrd_start, initrd_end;
 #endif
 
-#ifdef CONFIG_KGDB
-extern int kgdb_port;
-#endif
-
 static void __noreturn cfe_linux_exit(void *arg)
 {
 	int warm = *(int *)arg;
@@ -242,9 +238,6 @@ void __init prom_init(void)
 	int argc = fw_arg0;
 	char **envp = (char **) fw_arg2;
 	int *prom_vec = (int *) fw_arg3;
-#ifdef CONFIG_KGDB
-	char *arg;
-#endif
 
 	_machine_restart   = cfe_linux_restart;
 	_machine_halt      = cfe_linux_halt;
@@ -308,13 +301,6 @@ void __init prom_init(void)
 		}
 	}
 
-#ifdef CONFIG_KGDB
-	if ((arg = strstr(arcs_cmdline, "kgdb=duart")) != NULL)
-		kgdb_port = (arg[10] == '0') ? 0 : 1;
-	else
-		kgdb_port = 1;
-#endif
-
 #ifdef CONFIG_BLK_DEV_INITRD
 	{
 		char *ptr;
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -24,6 +24,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/kernel_stat.h>
+#include <linux/kgdb.h>
 
 #include <asm/errno.h>
 #include <asm/signal.h>
@@ -57,16 +58,6 @@ static void sb1250_set_affinity(unsigned
 extern unsigned long ldt_eoi_space;
 #endif
 
-#ifdef CONFIG_KGDB
-static int kgdb_irq;
-
-/* Default to UART1 */
-int kgdb_port = 1;
-#ifdef CONFIG_SERIAL_SB1250_DUART
-extern char sb1250_duart_present[];
-#endif
-#endif
-
 static struct irq_chip sb1250_irq_type = {
 	.name = "SB1250-IMR",
 	.ack = ack_sb1250_irq,
@@ -305,6 +296,11 @@ void __init arch_init_irq(void)
 	unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
 		STATUSF_IP1 | STATUSF_IP0;
 
+#ifdef CONFIG_KGDB
+	if (kgdb_early_setup)
+		return;
+#endif
+
 	/* Default everything to IP2 */
 	for (i = 0; i < SB1250_NR_IRQS; i++) {	/* was I0 */
 		__raw_writeq(IMR_IP2_VAL,
@@ -350,56 +346,13 @@ void __init arch_init_irq(void)
 	 * does its own management of IP7.
 	 */
 
-#ifdef CONFIG_KGDB
+#ifdef CONFIG_KGDB_SIBYTE
 	imask |= STATUSF_IP6;
 #endif
 	/* Enable necessary IPs, disable the rest */
 	change_c0_status(ST0_IM, imask);
-
-#ifdef CONFIG_KGDB
-	if (kgdb_flag) {
-		kgdb_irq = K_INT_UART_0 + kgdb_port;
-
-#ifdef CONFIG_SERIAL_SB1250_DUART
-		sb1250_duart_present[kgdb_port] = 0;
-#endif
-		/* Setup uart 1 settings, mapper */
-		__raw_writeq(M_DUART_IMR_BRK,
-			     IOADDR(A_DUART_IMRREG(kgdb_port)));
-
-		sb1250_steal_irq(kgdb_irq);
-		__raw_writeq(IMR_IP6_VAL,
-			     IOADDR(A_IMR_REGISTER(0,
-						   R_IMR_INTERRUPT_MAP_BASE) +
-				    (kgdb_irq << 3)));
-		sb1250_unmask_irq(0, kgdb_irq);
-	}
-#endif
 }
 
-#ifdef CONFIG_KGDB
-
-#include <linux/delay.h>
-
-#define duart_out(reg, val)     csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port, reg)))
-#define duart_in(reg)           csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port, reg)))
-
-static void sb1250_kgdb_interrupt(void)
-{
-	/*
-	 * Clear break-change status (allow some time for the remote
-	 * host to stop the break, since we would see another
-	 * interrupt on the end-of-break too)
-	 */
-	kstat_this_cpu.irqs[kgdb_irq]++;
-	mdelay(500);
-	duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT |
-				M_DUART_RX_EN | M_DUART_TX_EN);
-	set_async_breakpoint(&get_irq_regs()->cp0_epc);
-}
-
-#endif 	/* CONFIG_KGDB */
-
 static inline void sb1250_timer_interrupt(void)
 {
 	int cpu = smp_processor_id();
@@ -434,6 +387,7 @@ static inline void sb1250_timer_interrup
 }
 
 extern void sb1250_mailbox_interrupt(void);
+extern void sb1250_kgdb_interrupt(void);
 
 asmlinkage void plat_irq_dispatch(void)
 {
@@ -461,7 +415,7 @@ asmlinkage void plat_irq_dispatch(void)
 		sb1250_mailbox_interrupt();
 #endif
 
-#ifdef CONFIG_KGDB
+#ifdef CONFIG_KGDB_SIBYTE
 	else if (pending & CAUSEF_IP6)			/* KGDB (uart 1) */
 		sb1250_kgdb_interrupt();
 #endif
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/kgdb_sibyte.c
@@ -0,0 +1,145 @@
+/*
+ * arch/mips/sibyte/sb1250/kgdb_sibyte.c
+ *
+ * Author: Manish Lachwani, [email protected] or [email protected]
+ *
+ * 2004 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+/*
+ * Support for KGDB on the Broadcom Sibyte. The SWARM board
+ * for example does not have a 8250/16550 compatible serial
+ * port. Hence, we need to have a driver for the serial
+ * ports to handle KGDB.  This board needs nothing in addition
+ * to what is normally provided by the gdb portion of the stub.
+ */
+
+#include <linux/delay.h>
+#include <linux/kernel_stat.h>
+#include <linux/init.h>
+#include <linux/kgdb.h>
+#include <linux/io.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_uart.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/addrspace.h>
+
+int kgdb_port = 1;
+static int kgdb_irq;
+
+extern char sb1250_duart_present[];
+extern int sb1250_steal_irq(int irq);
+
+/* Forward declarations. */
+static void kgdbsibyte_init_duart(void);
+static int kgdb_init_io(void);
+
+#define IMR_IP6_VAL	K_INT_MAP_I4
+#define	duart_out(reg, val)	csr_out32(val, \
+		IOADDR(A_DUART_CHANREG(kgdb_port, reg)))
+#define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port, reg)))
+
+static void kgdbsibyte_write_char(u8 c)
+{
+	while ((duart_in(R_DUART_STATUS) & M_DUART_TX_RDY) == 0) ;
+	duart_out(R_DUART_TX_HOLD, c);
+}
+
+static int kgdbsibyte_read_char(void)
+{
+	int ret_char;
+	unsigned int status;
+
+	do {
+		status = duart_in(R_DUART_STATUS);
+	} while ((status & M_DUART_RX_RDY) == 0);
+
+	/*
+	 * Check for framing error
+	 */
+	if (status & M_DUART_FRM_ERR) {
+		kgdbsibyte_init_duart();
+		kgdbsibyte_write_char('-');
+		return '-';
+	}
+
+	ret_char = duart_in(R_DUART_RX_HOLD);
+
+	return ret_char;
+}
+
+void sb1250_kgdb_interrupt(void)
+{
+	int kgdb_irq = K_INT_UART_0 + kgdb_port;
+
+	/*
+	 * Clear break-change status (allow some time for the remote
+	 * host to stop the break, since we would see another
+	 * interrupt on the end-of-break too)
+	 */
+	kstat_this_cpu.irqs[kgdb_irq]++;
+	mdelay(500);
+	duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT |
+		  M_DUART_RX_EN | M_DUART_TX_EN);
+	breakpoint();
+
+}
+
+/*
+ * We use port #1 and we set it for 115200 BAUD, 8n1.
+ */
+static void kgdbsibyte_init_duart(void)
+{
+	/* Set 8n1. */
+	duart_out(R_DUART_MODE_REG_1,
+		  V_DUART_BITS_PER_CHAR_8 | V_DUART_PARITY_MODE_NONE);
+	duart_out(R_DUART_MODE_REG_2, M_DUART_STOP_BIT_LEN_1);
+	/* Set baud rate of 115200. */
+	duart_out(R_DUART_CLK_SEL, V_DUART_BAUD_RATE(115200));
+	/* Enable rx and tx */
+	duart_out(R_DUART_CMD, M_DUART_RX_EN | M_DUART_TX_EN);
+}
+
+static int kgdb_init_io(void)
+{
+#ifdef CONFIG_SIBYTE_SB1250_DUART
+	sb1250_duart_present[kgdb_port] = 0;
+#endif
+
+	kgdbsibyte_init_duart();
+
+	return 0;
+}
+
+/*
+ * Hookup our IRQ line.  We will already have been initialized a
+ * this point.
+ */
+static void __init kgdbsibyte_hookup_irq(void)
+{
+	/* Steal the IRQ. */
+	kgdb_irq = K_INT_UART_0 + kgdb_port;
+
+	/* Setup uart 1 settings, mapper */
+	__raw_writeq(M_DUART_IMR_BRK, IOADDR(A_DUART_IMRREG(kgdb_port)));
+
+	sb1250_steal_irq(kgdb_irq);
+
+	__raw_writeq(IMR_IP6_VAL,
+		     IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+			    (kgdb_irq << 3)));
+
+	sb1250_unmask_irq(0, kgdb_irq);
+}
+
+struct kgdb_io kgdb_io_ops = {
+	.read_char  = kgdbsibyte_read_char,
+	.write_char = kgdbsibyte_write_char,
+	.init = kgdb_init_io,
+	.late_init  = kgdbsibyte_hookup_irq,
+};
--- a/arch/mips/sibyte/swarm/Makefile
+++ b/arch/mips/sibyte/swarm/Makefile
@@ -1,3 +1 @@
 lib-y				= setup.o rtc_xicor1241.o rtc_m41t81.o
-
-lib-$(CONFIG_KGDB)		+= dbg_io.o
--- a/arch/mips/sibyte/swarm/dbg_io.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * kgdb debug routines for SiByte boards.
- *
- * Copyright (C) 2001 MontaVista Software Inc.
- * Author: Jun Sun, [email protected] or [email protected]
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- */
-
-/* -------------------- BEGINNING OF CONFIG --------------------- */
-
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/sibyte/sb1250.h>
-#include <asm/sibyte/sb1250_regs.h>
-#include <asm/sibyte/sb1250_uart.h>
-#include <asm/sibyte/sb1250_int.h>
-#include <asm/addrspace.h>
-
-/*
- * We use the second serial port for kgdb traffic.
- * 	115200, 8, N, 1.
- */
-
-#define	BAUD_RATE		115200
-#define	CLK_DIVISOR		V_DUART_BAUD_RATE(BAUD_RATE)
-#define	DATA_BITS		V_DUART_BITS_PER_CHAR_8		/* or 7    */
-#define	PARITY			V_DUART_PARITY_MODE_NONE	/* or even */
-#define	STOP_BITS		M_DUART_STOP_BIT_LEN_1		/* or 2    */
-
-static int duart_initialized = 0;	/* 0: need to be init'ed by kgdb */
-
-/* -------------------- END OF CONFIG --------------------- */
-extern int kgdb_port;
-
-#define	duart_out(reg, val)	csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port, reg)))
-#define duart_in(reg)		csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port, reg)))
-
-void putDebugChar(unsigned char c);
-unsigned char getDebugChar(void);
-static void
-duart_init(int clk_divisor, int data, int parity, int stop)
-{
-	duart_out(R_DUART_MODE_REG_1, data | parity);
-	duart_out(R_DUART_MODE_REG_2, stop);
-	duart_out(R_DUART_CLK_SEL, clk_divisor);
-
-	duart_out(R_DUART_CMD, M_DUART_RX_EN | M_DUART_TX_EN);	/* enable rx and tx */
-}
-
-void
-putDebugChar(unsigned char c)
-{
-	if (!duart_initialized) {
-		duart_initialized = 1;
-		duart_init(CLK_DIVISOR, DATA_BITS, PARITY, STOP_BITS);
-	}
-	while ((duart_in(R_DUART_STATUS) & M_DUART_TX_RDY) == 0);
-	duart_out(R_DUART_TX_HOLD, c);
-}
-
-unsigned char
-getDebugChar(void)
-{
-	if (!duart_initialized) {
-		duart_initialized = 1;
-		duart_init(CLK_DIVISOR, DATA_BITS, PARITY, STOP_BITS);
-	}
-	while ((duart_in(R_DUART_STATUS) & M_DUART_RX_RDY) == 0) ;
-	return duart_in(R_DUART_RX_HOLD);
-}
-
--- a/arch/mips/tx4927/common/Makefile
+++ b/arch/mips/tx4927/common/Makefile
@@ -9,6 +9,5 @@
 obj-y	+= tx4927_prom.o tx4927_setup.o tx4927_irq.o
 
 obj-$(CONFIG_TOSHIBA_FPCIB0)	   += smsc_fdc37m81x.o
-obj-$(CONFIG_KGDB)                 += tx4927_dbgio.o
 
 EXTRA_CFLAGS += -Werror
--- a/arch/mips/tx4927/common/tx4927_dbgio.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * linux/arch/mips/tx4927/common/tx4927_dbgio.c
- *
- * kgdb interface for gdb
- *
- * Author: MontaVista Software, Inc.
- *         [email protected]
- *
- * Copyright 2001-2002 MontaVista Software Inc.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-
-u8 getDebugChar(void)
-{
-	extern u8 txx9_sio_kdbg_rd(void);
-	return (txx9_sio_kdbg_rd());
-}
-
-
-int putDebugChar(u8 byte)
-{
-	extern int txx9_sio_kdbg_wr( u8 ch );
-	return (txx9_sio_kdbg_wr(byte));
-}
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -76,7 +76,7 @@
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 #endif
-#ifdef CONFIG_SERIAL_TXX9
+#if defined(CONFIG_SERIAL_TXX9) || defined(CONFIG_KGDB_TXX9)
 #include <linux/tty.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
@@ -891,9 +891,10 @@ void __init toshiba_rbtx4927_setup(void)
 
 #endif /* CONFIG_PCI */
 
-#ifdef CONFIG_SERIAL_TXX9
+#if defined(CONFIG_SERIAL_TXX9) || defined(CONFIG_KGDB_TXX9)
 	{
 		extern int early_serial_txx9_setup(struct uart_port *port);
+		extern int txx9_kgdb_add_port(int n, struct uart_port *port);
 		int i;
 		struct uart_port req;
 		for(i = 0; i < 2; i++) {
@@ -905,7 +906,12 @@ void __init toshiba_rbtx4927_setup(void)
 			req.irq = TX4927_IRQ_PIC_BEG + 8 + i;
 			req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
 			req.uartclk = 50000000;
+#ifdef CONFIG_SERIAL_TXX9
 			early_serial_txx9_setup(&req);
+#endif
+#ifdef CONFIG_KGDB_TXX9
+			txx9_kgdb_add_port(i, &req);
+#endif
 		}
 	}
 #ifdef CONFIG_SERIAL_TXX9_CONSOLE
@@ -914,7 +920,7 @@ void __init toshiba_rbtx4927_setup(void)
                 strcat(argptr, " console=ttyS0,38400");
         }
 #endif
-#endif
+#endif /* defined(CONFIG_SERIAL_TXX9) || defined(CONFIG_KGDB_TXX9) */
 
 #ifdef CONFIG_ROOT_NFS
         argptr = prom_getcmdline();
--- a/arch/mips/tx4938/common/Makefile
+++ b/arch/mips/tx4938/common/Makefile
@@ -7,6 +7,5 @@
 #
 
 obj-y	+= prom.o setup.o irq.o
-obj-$(CONFIG_KGDB) += dbgio.o
 
 EXTRA_CFLAGS += -Werror
--- a/arch/mips/tx4938/common/dbgio.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * linux/arch/mips/tx4938/common/dbgio.c
- *
- * kgdb interface for gdb
- *
- * Author: MontaVista Software, Inc.
- *         [email protected]
- *
- * Copyright 2005 MontaVista Software Inc.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Support for TX4938 in 2.6 - Hiroshi DOYU <[email protected]>
- */
-
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-#include <asm/tx4938/tx4938_mips.h>
-
-extern u8 txx9_sio_kdbg_rd(void);
-extern int txx9_sio_kdbg_wr( u8 ch );
-
-u8 getDebugChar(void)
-{
-	return (txx9_sio_kdbg_rd());
-}
-
-int putDebugChar(u8 byte)
-{
-	return (txx9_sio_kdbg_wr(byte));
-}
-
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -30,7 +30,7 @@
 #include <asm/io.h>
 #include <asm/bootinfo.h>
 #include <asm/tx4938/rbtx4938.h>
-#ifdef CONFIG_SERIAL_TXX9
+#if defined(CONFIG_SERIAL_TXX9) || defined(CONFIG_KGDB_TXX9)
 #include <linux/tty.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
@@ -878,9 +878,10 @@ void __init toshiba_rbtx4938_setup(void)
 	set_io_port_base(RBTX4938_ETHER_BASE);
 #endif
 
-#ifdef CONFIG_SERIAL_TXX9
+#if defined(CONFIG_SERIAL_TXX9) || defined(CONFIG_KGDB_TXX9)
 	{
 		extern int early_serial_txx9_setup(struct uart_port *port);
+		extern int txx9_kgdb_add_port(int n, struct uart_port *port);
 		int i;
 		struct uart_port req;
 		for(i = 0; i < 2; i++) {
@@ -892,7 +893,12 @@ void __init toshiba_rbtx4938_setup(void)
 			req.irq = RBTX4938_IRQ_IRC_SIO(i);
 			req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
 			req.uartclk = 50000000;
+#ifdef CONFIG_SERIAL_TXX9
 			early_serial_txx9_setup(&req);
+#endif
+#ifdef CONFIG_KGDB_TXX9
+			txx9_kgdb_add_port(i, &req);
+#endif
 		}
 	}
 #ifdef CONFIG_SERIAL_TXX9_CONSOLE
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1
 obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o
 obj-$(CONFIG_SERIAL_JSM) += jsm/
 obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
+obj-$(CONFIG_KGDB_TXX9) += serial_txx9_kgdb.o
 obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
 obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o
 obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -40,6 +40,10 @@
 static char *serial_version = "1.10";
 static char *serial_name = "TX39/49 Serial driver";
 
+#ifndef CONFIG_KGDB_TXX9
+#define CONFIG_KGDB_PORT_NUM -1
+#endif
+
 #define PASS_LIMIT	256
 
 #if !defined(CONFIG_SERIAL_TXX9_STDSERIAL)
@@ -473,6 +477,9 @@ static int serial_txx9_startup(struct ua
 	unsigned long flags;
 	int retval;
 
+	if (up->port.line == CONFIG_KGDB_PORT_NUM)
+		return -EBUSY;
+
 	/*
 	 * Clear the FIFO buffers and disable them.
 	 * (they will be reenabled in set_termios())
@@ -807,6 +814,9 @@ static void __init serial_txx9_register_
 	for (i = 0; i < UART_NR; i++) {
 		struct uart_txx9_port *up = &serial_txx9_ports[i];
 
+		if (up->port.line == CONFIG_KGDB_PORT_NUM)
+			continue;
+
 		up->port.line = i;
 		up->port.ops = &serial_txx9_pops;
 		up->port.dev = dev;
@@ -975,6 +985,9 @@ static int __devinit serial_txx9_registe
 
 	mutex_lock(&serial_txx9_mutex);
 	for (i = 0; i < UART_NR; i++) {
+		if (i == CONFIG_KGDB_PORT_NUM)
+			continue;
+
 		uart = &serial_txx9_ports[i];
 		if (uart_match_port(&uart->port, port)) {
 			uart_remove_one_port(&serial_txx9_reg, &uart->port);
--- a/include/asm-mips/kdebug.h
+++ b/include/asm-mips/kdebug.h
@@ -1 +1,29 @@
-#include <asm-generic/kdebug.h>
+/*
+ *
+ * Copyright (C) 2004  MontaVista Software Inc.
+ * Author: Manish Lachwani, [email protected] or [email protected]
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#ifndef _MIPS_KDEBUG_H
+#define _MIPS_KDEBUG_H
+
+#include <linux/notifier.h>
+
+struct pt_regs;
+
+extern struct atomic_notifier_head mips_die_head;
+
+enum die_val {
+	DIE_OOPS = 1,
+	DIE_PANIC,
+	DIE_DIE,
+	DIE_KERNELDEBUG,
+	DIE_TRAP,
+};
+
+#endif /* _MIPS_KDEBUG_H */
--- /dev/null
+++ b/include/asm-mips/kgdb.h
@@ -0,0 +1,48 @@
+#ifdef __KERNEL__
+#ifndef _ASM_KGDB_H_
+#define _ASM_KGDB_H_
+
+#include <asm/sgidefs.h>
+#include <asm-generic/kgdb.h>
+
+#ifndef __ASSEMBLY__
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
+	(_MIPS_ISA == _MIPS_ISA_MIPS32)
+
+#define KGDB_GDB_REG_SIZE 32
+
+#elif (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+	(_MIPS_ISA == _MIPS_ISA_MIPS64)
+
+#ifdef CONFIG_32BIT
+#define KGDB_GDB_REG_SIZE 32
+#else /* CONFIG_CPU_32BIT */
+#define KGDB_GDB_REG_SIZE 64
+#endif
+#else
+#error "Need to set KGDB_GDB_REG_SIZE for MIPS ISA"
+#endif /* _MIPS_ISA */
+
+#define BUFMAX			2048
+#if (KGDB_GDB_REG_SIZE == 32)
+#define NUMREGBYTES		(90*sizeof(u32))
+#define NUMCRITREGBYTES		(12*sizeof(u32))
+#else
+#define NUMREGBYTES		(90*sizeof(u64))
+#define NUMCRITREGBYTES		(12*sizeof(u64))
+#endif
+#define BREAK_INSTR_SIZE	4
+#define BREAKPOINT()		__asm__ __volatile__(\
+					".globl breakinst\n\t"	\
+					".set\tnoreorder\n\t"	\
+					"nop\n"			\
+					"breakinst:\tbreak\n\t"	\
+					"nop\n\t"		\
+					".set\treorder")
+#define CACHE_FLUSH_IS_SAFE	0
+
+extern int kgdb_early_setup;
+
+#endif				/* !__ASSEMBLY__ */
+#endif				/* _ASM_KGDB_H_ */
+#endif				/* __KERNEL__ */
--- a/lib/Kconfig.kgdb
+++ b/lib/Kconfig.kgdb
@@ -13,7 +13,7 @@ config UNWIND_INFO
 config KGDB
 	bool "KGDB: kernel debugging with remote gdb"
 	select WANT_EXTRA_DEBUG_INFORMATION
-	depends on DEBUG_KERNEL && (X86 || PPC)
+	depends on DEBUG_KERNEL && (X86 || MIPS || PPC)
 	help
 	  If you say Y here, it will be possible to remotely debug the
 	  kernel using gdb.  Documentation of kernel debugger is available
@@ -41,6 +41,8 @@ choice
 	depends on KGDB
 	default KGDB_MPSC if SERIAL_MPSC
 	default KGDB_CPM_UART if (CPM2 || 8xx)
+	default KGDB_SIBYTE if SIBYTE_SB1xxx_SOC
+ 	default KGDB_TXX9 if CPU_TX49XX
 	default KGDB_8250_NOMODULE
 	help
 	  There are a number of different ways in which you can communicate
@@ -91,6 +93,16 @@ config KGDB_CPM_UART
 	depends on PPC && (CPM2 || 8xx)
  	help
  	  Uses CPM UART to communicate with the host GDB.
+
+config KGDB_SIBYTE
+	bool "KGDB: On Broadcom SB1xxx serial port"
+	depends on MIPS && SIBYTE_SB1xxx_SOC
+
+config KGDB_TXX9
+	bool "KGDB: On TX49xx serial port"
+	depends on MIPS && CPU_TX49XX
+	help
+	  Uses TX49xx serial port to communicate with the host GDB.
 endchoice
 
 choice
@@ -158,7 +170,8 @@ config KGDB_SIMPLE_SERIAL
 config KGDB_BAUDRATE
 	int "Debug serial port baud rate"
 	depends on (KGDB_8250 && KGDB_SIMPLE_SERIAL) || \
-		KGDB_MPSC || KGDB_CPM_UART
+		KGDB_MPSC || KGDB_CPM_UART || \
+		KGDB_TXX9
 	default "115200"
 	help
 	  gdb and the kernel stub need to agree on the baud rate to be
@@ -169,7 +182,7 @@ config KGDB_PORT_NUM
 	int "Serial port number for KGDB"
 	range 0 1 if KGDB_MPSC
 	range 0 3
-	depends on (KGDB_8250 && KGDB_SIMPLE_SERIAL) || KGDB_MPSC
+	depends on (KGDB_8250 && KGDB_SIMPLE_SERIAL) || KGDB_MPSC || KGDB_TXX9
 	default "1"
 	help
 	  Pick the port number (0 based) for KGDB to use.
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -30,7 +30,6 @@ config BASLER_EXCITE
 	select SYS_HAS_CPU_RM9000
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
-	select SYS_SUPPORTS_KGDB
 	help
 	  The eXcite is a smart camera platform manufactured by
 	  Basler Vision Technologies AG.
@@ -302,7 +301,6 @@ config PMC_MSP
 	select SYS_HAS_CPU_MIPS32_R2
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
-	select SYS_SUPPORTS_KGDB
 	select IRQ_CPU
 	select SERIAL_8250
 	select SERIAL_8250_CONSOLE
@@ -326,7 +324,6 @@ config PMC_YOSEMITE
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select SYS_SUPPORTS_HIGHMEM
-	select SYS_SUPPORTS_KGDB
 	select SYS_SUPPORTS_SMP
 	help
 	  Yosemite is an evaluation board for the RM9000x2 processor
@@ -394,7 +391,6 @@ config SGI_IP27
 	select SYS_HAS_CPU_R10000
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
-	select SYS_SUPPORTS_KGDB
 	select SYS_SUPPORTS_NUMA
 	select SYS_SUPPORTS_SMP
 	select GENERIC_HARDIRQS_NO__DO_IRQ
@@ -476,7 +472,6 @@ config SIBYTE_SWARM
 	select SYS_HAS_CPU_SB1
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select SYS_SUPPORTS_HIGHMEM
-	select SYS_SUPPORTS_KGDB
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config SIBYTE_LITTLESUR
@@ -587,7 +582,6 @@ config TOSHIBA_RBTX4927
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_SUPPORTS_BIG_ENDIAN
-	select SYS_SUPPORTS_KGDB
 	select GENERIC_HARDIRQS_NO__DO_IRQ
 	help
 	  This Toshiba board is based on the TX4927 processor. Say Y here to
@@ -605,7 +599,6 @@ config TOSHIBA_RBTX4938
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_SUPPORTS_BIG_ENDIAN
-	select SYS_SUPPORTS_KGDB
 	select GENERIC_HARDIRQS_NO__DO_IRQ
 	select GENERIC_GPIO
 	help
@@ -860,7 +853,6 @@ config SOC_PNX8550
 	select SYS_HAS_EARLY_PRINTK
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select GENERIC_HARDIRQS_NO__DO_IRQ
-	select SYS_SUPPORTS_KGDB
 	select GENERIC_GPIO
 
 config SWAP_IO_SPACE
--- a/arch/mips/au1000/common/Makefile
+++ b/arch/mips/au1000/common/Makefile
@@ -10,7 +10,6 @@ obj-y += prom.o irq.o puts.o time.o rese
 	au1xxx_irqmap.o clocks.o platform.o power.o setup.o \
 	sleeper.o cputable.o dma.o dbdma.o gpio.o
 
-obj-$(CONFIG_KGDB)		+= dbg_io.o
 obj-$(CONFIG_PCI)		+= pci.o
 
 EXTRA_CFLAGS += -Werror
--- a/arch/mips/au1000/common/dbg_io.c
+++ /dev/null
@@ -1,121 +0,0 @@
-
-#include <asm/io.h>
-#include <asm/mach-au1x00/au1000.h>
-
-#ifdef CONFIG_KGDB
-
-/*
- * FIXME the user should be able to select the
- * uart to be used for debugging.
- */
-#define DEBUG_BASE  UART_DEBUG_BASE
-/**/
-
-/* we need uint32 uint8 */
-/* #include "types.h" */
-typedef         unsigned char uint8;
-typedef         unsigned int  uint32;
-
-#define         UART16550_BAUD_2400             2400
-#define         UART16550_BAUD_4800             4800
-#define         UART16550_BAUD_9600             9600
-#define         UART16550_BAUD_19200            19200
-#define         UART16550_BAUD_38400            38400
-#define         UART16550_BAUD_57600            57600
-#define         UART16550_BAUD_115200           115200
-
-#define         UART16550_PARITY_NONE           0
-#define         UART16550_PARITY_ODD            0x08
-#define         UART16550_PARITY_EVEN           0x18
-#define         UART16550_PARITY_MARK           0x28
-#define         UART16550_PARITY_SPACE          0x38
-
-#define         UART16550_DATA_5BIT             0x0
-#define         UART16550_DATA_6BIT             0x1
-#define         UART16550_DATA_7BIT             0x2
-#define         UART16550_DATA_8BIT             0x3
-
-#define         UART16550_STOP_1BIT             0x0
-#define         UART16550_STOP_2BIT             0x4
-
-
-#define UART_RX		0	/* Receive buffer */
-#define UART_TX		4	/* Transmit buffer */
-#define UART_IER	8	/* Interrupt Enable Register */
-#define UART_IIR	0xC	/* Interrupt ID Register */
-#define UART_FCR	0x10	/* FIFO Control Register */
-#define UART_LCR	0x14	/* Line Control Register */
-#define UART_MCR	0x18	/* Modem Control Register */
-#define UART_LSR	0x1C	/* Line Status Register */
-#define UART_MSR	0x20	/* Modem Status Register */
-#define UART_CLK	0x28	/* Baud Rat4e Clock Divider */
-#define UART_MOD_CNTRL	0x100	/* Module Control */
-
-/* memory-mapped read/write of the port */
-#define UART16550_READ(y)    (au_readl(DEBUG_BASE + y) & 0xff)
-#define UART16550_WRITE(y, z) (au_writel(z&0xff, DEBUG_BASE + y))
-
-extern unsigned long get_au1x00_uart_baud_base(void);
-extern unsigned long cal_r4koff(void);
-
-void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
-{
-
-	if (UART16550_READ(UART_MOD_CNTRL) != 0x3) {
-		UART16550_WRITE(UART_MOD_CNTRL, 3);
-	}
-	cal_r4koff();
-
-	/* disable interrupts */
-	UART16550_WRITE(UART_IER, 0);
-
-	/* set up baud rate */
-	{
-		uint32 divisor;
-
-		/* set divisor */
-		divisor = get_au1x00_uart_baud_base() / baud;
-		UART16550_WRITE(UART_CLK, divisor & 0xffff);
-	}
-
-	/* set data format */
-	UART16550_WRITE(UART_LCR, (data | parity | stop));
-}
-
-static int remoteDebugInitialized = 0;
-
-uint8 getDebugChar(void)
-{
-	if (!remoteDebugInitialized) {
-		remoteDebugInitialized = 1;
-		debugInit(UART16550_BAUD_115200,
-			  UART16550_DATA_8BIT,
-			  UART16550_PARITY_NONE,
-			  UART16550_STOP_1BIT);
-	}
-
-	while((UART16550_READ(UART_LSR) & 0x1) == 0);
-	return UART16550_READ(UART_RX);
-}
-
-
-int putDebugChar(uint8 byte)
-{
-//	int i;
-
-	if (!remoteDebugInitialized) {
-		remoteDebugInitialized = 1;
-		debugInit(UART16550_BAUD_115200,
-			  UART16550_DATA_8BIT,
-			  UART16550_PARITY_NONE,
-			  UART16550_STOP_1BIT);
-	}
-
-	while ((UART16550_READ(UART_LSR)&0x40) == 0);
-	UART16550_WRITE(UART_TX, byte);
-	//for (i=0;i<0xfff;i++);
-
-	return 1;
-}
-
-#endif
--- a/arch/mips/basler/excite/Makefile
+++ b/arch/mips/basler/excite/Makefile
@@ -5,5 +5,4 @@
 obj-$(CONFIG_BASLER_EXCITE)	+= excite_irq.o excite_prom.o excite_setup.o \
 				   excite_device.o excite_procfs.o
 
-obj-$(CONFIG_KGDB)		+= excite_dbg_io.o
 obj-m				+= excite_iodev.o
--- a/arch/mips/basler/excite/excite_dbg_io.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *  Copyright (C) 2004 by Basler Vision Technologies AG
- *  Author: Thomas Koeller <[email protected]>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <asm/gdb-stub.h>
-#include <asm/rm9k-ocd.h>
-#include <excite.h>
-
-#if defined(CONFIG_SERIAL_8250) && CONFIG_SERIAL_8250_NR_UARTS > 1
-#error Debug port used by serial driver
-#endif
-
-#define UART_CLK		25000000
-#define BASE_BAUD		(UART_CLK / 16)
-#define REGISTER_BASE_0		0x0208UL
-#define REGISTER_BASE_1		0x0238UL
-
-#define REGISTER_BASE_DBG	REGISTER_BASE_1
-
-#define CPRR	0x0004
-#define UACFG	0x0200
-#define UAINTS	0x0204
-#define UARBR	(REGISTER_BASE_DBG + 0x0000)
-#define UATHR	(REGISTER_BASE_DBG + 0x0004)
-#define UADLL	(REGISTER_BASE_DBG + 0x0008)
-#define UAIER	(REGISTER_BASE_DBG + 0x000c)
-#define UADLH	(REGISTER_BASE_DBG + 0x0010)
-#define UAIIR	(REGISTER_BASE_DBG + 0x0014)
-#define UAFCR	(REGISTER_BASE_DBG + 0x0018)
-#define UALCR	(REGISTER_BASE_DBG + 0x001c)
-#define UAMCR	(REGISTER_BASE_DBG + 0x0020)
-#define UALSR	(REGISTER_BASE_DBG + 0x0024)
-#define UAMSR	(REGISTER_BASE_DBG + 0x0028)
-#define UASCR	(REGISTER_BASE_DBG + 0x002c)
-
-#define	PARITY_NONE	0
-#define	PARITY_ODD	0x08
-#define	PARITY_EVEN	0x18
-#define	PARITY_MARK	0x28
-#define	PARITY_SPACE	0x38
-
-#define	DATA_5BIT	0x0
-#define	DATA_6BIT	0x1
-#define	DATA_7BIT	0x2
-#define	DATA_8BIT	0x3
-
-#define	STOP_1BIT	0x0
-#define	STOP_2BIT	0x4
-
-#define BAUD_DBG	57600
-#define	PARITY_DBG	PARITY_NONE
-#define	DATA_DBG	DATA_8BIT
-#define	STOP_DBG	STOP_1BIT
-
-/* Initialize the serial port for KGDB debugging */
-void __init excite_kgdb_init(void)
-{
-	const u32 divisor = BASE_BAUD / BAUD_DBG;
-
-	/* Take the UART out of reset */
-	titan_writel(0x00ff1cff, CPRR);
-	titan_writel(0x00000000, UACFG);
-	titan_writel(0x00000002, UACFG);
-
-	titan_writel(0x0, UALCR);
-	titan_writel(0x0, UAIER);
-
-	/* Disable FIFOs */
-	titan_writel(0x00, UAFCR);
-
-	titan_writel(0x80, UALCR);
-	titan_writel(divisor & 0xff, UADLL);
-	titan_writel((divisor & 0xff00) >> 8, UADLH);
-	titan_writel(0x0, UALCR);
-
-	titan_writel(DATA_DBG | PARITY_DBG | STOP_DBG, UALCR);
-
-	/* Enable receiver interrupt */
-	titan_readl(UARBR);
-	titan_writel(0x1, UAIER);
-}
-
-int getDebugChar(void)
-{
-	while (!(titan_readl(UALSR) & 0x1));
-	return titan_readl(UARBR);
-}
-
-int putDebugChar(int data)
-{
-	while (!(titan_readl(UALSR) & 0x20));
-	titan_writel(data, UATHR);
-	return 1;
-}
-
-/* KGDB interrupt handler */
-asmlinkage void excite_kgdb_inthdl(void)
-{
-	if (unlikely(
-		((titan_readl(UAIIR) & 0x7) == 4)
-		&& ((titan_readl(UARBR) & 0xff) == 0x3)))
-			set_async_breakpoint(&regs->cp0_epc);
-}
--- a/arch/mips/basler/excite/excite_irq.c
+++ b/arch/mips/basler/excite/excite_irq.c
@@ -50,10 +50,6 @@ void __init arch_init_irq(void)
 	mips_cpu_irq_init();
 	rm7k_cpu_irq_init();
 	rm9k_cpu_irq_init();
-
-#ifdef CONFIG_KGDB
-	excite_kgdb_init();
-#endif
 }
 
 asmlinkage void plat_irq_dispatch(void)
@@ -90,9 +86,6 @@ asmlinkage void plat_irq_dispatch(void)
 	msgint	    = msgintflags & msgintmask & (0x1 << (TITAN_MSGINT % 0x20));
 	if ((pending & (1 << TITAN_IRQ)) && msgint) {
 		ocd_writel(msgint, INTP0Clear0 + (TITAN_MSGINT / 0x20 * 0x10));
-#if defined(CONFIG_KGDB)
-		excite_kgdb_inthdl();
-#endif
 		do_IRQ(TITAN_IRQ);
 		return;
 	}
--- a/arch/mips/basler/excite/excite_setup.c
+++ b/arch/mips/basler/excite/excite_setup.c
@@ -96,13 +96,13 @@ static int __init excite_init_console(vo
 	/* Take the DUART out of reset */
 	titan_writel(0x00ff1cff, CPRR);
 
-#if defined(CONFIG_KGDB) || (CONFIG_SERIAL_8250_NR_UARTS > 1)
+#if (CONFIG_SERIAL_8250_NR_UARTS > 1)
 	/* Enable both ports */
 	titan_writel(MASK_SER0 | MASK_SER1, UACFG);
 #else
 	/* Enable port #0 only */
 	titan_writel(MASK_SER0, UACFG);
-#endif	/* defined(CONFIG_KGDB) */
+#endif
 
  	/*
 	 * Set up serial port #0. Do not use autodetection; the result is
--- a/arch/mips/jmr3927/rbhma3100/Makefile
+++ b/arch/mips/jmr3927/rbhma3100/Makefile
@@ -3,6 +3,5 @@
 #
 
 obj-y	 			+= init.o irq.o setup.o
-obj-$(CONFIG_KGDB)		+= kgdb_io.o
 
 EXTRA_CFLAGS += -Werror
--- a/arch/mips/jmr3927/rbhma3100/kgdb_io.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *	Low level uart routines to directly access a TX[34]927 SIO.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	[email protected] or [email protected]
- *
- * Based on arch/mips/ddb5xxx/ddb5477/kgdb_io.c
- *
- * Copyright (C) 2000-2001 Toshiba Corporation
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <asm/jmr3927/jmr3927.h>
-
-#define TIMEOUT       0xffffff
-
-static int remoteDebugInitialized = 0;
-static void debugInit(int baud);
-
-int putDebugChar(unsigned char c)
-{
-        int i = 0;
-
-	if (!remoteDebugInitialized) {
-		remoteDebugInitialized = 1;
-		debugInit(38400);
-	}
-
-        do {
-            slow_down();
-            i++;
-            if (i>TIMEOUT) {
-                break;
-            }
-        } while (!(tx3927_sioptr(0)->cisr & TXx927_SICISR_TXALS));
-	tx3927_sioptr(0)->tfifo = c;
-
-	return 1;
-}
-
-unsigned char getDebugChar(void)
-{
-        int i = 0;
-	int dicr;
-	char c;
-
-	if (!remoteDebugInitialized) {
-		remoteDebugInitialized = 1;
-		debugInit(38400);
-	}
-
-	/* diable RX int. */
-	dicr = tx3927_sioptr(0)->dicr;
-	tx3927_sioptr(0)->dicr = 0;
-
-        do {
-            slow_down();
-            i++;
-            if (i>TIMEOUT) {
-                break;
-            }
-        } while (tx3927_sioptr(0)->disr & TXx927_SIDISR_UVALID)
-		;
-	c = tx3927_sioptr(0)->rfifo;
-
-	/* clear RX int. status */
-	tx3927_sioptr(0)->disr &= ~TXx927_SIDISR_RDIS;
-	/* enable RX int. */
-	tx3927_sioptr(0)->dicr = dicr;
-
-	return c;
-}
-
-static void debugInit(int baud)
-{
-	tx3927_sioptr(0)->lcr = 0x020;
-	tx3927_sioptr(0)->dicr = 0;
-	tx3927_sioptr(0)->disr = 0x4100;
-	tx3927_sioptr(0)->cisr = 0x014;
-	tx3927_sioptr(0)->fcr = 0;
-	tx3927_sioptr(0)->flcr = 0x02;
-	tx3927_sioptr(0)->bgr = ((JMR3927_BASE_BAUD + baud / 2) / baud) |
-		TXx927_SIBGR_BCLK_T0;
-}
--- a/arch/mips/kernel/gdb-low.S
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * gdb-low.S contains the low-level trap handler for the GDB stub.
- *
- * Copyright (C) 1995 Andreas Busse
- */
-#include <linux/sys.h>
-
-#include <asm/asm.h>
-#include <asm/errno.h>
-#include <asm/irqflags.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/gdb-stub.h>
-
-#ifdef CONFIG_32BIT
-#define DMFC0	mfc0
-#define DMTC0	mtc0
-#define LDC1	lwc1
-#define SDC1	lwc1
-#endif
-#ifdef CONFIG_64BIT
-#define DMFC0	dmfc0
-#define DMTC0	dmtc0
-#define LDC1	ldc1
-#define SDC1	ldc1
-#endif
-
-/*
- * [jsun] We reserves about 2x GDB_FR_SIZE in stack.  The lower (addressed)
- * part is used to store registers and passed to exception handler.
- * The upper part is reserved for "call func" feature where gdb client
- * saves some of the regs, setups call frame and passes args.
- *
- * A trace shows about 200 bytes are used to store about half of all regs.
- * The rest should be big enough for frame setup and passing args.
- */
-
-/*
- * The low level trap handler
- */
-		.align 	5
-		NESTED(trap_low, GDB_FR_SIZE, sp)
-		.set	noat
-		.set 	noreorder
-
-		mfc0	k0, CP0_STATUS
-		sll	k0, 3     		/* extract cu0 bit */
-		bltz	k0, 1f
-		move	k1, sp
-
-		/*
-		 * Called from user mode, go somewhere else.
-		 */
-		mfc0	k0, CP0_CAUSE
-		andi	k0, k0, 0x7c
-#ifdef CONFIG_64BIT
-		dsll	k0, k0, 1
-#endif
-		PTR_L	k1, saved_vectors(k0)
-		jr	k1
-		nop
-1:
-		move	k0, sp
-		PTR_SUBU sp, k1, GDB_FR_SIZE*2	# see comment above
-		LONG_S	k0, GDB_FR_REG29(sp)
-		LONG_S	$2, GDB_FR_REG2(sp)
-
-/*
- * First save the CP0 and special registers
- */
-
-		mfc0	v0, CP0_STATUS
-		LONG_S	v0, GDB_FR_STATUS(sp)
-		mfc0	v0, CP0_CAUSE
-		LONG_S	v0, GDB_FR_CAUSE(sp)
-		DMFC0	v0, CP0_EPC
-		LONG_S	v0, GDB_FR_EPC(sp)
-		DMFC0	v0, CP0_BADVADDR
-		LONG_S	v0, GDB_FR_BADVADDR(sp)
-		mfhi	v0
-		LONG_S	v0, GDB_FR_HI(sp)
-		mflo	v0
-		LONG_S	v0, GDB_FR_LO(sp)
-
-/*
- * Now the integer registers
- */
-
-		LONG_S	zero, GDB_FR_REG0(sp)		/* I know... */
-		LONG_S	$1, GDB_FR_REG1(sp)
-		/* v0 already saved */
-		LONG_S	$3, GDB_FR_REG3(sp)
-		LONG_S	$4, GDB_FR_REG4(sp)
-		LONG_S	$5, GDB_FR_REG5(sp)
-		LONG_S	$6, GDB_FR_REG6(sp)
-		LONG_S	$7, GDB_FR_REG7(sp)
-		LONG_S	$8, GDB_FR_REG8(sp)
-		LONG_S	$9, GDB_FR_REG9(sp)
-		LONG_S	$10, GDB_FR_REG10(sp)
-		LONG_S	$11, GDB_FR_REG11(sp)
-		LONG_S	$12, GDB_FR_REG12(sp)
-		LONG_S	$13, GDB_FR_REG13(sp)
-		LONG_S	$14, GDB_FR_REG14(sp)
-		LONG_S	$15, GDB_FR_REG15(sp)
-		LONG_S	$16, GDB_FR_REG16(sp)
-		LONG_S	$17, GDB_FR_REG17(sp)
-		LONG_S	$18, GDB_FR_REG18(sp)
-		LONG_S	$19, GDB_FR_REG19(sp)
-		LONG_S	$20, GDB_FR_REG20(sp)
-		LONG_S	$21, GDB_FR_REG21(sp)
-		LONG_S	$22, GDB_FR_REG22(sp)
-		LONG_S	$23, GDB_FR_REG23(sp)
-		LONG_S	$24, GDB_FR_REG24(sp)
-		LONG_S	$25, GDB_FR_REG25(sp)
-		LONG_S	$26, GDB_FR_REG26(sp)
-		LONG_S	$27, GDB_FR_REG27(sp)
-		LONG_S	$28, GDB_FR_REG28(sp)
-		/* sp already saved */
-		LONG_S	$30, GDB_FR_REG30(sp)
-		LONG_S	$31, GDB_FR_REG31(sp)
-
-		CLI				/* disable interrupts */
-		TRACE_IRQS_OFF
-
-/*
- * Followed by the floating point registers
- */
-		mfc0	v0, CP0_STATUS		/* FPU enabled? */
-		srl	v0, v0, 16
-		andi	v0, v0, (ST0_CU1 >> 16)
-
-		beqz	v0,2f			/* disabled, skip */
-		 nop
-
-		SDC1	$0, GDB_FR_FPR0(sp)
-		SDC1	$1, GDB_FR_FPR1(sp)
-		SDC1	$2, GDB_FR_FPR2(sp)
-		SDC1	$3, GDB_FR_FPR3(sp)
-		SDC1	$4, GDB_FR_FPR4(sp)
-		SDC1	$5, GDB_FR_FPR5(sp)
-		SDC1	$6, GDB_FR_FPR6(sp)
-		SDC1	$7, GDB_FR_FPR7(sp)
-		SDC1	$8, GDB_FR_FPR8(sp)
-		SDC1	$9, GDB_FR_FPR9(sp)
-		SDC1	$10, GDB_FR_FPR10(sp)
-		SDC1	$11, GDB_FR_FPR11(sp)
-		SDC1	$12, GDB_FR_FPR12(sp)
-		SDC1	$13, GDB_FR_FPR13(sp)
-		SDC1	$14, GDB_FR_FPR14(sp)
-		SDC1	$15, GDB_FR_FPR15(sp)
-		SDC1	$16, GDB_FR_FPR16(sp)
-		SDC1	$17, GDB_FR_FPR17(sp)
-		SDC1	$18, GDB_FR_FPR18(sp)
-		SDC1	$19, GDB_FR_FPR19(sp)
-		SDC1	$20, GDB_FR_FPR20(sp)
-		SDC1	$21, GDB_FR_FPR21(sp)
-		SDC1	$22, GDB_FR_FPR22(sp)
-		SDC1	$23, GDB_FR_FPR23(sp)
-		SDC1	$24, GDB_FR_FPR24(sp)
-		SDC1	$25, GDB_FR_FPR25(sp)
-		SDC1	$26, GDB_FR_FPR26(sp)
-		SDC1	$27, GDB_FR_FPR27(sp)
-		SDC1	$28, GDB_FR_FPR28(sp)
-		SDC1	$29, GDB_FR_FPR29(sp)
-		SDC1	$30, GDB_FR_FPR30(sp)
-		SDC1	$31, GDB_FR_FPR31(sp)
-
-/*
- * FPU control registers
- */
-
-		cfc1	v0, CP1_STATUS
-		LONG_S	v0, GDB_FR_FSR(sp)
-		cfc1	v0, CP1_REVISION
-		LONG_S	v0, GDB_FR_FIR(sp)
-
-/*
- * Current stack frame ptr
- */
-
-2:
-		LONG_S	sp, GDB_FR_FRP(sp)
-
-/*
- * CP0 registers (R4000/R4400 unused registers skipped)
- */
-
-		mfc0	v0, CP0_INDEX
-		LONG_S	v0, GDB_FR_CP0_INDEX(sp)
-		mfc0	v0, CP0_RANDOM
-		LONG_S	v0, GDB_FR_CP0_RANDOM(sp)
-		DMFC0	v0, CP0_ENTRYLO0
-		LONG_S	v0, GDB_FR_CP0_ENTRYLO0(sp)
-		DMFC0	v0, CP0_ENTRYLO1
-		LONG_S	v0, GDB_FR_CP0_ENTRYLO1(sp)
-		DMFC0	v0, CP0_CONTEXT
-		LONG_S	v0, GDB_FR_CP0_CONTEXT(sp)
-		mfc0	v0, CP0_PAGEMASK
-		LONG_S	v0, GDB_FR_CP0_PAGEMASK(sp)
-		mfc0	v0, CP0_WIRED
-		LONG_S	v0, GDB_FR_CP0_WIRED(sp)
-		DMFC0	v0, CP0_ENTRYHI
-		LONG_S	v0, GDB_FR_CP0_ENTRYHI(sp)
-		mfc0	v0, CP0_PRID
-		LONG_S	v0, GDB_FR_CP0_PRID(sp)
-
-		.set	at
-
-/*
- * Continue with the higher level handler
- */
-
-		move	a0,sp
-
-		jal	handle_exception
-		 nop
-
-/*
- * Restore all writable registers, in reverse order
- */
-
-		.set	noat
-
-		LONG_L	v0, GDB_FR_CP0_ENTRYHI(sp)
-		LONG_L	v1, GDB_FR_CP0_WIRED(sp)
-		DMTC0	v0, CP0_ENTRYHI
-		mtc0	v1, CP0_WIRED
-		LONG_L	v0, GDB_FR_CP0_PAGEMASK(sp)
-		LONG_L	v1, GDB_FR_CP0_ENTRYLO1(sp)
-		mtc0	v0, CP0_PAGEMASK
-		DMTC0	v1, CP0_ENTRYLO1
-		LONG_L	v0, GDB_FR_CP0_ENTRYLO0(sp)
-		LONG_L	v1, GDB_FR_CP0_INDEX(sp)
-		DMTC0	v0, CP0_ENTRYLO0
-		LONG_L	v0, GDB_FR_CP0_CONTEXT(sp)
-		mtc0	v1, CP0_INDEX
-		DMTC0	v0, CP0_CONTEXT
-
-
-/*
- * Next, the floating point registers
- */
-		mfc0	v0, CP0_STATUS		/* check if the FPU is enabled */
-		srl	v0, v0, 16
-		andi	v0, v0, (ST0_CU1 >> 16)
-
-		beqz	v0, 3f			/* disabled, skip */
-		 nop
-
-		LDC1	$31, GDB_FR_FPR31(sp)
-		LDC1	$30, GDB_FR_FPR30(sp)
-		LDC1	$29, GDB_FR_FPR29(sp)
-		LDC1	$28, GDB_FR_FPR28(sp)
-		LDC1	$27, GDB_FR_FPR27(sp)
-		LDC1	$26, GDB_FR_FPR26(sp)
-		LDC1	$25, GDB_FR_FPR25(sp)
-		LDC1	$24, GDB_FR_FPR24(sp)
-		LDC1	$23, GDB_FR_FPR23(sp)
-		LDC1	$22, GDB_FR_FPR22(sp)
-		LDC1	$21, GDB_FR_FPR21(sp)
-		LDC1	$20, GDB_FR_FPR20(sp)
-		LDC1	$19, GDB_FR_FPR19(sp)
-		LDC1	$18, GDB_FR_FPR18(sp)
-		LDC1	$17, GDB_FR_FPR17(sp)
-		LDC1	$16, GDB_FR_FPR16(sp)
-		LDC1	$15, GDB_FR_FPR15(sp)
-		LDC1	$14, GDB_FR_FPR14(sp)
-		LDC1	$13, GDB_FR_FPR13(sp)
-		LDC1	$12, GDB_FR_FPR12(sp)
-		LDC1	$11, GDB_FR_FPR11(sp)
-		LDC1	$10, GDB_FR_FPR10(sp)
-		LDC1	$9, GDB_FR_FPR9(sp)
-		LDC1	$8, GDB_FR_FPR8(sp)
-		LDC1	$7, GDB_FR_FPR7(sp)
-		LDC1	$6, GDB_FR_FPR6(sp)
-		LDC1	$5, GDB_FR_FPR5(sp)
-		LDC1	$4, GDB_FR_FPR4(sp)
-		LDC1	$3, GDB_FR_FPR3(sp)
-		LDC1	$2, GDB_FR_FPR2(sp)
-		LDC1	$1, GDB_FR_FPR1(sp)
-		LDC1	$0, GDB_FR_FPR0(sp)
-
-/*
- * Now the CP0 and integer registers
- */
-
-3:
-#ifdef CONFIG_MIPS_MT_SMTC
-		/* Read-modify write of Status must be atomic */
-		mfc0	t2, CP0_TCSTATUS
-		ori	t1, t2, TCSTATUS_IXMT
-		mtc0	t1, CP0_TCSTATUS
-		andi	t2, t2, TCSTATUS_IXMT
-		_ehb
-		DMT	9				# dmt	t1
-		jal	mips_ihb
-		nop
-#endif /* CONFIG_MIPS_MT_SMTC */
-		mfc0	t0, CP0_STATUS
-		ori	t0, 0x1f
-		xori	t0, 0x1f
-		mtc0	t0, CP0_STATUS
-#ifdef CONFIG_MIPS_MT_SMTC
-        	andi    t1, t1, VPECONTROL_TE
-        	beqz    t1, 9f
-		nop
-        	EMT					# emt
-9:
-		mfc0	t1, CP0_TCSTATUS
-		xori	t1, t1, TCSTATUS_IXMT
-		or	t1, t1, t2
-		mtc0	t1, CP0_TCSTATUS
-		_ehb
-#endif /* CONFIG_MIPS_MT_SMTC */
-		LONG_L	v0, GDB_FR_STATUS(sp)
-		LONG_L	v1, GDB_FR_EPC(sp)
-		mtc0	v0, CP0_STATUS
-		DMTC0	v1, CP0_EPC
-		LONG_L	v0, GDB_FR_HI(sp)
-		LONG_L	v1, GDB_FR_LO(sp)
-		mthi	v0
-		mtlo	v1
-		LONG_L	$31, GDB_FR_REG31(sp)
-		LONG_L	$30, GDB_FR_REG30(sp)
-		LONG_L	$28, GDB_FR_REG28(sp)
-		LONG_L	$27, GDB_FR_REG27(sp)
-		LONG_L	$26, GDB_FR_REG26(sp)
-		LONG_L	$25, GDB_FR_REG25(sp)
-		LONG_L	$24, GDB_FR_REG24(sp)
-		LONG_L	$23, GDB_FR_REG23(sp)
-		LONG_L	$22, GDB_FR_REG22(sp)
-		LONG_L	$21, GDB_FR_REG21(sp)
-		LONG_L	$20, GDB_FR_REG20(sp)
-		LONG_L	$19, GDB_FR_REG19(sp)
-		LONG_L	$18, GDB_FR_REG18(sp)
-		LONG_L	$17, GDB_FR_REG17(sp)
-		LONG_L	$16, GDB_FR_REG16(sp)
-		LONG_L	$15, GDB_FR_REG15(sp)
-		LONG_L	$14, GDB_FR_REG14(sp)
-		LONG_L	$13, GDB_FR_REG13(sp)
-		LONG_L	$12, GDB_FR_REG12(sp)
-		LONG_L	$11, GDB_FR_REG11(sp)
-		LONG_L	$10, GDB_FR_REG10(sp)
-		LONG_L	$9, GDB_FR_REG9(sp)
-		LONG_L	$8, GDB_FR_REG8(sp)
-		LONG_L	$7, GDB_FR_REG7(sp)
-		LONG_L	$6, GDB_FR_REG6(sp)
-		LONG_L	$5, GDB_FR_REG5(sp)
-		LONG_L	$4, GDB_FR_REG4(sp)
-		LONG_L	$3, GDB_FR_REG3(sp)
-		LONG_L	$2, GDB_FR_REG2(sp)
-		LONG_L	$1, GDB_FR_REG1(sp)
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
-		LONG_L	k0, GDB_FR_EPC(sp)
-		LONG_L	$29, GDB_FR_REG29(sp)		/* Deallocate stack */
-		jr	k0
-		rfe
-#else
-		LONG_L	sp, GDB_FR_REG29(sp)		/* Deallocate stack */
-
-		.set	mips3
-		eret
-		.set	mips0
-#endif
-		.set	at
-		.set	reorder
-		END(trap_low)
-
-LEAF(kgdb_read_byte)
-4:		lb	t0, (a0)
-		sb	t0, (a1)
-		li	v0, 0
-		jr	ra
-		.section __ex_table,"a"
-		PTR	4b, kgdbfault
-		.previous
-		END(kgdb_read_byte)
-
-LEAF(kgdb_write_byte)
-5:		sb	a0, (a1)
-		li	v0, 0
-		jr	ra
-		.section __ex_table,"a"
-		PTR	5b, kgdbfault
-		.previous
-		END(kgdb_write_byte)
-
-		.type	kgdbfault@function
-		.ent	kgdbfault
-
-kgdbfault:	li	v0, -EFAULT
-		jr	ra
-		.end	kgdbfault
--- a/arch/mips/mips-boards/atlas/Makefile
+++ b/arch/mips/mips-boards/atlas/Makefile
@@ -17,6 +17,5 @@
 #
 
 obj-y			:= atlas_int.o atlas_setup.o
-obj-$(CONFIG_KGDB)	+= atlas_gdb.o
 
 EXTRA_CFLAGS += -Werror
--- a/arch/mips/mips-boards/atlas/atlas_gdb.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Carsten Langgaard, [email protected]
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * This is the interface to the remote debugger stub.
- */
-#include <asm/io.h>
-#include <asm/mips-boards/atlas.h>
-#include <asm/mips-boards/saa9730_uart.h>
-
-#define INB(a)     inb((unsigned long)a)
-#define OUTB(x, a)  outb(x, (unsigned long)a)
-
-/*
- * This is the interface to the remote debugger stub
- * if the Philips part is used for the debug port,
- * called from the platform setup code.
- */
-void *saa9730_base = (void *)ATLAS_SAA9730_REG;
-
-static int saa9730_kgdb_active = 0;
-
-#define SAA9730_BAUDCLOCK(baud) (((ATLAS_SAA9730_BAUDCLOCK/(baud))/16)-1)
-
-int saa9730_kgdb_hook(int speed)
-{
-	int baudclock;
-	t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR);
-
-        /*
-         * Clear all interrupts
-         */
-	(void) INB(&kgdb_uart->Lsr);
-	(void) INB(&kgdb_uart->Msr);
-	(void) INB(&kgdb_uart->Thr_Rbr);
-	(void) INB(&kgdb_uart->Iir_Fcr);
-
-        /*
-         * Now, initialize the UART
-         */
-	/* 8 data bits, one stop bit, no parity */
-	OUTB(SAA9730_LCR_DATA8, &kgdb_uart->Lcr);
-
-	baudclock = SAA9730_BAUDCLOCK(speed);
-
-	OUTB((baudclock >> 16) & 0xff, &kgdb_uart->BaudDivMsb);
-	OUTB( baudclock        & 0xff, &kgdb_uart->BaudDivLsb);
-
-	/* Set RTS/DTR active */
-	OUTB(SAA9730_MCR_DTR | SAA9730_MCR_RTS, &kgdb_uart->Mcr);
-	saa9730_kgdb_active = 1;
-
-	return speed;
-}
-
-int saa9730_putDebugChar(char c)
-{
-	t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR);
-
-        if (!saa9730_kgdb_active) {     /* need to init device first */
-                return 0;
-        }
-
-        while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_THRE))
-                ;
-	OUTB(c, &kgdb_uart->Thr_Rbr);
-
-        return 1;
-}
-
-char saa9730_getDebugChar(void)
-{
-	t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR);
-	char c;
-
-        if (!saa9730_kgdb_active) {     /* need to init device first */
-                return 0;
-        }
-        while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_DR))
-                ;
-
-	c = INB(&kgdb_uart->Thr_Rbr);
-	return(c);
-}
--- a/arch/mips/mips-boards/atlas/atlas_setup.c
+++ b/arch/mips/mips-boards/atlas/atlas_setup.c
@@ -36,10 +36,6 @@
 
 extern void mips_reboot_setup(void);
 
-#ifdef CONFIG_KGDB
-extern void kgdb_config(void);
-#endif
-
 static void __init serial_init(void);
 
 const char *get_system_type(void)
@@ -57,9 +53,6 @@ void __init plat_mem_setup(void)
 
 	serial_init();
 
-#ifdef CONFIG_KGDB
-	kgdb_config();
-#endif
 	mips_reboot_setup();
 }
 
--- a/arch/mips/mips-boards/generic/gdb_hook.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Carsten Langgaard, [email protected]
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * This is the interface to the remote debugger stub.
- */
-#include <linux/types.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-
-#include <asm/serial.h>
-#include <asm/io.h>
-
-static struct serial_state rs_table[] = {
-	SERIAL_PORT_DFNS	/* Defined in serial.h */
-};
-
-static struct async_struct kdb_port_info = {0};
-
-int (*generic_putDebugChar)(char);
-char (*generic_getDebugChar)(void);
-
-static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
-{
-	return inb(info->port + offset);
-}
-
-static __inline__ void serial_out(struct async_struct *info, int offset,
-				int value)
-{
-	outb(value, info->port+offset);
-}
-
-int rs_kgdb_hook(int tty_no, int speed) {
-	int t;
-	struct serial_state *ser = &rs_table[tty_no];
-
-	kdb_port_info.state = ser;
-	kdb_port_info.magic = SERIAL_MAGIC;
-	kdb_port_info.port = ser->port;
-	kdb_port_info.flags = ser->flags;
-
-	/*
-	 * Clear all interrupts
-	 */
-	serial_in(&kdb_port_info, UART_LSR);
-	serial_in(&kdb_port_info, UART_RX);
-	serial_in(&kdb_port_info, UART_IIR);
-	serial_in(&kdb_port_info, UART_MSR);
-
-	/*
-	 * Now, initialize the UART
-	 */
-	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
-	if (kdb_port_info.flags & ASYNC_FOURPORT) {
-		kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS;
-		t = UART_MCR_DTR | UART_MCR_OUT1;
-	} else {
-		kdb_port_info.MCR
-			= UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
-		t = UART_MCR_DTR | UART_MCR_RTS;
-	}
-
-	kdb_port_info.MCR = t;		/* no interrupts, please */
-	serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR);
-
-	/*
-	 * and set the speed of the serial port
-	 */
-	if (speed == 0)
-		speed = 9600;
-
-	t = kdb_port_info.state->baud_base / speed;
-	/* set DLAB */
-	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
-	serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */
-	serial_out(&kdb_port_info, UART_DLM, t >> 8);  /* MS of divisor */
-	/* reset DLAB */
-	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);
-
-	return speed;
-}
-
-int putDebugChar(char c)
-{
-	return generic_putDebugChar(c);
-}
-
-char getDebugChar(void)
-{
-	return generic_getDebugChar();
-}
-
-int rs_putDebugChar(char c)
-{
-
-	if (!kdb_port_info.state) { 	/* need to init device first */
-		return 0;
-	}
-
-	while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
-		;
-
-	serial_out(&kdb_port_info, UART_TX, c);
-
-	return 1;
-}
-
-char rs_getDebugChar(void)
-{
-	if (!kdb_port_info.state) { 	/* need to init device first */
-		return 0;
-	}
-
-	while (!(serial_in(&kdb_port_info, UART_LSR) & 1))
-		;
-
-	return serial_in(&kdb_port_info, UART_RX);
-}
--- a/arch/mips/pci/fixup-atlas.c
+++ b/arch/mips/pci/fixup-atlas.c
@@ -68,24 +68,3 @@ int pcibios_plat_dev_init(struct pci_dev
 {
 	return 0;
 }
-
-#ifdef CONFIG_KGDB
-/*
- * The PCI scan may have moved the saa9730 I/O address, so reread
- * the address here.
- * This does mean that it's not possible to debug the PCI bus configuration
- * code, but it is better than nothing...
- */
-
-static void atlas_saa9730_base_fixup(struct pci_dev *pdev)
-{
-	extern void *saa9730_base;
-	if (pdev->bus == 0 && PCI_SLOT(pdev->devfn) == 19)
-		(void) pci_read_config_dword(pdev, 0x14, (u32 *)&saa9730_base);
-	printk("saa9730_base = %x\n", saa9730_base);
-}
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA9730,
-	 atlas_saa9730_base_fixup);
-
-#endif
--- a/arch/mips/philips/pnx8550/common/Makefile
+++ b/arch/mips/philips/pnx8550/common/Makefile
@@ -24,6 +24,5 @@
 
 obj-y := setup.o prom.o int.o reset.o time.o proc.o platform.o
 obj-$(CONFIG_PCI) += pci.o
-obj-$(CONFIG_KGDB) += gdb_hook.o
 
 EXTRA_CFLAGS += -Werror
--- a/arch/mips/philips/pnx8550/common/gdb_hook.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Carsten Langgaard, [email protected]
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * This is the interface to the remote debugger stub.
- *
- */
-#include <linux/types.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-#include <linux/serial_ip3106.h>
-
-#include <asm/serial.h>
-#include <asm/io.h>
-
-#include <uart.h>
-
-static struct serial_state rs_table[IP3106_NR_PORTS] = {
-};
-static struct async_struct kdb_port_info = {0};
-
-void rs_kgdb_hook(int tty_no)
-{
-	struct serial_state *ser = &rs_table[tty_no];
-
-	kdb_port_info.state = ser;
-	kdb_port_info.magic = SERIAL_MAGIC;
-	kdb_port_info.port  = tty_no;
-	kdb_port_info.flags = ser->flags;
-
-	/*
-	 * Clear all interrupts
-	 */
-	/* Clear all the transmitter FIFO counters (pointer and status) */
-	ip3106_lcr(UART_BASE, tty_no) |= IP3106_UART_LCR_TX_RST;
-	/* Clear all the receiver FIFO counters (pointer and status) */
-	ip3106_lcr(UART_BASE, tty_no) |= IP3106_UART_LCR_RX_RST;
-	/* Clear all interrupts */
-	ip3106_iclr(UART_BASE, tty_no) = IP3106_UART_INT_ALLRX |
-		IP3106_UART_INT_ALLTX;
-
-	/*
-	 * Now, initialize the UART
-	 */
-	ip3106_lcr(UART_BASE, tty_no) = IP3106_UART_LCR_8BIT;
-	ip3106_baud(UART_BASE, tty_no) = 5; // 38400 Baud
-}
-
-int putDebugChar(char c)
-{
-	/* Wait until FIFO not full */
-	while (((ip3106_fifo(UART_BASE, kdb_port_info.port) & IP3106_UART_FIFO_TXFIFO) >> 16) >= 16)
-		;
-	/* Send one char */
-	ip3106_fifo(UART_BASE, kdb_port_info.port) = c;
-
-	return 1;
-}
-
-char getDebugChar(void)
-{
-	char ch;
-
-	/* Wait until there is a char in the FIFO */
-	while (!((ip3106_fifo(UART_BASE, kdb_port_info.port) &
-					IP3106_UART_FIFO_RXFIFO) >> 8))
-		;
-	/* Read one char */
-	ch = ip3106_fifo(UART_BASE, kdb_port_info.port) &
-		IP3106_UART_FIFO_RBRTHR;
-	/* Advance the RX FIFO read pointer */
-	ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_RX_NEXT;
-	return (ch);
-}
-
-void rs_disable_debug_interrupts(void)
-{
-	ip3106_ien(UART_BASE, kdb_port_info.port) = 0; /* Disable all interrupts */
-}
-
-void rs_enable_debug_interrupts(void)
-{
-	/* Clear all the transmitter FIFO counters (pointer and status) */
-	ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_TX_RST;
-	/* Clear all the receiver FIFO counters (pointer and status) */
-	ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_RX_RST;
-	/* Clear all interrupts */
-	ip3106_iclr(UART_BASE, kdb_port_info.port) = IP3106_UART_INT_ALLRX |
-		IP3106_UART_INT_ALLTX;
-	ip3106_ien(UART_BASE, kdb_port_info.port)  = IP3106_UART_INT_ALLRX; /* Enable RX interrupts */
-}
--- a/arch/mips/philips/pnx8550/common/setup.c
+++ b/arch/mips/philips/pnx8550/common/setup.c
@@ -142,16 +142,5 @@ void __init plat_mem_setup(void)
 		ip3106_baud(UART_BASE, pnx8550_console_port) = 5;
 	}
 
-#ifdef CONFIG_KGDB
-	argptr = prom_getcmdline();
-	if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) {
-		int line;
-		argptr += strlen("kgdb=ttyS");
-		line = *argptr == '0' ? 0 : 1;
-		rs_kgdb_hook(line);
-		pr_info("KGDB: Using ttyS%i for session, "
-		        "please connect your debugger\n", line ? 1 : 0);
-	}
-#endif
 	return;
 }
--- a/arch/mips/pmc-sierra/yosemite/Makefile
+++ b/arch/mips/pmc-sierra/yosemite/Makefile
@@ -4,7 +4,6 @@
 
 obj-y    += irq.o prom.o py-console.o setup.o
 
-obj-$(CONFIG_KGDB)		+= dbg_io.o
 obj-$(CONFIG_SMP)		+= smp.o
 
 EXTRA_CFLAGS += -Werror
--- a/arch/mips/pmc-sierra/yosemite/dbg_io.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright 2003 PMC-Sierra
- * Author: Manish Lachwani ([email protected])
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * Support for KGDB for the Yosemite board. We make use of single serial
- * port to be used for KGDB as well as console. The second serial port
- * seems to be having a problem. Single IRQ is allocated for both the
- * ports. Hence, the interrupt routing code needs to figure out whether
- * the interrupt came from channel A or B.
- */
-
-#include <asm/serial.h>
-
-/*
- * Baud rate, Parity, Data and Stop bit settings for the
- * serial port on the Yosemite. Note that the Early printk
- * patch has been added. So, we should be all set to go
- */
-#define	YOSEMITE_BAUD_2400	2400
-#define	YOSEMITE_BAUD_4800	4800
-#define	YOSEMITE_BAUD_9600	9600
-#define	YOSEMITE_BAUD_19200	19200
-#define	YOSEMITE_BAUD_38400	38400
-#define	YOSEMITE_BAUD_57600	57600
-#define	YOSEMITE_BAUD_115200	115200
-
-#define	YOSEMITE_PARITY_NONE	0
-#define	YOSEMITE_PARITY_ODD	0x08
-#define	YOSEMITE_PARITY_EVEN	0x18
-#define	YOSEMITE_PARITY_MARK	0x28
-#define	YOSEMITE_PARITY_SPACE	0x38
-
-#define	YOSEMITE_DATA_5BIT	0x0
-#define	YOSEMITE_DATA_6BIT	0x1
-#define	YOSEMITE_DATA_7BIT	0x2
-#define	YOSEMITE_DATA_8BIT	0x3
-
-#define	YOSEMITE_STOP_1BIT	0x0
-#define	YOSEMITE_STOP_2BIT	0x4
-
-/* This is crucial */
-#define	SERIAL_REG_OFS		0x1
-
-#define	SERIAL_RCV_BUFFER	0x0
-#define	SERIAL_TRANS_HOLD	0x0
-#define	SERIAL_SEND_BUFFER	0x0
-#define	SERIAL_INTR_ENABLE	(1 * SERIAL_REG_OFS)
-#define	SERIAL_INTR_ID		(2 * SERIAL_REG_OFS)
-#define	SERIAL_DATA_FORMAT	(3 * SERIAL_REG_OFS)
-#define	SERIAL_LINE_CONTROL	(3 * SERIAL_REG_OFS)
-#define	SERIAL_MODEM_CONTROL	(4 * SERIAL_REG_OFS)
-#define	SERIAL_RS232_OUTPUT	(4 * SERIAL_REG_OFS)
-#define	SERIAL_LINE_STATUS	(5 * SERIAL_REG_OFS)
-#define	SERIAL_MODEM_STATUS	(6 * SERIAL_REG_OFS)
-#define	SERIAL_RS232_INPUT	(6 * SERIAL_REG_OFS)
-#define	SERIAL_SCRATCH_PAD	(7 * SERIAL_REG_OFS)
-
-#define	SERIAL_DIVISOR_LSB	(0 * SERIAL_REG_OFS)
-#define	SERIAL_DIVISOR_MSB	(1 * SERIAL_REG_OFS)
-
-/*
- * Functions to READ and WRITE to serial port 0
- */
-#define	SERIAL_READ(ofs)		(*((volatile unsigned char*)	\
-					(TITAN_SERIAL_BASE + ofs)))
-
-#define	SERIAL_WRITE(ofs, val)		((*((volatile unsigned char*)	\
-					(TITAN_SERIAL_BASE + ofs))) = val)
-
-/*
- * Functions to READ and WRITE to serial port 1
- */
-#define	SERIAL_READ_1(ofs)		(*((volatile unsigned char*)	\
-					(TITAN_SERIAL_BASE_1 + ofs)))
-
-#define	SERIAL_WRITE_1(ofs, val)	((*((volatile unsigned char*)	\
-					(TITAN_SERIAL_BASE_1 + ofs))) = val)
-
-/*
- * Second serial port initialization
- */
-void init_second_port(void)
-{
-	/* Disable Interrupts */
-	SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0);
-	SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0x0);
-
-	{
-		unsigned int divisor;
-
-		SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x80);
-		divisor = TITAN_SERIAL_BASE_BAUD / YOSEMITE_BAUD_115200;
-		SERIAL_WRITE_1(SERIAL_DIVISOR_LSB, divisor & 0xff);
-
-		SERIAL_WRITE_1(SERIAL_DIVISOR_MSB,
-			       (divisor & 0xff00) >> 8);
-		SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0);
-	}
-
-	SERIAL_WRITE_1(SERIAL_DATA_FORMAT, YOSEMITE_DATA_8BIT |
-		       YOSEMITE_PARITY_NONE | YOSEMITE_STOP_1BIT);
-
-	/* Enable Interrupts */
-	SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0xf);
-}
-
-/* Initialize the serial port for KGDB debugging */
-void debugInit(unsigned int baud, unsigned char data, unsigned char parity,
-	       unsigned char stop)
-{
-	/* Disable Interrupts */
-	SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0);
-	SERIAL_WRITE(SERIAL_INTR_ENABLE, 0x0);
-
-	{
-		unsigned int divisor;
-
-		SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x80);
-
-		divisor = TITAN_SERIAL_BASE_BAUD / baud;
-		SERIAL_WRITE(SERIAL_DIVISOR_LSB, divisor & 0xff);
-
-		SERIAL_WRITE(SERIAL_DIVISOR_MSB, (divisor & 0xff00) >> 8);
-		SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0);
-	}
-
-	SERIAL_WRITE(SERIAL_DATA_FORMAT, data | parity | stop);
-}
-
-static int remoteDebugInitialized = 0;
-
-unsigned char getDebugChar(void)
-{
-	if (!remoteDebugInitialized) {
-		remoteDebugInitialized = 1;
-		debugInit(YOSEMITE_BAUD_115200,
-			  YOSEMITE_DATA_8BIT,
-			  YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT);
-	}
-
-	while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x1) == 0);
-	return SERIAL_READ(SERIAL_RCV_BUFFER);
-}
-
-int putDebugChar(unsigned char byte)
-{
-	if (!remoteDebugInitialized) {
-		remoteDebugInitialized = 1;
-		debugInit(YOSEMITE_BAUD_115200,
-			  YOSEMITE_DATA_8BIT,
-			  YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT);
-	}
-
-	while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x20) == 0);
-	SERIAL_WRITE(SERIAL_SEND_BUFFER, byte);
-
-	return 1;
-}
--- a/arch/mips/pmc-sierra/yosemite/irq.c
+++ b/arch/mips/pmc-sierra/yosemite/irq.c
@@ -141,10 +141,6 @@ asmlinkage void plat_irq_dispatch(void)
 	}
 }
 
-#ifdef CONFIG_KGDB
-extern void init_second_port(void);
-#endif
-
 /*
  * Initialize the next level interrupt handler
  */
@@ -156,11 +152,6 @@ void __init arch_init_irq(void)
 	rm7k_cpu_irq_init();
 	rm9k_cpu_irq_init();
 
-#ifdef CONFIG_KGDB
-	/* At this point, initialize the second serial port */
-	init_second_port();
-#endif
-
 #ifdef CONFIG_GDB_CONSOLE
 	register_gdb_console();
 #endif
--- a/arch/mips/sgi-ip22/ip22-setup.c
+++ b/arch/mips/sgi-ip22/ip22-setup.c
@@ -100,30 +100,6 @@ void __init plat_mem_setup(void)
 		add_preferred_console("arc", 0, NULL);
 	}
 
-#ifdef CONFIG_KGDB
-	{
-	char *kgdb_ttyd = prom_getcmdline();
-
-	if ((kgdb_ttyd = strstr(kgdb_ttyd, "kgdb=ttyd")) != NULL) {
-		int line;
-		kgdb_ttyd += strlen("kgdb=ttyd");
-		if (*kgdb_ttyd != '1' && *kgdb_ttyd != '2')
-			printk(KERN_INFO "KGDB: Uknown serial line /dev/ttyd%c"
-			       ", falling back to /dev/ttyd1\n", *kgdb_ttyd);
-		line = *kgdb_ttyd == '2' ? 0 : 1;
-		printk(KERN_INFO "KGDB: Using serial line /dev/ttyd%d for "
-		       "session\n", line ? 1 : 2);
-		rs_kgdb_hook(line);
-
-		printk(KERN_INFO "KGDB: Using serial line /dev/ttyd%d for "
-		       "session, please connect your debugger\n", line ? 1:2);
-
-		kgdb_enabled = 1;
-		/* Breakpoints and stuff are in sgi_irq_setup() */
-	}
-	}
-#endif
-
 #if defined(CONFIG_VT) && defined(CONFIG_SGI_NEWPORT_CONSOLE)
 	{
 		ULONG *gfxinfo;
--- a/arch/mips/sgi-ip27/Makefile
+++ b/arch/mips/sgi-ip27/Makefile
@@ -7,7 +7,6 @@ obj-y	:= ip27-berr.o ip27-irq.o ip27-ini
 	   ip27-xtalk.o
 
 obj-$(CONFIG_EARLY_PRINTK)	+= ip27-console.o
-obj-$(CONFIG_KGDB)		+= ip27-dbgio.o
 obj-$(CONFIG_SMP)		+= ip27-smp.o
 
 EXTRA_CFLAGS += -Werror
--- a/arch/mips/sgi-ip27/ip27-dbgio.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Copyright 2004 Ralf Baechle <[email protected]>
- */
-#include <asm/sn/addrs.h>
-#include <asm/sn/sn0/hub.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/ioc3.h>
-#include <asm/sn/sn_private.h>
-
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-#include <linux/serial_reg.h>
-
-#define IOC3_CLK        (22000000 / 3)
-#define IOC3_FLAGS      (0)
-
-static inline struct ioc3_uartregs *console_uart(void)
-{
-	struct ioc3 *ioc3;
-
-	ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(get_nasid())->memory_base;
-
-	return &ioc3->sregs.uarta;
-}
-
-unsigned char getDebugChar(void)
-{
-	struct ioc3_uartregs *uart = console_uart();
-
-	while ((uart->iu_lsr & UART_LSR_DR) == 0);
-	return uart->iu_rbr;
-}
-
-void putDebugChar(unsigned char c)
-{
-	struct ioc3_uartregs *uart = console_uart();
-
-	while ((uart->iu_lsr & UART_LSR_THRE) == 0);
-	uart->iu_thr = c;
-}
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -57,30 +57,6 @@ static void bcm1480_set_affinity(unsigne
 extern unsigned long ht_eoi_space;
 #endif
 
-#ifdef CONFIG_KGDB
-#include <asm/gdb-stub.h>
-extern void breakpoint(void);
-static int kgdb_irq;
-#ifdef CONFIG_GDB_CONSOLE
-extern void register_gdb_console(void);
-#endif
-
-/* kgdb is on when configured.  Pass "nokgdb" kernel arg to turn it off */
-static int kgdb_flag = 1;
-static int __init nokgdb(char *str)
-{
-	kgdb_flag = 0;
-	return 1;
-}
-__setup("nokgdb", nokgdb);
-
-/* Default to UART1 */
-int kgdb_port = 1;
-#ifdef CONFIG_SERIAL_SB1250_DUART
-extern char sb1250_duart_present[];
-#endif
-#endif
-
 static struct irq_chip bcm1480_irq_type = {
 	.name = "BCM1480-IMR",
 	.ack = ack_bcm1480_irq,
@@ -394,62 +370,10 @@ void __init arch_init_irq(void)
 	 * does its own management of IP7.
 	 */
 
-#ifdef CONFIG_KGDB
-	imask |= STATUSF_IP6;
-#endif
 	/* Enable necessary IPs, disable the rest */
 	change_c0_status(ST0_IM, imask);
-
-#ifdef CONFIG_KGDB
-	if (kgdb_flag) {
-		kgdb_irq = K_BCM1480_INT_UART_0 + kgdb_port;
-
-#ifdef CONFIG_SERIAL_SB1250_DUART
-		sb1250_duart_present[kgdb_port] = 0;
-#endif
-		/* Setup uart 1 settings, mapper */
-		/* QQQ FIXME */
-		__raw_writeq(M_DUART_IMR_BRK, IO_SPACE_BASE + A_DUART_IMRREG(kgdb_port));
-
-		bcm1480_steal_irq(kgdb_irq);
-		__raw_writeq(IMR_IP6_VAL,
-			     IO_SPACE_BASE + A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) +
-			     (kgdb_irq<<3));
-		bcm1480_unmask_irq(0, kgdb_irq);
-
-#ifdef CONFIG_GDB_CONSOLE
-		register_gdb_console();
-#endif
-		printk("Waiting for GDB on UART port %d\n", kgdb_port);
-		set_debug_traps();
-		breakpoint();
-	}
-#endif
-}
-
-#ifdef CONFIG_KGDB
-
-#include <linux/delay.h>
-
-#define duart_out(reg, val)     csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port, reg)))
-#define duart_in(reg)           csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port, reg)))
-
-static void bcm1480_kgdb_interrupt(void)
-{
-	/*
-	 * Clear break-change status (allow some time for the remote
-	 * host to stop the break, since we would see another
-	 * interrupt on the end-of-break too)
-	 */
-	kstat.irqs[smp_processor_id()][kgdb_irq]++;
-	mdelay(500);
-	duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT |
-				M_DUART_RX_EN | M_DUART_TX_EN);
-	set_async_breakpoint(&get_irq_regs()->cp0_epc);
 }
 
-#endif 	/* CONFIG_KGDB */
-
 extern void bcm1480_mailbox_interrupt(void);
 
 asmlinkage void plat_irq_dispatch(void)
@@ -485,11 +409,6 @@ asmlinkage void plat_irq_dispatch(void)
 		bcm1480_mailbox_interrupt();
 #endif
 
-#ifdef CONFIG_KGDB
-	else if (pending & CAUSEF_IP6)
-		bcm1480_kgdb_interrupt();		/* KGDB (uart 1) */
-#endif
-
 	else if (pending & CAUSEF_IP2) {
 		unsigned long long mask_h, mask_l;
 		unsigned long base;
--- /dev/null
+++ b/drivers/serial/serial_txx9_kgdb.c
@@ -0,0 +1,152 @@
+/*
+ * drivers/serial/serial_txx9_kgdb.c
+ *
+ * kgdb interface for gdb
+ *
+ * Author: MontaVista Software, Inc.
+ *         [email protected]
+ *
+ * Copyright (C) 2005-2006 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/kgdb.h>
+#include <linux/io.h>
+
+/* Speed of the UART. */
+static unsigned int kgdb_txx9_baud = CONFIG_KGDB_BAUDRATE;
+
+#define TXX9_NPORT 4		/* TX4939 has 4 UARTs, others only have 2 */
+
+static struct uart_port  kgdb_txx9_ports[TXX9_NPORT];
+static struct uart_port *kgdb_port;
+
+/* TXX9 Serial Registers */
+#define TXX9_SILCR	0x00
+#define TXX9_SIDISR	0x08
+#define TXX9_SISCISR	0x0c
+#define TXX9_SIFCR	0x10
+#define TXX9_SIFLCR	0x14
+#define TXX9_SIBGR	0x18
+#define TXX9_SITFIFO	0x1c
+#define TXX9_SIRFIFO	0x20
+
+/* SILCR : Line Control */
+#define TXX9_SILCR_SCS_IMCLK_BG	0x00000020
+#define TXX9_SILCR_SCS_SCLK_BG	0x00000060
+#define TXX9_SILCR_USBL_1BIT	0x00000000
+#define TXX9_SILCR_UMODE_8BIT	0x00000000
+
+/* SIDISR : DMA/Int. Status */
+#define TXX9_SIDISR_RFDN_MASK	0x0000001f
+
+/* SISCISR : Status Change Int. Status */
+#define TXX9_SISCISR_TRDY	0x00000004
+
+/* SIFCR : FIFO Control */
+#define TXX9_SIFCR_SWRST	0x00008000
+
+/* SIBGR : Baud Rate Control */
+#define TXX9_SIBGR_BCLK_T0	0x00000000
+#define TXX9_SIBGR_BCLK_T2	0x00000100
+#define TXX9_SIBGR_BCLK_T4	0x00000200
+#define TXX9_SIBGR_BCLK_T6	0x00000300
+
+static inline unsigned int sio_in(struct uart_port *port, int offset)
+{
+	return *(volatile u32 *)(port->membase + offset);
+}
+
+static inline void sio_out(struct uart_port *port, int offset,
+	unsigned int value)
+{
+	*(volatile u32 *)(port->membase + offset) = value;
+}
+
+void __init txx9_kgdb_add_port(int n, struct uart_port *port)
+{
+	memcpy(&kgdb_txx9_ports[n], port, sizeof(struct uart_port));
+}
+
+static int txx9_kgdb_init(void)
+{
+	unsigned int quot, sibgr;
+
+	kgdb_port = &kgdb_txx9_ports[CONFIG_KGDB_PORT_NUM];
+
+	if (kgdb_port->iotype != UPIO_MEM &&
+	    kgdb_port->iotype != UPIO_MEM32)
+		return -1;
+
+	/* Reset the UART. */
+	sio_out(kgdb_port, TXX9_SIFCR, TXX9_SIFCR_SWRST);
+#ifdef CONFIG_CPU_TX49XX
+	/*
+	 * TX4925 BUG WORKAROUND.  Accessing SIOC register
+	 * immediately after soft reset causes bus error.
+	 */
+	iob();
+	udelay(1);
+#endif
+	/* Wait until reset is complete. */
+	while (sio_in(kgdb_port, TXX9_SIFCR) & TXX9_SIFCR_SWRST);
+
+	/* Select the frame format and input clock. */
+	sio_out(kgdb_port, TXX9_SILCR,
+		TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
+		((kgdb_port->flags & UPF_MAGIC_MULTIPLIER) ?
+		TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
+
+	/* Select the input clock prescaler that fits the baud rate. */
+	quot = (kgdb_port->uartclk + 8 * kgdb_txx9_baud) /
+		(16 * kgdb_txx9_baud);
+	if (quot < (256 << 1))
+		sibgr = (quot >> 1) | TXX9_SIBGR_BCLK_T0;
+	else if (quot < ( 256 << 3))
+		sibgr = (quot >> 3) | TXX9_SIBGR_BCLK_T2;
+	else if (quot < ( 256 << 5))
+		sibgr = (quot >> 5) | TXX9_SIBGR_BCLK_T4;
+	else if (quot < ( 256 << 7))
+		sibgr = (quot >> 7) | TXX9_SIBGR_BCLK_T6;
+	else
+		sibgr = 0xff | TXX9_SIBGR_BCLK_T6;
+
+	sio_out(kgdb_port, TXX9_SIBGR, sibgr);
+
+	/* Enable receiver and transmitter. */
+	sio_out(kgdb_port, TXX9_SIFLCR, 0);
+
+	return 0;
+}
+
+static void txx9_kgdb_late_init(void)
+{
+	request_mem_region(kgdb_port->mapbase, 0x40, "serial_txx9(debug)");
+}
+
+static int txx9_kgdb_read(void)
+{
+	while (!(sio_in(kgdb_port, TXX9_SIDISR) & TXX9_SIDISR_RFDN_MASK));
+
+	return sio_in(kgdb_port, TXX9_SIRFIFO);
+}
+
+static void txx9_kgdb_write(u8 ch)
+{
+	while (!(sio_in(kgdb_port, TXX9_SISCISR) & TXX9_SISCISR_TRDY));
+
+	sio_out(kgdb_port, TXX9_SITFIFO, ch);
+}
+
+struct kgdb_io kgdb_io_ops = {
+	.read_char	= txx9_kgdb_read,
+	.write_char	= txx9_kgdb_write,
+	.init		= txx9_kgdb_init,
+	.late_init	= txx9_kgdb_late_init
+};
--- a/include/asm-mips/asmmacro-32.h
+++ b/include/asm-mips/asmmacro-32.h
@@ -11,6 +11,28 @@
 #include <asm/regdef.h>
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
+#include <asm/gdb-stub.h>
+
+	.macro	fpu_save_double_kgdb stack status tmp1 = t0
+	cfc1	\tmp1,  fcr31
+	sdc1	$f0, GDB_FR_FPR0(\stack)
+	sdc1	$f2, GDB_FR_FPR2(\stack)
+	sdc1	$f4, GDB_FR_FPR4(\stack)
+	sdc1	$f6, GDB_FR_FPR6(\stack)
+	sdc1	$f8, GDB_FR_FPR8(\stack)
+	sdc1	$f10, GDB_FR_FPR10(\stack)
+	sdc1	$f12, GDB_FR_FPR12(\stack)
+	sdc1	$f14, GDB_FR_FPR14(\stack)
+	sdc1	$f16, GDB_FR_FPR16(\stack)
+	sdc1	$f18, GDB_FR_FPR18(\stack)
+	sdc1	$f20, GDB_FR_FPR20(\stack)
+	sdc1	$f22, GDB_FR_FPR22(\stack)
+	sdc1	$f24, GDB_FR_FPR24(\stack)
+	sdc1	$f26, GDB_FR_FPR26(\stack)
+	sdc1	$f28, GDB_FR_FPR28(\stack)
+	sdc1	$f30, GDB_FR_FPR30(\stack)
+	sw	\tmp1, GDB_FR_FSR(\stack)
+	.endm
 
 	.macro	fpu_save_double thread status tmp1=t0
 	cfc1	\tmp1,  fcr31
@@ -91,6 +113,27 @@
 	ctc1	\tmp, fcr31
 	.endm
 
+	.macro	fpu_restore_double_kgdb stack status tmp = t0
+	lw	\tmp, GDB_FR_FSR(\stack)
+	ldc1	$f0,  GDB_FR_FPR0(\stack)
+	ldc1	$f2,  GDB_FR_FPR2(\stack)
+	ldc1	$f4,  GDB_FR_FPR4(\stack)
+	ldc1	$f6,  GDB_FR_FPR6(\stack)
+	ldc1	$f8,  GDB_FR_FPR8(\stack)
+	ldc1	$f10, GDB_FR_FPR10(\stack)
+	ldc1	$f12, GDB_FR_FPR12(\stack)
+	ldc1	$f14, GDB_FR_FPR14(\stack)
+	ldc1	$f16, GDB_FR_FPR16(\stack)
+	ldc1	$f18, GDB_FR_FPR18(\stack)
+	ldc1	$f20, GDB_FR_FPR20(\stack)
+	ldc1	$f22, GDB_FR_FPR22(\stack)
+	ldc1	$f24, GDB_FR_FPR24(\stack)
+	ldc1	$f26, GDB_FR_FPR26(\stack)
+	ldc1	$f28, GDB_FR_FPR28(\stack)
+	ldc1	$f30, GDB_FR_FPR30(\stack)
+	ctc1	\tmp, fcr31
+	.endm
+
 	.macro	fpu_restore_single thread tmp=t0
 	lw	\tmp, THREAD_FCR31(\thread)
 	lwc1	$f0,  THREAD_FPR0(\thread)
--- a/include/asm-mips/asmmacro-64.h
+++ b/include/asm-mips/asmmacro-64.h
@@ -12,6 +12,7 @@
 #include <asm/regdef.h>
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
+#include <asm/gdb-stub.h>
 
 	.macro	fpu_save_16even thread tmp=t0
 	cfc1	\tmp, fcr31
@@ -53,6 +54,46 @@
 	sdc1	$f31, THREAD_FPR31(\thread)
 	.endm
 
+	.macro	fpu_save_16odd_kgdb stack
+	sdc1	$f1, GDB_FR_FPR1(\stack)
+	sdc1	$f3, GDB_FR_FPR3(\stack)
+	sdc1	$f5, GDB_FR_FPR5(\stack)
+	sdc1	$f7, GDB_FR_FPR7(\stack)
+	sdc1	$f9, GDB_FR_FPR9(\stack)
+	sdc1	$f11, GDB_FR_FPR11(\stack)
+	sdc1	$f13, GDB_FR_FPR13(\stack)
+	sdc1	$f15, GDB_FR_FPR15(\stack)
+	sdc1	$f17, GDB_FR_FPR17(\stack)
+	sdc1	$f19, GDB_FR_FPR19(\stack)
+	sdc1	$f21, GDB_FR_FPR21(\stack)
+	sdc1	$f23, GDB_FR_FPR23(\stack)
+	sdc1	$f25, GDB_FR_FPR25(\stack)
+	sdc1	$f27, GDB_FR_FPR27(\stack)
+	sdc1	$f29, GDB_FR_FPR29(\stack)
+	sdc1	$f31, GDB_FR_FPR31(\stack)
+	.endm
+
+	.macro	fpu_save_16even_kgdb stack tmp = t0
+	cfc1	\tmp,  fcr31
+	sdc1	$f0, GDB_FR_FPR0(\stack)
+	sdc1	$f2, GDB_FR_FPR2(\stack)
+	sdc1	$f4, GDB_FR_FPR4(\stack)
+	sdc1	$f6, GDB_FR_FPR6(\stack)
+	sdc1	$f8, GDB_FR_FPR8(\stack)
+	sdc1	$f10, GDB_FR_FPR10(\stack)
+	sdc1	$f12, GDB_FR_FPR12(\stack)
+	sdc1	$f14, GDB_FR_FPR14(\stack)
+	sdc1	$f16, GDB_FR_FPR16(\stack)
+	sdc1	$f18, GDB_FR_FPR18(\stack)
+	sdc1	$f20, GDB_FR_FPR20(\stack)
+	sdc1	$f22, GDB_FR_FPR22(\stack)
+	sdc1	$f24, GDB_FR_FPR24(\stack)
+	sdc1	$f26, GDB_FR_FPR26(\stack)
+	sdc1	$f28, GDB_FR_FPR28(\stack)
+	sdc1	$f30, GDB_FR_FPR30(\stack)
+	sw	\tmp, GDB_FR_FSR(\stack)
+	.endm
+
 	.macro	fpu_save_double thread status tmp
 	sll	\tmp, \status, 5
 	bgez	\tmp, 2f
@@ -61,6 +102,15 @@
 	fpu_save_16even \thread \tmp
 	.endm
 
+	.macro	fpu_save_double_kgdb stack status tmp
+	sll	\tmp, \status, 5
+	bgez	\tmp, 2f
+	nop
+	fpu_save_16odd_kgdb \stack
+2:
+	fpu_save_16even_kgdb \stack \tmp
+	.endm
+
 	.macro	fpu_restore_16even thread tmp=t0
 	lw	\tmp, THREAD_FCR31(\thread)
 	ldc1	$f0,  THREAD_FPR0(\thread)
@@ -101,6 +151,46 @@
 	ldc1	$f31, THREAD_FPR31(\thread)
 	.endm
 
+	.macro	fpu_restore_16even_kgdb stack tmp = t0
+	lw	\tmp, GDB_FR_FSR(\stack)
+	ldc1	$f0,  GDB_FR_FPR0(\stack)
+	ldc1	$f2,  GDB_FR_FPR2(\stack)
+	ldc1	$f4,  GDB_FR_FPR4(\stack)
+	ldc1	$f6,  GDB_FR_FPR6(\stack)
+	ldc1	$f8,  GDB_FR_FPR8(\stack)
+	ldc1	$f10, GDB_FR_FPR10(\stack)
+	ldc1	$f12, GDB_FR_FPR12(\stack)
+	ldc1	$f14, GDB_FR_FPR14(\stack)
+	ldc1	$f16, GDB_FR_FPR16(\stack)
+	ldc1	$f18, GDB_FR_FPR18(\stack)
+	ldc1	$f20, GDB_FR_FPR20(\stack)
+	ldc1	$f22, GDB_FR_FPR22(\stack)
+	ldc1	$f24, GDB_FR_FPR24(\stack)
+	ldc1	$f26, GDB_FR_FPR26(\stack)
+	ldc1	$f28, GDB_FR_FPR28(\stack)
+	ldc1	$f30, GDB_FR_FPR30(\stack)
+	ctc1	\tmp, fcr31
+	.endm
+
+	.macro	fpu_restore_16odd_kgdb stack
+	ldc1	$f1,  GDB_FR_FPR1(\stack)
+	ldc1	$f3,  GDB_FR_FPR3(\stack)
+	ldc1	$f5,  GDB_FR_FPR5(\stack)
+	ldc1	$f7,  GDB_FR_FPR7(\stack)
+	ldc1	$f9,  GDB_FR_FPR9(\stack)
+	ldc1	$f11, GDB_FR_FPR11(\stack)
+	ldc1	$f13, GDB_FR_FPR13(\stack)
+	ldc1	$f15, GDB_FR_FPR15(\stack)
+	ldc1	$f17, GDB_FR_FPR17(\stack)
+	ldc1	$f19, GDB_FR_FPR19(\stack)
+	ldc1	$f21, GDB_FR_FPR21(\stack)
+	ldc1	$f23, GDB_FR_FPR23(\stack)
+	ldc1	$f25, GDB_FR_FPR25(\stack)
+	ldc1	$f27, GDB_FR_FPR27(\stack)
+	ldc1	$f29, GDB_FR_FPR29(\stack)
+	ldc1	$f31, GDB_FR_FPR31(\stack)
+	.endm
+
 	.macro	fpu_restore_double thread status tmp
 	sll	\tmp, \status, 5
 	bgez	\tmp, 1f				# 16 register mode?
@@ -109,6 +199,15 @@
 1:	fpu_restore_16even \thread \tmp
 	.endm
 
+	.macro	fpu_restore_double_kgdb stack status tmp
+	sll	\tmp, \status, 5
+	bgez	\tmp, 1f				# 16 register mode?
+	nop
+
+	fpu_restore_16odd_kgdb \stack
+1:	fpu_restore_16even_kgdb \stack \tmp
+	.endm
+
 	.macro	cpu_save_nonscratch thread
 	LONG_S	s0, THREAD_REG16(\thread)
 	LONG_S	s1, THREAD_REG17(\thread)

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux