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

📄 8250.patch

📁 Linux-2.6.18内核调试工具补丁程序KGDB。
💻 PATCH
📖 第 1 页 / 共 2 页
字号:
This is the I/O driver for any 8250-compatible UARTs.  This also adds somesmall hooks into the normal serial core so that we can take away the uart andmake sure only KGDB is trying to use it.  We also make sure that if KGDB_8250is enabled, SERIAL_8250_NR_UARTS is set to the default of 4.  This is so thatif we can always depend on that constant in the 8250 driver for giving ourtable a size.  We add a hook to the main core for unregistering a portwith a struct uart_port and add a hook into uart_add_one_port fordiscovered 8250-like uarts.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> drivers/serial/8250.c        |   19 + drivers/serial/8250_kgdb.c   |  516 +++++++++++++++++++++++++++++++++++++++++++ drivers/serial/Kconfig       |    2 drivers/serial/Makefile      |    1 drivers/serial/serial_core.c |   23 + include/linux/serial_8250.h  |    1 lib/Kconfig.debug            |   58 ++++ 7 files changed, 615 insertions(+), 5 deletions(-)Index: linux-2.6.16-x86_64/drivers/serial/Kconfig===================================================================--- linux-2.6.16-x86_64.orig/drivers/serial/Kconfig	2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16-x86_64/drivers/serial/Kconfig	2006-04-26 12:28:57.000000000 +0530@@ -87,7 +87,7 @@  config SERIAL_8250_NR_UARTS 	int "Maximum number of 8250/16550 serial ports"-	depends on SERIAL_8250+	depends on SERIAL_8250 || KGDB_8250 	default "4" 	help 	  Set this to the number of serial ports you want the driverIndex: linux-2.6.16-x86_64/drivers/serial/8250_kgdb.c===================================================================--- linux-2.6.16-x86_64.orig/drivers/serial/8250_kgdb.c	2006-04-26 10:45:04.546079250 +0530+++ linux-2.6.16-x86_64/drivers/serial/8250_kgdb.c	2006-04-26 12:28:57.000000000 +0530@@ -0,0 +1,516 @@+/*+ * 8250 interface for kgdb.+ *+ * This is a merging of many different drivers, and all of the people have+ * had an impact in some form or another:+ *+ * 2004-2005 (c) MontaVista Software, Inc.+ * 2005-2006 (c) Wind River Systems, Inc.+ *+ * Amit Kale <amitkale@emsyssoft.com>, David Grothe <dave@gcom.com>,+ * Scott Foehner <sfoehner@engr.sgi.com>, George Anzinger <george@mvista.com>,+ * Robert Walsh <rjwalsh@durables.org>, wangdi <wangdi@clusterfs.com>,+ * San Mehat, Tom Rini <trini@mvista.com>,+ * Jason Wessel <jason.wessel@windriver.com>+ */++#include <linux/config.h>+#include <linux/kernel.h>+#include <linux/init.h>+#include <linux/kgdb.h>+#include <linux/interrupt.h>+#include <linux/tty.h>+#include <linux/serial.h>+#include <linux/serial_reg.h>+#include <linux/serialP.h>+#include <linux/ioport.h>++#include <asm/io.h>+#include <asm/serial.h>		/* For BASE_BAUD and SERIAL_PORT_DFNS */++#include "8250.h"++#define GDB_BUF_SIZE	512	/* power of 2, please */++MODULE_DESCRIPTION("KGDB driver for the 8250");+MODULE_LICENSE("GPL");+/* These will conflict with early_param otherwise. */+#ifdef CONFIG_KGDB_8250_MODULE+static char config[256];+module_param_string(kgdb8250, config, 256, 0);+MODULE_PARM_DESC(kgdb8250,+		 " kgdb8250=<io or mmio>,<address>,<baud rate>,<irq>\n");+static struct kgdb_io local_kgdb_io_ops;+#endif				/* CONFIG_KGDB_8250_MODULE */++/* Speed of the UART. */+static int kgdb8250_baud;++/* Flag for if we need to call request_mem_region */+static int kgdb8250_needs_request_mem_region;++static char kgdb8250_buf[GDB_BUF_SIZE];+static atomic_t kgdb8250_buf_in_cnt;+static int kgdb8250_buf_out_inx;++/* Old-style serial definitions, if existant, and a counter. */+#ifdef CONFIG_KGDB_SIMPLE_SERIAL+static int __initdata should_copy_rs_table = 1;+static struct serial_state old_rs_table[] __initdata = {+#ifdef SERIAL_PORT_DFNS+	SERIAL_PORT_DFNS+#endif+};+#endif++/* Our internal table of UARTS. */+#define UART_NR	CONFIG_SERIAL_8250_NR_UARTS+static struct uart_port kgdb8250_ports[UART_NR];++static struct uart_port *current_port;++/* Base of the UART. */+static void *kgdb8250_addr;++/* Forward declarations. */+static int kgdb8250_uart_init(void);+static int __init kgdb_init_io(void);+static int __init kgdb8250_opt(char *str);++/* These are much shorter calls to ioread8/iowrite8 that take into+ * account our shifts, etc. */+static inline unsigned int kgdb_ioread(u8 mask)+{+	return ioread8(kgdb8250_addr + (mask << current_port->regshift));+}++static inline void kgdb_iowrite(u8 val, u8 mask)+{+	iowrite8(val, kgdb8250_addr + (mask << current_port->regshift));+}++/*+ * Wait until the interface can accept a char, then write it.+ */+static void kgdb_put_debug_char(u8 chr)+{+	while (!(kgdb_ioread(UART_LSR) & UART_LSR_THRE)) ;++	kgdb_iowrite(chr, UART_TX);+}++/*+ * Get a byte from the hardware data buffer and return it+ */+static int read_data_bfr(void)+{+	char it = kgdb_ioread(UART_LSR);++	if (it & UART_LSR_DR)+		return kgdb_ioread(UART_RX);++	/*+	 * If we have a framing error assume somebody messed with+	 * our uart.  Reprogram it and send '-' both ways...+	 */+	if (it & 0xc) {+		kgdb8250_uart_init();+		kgdb_put_debug_char('-');+		return '-';+	}++	return -1;+}++/*+ * Get a char if available, return -1 if nothing available.+ * Empty the receive buffer first, then look at the interface hardware.+ */+static int kgdb_get_debug_char(void)+{+	int retchr;++	/* intr routine has q'd chars */+	if (atomic_read(&kgdb8250_buf_in_cnt) != 0) {+		retchr = kgdb8250_buf[kgdb8250_buf_out_inx++];+		kgdb8250_buf_out_inx &= (GDB_BUF_SIZE - 1);+		atomic_dec(&kgdb8250_buf_in_cnt);+		return retchr;+	}++	do {+		retchr = read_data_bfr();+	} while (retchr < 0);++	return retchr;+}++/*+ * This is the receiver interrupt routine for the GDB stub.+ * All that we need to do is verify that the interrupt happened on the+ * line we're in charge of.  If this is true, schedule a breakpoint and+ * return.+ */+static irqreturn_t+kgdb8250_interrupt(int irq, void *dev_id, struct pt_regs *regs)+{+	if (kgdb_ioread(UART_IIR) & UART_IIR_RDI) {+		/* Throw away the data if another I/O routine is active. */+		if (kgdb_io_ops.read_char != kgdb_get_debug_char &&+				(kgdb_ioread(UART_LSR) & UART_LSR_DR))+			kgdb_ioread(UART_RX);+		else+			breakpoint();+	}++	return IRQ_HANDLED;+}++/*+ *  Initializes the UART.+ *  Returns:+ *	0 on success, 1 on failure.+ */+static int+kgdb8250_uart_init (void)+{+	unsigned int ier, base_baud = current_port->uartclk ?+		current_port->uartclk / 16 : BASE_BAUD;++	/* test uart existance */+	if(kgdb_ioread(UART_LSR) == 0xff)+		return -1;++	/* disable interrupts */+	kgdb_iowrite(0, UART_IER);++#if defined(CONFIG_ARCH_OMAP1510)+	/* Workaround to enable 115200 baud on OMAP1510 internal ports */+	if (cpu_is_omap1510() && is_omap_port((void *)kgdb8250_addr)) {+		if (kgdb8250_baud == 115200) {+			base_baud = 1;+			kgdb8250_baud = 1;+			kgdb_iowrite(1, UART_OMAP_OSC_12M_SEL);+		} else+			kgdb_iowrite(0, UART_OMAP_OSC_12M_SEL);+	}+#endif+	/* set DLAB */+	kgdb_iowrite(UART_LCR_DLAB, UART_LCR);++	/* set baud */+	kgdb_iowrite((base_baud / kgdb8250_baud) & 0xff, UART_DLL);+	kgdb_iowrite((base_baud / kgdb8250_baud) >> 8, UART_DLM);++	/* reset DLAB, set LCR */+	kgdb_iowrite(UART_LCR_WLEN8, UART_LCR);++	/* set DTR and RTS */+	kgdb_iowrite(UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS, UART_MCR);++	/* setup fifo */+	kgdb_iowrite(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR+		| UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_8,+		UART_FCR);++	/* clear pending interrupts */+	kgdb_ioread(UART_IIR);+	kgdb_ioread(UART_RX);+	kgdb_ioread(UART_LSR);+	kgdb_ioread(UART_MSR);++	/* turn on RX interrupt only */+	kgdb_iowrite(UART_IER_RDI, UART_IER);++	/*+	 * Borrowed from the main 8250 driver.+	 * Try writing and reading the UART_IER_UUE bit (b6).+	 * If it works, this is probably one of the Xscale platform's+	 * internal UARTs.+	 * We're going to explicitly set the UUE bit to 0 before+	 * trying to write and read a 1 just to make sure it's not+	 * already a 1 and maybe locked there before we even start start.+	 */+	ier = kgdb_ioread(UART_IER);+	kgdb_iowrite(ier & ~UART_IER_UUE, UART_IER);+	if (!(kgdb_ioread(UART_IER) & UART_IER_UUE)) {+		/*+		 * OK it's in a known zero state, try writing and reading+		 * without disturbing the current state of the other bits.+		 */+		kgdb_iowrite(ier | UART_IER_UUE, UART_IER);+		if (kgdb_ioread(UART_IER) & UART_IER_UUE)+			/*+			 * It's an Xscale.+			 */+			ier |= UART_IER_UUE | UART_IER_RTOIE;+	}+	kgdb_iowrite(ier, UART_IER);+	return 0;+}++/*+ * Copy the old serial_state table to our uart_port table if we haven't+ * had values specifically configured in.  We need to make sure this only+ * happens once.+ */+static void __init kgdb8250_copy_rs_table(void)+{+#ifdef CONFIG_KGDB_SIMPLE_SERIAL+	int i;++	if (!should_copy_rs_table)+		return;++	for (i = 0; i < ARRAY_SIZE(old_rs_table); i++) {+		kgdb8250_ports[i].iobase = old_rs_table[i].port;+		kgdb8250_ports[i].irq = irq_canonicalize(old_rs_table[i].irq);+		kgdb8250_ports[i].uartclk = old_rs_table[i].baud_base * 16;+		kgdb8250_ports[i].membase = old_rs_table[i].iomem_base;+		kgdb8250_ports[i].iotype = old_rs_table[i].io_type;+		kgdb8250_ports[i].regshift = old_rs_table[i].iomem_reg_shift;+		kgdb8250_ports[i].line = i;+	}++	should_copy_rs_table = 0;+#endif+}++/*+ * Hookup our IRQ line now that it is safe to do so, after we grab any+ * memory regions we might need to.  If we haven't been initialized yet,+ * go ahead and copy the old_rs_table in.+ */+static void __init kgdb8250_late_init(void)+{+	/* Try and copy the old_rs_table. */+	kgdb8250_copy_rs_table();++#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)+	/* Take the port away from the main driver. */+	serial8250_unregister_by_port(current_port);++	/* Now reinit the port as the above has disabled things. */+	kgdb8250_uart_init();+#endif+	/* We may need to call request_mem_region() first. */+	if (kgdb8250_needs_request_mem_region)+		request_mem_region(current_port->mapbase,+				   8 << current_port->regshift, "kgdb");+	if (request_irq(current_port->irq, kgdb8250_interrupt, SA_SHIRQ,+			"GDB-stub", current_port) < 0)+		printk(KERN_ERR "KGDB failed to request the serial IRQ (%d)\n",+		       current_port->irq);+}++static __init int kgdb_init_io(void)+{+	/* Give us the basic table of uarts. */+	kgdb8250_copy_rs_table();++	/* We're either a module and parse a config string, or we have a+	 * semi-static config. */+#ifdef CONFIG_KGDB_8250_MODULE+	if (strlen(config)) {+		if (kgdb8250_opt(config))+			return -EINVAL;+	} else {+		printk(KERN_ERR "kgdb8250: argument error, usage: "+		       "kgdb8250=<io or mmio>,<address>,<baud rate>,<irq>\n");+		return -EINVAL;+	}+#elif defined(CONFIG_KGDB_SIMPLE_SERIAL)+	kgdb8250_baud = CONFIG_KGDB_BAUDRATE;++	/* Setup our pointer to the serial port now. */+	current_port = &kgdb8250_ports[CONFIG_KGDB_PORT_NUM];+#else+	if (kgdb8250_opt(CONFIG_KGDB_8250_CONF_STRING))+		return -EINVAL;+#endif+++	/* Internal driver setup. */+	switch (current_port->iotype) {+	case UPIO_MEM:+		if (current_port->mapbase)

⌨️ 快捷键说明

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