⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sh-lite.patch

📁 Linux-2.6.18内核调试工具补丁程序KGDB。
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
This adds basic support for KGDB on SuperH as well as adding some architecturespecific notes to the DocBook file and converting the 7751 to use this.  Ihave tested all combinations of 8250 and SCI(F) ports being used as KGDB andconsole that I could (one of each usable to me).Signed-off-by: Milind Dumbare <milind@linsyssoft.com>Signed-off-by: Tom Rini <trini@kernel.crashing.org> Documentation/DocBook/kgdb.tmpl |   16 arch/sh/Kconfig.debug           |   92 -- arch/sh/Makefile                |    1 arch/sh/boards/se/7751/setup.c  |  139 --- arch/sh/kernel/Makefile         |    2 arch/sh/kernel/cpu/sh3/ex.S     |    2 arch/sh/kernel/cpu/sh4/ex.S     |    2 arch/sh/kernel/entry.S          |   30 arch/sh/kernel/kgdb-jmp.S       |   32 arch/sh/kernel/kgdb.c           |  363 +++++++++ arch/sh/kernel/kgdb_jmp.S       |   33 arch/sh/kernel/kgdb_stub.c      | 1491 ---------------------------------------- arch/sh/kernel/setup.c          |   94 -- arch/sh/kernel/time.c           |    8 arch/sh/kernel/traps.c          |   20 arch/sh/mm/extable.c            |    7 arch/sh/mm/fault-nommu.c        |   14 arch/sh/mm/fault.c              |   12 drivers/serial/sh-sci.c         |  300 ++++---- include/asm-sh/kgdb.h           |  116 --- include/asm-sh/system.h         |   40 + lib/Kconfig.debug               |    6 22 files changed, 677 insertions(+), 2143 deletions(-)Index: linux-2.6.16/Documentation/DocBook/kgdb.tmpl===================================================================--- linux-2.6.16.orig/Documentation/DocBook/kgdb.tmpl	2006-04-25 11:27:15.000000000 +0530+++ linux-2.6.16/Documentation/DocBook/kgdb.tmpl	2006-04-25 11:34:01.000000000 +0530@@ -124,6 +124,10 @@     serial driver, pass in: <constant>kgdbwait</constant>.     </para>     <para>+    To specify the values of the SH SCI(F) serial port at boot:+    <constant>kgdbsci=0,115200</constant>.+    </para>+    <para>     To specify the values of the serial port at boot:     <constant>kgdb8250=io,3f8,115200,3</constant>.     On IA64 this could also be:@@ -181,6 +185,18 @@     application program.     </para>   </chapter>+  <chapter id="ArchitectureNotes">+    <title>Architecture specific notes</title>+      <para>+      SuperH: The NMI switch found on some boards can be used to trigger an+      initial breakpoint.  Subsequent triggers do nothing.  If console+      is enabled on the SCI(F) serial port, and that is the port being used+      for KGDB, then you must trigger a breakpoint via sysrq, NMI, or+      some other method prior to connecting, or echo a control-c to the+      serial port.  Also, to use the SCI(F) port for KGDB, the+      <symbol>CONFIG_SERIAL_SH_SCI</symbol> driver must be enabled.+      </para>+  </chapter>   <chapter id="CommonBackEndReq">     <title>The common backend (required)</title>       <para>Index: linux-2.6.16/drivers/serial/sh-sci.c===================================================================--- linux-2.6.16.orig/drivers/serial/sh-sci.c	2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16/drivers/serial/sh-sci.c	2006-04-25 11:38:27.000000000 +0530@@ -43,6 +43,7 @@ #include <linux/console.h> #include <linux/bitops.h> #include <linux/generic_serial.h>+#include <linux/kgdb.h>  #ifdef CONFIG_CPU_FREQ #include <linux/notifier.h>@@ -68,14 +69,16 @@  #include "sh-sci.h" -#ifdef CONFIG_SH_KGDB-#include <asm/kgdb.h>--static int kgdb_get_char(struct sci_port *port);-static void kgdb_put_char(struct sci_port *port, char c);-static void kgdb_handle_error(struct sci_port *port);-static struct sci_port *kgdb_sci_port;-#endif /* CONFIG_SH_KGDB */+#ifdef CONFIG_KGDB_SH_SCI+/* Speed of the UART. */+static int kgdbsci_baud = CONFIG_KGDB_BAUDRATE++/* Index of the UART, matches ttySCX naming. */+static int kgdbsci_ttySC = CONFIG_KGDB_PORT_NUM;++/* Make life easier on us. */+#define KGDBPORT	sci_ports[kgdbsci_ttySC]+#endif /* CONFIG_KGDB_SH_SCI */  #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE static struct sci_port *serial_console_port = 0;@@ -88,20 +91,17 @@ static void sci_stop_rx(struct uart_port *port); static int sci_request_irq(struct sci_port *port); static void sci_free_irq(struct sci_port *port);+static void sci_set_termios(struct uart_port *port, struct termios *termios,+			struct termios *old);+static int kgdbsci_init(void);  static struct sci_port sci_ports[]; static struct uart_driver sci_uart_driver;  #define SCI_NPORTS sci_uart_driver.nr -#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)--static void handle_error(struct uart_port *port)-{				/* Clear error flags */-	sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));-}--static int get_char(struct uart_port *port)+#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_KGDB_SH_SCI)+static int get_char_for_gdb(struct uart_port *port) { 	unsigned long flags; 	unsigned short status;@@ -111,7 +111,8 @@         do { 		status = sci_in(port, SCxSR); 		if (status & SCxSR_ERRORS(port)) {-			handle_error(port);+			/* Clear error flags. */+			sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); 			continue; 		} 	} while (!(status & SCxSR_RDxF(port)));@@ -122,21 +123,7 @@  	return c; }--/* Taken from sh-stub.c of GDB 4.18 */-static const char hexchars[] = "0123456789abcdef";--static __inline__ char highhex(int  x)-{-	return hexchars[(x >> 4) & 0xf];-}--static __inline__ char lowhex(int  x)-{-	return hexchars[x & 0xf];-}--#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */+#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_KGDB_SH_SCI */  /*  * Send the packet in buffer.  The host gets one chance to read it.@@ -168,21 +155,14 @@ 	const unsigned char *p = buffer; 	int i; -#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)-	int checksum;-	int usegdb=0;- #ifdef CONFIG_SH_STANDARD_BIOS+	int checksum;+	 const char hexchars[] = "0123456789abcdef";+	 	/* This call only does a trap the first time it is 	 * called, and so is safe to do here unconditionally 	 */-	usegdb |= sh_bios_in_gdb_mode();-#endif-#ifdef CONFIG_SH_KGDB-	usegdb |= (kgdb_in_gdb_mode && (port == kgdb_sci_port));-#endif--	if (usegdb) {+	if (sh_bios_in_gdb_mode()) { 	    /*  $<packet info>#<checksum>. */ 	    do { 		unsigned char c;@@ -194,18 +174,18 @@ 			int h, l;  			c = *p++;-			h = highhex(c);-			l = lowhex(c);+			h = hexchars[c >> 4];+			l = hexchars[c % 16]; 			put_char(port, h); 			put_char(port, l); 			checksum += h + l; 		} 		put_char(port, '#');-		put_char(port, highhex(checksum));-		put_char(port, lowhex(checksum));+		put_char(port, hexchars[checksum >> 4]);+		put_char(port, hexchars[checksum & 16]); 	    } while  (get_char(port) != '+'); 	} else-#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */+#endif /* CONFIG_SH_STANDARD_BIOS */ 	for (i=0; i<count; i++) { 		if (*p == 10) 			put_char(port, '\r');@@ -215,90 +195,163 @@ #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */  -#ifdef CONFIG_SH_KGDB--/* Is the SCI ready, ie is there a char waiting? */-static int kgdb_is_char_ready(struct sci_port *port)+#ifdef CONFIG_KGDB_SH_SCI+static int kgdbsci_read_char(void) {-        unsigned short status = sci_in(port, SCxSR);--        if (status & (SCxSR_ERRORS(port) | SCxSR_BRK(port)))-                kgdb_handle_error(port);--        return (status & SCxSR_RDxF(port));+	return get_char_for_gdb(&KGDBPORT.port); } -/* Write a char */-static void kgdb_put_char(struct sci_port *port, char c)+/* Called from kgdbstub.c to put a character, just a wrapper */+static void kgdbsci_write_char(int c) {-        unsigned short status;--        do-                status = sci_in(port, SCxSR);-        while (!(status & SCxSR_TDxE(port)));+	unsigned short status; -        sci_out(port, SCxTDR, c);-        sci_in(port, SCxSR);    /* Dummy read */-        sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));+	do+		status = sci_in(&KGDBPORT.port, SCxSR);+	while (!(status & SCxSR_TDxE(&KGDBPORT.port)));++	sci_out(&KGDBPORT.port, SCxTDR, c);+	sci_in(&KGDBPORT.port, SCxSR);	/* Dummy read */+	sci_out(&KGDBPORT.port, SCxSR, SCxSR_TDxE_CLEAR(&KGDBPORT.port)); } -/* Get a char if there is one, else ret -1 */-static int kgdb_get_char(struct sci_port *port)+#ifndef CONFIG_SERIAL_SH_SCI_CONSOLE+/* If we don't have console, we never hookup IRQs.  But we need to+ * hookup one so that we can interrupt the system.+ */+static irqreturn_t kgdbsci_rx_interrupt(int irq, void *ptr,+		struct pt_regs *regs) {-        int c;+	struct uart_port *port = ptr; -        if (kgdb_is_char_ready(port) == 0)-                c = -1;-        else {-                c = sci_in(port, SCxRDR);-                sci_in(port, SCxSR);    /* Dummy read */-                sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));-        }+	if (!(sci_in(port, SCxSR) & SCxSR_RDxF(port)))+		return IRQ_NONE; -        return c;-}--/* Called from kgdbstub.c to get a character, i.e. is blocking */-static int kgdb_sci_getchar(void)-{-        volatile int c;+	if (kgdb_io_ops.init != kgdbsci_init) {+		/* Throw away the data if another I/O routine is active */+		get_char_for_gdb(&KGDBPORT.port);+	} else+		/* We've got an interrupt, so go ahead and call breakpoint() */+		breakpoint(); -        /* Keep trying to read a character, this could be neater */-        while ((c = kgdb_get_char(kgdb_sci_port)) < 0);+	sci_in(port, SCxSR); /* dummy read */+	sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); -        return c;+	return IRQ_HANDLED; } -/* Called from kgdbstub.c to put a character, just a wrapper */-static void kgdb_sci_putchar(int c)+static irqreturn_t kgdbsci_mpxed_interrupt(int irq, void *ptr,+		struct pt_regs *regs) {+        unsigned short ssr_status, scr_status;+        struct uart_port *port = ptr;++        ssr_status = sci_in(port,SCxSR);+        scr_status = sci_in(port,SCSCR);++	/* Rx Interrupt */+        if ((ssr_status&0x0002) && (scr_status&0x0040))+		kgdbsci_rx_interrupt(irq, ptr, regs); -        kgdb_put_char(kgdb_sci_port, c);+	return IRQ_HANDLED; } -/* Clear any errors on the SCI */-static void kgdb_handle_error(struct sci_port *port)+static void __init kgdbsci_lateinit(void) {-        sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));  /* Clear error flags */+	if (KGDBPORT.irqs[0] == KGDBPORT.irqs[1]) {+		if (!KGDBPORT.irqs[0]) {+			printk(KERN_ERR "kgdbsci: Cannot allocate irq.\n");+			return;+		}+		if (request_irq(KGDBPORT.irqs[0], kgdbsci_mpxed_interrupt,+					SA_INTERRUPT, "kgdbsci",+					&KGDBPORT.port)) {+			printk(KERN_ERR "kgdbsci: Cannot allocate irq.\n");+			return;+		}+	} else {+		if (KGDBPORT.irqs[1])+			request_irq(KGDBPORT.irqs[1],+					kgdbsci_rx_interrupt, SA_INTERRUPT,+					"kgdbsci", &KGDBPORT.port);+	} }+#endif -/* Breakpoint if there's a break sent on the serial port */-static void kgdb_break_interrupt(int irq, void *ptr, struct pt_regs *regs)+/*+ * We use the normal init routine to setup the port, so we can't be+ * in here too early.+ */+static int kgdbsci_init(void) {-        struct sci_port *port = ptr;-        unsigned short status = sci_in(port, SCxSR);+	struct termios termios; -        if (status & SCxSR_BRK(port)) {+	memset(&termios, 0, sizeof(struct termios)); -                /* Break into the debugger if a break is detected */-                BREAKPOINT();+	termios.c_cflag = CREAD | HUPCL | CLOCAL | CS8;+	switch (kgdbsci_baud) {+	case 9600:+		termios.c_cflag |= B9600;+		break;+	case 19200:+		termios.c_cflag |= B19200;+		break;+	case 38400:+		termios.c_cflag |= B38400;+		break;+	case 57600:+		termios.c_cflag |= B57600;+		break;+	case 115200:+		termios.c_cflag |= B115200;+		break;+	}+	sci_set_termios(&KGDBPORT.port, &termios, NULL); -                /* Clear */-                sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));-        }+	return 0; } -#endif /* CONFIG_SH_KGDB */+struct kgdb_io kgdb_io_ops = {+	.read_char = kgdbsci_read_char,+	.write_char = kgdbsci_write_char,+	.init = kgdbsci_init,+#ifndef CONFIG_SERIAL_SH_SCI_CONSOLE+	.late_init = kgdbsci_lateinit,+#else /* ! CONFIG_SERIAL_SH_SCI_CONSOLE */+	.late_init = NULL,+#endif /* ! CONFIG_SERIAL_SH_SCI_CONSOLE */+	.pre_exception = NULL,+	.post_exception = NULL+};++/*+ * Syntax for this cmdline option is "kgdbsci=ttyno,baudrate".+ */+static int __init+kgdbsci_opt(char *str)+{+	/* We might have anywhere from 1 to 3 ports. */+	if (*str < '0' || *str > SCI_NPORTS + '0')+		 goto errout;+	kgdbsci_ttySC = *str - '0';+	str++;+	if (*str != ',')+		 goto errout;+	str++;+	kgdbsci_baud = simple_strtoul(str, &str, 10);+	if (kgdbsci_baud != 9600 && kgdbsci_baud != 19200 &&+	    kgdbsci_baud != 38400 && kgdbsci_baud != 57600 &&+	    kgdbsci_baud != 115200)+		 goto errout;++	return 0;++errout:+	printk(KERN_ERR "Invalid syntax for option kgdbsci=\n");+	return 1;+}+__setup("kgdbsci", kgdbsci_opt);+#endif /* CONFIG_KGDB_SH_SCI */  #if defined(__H8300S__) enum { sci_disable, sci_enable };@@ -556,6 +609,16 @@ 					continue; 				} +#ifdef CONFIG_KGDB_SH_SCI+				/* We assume that a ^C on the port KGDB+				 * is using means that KGDB wants to+				 * interrupt the running system.+				 */+				if (port->line == KGDBPORT.port.line &&+						c == 3)+					breakpoint();+#endif+ 				/* Store data and status */ 				if (status&SCxSR_FER(port)) { 					flag = TTY_FRAME;@@ -1619,6 +1682,7 @@ console_initcall(sci_console_init); #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ +#if 0 #ifdef CONFIG_SH_KGDB /*  * FIXME: Most of this can go away.. at the moment, we rely on@@ -1664,30 +1728,9 @@ 	return uart_set_options(port, co, baud, parity, bits, flow); } #endif /* CONFIG_SH_KGDB */+#endif /* 0 */ -#ifdef CONFIG_SH_KGDB_CONSOLE-static struct console kgdb_console = {-        .name		= "ttySC",-        .write		= kgdb_console_write,-        .setup		= kgdb_console_setup,-        .flags		= CON_PRINTBUFFER | CON_ENABLED,-        .index		= -1,-	.data		= &sci_uart_driver,-};--/* Register the KGDB console so we get messages (d'oh!) */-static int __init kgdb_console_init(void)-{-	register_console(&kgdb_console);-	return 0;-}--console_initcall(kgdb_console_init);-#endif /* CONFIG_SH_KGDB_CONSOLE */--#if defined(CONFIG_SH_KGDB_CONSOLE)-#define SCI_CONSOLE	&kgdb_console-#elif defined(CONFIG_SERIAL_SH_SCI_CONSOLE)+#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE #define SCI_CONSOLE	&serial_console #else #define SCI_CONSOLE	0@@ -1761,4 +1804,3 @@  module_init(sci_init); module_exit(sci_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -