Sergei Shtylyov wrote:
Hello.

Jason Wessel wrote:

mips-fix.diff - Updated exception handling for MIPS
mips64_defines.patch - Fix MIPS64 defines for proper compilation
mips64_kgdb_dsubu.patch - Fixed stack pointer corruption in mips64 code
wrs_mips64-usermode-dbg.patch - Usermode debug & exception forwarding fix
mips_kgdb_fpu.patch - mips kgdb save/restore fpu registers patch

The above patches have various contributors, and I rolled them into 1 patch called mips-ALL-folded.patch As a last ditch effort because the Source Forge now eats all attachments... I'll try a tar.gz file.
I am close to considering a new mailing list at this point... Last try and then time to consider another alternative as I am out of mail agents...

Jason.
Fix 64 bit MIPS define

Signed-off-by: Jason Wessel <[EMAIL PROTECTED]>

Index: linux-2.6.21.1/arch/mips/kernel/kgdb-setjmp.S
===================================================================
--- linux-2.6.21.1.orig/arch/mips/kernel/kgdb-setjmp.S
+++ linux-2.6.21.1/arch/mips/kernel/kgdb-setjmp.S
@@ -21,7 +21,7 @@
 ENTRY (kgdb_fault_setjmp)
        move    a1, sp
        move    a2, fp
-#ifdef CONFIG_MIPS64
+#ifdef CONFIG_64BIT
        nop
 #endif
        j       kgdb_fault_setjmp_aux
The subu instruction is improperly used in mips64 code resulting in a 
corrupt stack pointer. Debugging this with a 10MHz 5kf that takes 25 
minutes to boot really builds character ;)

This patch fixes one mips64 kgdb problem. Now you can set a break 
point, get there, continue, etc.
Signed-off-by:   Pete Popov <[EMAIL PROTECTED]>

Index: linux-2.6.21.1/arch/mips/kernel/kgdb_handler.S
===================================================================
--- linux-2.6.21.1.orig/arch/mips/kernel/kgdb_handler.S
+++ linux-2.6.21.1/arch/mips/kernel/kgdb_handler.S
@@ -74,7 +74,7 @@
                nop
 1:
                move    k0, sp
-               subu    sp, k1, GDB_FR_SIZE*2   # see comment above
+               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)
 
Fix the floating point save to stack for KGDB

Signed-off-by:   Pete Popov <[EMAIL PROTECTED]>

Index: linux-2.6.21.1/arch/mips/kernel/kgdb_handler.S
===================================================================
--- linux-2.6.21.1.orig/arch/mips/kernel/kgdb_handler.S
+++ linux-2.6.21.1/arch/mips/kernel/kgdb_handler.S
@@ -30,15 +30,17 @@
 #define DMFC0  mfc0
 #define DMTC0  mtc0
 #define LDC1   lwc1
-#define SDC1   lwc1
+#define SDC1   swc1
 #endif
 #ifdef CONFIG_64BIT
 #define DMFC0  dmfc0
 #define DMTC0  dmtc0
 #define LDC1   ldc1
-#define SDC1   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.
@@ -156,56 +158,21 @@
                srl     v0, v0, 16
                andi    v0, v0, (ST0_CU1 >> 16)
 
-               beqz    v0,2f                   /* disabled, skip */
+               beqz    v0,3f                   /* 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)
+               li      t0, 0
+#ifdef CONFIG_64BIT
+               mfc0    t0, CP0_STATUS
+#endif
+               fpu_save_double_kgdb sp t0 t1   # clobbers t1
+
 
 /*
  * Current stack frame ptr
  */
 
-2:
+3:
                LONG_S  sp, GDB_FR_FRP(sp)
 
 /*
@@ -274,38 +241,12 @@
                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)
+               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
Index: linux-2.6.21.1/include/asm-mips/asmmacro-32.h
===================================================================
--- linux-2.6.21.1.orig/include/asm-mips/asmmacro-32.h
+++ linux-2.6.21.1/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)
Index: linux-2.6.21.1/include/asm-mips/asmmacro-64.h
===================================================================
--- linux-2.6.21.1.orig/include/asm-mips/asmmacro-64.h
+++ linux-2.6.21.1/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: linux-2.6.21.1/arch/mips/kernel/kgdb-setjmp.S
===================================================================
--- linux-2.6.21.1.orig/arch/mips/kernel/kgdb-setjmp.S
+++ linux-2.6.21.1/arch/mips/kernel/kgdb-setjmp.S
@@ -21,7 +21,7 @@
 ENTRY (kgdb_fault_setjmp)
        move    a1, sp
        move    a2, fp
-#ifdef CONFIG_MIPS64
+#ifdef CONFIG_64BIT
        nop
 #endif
        j       kgdb_fault_setjmp_aux
Index: linux-2.6.21.1/arch/mips/kernel/kgdb_handler.S
===================================================================
--- linux-2.6.21.1.orig/arch/mips/kernel/kgdb_handler.S
+++ linux-2.6.21.1/arch/mips/kernel/kgdb_handler.S
@@ -1,6 +1,8 @@
 /*
  * 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]
  *
@@ -22,35 +24,316 @@
 #include <asm/mipsregs.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
+#include <asm/gdb-stub.h>
 
-       .align  5
-       NESTED(trap_low, PT_SIZE, sp)
-               .set    noat
-               .set    noreorder
+#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
 
-               /*
-                * Check for privileged instructions in user mode. For
-                * this, check the cu0 bit in the CPU status register.
-                */
                mfc0    k0, CP0_STATUS
-               sll     k0, 3
+               sll     k0, 3                   /* extract cu0 bit */
                bltz    k0, 1f
                move    k1, sp
 
                /*
-                * GDB userland from within KGDB. If a user mode address
-                * then jump to the saved exception handler
+                * Called from user mode, go somewhere else.
                 */
-               mfc0    k1, CP0_CAUSE
-               andi    k1, k1, 0x7c
-               PTR_L   k0, saved_vectors(k1)
+#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:
-               SAVE_ALL
-               .set    at
+               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 the 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
-               move    a0, sp
-               jal     handle_exception
-               j       ret_from_exception
-       END(trap_low)
+               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   [EMAIL PROTECTED]
+               .ent    kgdbfault
+
+kgdbfault:     li      v0, -EFAULT
+               jr      ra
+               .end    kgdbfault
Index: linux-2.6.21.1/include/asm-mips/asmmacro-32.h
===================================================================
--- linux-2.6.21.1.orig/include/asm-mips/asmmacro-32.h
+++ linux-2.6.21.1/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)
Index: linux-2.6.21.1/include/asm-mips/asmmacro-64.h
===================================================================
--- linux-2.6.21.1.orig/include/asm-mips/asmmacro-64.h
+++ linux-2.6.21.1/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)
Add better exception handling for mips.

Signed-off-by: Jason Wessel <[EMAIL PROTECTED]>


 kgdb_handler.S |  367 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 347 insertions(+), 20 deletions(-)


Index: linux-2.6.21.1/arch/mips/kernel/kgdb_handler.S
===================================================================
--- linux-2.6.21.1.orig/arch/mips/kernel/kgdb_handler.S
+++ linux-2.6.21.1/arch/mips/kernel/kgdb_handler.S
@@ -1,6 +1,8 @@
 /*
  * 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]
  *
@@ -22,35 +24,360 @@
 #include <asm/mipsregs.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
+#include <asm/gdb-stub.h>
 
-       .align  5
-       NESTED(trap_low, PT_SIZE, sp)
-               .set    noat
-               .set    noreorder
+#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
 
-               /*
-                * Check for privileged instructions in user mode. For
-                * this, check the cu0 bit in the CPU status register.
-                */
                mfc0    k0, CP0_STATUS
-               sll     k0, 3
+               sll     k0, 3                   /* extract cu0 bit */
                bltz    k0, 1f
                move    k1, sp
 
                /*
-                * GDB userland from within KGDB. If a user mode address
-                * then jump to the saved exception handler
+                * Called from user mode, go somewhere else.
                 */
-               mfc0    k1, CP0_CAUSE
-               andi    k1, k1, 0x7c
-               PTR_L   k0, saved_vectors(k1)
+               lui     k1, %hi(saved_vectors)
+               mfc0    k0, CP0_CAUSE
+               andi    k0, k0, 0x7c
+               add     k1, k1, k0
+               lw      k0, %lo(saved_vectors)(k1)
                jr      k0
                nop
 1:
-               SAVE_ALL
-               .set    at
+               move    k0, sp
+               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,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:
+               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
-               move    a0, sp
-               jal     handle_exception
-               j       ret_from_exception
-       END(trap_low)
+               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   [EMAIL PROTECTED]
+               .ent    kgdbfault
+
+kgdbfault:     li      v0, -EFAULT
+               jr      ra
+               .end    kgdbfault
  This patch fixes exception forwarding for user mode exceptions 
  when kgdb enabled.

  Wind River Systems, Inc.

Signed-off-by: Jason Wessel <[EMAIL PROTECTED]>

Index: linux-2.6.21.1/arch/mips/kernel/kgdb_handler.S
===================================================================
--- linux-2.6.21.1.orig/arch/mips/kernel/kgdb_handler.S
+++ linux-2.6.21.1/arch/mips/kernel/kgdb_handler.S
@@ -65,11 +65,26 @@
                /*
                 * 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:
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Kgdb-bugreport mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to