X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fkgdb.c;h=daf53bed7a9630133c659e0384307c480a8292b6;hb=1321aef8cd13d89d36e8cda8482b87fcea93994a;hp=b563094d545e9efb77cf67c850395d38157134d1;hpb=4a9cbbe832e1c377d04cfb53e9679844595bc3cf;p=oweals%2Fu-boot.git diff --git a/common/kgdb.c b/common/kgdb.c index b563094d54..daf53bed7a 100644 --- a/common/kgdb.c +++ b/common/kgdb.c @@ -1,4 +1,4 @@ -/* taken from arch/ppc/kernel/ppc-stub.c */ +/* taken from arch/powerpc/kernel/ppc-stub.c */ /**************************************************************************** @@ -92,8 +92,6 @@ #include #include -#if (CONFIG_COMMANDS & CFG_CMD_KGDB) - #undef KGDB_DEBUG /* @@ -105,9 +103,9 @@ static char remcomOutBuffer[BUFMAX]; static char remcomRegBuffer[BUFMAX]; static int initialized = 0; -static int kgdb_active = 0, first_entry = 1; +static int kgdb_active; static struct pt_regs entry_regs; -static u_int error_jmp_buf[BUFMAX/2]; +static long error_jmp_buf[BUFMAX/2]; static int longjmp_on_fault = 0; #ifdef KGDB_DEBUG static int kdebug = 1; @@ -134,17 +132,26 @@ hex(unsigned char ch) static unsigned char * mem2hex(char *mem, char *buf, int count) { + char *tmp; unsigned char ch; + /* + * We use the upper half of buf as an intermediate buffer for the + * raw memory copy. Hex conversion will work against this one. + */ + tmp = buf + count; longjmp_on_fault = 1; + + memcpy(tmp, mem, count); + while (count-- > 0) { - ch = *mem++; + ch = *tmp++; *buf++ = hexchars[ch >> 4]; *buf++ = hexchars[ch & 0xf]; } *buf = 0; longjmp_on_fault = 0; - return buf; + return (unsigned char *)buf; } /* convert the hex array pointed to by buf into binary to be placed in mem @@ -153,21 +160,33 @@ mem2hex(char *mem, char *buf, int count) static char * hex2mem(char *buf, char *mem, int count) { - int i, hexValue; - unsigned char ch; - char *mem_start = mem; + int hexValue; + char *tmp_raw, *tmp_hex; + + /* + * We use the upper half of buf as an intermediate buffer for the + * raw memory that is converted from hex. + */ + tmp_raw = buf + count * 2; + tmp_hex = tmp_raw - 1; longjmp_on_fault = 1; - for (i=0; i= buf) { + tmp_raw--; + hexValue = hex(*tmp_hex--); + if (hexValue < 0) kgdb_error(KGDBERR_NOTHEXDIG); - ch = hexValue << 4; - if ((hexValue = hex(*buf++)) < 0) + *tmp_raw = hexValue; + hexValue = hex(*tmp_hex--); + if (hexValue < 0) kgdb_error(KGDBERR_NOTHEXDIG); - ch |= hexValue; - *mem++ = ch; + *tmp_raw |= hexValue << 4; + } - kgdb_flush_cache_range((void *)mem_start, (void *)(mem - 1)); + + memcpy(mem, tmp_raw, count); + + kgdb_flush_cache_range((void *)mem, (void *)(mem+count)); longjmp_on_fault = 0; return buf; @@ -307,10 +326,10 @@ handle_exception (struct pt_regs *regs) return (0); } - /* probably should check which exception occured as well */ + /* probably should check which exception occurred as well */ if (longjmp_on_fault) { longjmp_on_fault = 0; - kgdb_longjmp((long*)error_jmp_buf, KGDBERR_MEMFAULT); + kgdb_longjmp(error_jmp_buf, KGDBERR_MEMFAULT); panic("kgdb longjump failed!\n"); } @@ -324,21 +343,12 @@ handle_exception (struct pt_regs *regs) printf("kgdb: handle_exception; trap [0x%x]\n", kgdb_trap(regs)); - if (kgdb_setjmp((long*)error_jmp_buf) != 0) + if (kgdb_setjmp(error_jmp_buf) != 0) panic("kgdb: error or fault in entry init!\n"); kgdb_enter(regs, &kd); - if (first_entry) { - /* - * the first time we enter kgdb, we save the processor - * state so that we can return to the monitor if the - * remote end quits gdb (or at least, tells us to quit - * with the 'k' packet) - */ - entry_regs = *regs; - first_entry = 0; - } + entry_regs = *regs; ptr = remcomOutBuffer; @@ -353,7 +363,7 @@ handle_exception (struct pt_regs *regs) *ptr++ = hexchars[rp->num >> 4]; *ptr++ = hexchars[rp->num & 0xf]; *ptr++ = ':'; - ptr = mem2hex((char *)&rp->val, ptr, 4); + ptr = (char *)mem2hex((char *)&rp->val, ptr, 4); *ptr++ = ';'; } @@ -364,7 +374,7 @@ handle_exception (struct pt_regs *regs) printf("kgdb: remcomOutBuffer: %s\n", remcomOutBuffer); #endif - putpacket(remcomOutBuffer); + putpacket((unsigned char *)&remcomOutBuffer); while (1) { volatile int errnum; @@ -379,7 +389,7 @@ handle_exception (struct pt_regs *regs) printf("kgdb: remcomInBuffer: %s\n", remcomInBuffer); #endif - errnum = kgdb_setjmp((long*)error_jmp_buf); + errnum = kgdb_setjmp(error_jmp_buf); if (errnum == 0) switch (remcomInBuffer[0]) { @@ -440,7 +450,6 @@ handle_exception (struct pt_regs *regs) case 'k': /* kill the program, actually return to monitor */ kd.extype = KGDBEXIT_KILL; *regs = entry_regs; - first_entry = 1; goto doexit; case 'C': /* CSS continue with signal SS */ @@ -508,7 +517,7 @@ handle_exception (struct pt_regs *regs) #endif /* reply to the request */ - putpacket(remcomOutBuffer); + putpacket((unsigned char *)&remcomOutBuffer); } /* while(1) */ } @@ -532,7 +541,7 @@ void kgdb_error(int errnum) { longjmp_on_fault = 0; - kgdb_longjmp((long*)error_jmp_buf, errnum); + kgdb_longjmp(error_jmp_buf, errnum); panic("kgdb_error: longjmp failed!\n"); } @@ -548,7 +557,7 @@ kgdb_output_string (const char* s, unsigned int count) buffer[0] = 'O'; mem2hex ((char *)s, &buffer[1], count); - putpacket(buffer); + putpacket((unsigned char *)&buffer); return 1; } @@ -565,7 +574,7 @@ breakpoint(void) } int -do_kgdb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +do_kgdb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { printf("Entering KGDB mode via exception handler...\n\n"); kgdb_breakpoint(argc - 1, argv + 1); @@ -573,8 +582,17 @@ do_kgdb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } -#else - -int kgdb_not_configured = 1; - -#endif /* CFG_CMD_KGDB */ +U_BOOT_CMD( + kgdb, CONFIG_SYS_MAXARGS, 1, do_kgdb, + "enter gdb remote debug mode", + "[arg0 arg1 .. argN]\n" + " - executes a breakpoint so that kgdb mode is\n" + " entered via the exception handler. To return\n" + " to the monitor, the remote gdb debugger must\n" + " execute a \"continue\" or \"quit\" command.\n" + "\n" + " if a program is loaded by the remote gdb, any args\n" + " passed to the kgdb command are given to the loaded\n" + " program if it is executed (see the \"hello_world\"\n" + " example program in the U-Boot examples directory)." +);