📄 arm-lite.patch
字号:
This adds a backend, written by Deepak Saxena <dsaxena@plexity.net> and GeorgeDavis <gdavis@mvista.com> as well as support for the TI OMAP boards, ADICoyote, PXA2xx, and ARM Versatile. Geoff Levand <geoffrey.levand@am.sony.com>Nicolas Pitre, and Manish Lachwani have contributed various fixups here aswell. This should only require (on boards that don't have a custom uart)registering the uart with KGDB to add any other boards, or using kgdboe itshould Just Work.Signed-off-by: Milind Dumbare <milind@linsyssoft.com>Signed-off-by: Dmitry Antipov <antipov@ru.mvista.com>Signed-off-by: Tom Rini <trini@kernel.crashing.org> arch/arm/kernel/Makefile | 1 arch/arm/kernel/kgdb-jmp.S | 30 ++++ arch/arm/kernel/kgdb.c | 208 ++++++++++++++++++++++++++++++++++ arch/arm/kernel/setup.c | 5 arch/arm/kernel/traps.c | 11 + arch/arm/mach-ixp2000/core.c | 4 arch/arm/mach-ixp2000/ixdp2x01.c | 6 arch/arm/mach-ixp4xx/coyote-setup.c | 4 arch/arm/mach-ixp4xx/ixdp425-setup.c | 12 + arch/arm/mach-omap1/serial.c | 4 arch/arm/mach-pxa/Makefile | 1 arch/arm/mach-pxa/kgdb-serial.c | 98 ++++++++++++++++ arch/arm/mach-versatile/kgdb_serial.c | 121 +++++++++++++++++++ arch/arm/mm/extable.c | 7 + drivers/serial/amba-pl011.c | 2 drivers/serial/pxa.c | 5 include/asm-arm/kgdb.h | 87 ++++++++++++++ include/asm-arm/system.h | 41 ++++++ lib/Kconfig.debug | 2 19 files changed, 645 insertions(+), 4 deletions(-)Index: linux-2.6.16/drivers/serial/amba-pl011.c===================================================================--- linux-2.6.16.orig/drivers/serial/amba-pl011.c 2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16/drivers/serial/amba-pl011.c 2006-04-25 11:40:09.000000000 +0530@@ -341,7 +341,7 @@ /* * Allocate the IRQ */- retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);+ retval = request_irq(uap->port.irq, pl011_int, SA_SHIRQ, "uart-pl011", uap); if (retval) goto clk_dis; Index: linux-2.6.16/drivers/serial/pxa.c===================================================================--- linux-2.6.16.orig/drivers/serial/pxa.c 2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16/drivers/serial/pxa.c 2006-04-25 11:40:09.000000000 +0530@@ -43,6 +43,9 @@ #include <linux/tty.h> #include <linux/tty_flip.h> #include <linux/serial_core.h>+#ifdef CONFIG_KGDB_CONSOLE+#include <linux/kgdb.h>+#endif #include <asm/io.h> #include <asm/hardware.h>@@ -702,6 +705,8 @@ console_initcall(serial_pxa_console_init); #define PXA_CONSOLE &serial_pxa_console+#elif defined(CONFIG_KGDB_CONSOLE)+#define PXA_CONSOLE &kgdbcons #else #define PXA_CONSOLE NULL #endifIndex: linux-2.6.16/arch/arm/mach-versatile/kgdb_serial.c===================================================================--- linux-2.6.16.orig/arch/arm/mach-versatile/kgdb_serial.c 2006-04-25 10:59:23.506518750 +0530+++ linux-2.6.16/arch/arm/mach-versatile/kgdb_serial.c 2006-04-25 11:40:09.000000000 +0530@@ -0,0 +1,121 @@+/*+ * arch/arm/mach-versatile/kgdb_serial.c+ *+ * Author: Manish Lachwani, mlachwani@mvista.com+ *+ * 2005 (c) MontaVista Software, Inc. This file is licensed under+ * the terms of the GNU General Public License version 2. This program+ * is licensed "as is" without any warranty of any kind, whether express+ * or implied.+ *+ * Support for KGDB on ARM Versatile.+ */+#include <linux/config.h>+#include <linux/serial_reg.h>+#include <linux/kgdb.h>+#include <asm/io.h>+#include <asm/processor.h>+#include <asm/hardware.h>+#include <asm/hardware/amba_serial.h>+#include <asm/arch-versatile/hardware.h>++#define ARM_BAUD_38400 23+/*+ * Functions that will be used later+ */+#define UART_GET_INT_STATUS(p) readb((p) + UART010_IIR)+#define UART_GET_MIS(p) readw((p) + UART011_MIS)+#define UART_PUT_ICR(p, c) writel((c), (p) + UART010_ICR)+#define UART_GET_FR(p) readb((p) + UART01x_FR)+#define UART_GET_CHAR(p) readb((p) + UART01x_DR)+#define UART_PUT_CHAR(p, c) writel((c), (p) + UART01x_DR)+#define UART_GET_RSR(p) readb((p) + UART01x_RSR)+#define UART_GET_CR(p) readb((p) + UART010_CR)+#define UART_PUT_CR(p,c) writel((c), (p) + UART010_CR)+#define UART_GET_LCRL(p) readb((p) + UART010_LCRL)+#define UART_PUT_LCRL(p,c) writel((c), (p) + UART010_LCRL)+#define UART_GET_LCRM(p) readb((p) + UART010_LCRM)+#define UART_PUT_LCRM(p,c) writel((c), (p) + UART010_LCRM)+#define UART_GET_LCRH(p) readb((p) + UART010_LCRH)+#define UART_PUT_LCRH(p,c) writel((c), (p) + UART010_LCRH)+#define UART_RX_DATA(s) (((s) & UART01x_FR_RXFE) == 0)+#define UART_TX_READY(s) (((s) & UART01x_FR_TXFF) == 0)+#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & UART01x_FR_TMSK) == 0)++/*+ * KGDB IRQ+ */+static int kgdb_irq = 12;+static volatile unsigned char *port = NULL;++static int kgdb_serial_init(void)+{+ int rate = ARM_BAUD_38400;++ port = IO_ADDRESS(0x101F1000);+ UART_PUT_CR(port, 0);++ /* Set baud rate */+ UART_PUT_LCRM(port, ((rate & 0xf00) >> 8));+ UART_PUT_LCRL(port, (rate & 0xff));+ UART_PUT_LCRH(port, UART01x_LCRH_WLEN_8 | UART01x_LCRH_FEN);+ UART_PUT_CR(port, UART01x_CR_UARTEN);++ return 0;+}++static void kgdb_serial_putchar(int ch)+{+ unsigned int status;++ do {+ status = UART_GET_FR(port);+ } while (!UART_TX_READY(status));++ UART_PUT_CHAR(port, ch);+}++static int kgdb_serial_getchar(void)+{+ unsigned int status;+ int ch;++ do {+ status = UART_GET_FR(port);+ } while (!UART_RX_DATA(status));+ ch = UART_GET_CHAR(port);+ return ch;+}++static struct uart_port kgdb_amba_port = {+ .irq = 12,+ .iobase = 0,+ .iotype = UPIO_MEM,+ .membase = (unsigned char *)IO_ADDRESS(0x101F1000),+};++static irqreturn_t kgdb_interrupt(int irq, void *dev_id, struct pt_regs *regs)+{+ int status = UART_GET_MIS(port);++ if (irq != kgdb_irq)+ return IRQ_NONE;++ if (status & 0x40)+ breakpoint();++ return IRQ_HANDLED;+}++static void __init kgdb_hookup_irq(void)+{+ request_irq(kgdb_irq, kgdb_interrupt, SA_SHIRQ, "GDB-stub",+ &kgdb_amba_port);+}++struct kgdb_io kgdb_io_ops = {+ .init = kgdb_serial_init,+ .write_char = kgdb_serial_putchar,+ .read_char = kgdb_serial_getchar,+ .late_init = kgdb_hookup_irq,+};Index: linux-2.6.16/arch/arm/mach-pxa/kgdb-serial.c===================================================================--- linux-2.6.16.orig/arch/arm/mach-pxa/kgdb-serial.c 2006-04-25 10:59:23.506518750 +0530+++ linux-2.6.16/arch/arm/mach-pxa/kgdb-serial.c 2006-04-25 11:40:09.000000000 +0530@@ -0,0 +1,98 @@+/*+ * linux/arch/arm/mach-pxa/kgdb-serial.c+ *+ * Provides low level kgdb serial support hooks for PXA2xx boards+ *+ * Author: Nicolas Pitre+ * Copyright: (C) 2002-2005 MontaVista Software Inc.+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License version 2 as+ * published by the Free Software Foundation.+ */++#include <linux/config.h>+#include <linux/serial_reg.h>+#include <linux/kgdb.h>+#include <asm/processor.h>+#include <asm/hardware.h>+#include <asm/arch/pxa-regs.h>++#if defined(CONFIG_KGDB_PXA_FFUART)++#define UART FFUART+#define CKEN_UART CKEN6_FFUART+#define GPIO_RX_MD GPIO34_FFRXD_MD+#define GPIO_TX_MD GPIO39_FFTXD_MD++#elif defined(CONFIG_KGDB_PXA_BTUART)++#define UART BTUART+#define CKEN_UART CKEN7_BTUART+#define GPIO_RX_MD GPIO42_BTRXD_MD+#define GPIO_TX_MD GPIO43_BTTXD_MD++#elif defined(CONFIG_KGDB_PXA_STUART)++#define UART STUART+#define CKEN_UART CKEN5_STUART+#define GPIO_RX_MD GPIO46_STRXD_MD+#define GPIO_TX_MD GPIO47_STTXD_MD++#endif++#define UART_BAUDRATE (CONFIG_KGDB_BAUDRATE)++static volatile unsigned long *port = (unsigned long *)&UART;++static int kgdb_serial_init(void)+{+ pxa_set_cken(CKEN_UART, 1);+ pxa_gpio_mode(GPIO_RX_MD);+ pxa_gpio_mode(GPIO_TX_MD);++ port[UART_IER] = 0;+ port[UART_LCR] = LCR_DLAB;+ port[UART_DLL] = ((921600 / UART_BAUDRATE) & 0xff);+ port[UART_DLM] = ((921600 / UART_BAUDRATE) >> 8);+ port[UART_LCR] = LCR_WLS1 | LCR_WLS0;+ port[UART_MCR] = 0;+ port[UART_IER] = IER_UUE;+ port[UART_FCR] = FCR_ITL_16;++ return 0;+}++static void kgdb_serial_putchar(int c)+{+ if (!(CKEN & CKEN_UART) || port[UART_IER] != IER_UUE)+ kgdb_serial_init();+ while (!(port[UART_LSR] & LSR_TDRQ))+ cpu_relax();+ port[UART_TX] = c;+}++static void kgdb_serial_flush(void)+{+ if ((CKEN & CKEN_UART) && (port[UART_IER] & IER_UUE))+ while (!(port[UART_LSR] & LSR_TEMT))+ cpu_relax();+}++static int kgdb_serial_getchar(void)+{+ unsigned char c;+ if (!(CKEN & CKEN_UART) || port[UART_IER] != IER_UUE)+ kgdb_serial_init();+ while (!(port[UART_LSR] & UART_LSR_DR))+ cpu_relax();+ c = port[UART_RX];+ return c;+}++struct kgdb_io kgdb_io_ops = {+ .init = kgdb_serial_init,+ .write_char = kgdb_serial_putchar,+ .flush = kgdb_serial_flush,+ .read_char = kgdb_serial_getchar,+};Index: linux-2.6.16/arch/arm/mach-pxa/Makefile===================================================================--- linux-2.6.16.orig/arch/arm/mach-pxa/Makefile 2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16/arch/arm/mach-pxa/Makefile 2006-04-25 11:40:09.000000000 +0530@@ -28,6 +28,7 @@ # Misc features obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_PXA_SSP) += ssp.o+obj-$(CONFIG_KGDB_PXA_SERIAL) += kgdb-serial.o ifeq ($(CONFIG_PXA27x),y) obj-$(CONFIG_PM) += standby.oIndex: linux-2.6.16/arch/arm/mm/extable.c===================================================================--- linux-2.6.16.orig/arch/arm/mm/extable.c 2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16/arch/arm/mm/extable.c 2006-04-25 11:40:09.000000000 +0530@@ -2,6 +2,7 @@ * linux/arch/arm/mm/extable.c */ #include <linux/module.h>+#include <linux/kgdb.h> #include <asm/uaccess.h> int fixup_exception(struct pt_regs *regs)@@ -11,6 +12,12 @@ fixup = search_exception_tables(instruction_pointer(regs)); if (fixup) regs->ARM_pc = fixup->fixup;+#ifdef CONFIG_KGDB+ if (atomic_read(&debugger_active) && kgdb_may_fault)+ /* Restore our previous state. */+ kgdb_fault_longjmp(kgdb_fault_jmp_regs);+ /* Not reached. */+#endif return fixup != NULL; }Index: linux-2.6.16/arch/arm/kernel/kgdb-jmp.S===================================================================--- linux-2.6.16.orig/arch/arm/kernel/kgdb-jmp.S 2006-04-25 10:59:23.506518750 +0530+++ linux-2.6.16/arch/arm/kernel/kgdb-jmp.S 2006-04-25 11:40:09.000000000 +0530@@ -0,0 +1,30 @@+/*+ * arch/arm/kernel/kgdb-jmp.S+ *+ * Trivial setjmp and longjmp procedures to support bus error recovery+ * which may occur during kgdb memory read/write operations.+ *+ * Author: MontaVista Software, Inc. <source@mvista.com>+ * source@mvista.com+ *+ * 2002-2005 (c) MontaVista Software, Inc. 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/linkage.h>++ENTRY (kgdb_fault_setjmp)+ /* Save registers */+ stmia r0, {r0-r14}+ str lr,[r0, #60]+ mrs r1,cpsr+ str r1,[r0,#64]+ ldr r1,[r0,#4]+ mov r0, #0+ mov pc,lr++ENTRY (kgdb_fault_longjmp)+ /* Restore registers */+ mov r1,#1+ str r1,[r0]+ ldmia r0,{r0-pc}^Index: linux-2.6.16/arch/arm/kernel/kgdb.c===================================================================--- linux-2.6.16.orig/arch/arm/kernel/kgdb.c 2006-04-25 10:59:23.506518750 +0530+++ linux-2.6.16/arch/arm/kernel/kgdb.c 2006-04-25 11:40:09.000000000 +0530@@ -0,0 +1,208 @@+/*+ * arch/arm/kernel/kgdb.c+ *+ * ARM KGDB support+ *+ * Copyright (c) 2002-2004 MontaVista Software, Inc+ *+ * Authors: George Davis <davis_g@mvista.com>+ * Deepak Saxena <dsaxena@plexity.net>+ */+#include <linux/config.h>+#include <linux/types.h>+#include <linux/kernel.h>+#include <linux/signal.h>+#include <linux/sched.h>+#include <linux/mm.h>+#include <linux/spinlock.h>+#include <linux/personality.h>+#include <linux/ptrace.h>+#include <linux/elf.h>+#include <linux/interrupt.h>+#include <linux/init.h>+#include <linux/kgdb.h>++#include <asm/atomic.h>+#include <asm/io.h>+#include <asm/pgtable.h>+#include <asm/system.h>+#include <asm/uaccess.h>+#include <asm/unistd.h>+#include <asm/ptrace.h>+#include <asm/traps.h>++/* Make a local copy of the registers passed into the handler (bletch) */+void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)+{+ int regno;++ /* Initialize all to zero (??) */+ for (regno = 0; regno < GDB_MAX_REGS; regno++)+ gdb_regs[regno] = 0;++ gdb_regs[_R0] = kernel_regs->ARM_r0;+ gdb_regs[_R1] = kernel_regs->ARM_r1;+ gdb_regs[_R2] = kernel_regs->ARM_r2;+ gdb_regs[_R3] = kernel_regs->ARM_r3;+ gdb_regs[_R4] = kernel_regs->ARM_r4;+ gdb_regs[_R5] = kernel_regs->ARM_r5;+ gdb_regs[_R6] = kernel_regs->ARM_r6;+ gdb_regs[_R7] = kernel_regs->ARM_r7;+ gdb_regs[_R8] = kernel_regs->ARM_r8;+ gdb_regs[_R9] = kernel_regs->ARM_r9;+ gdb_regs[_R10] = kernel_regs->ARM_r10;+ gdb_regs[_FP] = kernel_regs->ARM_fp;+ gdb_regs[_IP] = kernel_regs->ARM_ip;+ gdb_regs[_SP] = kernel_regs->ARM_sp;+ gdb_regs[_LR] = kernel_regs->ARM_lr;+ gdb_regs[_PC] = kernel_regs->ARM_pc;+ gdb_regs[_CPSR] = kernel_regs->ARM_cpsr;+}++/* Copy local gdb registers back to kgdb regs, for later copy to kernel */+void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)+{+ kernel_regs->ARM_r0 = gdb_regs[_R0];+ kernel_regs->ARM_r1 = gdb_regs[_R1];+ kernel_regs->ARM_r2 = gdb_regs[_R2];+ kernel_regs->ARM_r3 = gdb_regs[_R3];+ kernel_regs->ARM_r4 = gdb_regs[_R4];+ kernel_regs->ARM_r5 = gdb_regs[_R5];+ kernel_regs->ARM_r6 = gdb_regs[_R6];+ kernel_regs->ARM_r7 = gdb_regs[_R7];+ kernel_regs->ARM_r8 = gdb_regs[_R8];+ kernel_regs->ARM_r9 = gdb_regs[_R9];+ kernel_regs->ARM_r10 = gdb_regs[_R10];+ kernel_regs->ARM_fp = gdb_regs[_FP];+ kernel_regs->ARM_ip = gdb_regs[_IP];+ kernel_regs->ARM_sp = gdb_regs[_SP];+ kernel_regs->ARM_lr = gdb_regs[_LR];+ kernel_regs->ARM_pc = gdb_regs[_PC];+ kernel_regs->ARM_cpsr = gdb_regs[GDB_MAX_REGS - 1];+}++static inline struct pt_regs *kgdb_get_user_regs(struct task_struct *task)+{+ return (struct pt_regs *)+ ((unsigned long)task->thread_info + THREAD_SIZE -+ 8 - sizeof(struct pt_regs));+}++void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs,+ struct task_struct *task)+{+ int regno;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -