📄 mips-lite.patch
字号:
++ regs->cp0_status = *(ptr++);+ regs->lo = *(ptr++);+ regs->hi = *(ptr++);+ regs->cp0_badvaddr = *(ptr++);+ regs->cp0_cause = *(ptr++);+ regs->cp0_epc = *(ptr++);++ return;+}++/*+ * Similar to regs_to_gdb_regs() except that process is sleeping and so+ * we may not be able to get all the info.+ */+void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)+{+ int reg;+ struct thread_info *ti = p->thread_info;+ unsigned long ksp = (unsigned long)ti + THREAD_SIZE - 32;+ struct pt_regs *regs = (struct pt_regs *)ksp - 1;+ gdb_reg_t *ptr = (gdb_reg_t*)gdb_regs;++ for (reg = 0; reg < 16; reg++)+ *(ptr++) = regs->regs[reg];++ /* S0 - S7 */+ for (reg = 16; reg < 24; reg++)+ *(ptr++) = regs->regs[reg];++ for (reg = 24; reg < 28; reg++)+ *(ptr++) = 0;++ /* GP, SP, FP, RA */+ for (reg = 28; reg < 32; reg++)+ *(ptr++) = regs->regs[reg];++ *(ptr++) = regs->cp0_status;+ *(ptr++) = regs->lo;+ *(ptr++) = regs->hi;+ *(ptr++) = regs->cp0_badvaddr;+ *(ptr++) = regs->cp0_cause;+ *(ptr++) = regs->cp0_epc;++ return;+}++/*+ * Calls linux_debug_hook before the kernel dies. If KGDB is enabled,+ * then try to fall into the debugger+ */+static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,+ void *ptr)+{+ struct die_args *args = (struct die_args *)ptr;+ struct pt_regs *regs = args->regs;+ int trap = (regs->cp0_cause & 0x7c) >> 2;++ /* See if KGDB is interested. */+ if (user_mode(regs))+ /* Userpace events, ignore. */+ return NOTIFY_DONE;++ kgdb_handle_exception(trap, compute_signal(trap), 0, regs);+ return NOTIFY_OK;+}++static struct notifier_block kgdb_notifier = {+ .notifier_call = kgdb_mips_notify,+};++/*+ * Handle the 's' and 'c' commands+ */+int kgdb_arch_handle_exception(int vector, int signo, int err_code,+ char *remcom_in_buffer, char *remcom_out_buffer,+ struct pt_regs *regs)+{+ char *ptr;+ unsigned long address;+ int cpu = smp_processor_id();++ switch (remcom_in_buffer[0]) {+ case 's':+ case 'c':+ /* handle the optional parameter */+ ptr = &remcom_in_buffer[1];+ if (kgdb_hex2long(&ptr, &address))+ regs->cp0_epc = address;++ atomic_set(&cpu_doing_single_step, -1);+ if (remcom_in_buffer[0] == 's')+ if (kgdb_contthread)+ atomic_set(&cpu_doing_single_step, cpu);++ return 0;+ }++ return -1;+}++struct kgdb_arch arch_kgdb_ops = {+#ifdef CONFIG_CPU_LITTLE_ENDIAN+ .gdb_bpt_instr = {0xd},+#else+ .gdb_bpt_instr = {0x00, 0x00, 0x00, 0x0d},+#endif+};++/*+ * We use kgdb_early_setup so that functions we need to call now don't+ * cause trouble when called again later.+ */+int kgdb_arch_init(void)+{+ /* Board-specifics. */+ /* Force some calls to happen earlier. */+ if (kgdb_early_setup == 0) {+ trap_init();+ init_IRQ();+ kgdb_early_setup = 1;+ }++ /* Set our traps. */+ /* This needs to be done more finely grained again, paired in+ * a before/after in kgdb_handle_exception(...) -- Tom */+ set_debug_traps();+ notifier_chain_register(&mips_die_chain, &kgdb_notifier);++ return 0;+}Index: linux-2.6.16/arch/mips/kernel/kgdb-jmp.c===================================================================--- linux-2.6.16.orig/arch/mips/kernel/kgdb-jmp.c 2006-04-25 03:03:31.107356424 -0400+++ linux-2.6.16/arch/mips/kernel/kgdb-jmp.c 2006-04-25 08:01:03.992033568 -0400@@ -0,0 +1,116 @@+/*+ * arch/mips/kernel/kgdb-jmp.c+ *+ * Save and restore system registers so that within a limited frame we+ * may have a fault and "jump back" to a known safe location.+ *+ * Author: Tom Rini <trini@kernel.crashing.org>+ * Author: Manish Lachwani <mlachwani@mvista.com>+ *+ * Cribbed from glibc, which carries the following:+ * Copyright (C) 1996, 1997, 2000, 2002, 2003 Free Software Foundation, Inc.+ * Copyright (C) 2005 by MontaVista Software.+ *+ * This file is licensed under the terms of the GNU General Public License+ * version 2. This program as licensed "as is" without any warranty of+ * any kind, whether express or implied.+ */++#include <linux/kgdb.h>+#include <asm/interrupt.h>++#ifdef CONFIG_MIPS64+/*+ * MIPS 64-bit+ */++int kgdb_fault_setjmp_aux(unsigned long *curr_context, int sp, int fp)+{+ __asm__ __volatile__ ("sd $gp, %0" : : "m" (curr_context[0]));+ __asm__ __volatile__ ("sd $16, %0" : : "m" (curr_context[1]));+ __asm__ __volatile__ ("sd $17, %0" : : "m" (curr_context[2]));+ __asm__ __volatile__ ("sd $18, %0" : : "m" (curr_context[3]));+ __asm__ __volatile__ ("sd $19, %0" : : "m" (curr_context[4]));+ __asm__ __volatile__ ("sd $20, %0" : : "m" (curr_context[5]));+ __asm__ __volatile__ ("sd $21, %0" : : "m" (curr_context[6]));+ __asm__ __volatile__ ("sd $22, %0" : : "m" (curr_context[7]));+ __asm__ __volatile__ ("sd $23, %0" : : "m" (curr_context[8]));+ __asm__ __volatile__ ("sd $31, %0" : : "m" (curr_context[9]));+ curr_context[10] = (long *)sp;+ curr_context[11] = (long *)fp;++ return 0;+}++void kgdb_fault_longjmp(unsigned long *curr_context)+{+ unsigned long sp_val, fp_val;++ __asm__ __volatile__ ("ld $gp, %0" : : "m" (curr_context[0]));+ __asm__ __volatile__ ("ld $16, %0" : : "m" (curr_context[1]));+ __asm__ __volatile__ ("ld $17, %0" : : "m" (curr_context[2]));+ __asm__ __volatile__ ("ld $18, %0" : : "m" (curr_context[3]));+ __asm__ __volatile__ ("ld $19, %0" : : "m" (curr_context[4]));+ __asm__ __volatile__ ("ld $20, %0" : : "m" (curr_context[5]));+ __asm__ __volatile__ ("ld $21, %0" : : "m" (curr_context[6]));+ __asm__ __volatile__ ("ld $22, %0" : : "m" (curr_context[7]));+ __asm__ __volatile__ ("ld $23, %0" : : "m" (curr_context[8]));+ __asm__ __volatile__ ("ld $25, %0" : : "m" (curr_context[9]));+ sp_val = curr_context[10];+ fp_val = curr_context[11];+ __asm__ __volatile__ ("ld $29, %0\n\t"+ "ld $30, %1\n\t" : : "m" (sp_val), "m" (fp_val));++ __asm__ __volatile__ ("dli $2, 1");+ __asm__ __volatile__ ("j $25");++ for (;;);+}+#else+/*+ * MIPS 32-bit+ */++int kgdb_fault_setjmp_aux(unsigned long *curr_context, int sp, int fp)+{+ __asm__ __volatile__("sw $gp, %0" : : "m" (curr_context[0]));+ __asm__ __volatile__("sw $16, %0" : : "m" (curr_context[1]));+ __asm__ __volatile__("sw $17, %0" : : "m" (curr_context[2]));+ __asm__ __volatile__("sw $18, %0" : : "m" (curr_context[3]));+ __asm__ __volatile__("sw $19, %0" : : "m" (curr_context[4]));+ __asm__ __volatile__("sw $20, %0" : : "m" (curr_context[5]));+ __asm__ __volatile__("sw $21, %0" : : "m" (curr_context[6]));+ __asm__ __volatile__("sw $22, %0" : : "m" (curr_context[7]));+ __asm__ __volatile__("sw $23, %0" : : "m" (curr_context[8]));+ __asm__ __volatile__("sw $31, %0" : : "m" (curr_context[9]));+ curr_context[10] = (long *)sp;+ curr_context[11] = (long *)fp;++ return 0;+}++void kgdb_fault_longjmp(unsigned long *curr_context)+{+ unsigned long sp_val, fp_val;++ __asm__ __volatile__("lw $gp, %0" : : "m" (curr_context[0]));+ __asm__ __volatile__("lw $16, %0" : : "m" (curr_context[1]));+ __asm__ __volatile__("lw $17, %0" : : "m" (curr_context[2]));+ __asm__ __volatile__("lw $18, %0" : : "m" (curr_context[3]));+ __asm__ __volatile__("lw $19, %0" : : "m" (curr_context[4]));+ __asm__ __volatile__("lw $20, %0" : : "m" (curr_context[5]));+ __asm__ __volatile__("lw $21, %0" : : "m" (curr_context[6]));+ __asm__ __volatile__("lw $22, %0" : : "m" (curr_context[7]));+ __asm__ __volatile__("lw $23, %0" : : "m" (curr_context[8]));+ __asm__ __volatile__("lw $25, %0" : : "m" (curr_context[9]));+ sp_val = curr_context[10];+ fp_val = curr_context[11];+ __asm__ __volatile__("lw $29, %0\n\t"+ "lw $30, %1\n\t" : : "m" (sp_val), "m" (fp_val));++ __asm__ __volatile__("li $2, 1");+ __asm__ __volatile__("jr $25");++ for (;;);+}+#endifIndex: linux-2.6.16/arch/mips/kernel/kgdb_handler.S===================================================================--- linux-2.6.16.orig/arch/mips/kernel/kgdb_handler.S 2006-04-25 03:03:31.107356424 -0400+++ linux-2.6.16/arch/mips/kernel/kgdb_handler.S 2006-04-25 08:01:03.999032504 -0400@@ -0,0 +1,57 @@+/*+ * arch/mips/kernel/kgdb_handler.S+ *+ * Copyright (C) 2004-2005 MontaVista Software Inc.+ * Author: Manish Lachwani, mlachwani@mvista.com or manish@koffee-break.com+ *+ * This file is licensed under the terms of the GNU General Public+ * version 2. This program is licensed "as is" without any warranty of any+ * kind, whether express or implied.+ */++/*+ * Trap Handler for the new KGDB framework. The main KGDB handler is+ * handle_exception that will be called from here+ *+ */++#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>++ .align 5+ NESTED(trap_low, PT_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+ bltz k0, 1f+ move k1, sp++ /*+ * GDB userland from within KGDB. If a user mode address+ * then jump to the saved exception handler+ */+ mfc0 k1, CP0_CAUSE+ andi k1, k1, 0x7c+ PTR_L k0, saved_vectors(k1)+ jr k0+ nop+1:+ SAVE_ALL+ .set at+ .set reorder+ move a0, sp+ jal handle_exception+ j ret_from_exception+ END(trap_low)Index: linux-2.6.16/arch/mips/sibyte/swarm/Makefile===================================================================--- linux-2.6.16.orig/arch/mips/sibyte/swarm/Makefile 2006-03-20 00:53:29.000000000 -0500+++ linux-2.6.16/arch/mips/sibyte/swarm/Makefile 2006-04-25 08:01:03.958038736 -0400@@ -1,3 +1 @@ lib-y = setup.o rtc_xicor1241.o rtc_m41t81.o--lib-$(CONFIG_KGDB) += dbg_io.oIndex: linux-2.6.16/arch/mips/sibyte/swarm/dbg_io.c===================================================================--- linux-2.6.16.orig/arch/mips/sibyte/swarm/dbg_io.c 2006-03-20 00:53:29.000000000 -0500+++ linux-2.6.16/arch/mips/sibyte/swarm/dbg_io.c 2006-04-25 03:03:31.107356424 -0400@@ -1,76 +0,0 @@-/*- * kgdb debug routines for SiByte boards.- *- * Copyright (C) 2001 MontaVista Software Inc.- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net- *- * This program is free software; you can redistribute it and/or modify it- * under the terms of the GNU General Public License as published by the- * Free Software Foundation; either version 2 of the License, or (at your- * option) any later version.- *- */--/* -------------------- BEGINNING OF CONFIG --------------------- */--#include <linux/delay.h>-#include <asm/io.h>-#include <asm/sibyte/sb1250.h>-#include <asm/sibyte/sb1250_regs.h>-#include <asm/sibyte/sb1250_uart.h>-#include <asm/sibyte/sb1250_int.h>-#include <asm/addrspace.h>--/*- * We use the second serial port for kgdb traffic.- * 115200, 8, N, 1.- */--#define BAUD_RATE 115200-#define CLK_DIVISOR V_DUART_BAUD_RATE(BAUD_RATE)-#define DATA_BITS V_DUART_BITS_PER_CHAR_8 /* or 7 */-#define PARITY V_DUART_PARITY_MODE_NONE /* or even */-#define STOP_BITS M_DUART_STOP_BIT_LEN_1 /* or 2 */--static int duart_initialized = 0; /* 0: need to be init'ed by kgdb */--/* -------------------- END OF CONFIG --------------------- */-extern int kgdb_port;--#define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg)))-#define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg)))--void putDebugChar(unsigned char c);-unsigned char getDebugChar(void);-static void-duart_init(int clk_divisor, int data, int parity, int stop)-{- duart_out(R_DUART_MODE_REG_1, data | parity);- duart_out(R_DUART_MODE_REG_2, stop);- duart_out(R_DUART_CLK_SEL, clk_divisor);-- duart_out(R_DUART_CMD, M_DUART_RX_EN | M_DUART_TX_EN); /* enable rx and tx */-}--void-putDebugChar(unsigned char c)-{- if (!duart_initialized) {- duart_initialized = 1;- duart_init(CLK_DIVISOR, DATA_BITS, PARITY, STOP_BITS);- }- while ((duart_in(R_DUART_STATUS) & M_DUART_TX_RDY) == 0);- duart_out(R_DUART_TX_HOLD, c);-}--unsigned char-getDebugChar(void)-{- if (!duart_initialized) {- duart_initialized = 1;- duart_init(CLK_DIVISOR, DATA_BITS, PARITY, STOP_BITS);- }- while ((duart_in(R_DUART_STATUS) & M_DUART_RX_RDY) == 0) ;- return duart_in(R_DUART_RX_HOLD);-}-Index: linux-2.6.16/arch/mips/sibyte/sb1250/irq.c===================================================================--- linux-2.6.16.orig/arch/mips/sibyte/sb1250/irq.c 2006-03-20 00:53:29.000000000 -0500+++ linux-2.6.16/arch/mips/sibyte/sb1250/irq.c 2006-04-25 08:01:03.960038432 -0400@@ -31,6 +31,7 @@ #include <asm/system.h> #include <asm/ptrace.h> #include <asm/io.h>+#include <asm/kgdb.h> #include <asm/sibyte/sb1250_regs.h> #include <asm/sibyte/sb1250_int.h>@@ -60,16 +61,6 @@ extern unsigned long ldt_eoi_space; #endif -#ifdef CONFIG_KGDB-static int kgdb_irq;--/* Default to UART1 */-int kgdb_port = 1;-#ifdef CONFIG_SIBYTE_SB1250_DUART-extern char sb1250_duart_present[];-#endif-#endif- static struct hw_interrupt_type sb1250_irq_type = { .typename = "SB1250-IMR", .startup = startup_sb1250_irq,@@ -329,6 +320,11 @@ unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 | STATUSF_IP1 | STATUSF_IP0; +#ifdef CONFIG_KGDB+ if (kgdb_early_setup)+ return;+#endif+ /* Default everything to IP2 */ for (i = 0; i < SB1250_NR_IRQS; i++) { /* was I0 */ __raw_writeq(IMR_IP2_VAL,@@ -380,47 +376,4 @@ /* Enable necessary IPs, disable the rest */ change_c0_status(ST0_IM, imask); set_except_vector(0, sb1250_irq_handler);--#ifdef CONFIG_KGDB- if (kgdb_flag) {- kgdb_irq = K_INT_UART_0 + kgdb_port;--#ifdef CONFIG_SIBYTE_SB1250_DUART- sb1250_duart_present[kgdb_port] = 0;-#endif- /* Setup uart 1 settings, mapper */- __raw_writeq(M_DUART_IMR_BRK,- IOADDR(A_DUART_IMRREG(kgdb_port)));-- sb1250_steal_irq(kgdb_irq);- __raw_writeq(IMR_IP6_VAL,- IOADDR(A_IMR_REGISTER(0,- R_IMR_INTERRUPT_MAP_BASE) +- (kgdb_irq << 3)));- sb1250_unmask_irq(0, kgdb_irq);- }-#endif-}--#ifdef CONFIG_KGDB--#include <linux/delay.h>--#define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg)))-#define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg)))--void sb1250_kgdb_interrupt(struct pt_regs *regs)-{- /*- * Clear break-change status (allow some time for the remote- * host to stop the break, since we would see another- * interrupt on the end-of-break too)- */- kstat_this_cpu.irqs[kgdb_irq]++;- mdelay(500);- duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT |- M_DUART_RX_EN | M_DUART_TX_EN);- set_async_breakpoint(®s->cp0_epc); }--#endif /* CONFIG_KGDB */Index: linux-2.6.16/arch/mips/sibyte/sb1250/irq_handler.S===================================================================--- linux-2.6.16.orig/arch/mips/sibyte/sb1250/irq_handler.S 2006-03-20 00:53:29.000000000 -0500+++ linux-2.6.16/arch
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -