📄 mips-lite.patch
字号:
- *ptr++ = 0;- putpacket(output_buffer); /* send it off... */-- /*- * Wait for input from remote GDB- */- while (1) {- output_buffer[0] = 0;- getpacket(input_buffer);-- switch (input_buffer[0])- {- case '?':- output_buffer[0] = 'S';- output_buffer[1] = hexchars[sigval >> 4];- output_buffer[2] = hexchars[sigval & 0xf];- output_buffer[3] = 0;- break;-- /*- * Detach debugger; let CPU run- */- case 'D':- putpacket(output_buffer);- goto finish_kgdb;- break;-- case 'd':- /* toggle debug flag */- break;-- /*- * Return the value of the CPU registers- */- case 'g':- ptr = output_buffer;- ptr = mem2hex((char *)®s->reg0, ptr, 32*sizeof(long), 0); /* r0...r31 */- ptr = mem2hex((char *)®s->cp0_status, ptr, 6*sizeof(long), 0); /* cp0 */- ptr = mem2hex((char *)®s->fpr0, ptr, 32*sizeof(long), 0); /* f0...31 */- ptr = mem2hex((char *)®s->cp1_fsr, ptr, 2*sizeof(long), 0); /* cp1 */- ptr = mem2hex((char *)®s->frame_ptr, ptr, 2*sizeof(long), 0); /* frp */- ptr = mem2hex((char *)®s->cp0_index, ptr, 16*sizeof(long), 0); /* cp0 */- break;-- /*- * set the value of the CPU registers - return OK- */- case 'G':- {- ptr = &input_buffer[1];- hex2mem(ptr, (char *)®s->reg0, 32*sizeof(long), 0, 0);- ptr += 32*(2*sizeof(long));- hex2mem(ptr, (char *)®s->cp0_status, 6*sizeof(long), 0, 0);- ptr += 6*(2*sizeof(long));- hex2mem(ptr, (char *)®s->fpr0, 32*sizeof(long), 0, 0);- ptr += 32*(2*sizeof(long));- hex2mem(ptr, (char *)®s->cp1_fsr, 2*sizeof(long), 0, 0);- ptr += 2*(2*sizeof(long));- hex2mem(ptr, (char *)®s->frame_ptr, 2*sizeof(long), 0, 0);- ptr += 2*(2*sizeof(long));- hex2mem(ptr, (char *)®s->cp0_index, 16*sizeof(long), 0, 0);- strcpy(output_buffer,"OK");- }- break;-- /*- * mAA..AA,LLLL Read LLLL bytes at address AA..AA- */- case 'm':- ptr = &input_buffer[1];-- if (hexToLong(&ptr, &addr)- && *ptr++ == ','- && hexToInt(&ptr, &length)) {- if (mem2hex((char *)addr, output_buffer, length, 1))- break;- strcpy (output_buffer, "E03");- } else- strcpy(output_buffer,"E01");- break;-- /*- * XAA..AA,LLLL: Write LLLL escaped binary bytes at address AA.AA- */- case 'X':- bflag = 1;- /* fall through */-- /*- * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK- */- case 'M':- ptr = &input_buffer[1];-- if (hexToLong(&ptr, &addr)- && *ptr++ == ','- && hexToInt(&ptr, &length)- && *ptr++ == ':') {- if (hex2mem(ptr, (char *)addr, length, bflag, 1))- strcpy(output_buffer, "OK");- else- strcpy(output_buffer, "E03");- }- else- strcpy(output_buffer, "E02");- break;-- /*- * cAA..AA Continue at address AA..AA(optional)- */- case 'c':- /* try to read optional parameter, pc unchanged if no parm */-- ptr = &input_buffer[1];- if (hexToLong(&ptr, &addr))- regs->cp0_epc = addr;-- goto exit_kgdb_exception;- break;-- /*- * kill the program; let us try to restart the machine- * Reset the whole machine.- */- case 'k':- case 'r':- machine_restart("kgdb restarts machine");- break;-- /*- * Step to next instruction- */- case 's':- /*- * There is no single step insn in the MIPS ISA, so we- * use breakpoints and continue, instead.- */- single_step(regs);- goto exit_kgdb_exception;- /* NOTREACHED */- break;-- /*- * Set baud rate (bBB)- * FIXME: Needs to be written- */- case 'b':- {-#if 0- int baudrate;- extern void set_timer_3();-- ptr = &input_buffer[1];- if (!hexToInt(&ptr, &baudrate))- {- strcpy(output_buffer,"B01");- break;- }-- /* Convert baud rate to uart clock divider */-- switch (baudrate)- {- case 38400:- baudrate = 16;- break;- case 19200:- baudrate = 33;- break;- case 9600:- baudrate = 65;- break;- default:- baudrate = 0;- strcpy(output_buffer,"B02");- goto x1;- }-- if (baudrate) {- putpacket("OK"); /* Ack before changing speed */- set_timer_3(baudrate); /* Set it */- }-#endif- }- break;-- } /* switch */-- /*- * reply to the request- */-- putpacket(output_buffer);-- } /* while */-- return;--finish_kgdb:- restore_debug_traps();--exit_kgdb_exception:- /* release locks so other CPUs can go */- for (i = num_online_cpus()-1; i >= 0; i--)- __raw_spin_unlock(&kgdb_cpulock[i]);- spin_unlock(&kgdb_lock);-- __flush_cache_all();- return;-}--/*- * This function will generate a breakpoint exception. It is used at the- * beginning of a program to sync up with a debugger and can be used- * otherwise as a quick means to stop program execution and "break" into- * the debugger.- */-void breakpoint(void)-{- if (!initialized)- return;-- __asm__ __volatile__(- ".globl breakinst\n\t"- ".set\tnoreorder\n\t"- "nop\n"- "breakinst:\tbreak\n\t"- "nop\n\t"- ".set\treorder"- );-}--/* Nothing but the break; don't pollute any registers */-void async_breakpoint(void)-{- __asm__ __volatile__(- ".globl async_breakinst\n\t"- ".set\tnoreorder\n\t"- "nop\n"- "async_breakinst:\tbreak\n\t"- "nop\n\t"- ".set\treorder"- );-}--void adel(void)-{- __asm__ __volatile__(- ".globl\tadel\n\t"- "lui\t$8,0x8000\n\t"- "lw\t$9,1($8)\n\t"- );-}--/*- * malloc is needed by gdb client in "call func()", even a private one- * will make gdb happy- */-static void * __attribute_used__ malloc(size_t size)-{- return kmalloc(size, GFP_ATOMIC);-}--static void __attribute_used__ free (void *where)-{- kfree(where);-}--#ifdef CONFIG_GDB_CONSOLE--void gdb_putsn(const char *str, int l)-{- char outbuf[18];-- if (!kgdb_started)- return;-- outbuf[0]='O';-- while(l) {- int i = (l>8)?8:l;- mem2hex((char *)str, &outbuf[1], i, 0);- outbuf[(i*2)+1]=0;- putpacket(outbuf);- str += i;- l -= i;- }-}--static void gdb_console_write(struct console *con, const char *s, unsigned n)-{- gdb_putsn(s, n);-}--static struct console gdb_console = {- .name = "gdb",- .write = gdb_console_write,- .flags = CON_PRINTBUFFER,- .index = -1-};--static int __init register_gdb_console(void)-{- register_console(&gdb_console);-- return 0;-}--console_initcall(register_gdb_console);--#endifIndex: linux-2.6.16/arch/mips/kernel/irq.c===================================================================--- linux-2.6.16.orig/arch/mips/kernel/irq.c 2006-03-20 00:53:29.000000000 -0500+++ linux-2.6.16/arch/mips/kernel/irq.c 2006-04-25 08:01:03.991033720 -0400@@ -26,6 +26,10 @@ #include <asm/atomic.h> #include <asm/system.h> #include <asm/uaccess.h>+#include <asm/kgdb.h>++/* Keep track of if we've done certain initialization already or not. */+int kgdb_early_setup; /* * 'what should we do if we get a hw irq event on an illegal vector'.@@ -103,23 +107,13 @@ return 0; } -#ifdef CONFIG_KGDB-extern void breakpoint(void);-extern void set_debug_traps(void);--static int kgdb_flag = 1;-static int __init nokgdb(char *str)-{- kgdb_flag = 0;- return 1;-}-__setup("nokgdb", nokgdb);-#endif- void __init init_IRQ(void) { int i; + if (kgdb_early_setup)+ return;+ for (i = 0; i < NR_IRQS; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL;@@ -129,12 +123,12 @@ } arch_init_irq();- #ifdef CONFIG_KGDB- if (kgdb_flag) {- printk("Wait for gdb client connection ...\n");- set_debug_traps();- breakpoint();- }+ /*+ * We have been called before kgdb_arch_init(). Hence,+ * we dont want the traps to be reinitialized+ */+ if (kgdb_early_setup == 0)+ kgdb_early_setup = 1; #endif }Index: linux-2.6.16/arch/mips/kernel/traps.c===================================================================--- linux-2.6.16.orig/arch/mips/kernel/traps.c 2006-03-20 00:53:29.000000000 -0500+++ linux-2.6.16/arch/mips/kernel/traps.c 2006-04-25 08:01:03.998032656 -0400@@ -10,6 +10,8 @@ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000, 01 MIPS Technologies, Inc. * Copyright (C) 2002, 2003, 2004, 2005 Maciej W. Rozycki+ *+ * KGDB specific changes - Manish Lachwani (mlachwani@mvista.com) */ #include <linux/config.h> #include <linux/init.h>@@ -21,6 +23,7 @@ #include <linux/spinlock.h> #include <linux/kallsyms.h> #include <linux/bootmem.h>+#include <linux/kgdb.h> #include <asm/bootinfo.h> #include <asm/branch.h>@@ -41,6 +44,7 @@ #include <asm/mmu_context.h> #include <asm/watch.h> #include <asm/types.h>+#include <asm/kdebug.h> extern asmlinkage void handle_tlbm(void); extern asmlinkage void handle_tlbl(void);@@ -78,6 +82,21 @@ */ #define MODULE_RANGE (8*1024*1024) +struct notifier_block *mips_die_chain;+static spinlock_t die_notifier_lock = SPIN_LOCK_UNLOCKED;++int register_die_notifier(struct notifier_block *nb)+{+ int err = 0;+ unsigned long flags;++ spin_lock_irqsave(&die_notifier_lock, flags);+ err = notifier_chain_register(&mips_die_chain, nb);+ spin_unlock_irqrestore(&die_notifier_lock, flags);++ return err;+}+ /* * This routine abuses get_user()/put_user() to reference pointers * with at least a bit of error checking ...@@ -1235,6 +1254,11 @@ extern char except_vec4; unsigned long i; +#if defined(CONFIG_KGDB)+ if (kgdb_early_setup)+ return; /* Already done */+#endif+ if (cpu_has_veic || cpu_has_vint) ebase = (unsigned long) alloc_bootmem_low_pages (0x200 + VECTORSPACING*64); elseIndex: linux-2.6.16/arch/mips/kernel/Makefile===================================================================--- linux-2.6.16.orig/arch/mips/kernel/Makefile 2006-03-20 00:53:29.000000000 -0500+++ linux-2.6.16/arch/mips/kernel/Makefile 2006-04-25 08:01:03.999032504 -0400@@ -54,7 +54,8 @@ obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o ptrace32.o -obj-$(CONFIG_KGDB) += gdb-low.o gdb-stub.o+obj-$(CONFIG_KGDB) += kgdb_handler.o kgdb.o kgdb-jmp.o \+ kgdb-setjmp.o obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_64BIT) += cpu-bugs64.oIndex: linux-2.6.16/arch/mips/kernel/gdb-low.S===================================================================--- linux-2.6.16.orig/arch/mips/kernel/gdb-low.S 2006-03-20 00:53:29.000000000 -0500+++ linux-2.6.16/arch/mips/kernel/gdb-low.S 2006-04-25 03:03:31.107356424 -0400@@ -1,369 +0,0 @@-/*- * gdb-low.S contains the low-level trap handler for the GDB stub.- *- * Copyright (C) 1995 Andreas Busse- */-#include <linux/config.h>-#include <linux/sys.h>--#include <asm/asm.h>-#include <asm/errno.h>-#include <asm/mipsregs.h>-#include <asm/regdef.h>-#include <asm/stackframe.h>-#include <asm/gdb-stub.h>--#ifdef CONFIG_32BIT-#define DMFC0 mfc0-#define DMTC0 mtc0-#define LDC1 lwc1-#define SDC1 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -