Index: arch/mips/kernel/gdb-low.S =================================================================== RCS file: /home/cvs/linux/arch/mips/kernel/gdb-low.S,v retrieving revision 1.13 diff -u -r1.13 gdb-low.S --- arch/mips/kernel/gdb-low.S 6 Aug 2002 00:08:55 -0000 1.13 +++ arch/mips/kernel/gdb-low.S 20 Feb 2003 18:17:40 -0000 @@ -14,6 +14,16 @@ #include /* + * [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 @@ -38,7 +48,7 @@ nop 1: move k0,sp - subu sp,k1,GDB_FR_SIZE + subu sp,k1,GDB_FR_SIZE*2 # see comment above sw k0,GDB_FR_REG29(sp) sw v0,GDB_FR_REG2(sp) Index: arch/mips/kernel/gdb-stub.c =================================================================== RCS file: /home/cvs/linux/arch/mips/kernel/gdb-stub.c,v retrieving revision 1.20 diff -u -r1.20 gdb-stub.c --- arch/mips/kernel/gdb-stub.c 14 Feb 2003 18:51:22 -0000 1.20 +++ arch/mips/kernel/gdb-stub.c 20 Feb 2003 18:17:40 -0000 @@ -125,6 +125,8 @@ #include #include #include +#include +#include #include #include @@ -593,30 +595,10 @@ char *ptr; unsigned long *stack; -#if 0 - printk("in handle_exception()\n"); - show_gdbregs(regs); -#endif - - /* - * First check trap type. If this is CPU_UNUSABLE and CPU_ID is 1, - * the simply switch the FPU on and return since this is no error - * condition. kernel/traps.c does the same. - * FIXME: This doesn't work yet, so we don't catch CPU_UNUSABLE - * traps for now. - */ - trap = (regs->cp0_cause & 0x7c) >> 2; -/* printk("trap=%d\n",trap); */ - if (trap == 11) { - if (((regs->cp0_cause >> CAUSEB_CE) & 3) == 1) { - regs->cp0_status |= ST0_CU1; - return; - } - } - /* * 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; @@ -705,6 +687,11 @@ output_buffer[3] = 0; break; + case 'D': + /* detach; let CPU run */ + putpacket(output_buffer); + return; + case 'd': /* toggle debug flag */ break; @@ -724,26 +711,21 @@ /* * set the value of the CPU registers - return OK - * FIXME: Needs to be written */ case 'G': { -#if 0 - unsigned long *newsp, psr; - ptr = &input_buffer[1]; - hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */ - - /* - * See if the stack pointer has moved. If so, then copy the - * saved locals and ins to the new location. - */ - - newsp = (unsigned long *)registers[SP]; - if (sp != newsp) - sp = memcpy(newsp, sp, 16 * 4); - -#endif + hex2mem(ptr, (char *)®s->reg0, 32*4, 0); + ptr += 32*8; + hex2mem(ptr, (char *)®s->cp0_status, 6*4, 0); + ptr += 6*8; + hex2mem(ptr, (char *)®s->fpr0, 32*4, 0); + ptr += 32*8; + hex2mem(ptr, (char *)®s->cp1_fsr, 2*4, 0); + ptr += 2*8; + hex2mem(ptr, (char *)®s->frame_ptr, 2*4, 0); + ptr += 2*8; + hex2mem(ptr, (char *)®s->cp0_index, 16*4, 0); strcpy(output_buffer,"OK"); } break; @@ -809,19 +791,14 @@ /* - * kill the program - */ - case 'k' : - break; /* do nothing */ - - - /* - * Reset the whole machine (FIXME: system dependent) + * 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 */ @@ -918,6 +895,20 @@ "la\t$8,0x80000001\n\t" "lw\t$9,0($8)\n\t" ); +} + +/* + * malloc is needed by gdb client in "call func()", even a private one + * will make gdb happy + */ +static void *malloc(size_t size) +{ + return kmalloc(size, GFP_ATOMIC); +} + +static void free(void *where) +{ + kfree(where); } #ifdef CONFIG_GDB_CONSOLE