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