Signed-off-by: Andrew Morton Index: linux-2.6.17-rc4/drivers/serial/8250.c =================================================================== --- linux-2.6.17-rc4.orig/drivers/serial/8250.c 2006-05-25 18:52:24.000000000 +0100 +++ linux-2.6.17-rc4/drivers/serial/8250.c 2006-05-25 18:52:51.000000000 +0100 @@ -2613,6 +2613,27 @@ void serial8250_unregister_port(int line } EXPORT_SYMBOL(serial8250_unregister_port); +/** + * serial8250_unregister_by_port - remove a 16x50 serial port + * at runtime. + * @port: A &struct uart_port that describes the port to remove. + * + * Remove one serial port. This may not be called from interrupt + * context. We hand the port back to the our control. + */ +void serial8250_unregister_by_port(struct uart_port *port) +{ + struct uart_8250_port *uart; + + mutex_lock(&serial_mutex); + uart = serial8250_find_match_or_unused(port); + mutex_unlock(&serial_mutex); + + if (uart) + serial8250_unregister_port(uart->port.line); +} +EXPORT_SYMBOL(serial8250_unregister_by_port); + static int __init serial8250_init(void) { int ret, i; Index: linux-2.6.17-rc4/drivers/serial/8250_kgdb.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.17-rc4/drivers/serial/8250_kgdb.c 2006-05-25 18:52:51.000000000 +0100 @@ -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 , David Grothe , + * Scott Foehner , George Anzinger , + * Robert Walsh , wangdi , + * San Mehat, Tom Rini , + * Jason Wessel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include /* 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=,
,,\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=,
,,\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) + kgdb8250_needs_request_mem_region = 1; + if (current_port->flags & UPF_IOREMAP) { + current_port->membase = ioremap(current_port->mapbase, + 8 << current_port->regshift); + if (!current_port->membase) + return -EIO; /* Failed. */ + } + kgdb8250_addr = current_port->membase; + break; + case UPIO_PORT: + default: + kgdb8250_addr = ioport_map(current_port->iobase, + 8 << current_port->regshift); + if (!kgdb8250_addr) + return -EIO; /* Failed. */ + } + + if (kgdb8250_uart_init() == -1) { + printk(KERN_ERR "kgdb8250: init failed\n"); + return -EIO; + } +#ifdef CONFIG_KGDB_8250_MODULE + /* Attach the kgdb irq. When this is built into the kernel, it + * is called as a part of late_init sequence. + */ + kgdb8250_late_init(); + if (kgdb_register_io_module(&local_kgdb_io_ops)) + return -EINVAL; + + printk(KERN_INFO "kgdb8250: debugging enabled\n"); +#endif /* CONFIG_KGD_8250_MODULE */ + + return 0; +} + +#ifdef CONFIG_KGDB_8250_MODULE +/* If it is a module the kgdb_io_ops should be a static which + * is passed to the KGDB I/O initialization + */ +static struct kgdb_io local_kgdb_io_ops = { +#else /* ! CONFIG_KGDB_8250_MODULE */ +struct kgdb_io kgdb_io_ops = { +#endif /* ! CONFIG_KGD_8250_MODULE */ + .read_char = kgdb_get_debug_char, + .write_char = kgdb_put_debug_char, + .init = kgdb_init_io, + .late_init = kgdb8250_late_init, +}; + +/** + * kgdb8250_add_port - Define a serial port for use with KGDB + * @i: The index of the port being added + * @serial_req: The &struct uart_port describing the port + * + * On platforms where we must register the serial device + * dynamically, this is the best option if a platform also normally + * calls early_serial_setup(). + */ +void __init kgdb8250_add_port(int i, struct uart_port *serial_req) +{ + /* Make sure we've got the built-in data before we override. */ + kgdb8250_copy_rs_table(); + + /* Copy the whole thing over. */ + if (current_port != &kgdb8250_ports[i]) + memcpy(&kgdb8250_ports[i], serial_req, sizeof(struct uart_port)); +} + +/** + * kgdb8250_add_platform_port - Define a serial port for use with KGDB + * @i: The index of the port being added + * @p: The &struct plat_serial8250_port describing the port + * + * On platforms where we must register the serial device + * dynamically, this is the best option if a platform normally + * handles uart setup with an array of &struct plat_serial8250_port. + */ +void __init kgdb8250_add_platform_port(int i, struct plat_serial8250_port *p) +{ + /* Make sure we've got the built-in data before we override. */ + kgdb8250_copy_rs_table(); + + kgdb8250_ports[i].iobase = p->iobase; + kgdb8250_ports[i].membase = p->membase; + kgdb8250_ports[i].irq = p->irq; + kgdb8250_ports[i].uartclk = p->uartclk; + kgdb8250_ports[i].regshift = p->regshift; + kgdb8250_ports[i].iotype = p->iotype; + kgdb8250_ports[i].flags = p->flags; + kgdb8250_ports[i].mapbase = p->mapbase; +} + +/* + * Syntax for this cmdline option is: + * kgdb8250=,
,," + */ +static int __init kgdb8250_opt(char *str) +{ + /* We'll fill out and use the first slot. */ + current_port = &kgdb8250_ports[0]; + + if (!strncmp(str, "io", 2)) { + current_port->iotype = UPIO_PORT; + str += 2; + } else if (!strncmp(str, "mmap", 4)) { + current_port->iotype = UPIO_MEM; + current_port->flags |= UPF_IOREMAP; + str += 4; + } else if (!strncmp(str, "mmio", 4)) { + current_port->iotype = UPIO_MEM; + current_port->flags &= ~UPF_IOREMAP; + str += 4; + } else + goto errout; + + if (*str != ',') + goto errout; + str++; + + if (current_port->iotype == UPIO_PORT) + current_port->iobase = simple_strtoul(str, &str, 16); + else { + if (current_port->flags & UPF_IOREMAP) + current_port->mapbase = + (unsigned long) simple_strtoul(str, &str, 16); + else + current_port->membase = + (void *) simple_strtoul(str, &str, 16); + } + + if (*str != ',') + goto errout; + str++; + + kgdb8250_baud = simple_strtoul(str, &str, 10); + if (!kgdb8250_baud) + goto errout; + + if (*str != ',') + goto errout; + str++; + + current_port->irq = simple_strtoul(str, &str, 10); + +#ifdef CONFIG_KGDB_SIMPLE_SERIAL + should_copy_rs_table = 0; +#endif + + return 0; + + errout: + printk(KERN_ERR "Invalid syntax for option kgdb8250=\n"); + return 1; +} + +#ifdef CONFIG_KGDB_8250_MODULE +static void cleanup_kgdb8250(void) +{ + kgdb_unregister_io_module(&local_kgdb_io_ops); + + /* Clean up the irq and memory */ + free_irq(current_port->irq, current_port); + + if (kgdb8250_needs_request_mem_region) + release_mem_region(current_port->mapbase, + 8 << current_port->regshift); + /* Hook up the serial port back to what it was previously + * hooked up to. + */ +#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) + /* Give the port back to the 8250 driver. */ + serial8250_register_port(current_port); +#endif +} + +module_init(kgdb_init_io); +module_exit(cleanup_kgdb8250); +#else /* ! CONFIG_KGDB_8250_MODULE */ +early_param("kgdb8250", kgdb8250_opt); +#endif /* ! CONFIG_KGDB_8250_MODULE */ Index: linux-2.6.17-rc4/drivers/serial/Kconfig =================================================================== --- linux-2.6.17-rc4.orig/drivers/serial/Kconfig 2006-05-25 18:52:24.000000000 +0100 +++ linux-2.6.17-rc4/drivers/serial/Kconfig 2006-05-25 18:52:51.000000000 +0100 @@ -106,7 +106,7 @@ config SERIAL_8250_CS 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 driver Index: linux-2.6.17-rc4/drivers/serial/Makefile =================================================================== --- linux-2.6.17-rc4.orig/drivers/serial/Makefile 2006-05-25 18:52:24.000000000 +0100 +++ linux-2.6.17-rc4/drivers/serial/Makefile 2006-05-25 18:52:51.000000000 +0100 @@ -48,6 +48,7 @@ obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_ obj-$(CONFIG_SERIAL_ICOM) += icom.o obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o obj-$(CONFIG_SERIAL_MPSC) += mpsc.o +obj-$(CONFIG_KGDB_8250) += 8250_kgdb.o obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o obj-$(CONFIG_SERIAL_JSM) += jsm/ obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o Index: linux-2.6.17-rc4/drivers/serial/serial_core.c =================================================================== --- linux-2.6.17-rc4.orig/drivers/serial/serial_core.c 2006-05-25 18:52:24.000000000 +0100 +++ linux-2.6.17-rc4/drivers/serial/serial_core.c 2006-05-25 18:52:51.000000000 +0100 @@ -34,6 +34,7 @@ #include /* for serial_state and serial_icounter_struct */ #include #include +#include #include #include @@ -1666,6 +1667,9 @@ static int uart_line_info(char *buf, str port->iotype == UPIO_MEM ? port->mapbase : (unsigned long) port->iobase, port->irq); + if (port->iotype == UPIO_MEM) + ret += sprintf(buf+ret, " membase 0x%08lX", + (unsigned long) port->membase); if (port->type == PORT_UNKNOWN) { strcat(buf, "\n"); @@ -2029,7 +2033,8 @@ uart_report_port(struct uart_driver *drv case UPIO_MEM32: case UPIO_AU: snprintf(address, sizeof(address), - "MMIO 0x%lx", port->mapbase); + "MMIO map 0x%lx mem 0x%lx", port->mapbase, + (unsigned long) port->membase); break; default: strlcpy(address, "*unknown*", sizeof(address)); @@ -2274,6 +2279,12 @@ int uart_add_one_port(struct uart_driver */ port->flags &= ~UPF_DEAD; +#if defined(CONFIG_KGDB_8250) + /* Add any 8250-like ports we find later. */ + if (port->type <= PORT_MAX_8250) + kgdb8250_add_port(port->line, port); +#endif + out: mutex_unlock(&state->mutex); mutex_unlock(&port_mutex); Index: linux-2.6.17-rc4/include/linux/serial_8250.h =================================================================== --- linux-2.6.17-rc4.orig/include/linux/serial_8250.h 2006-05-25 18:52:24.000000000 +0100 +++ linux-2.6.17-rc4/include/linux/serial_8250.h 2006-05-25 18:52:51.000000000 +0100 @@ -56,6 +56,7 @@ struct uart_port; int serial8250_register_port(struct uart_port *); void serial8250_unregister_port(int line); +void serial8250_unregister_by_port(struct uart_port *port); void serial8250_suspend_port(int line); void serial8250_resume_port(int line); Index: linux-2.6.17-rc4/lib/Kconfig.debug =================================================================== --- linux-2.6.17-rc4.orig/lib/Kconfig.debug 2006-05-25 18:52:24.000000000 +0100 +++ linux-2.6.17-rc4/lib/Kconfig.debug 2006-05-25 18:52:51.000000000 +0100 @@ -258,7 +258,7 @@ config KGDB_CONSOLE choice prompt "Method for KGDB communication" depends on KGDB - default KGDB_ONLY_MODULES + default KGDB_8250_NOMODULE help There are a number of different ways in which you can communicate with KGDB. The most common is via serial, with the 8250 driver @@ -276,4 +276,60 @@ config KGDB_ONLY_MODULES Use only kernel modules to configure KGDB I/O after the kernel is booted. +config KGDB_8250_NOMODULE + bool "KGDB: On generic serial port (8250)" + select KGDB_8250 + help + Uses generic serial port (8250) to communicate with the host + GDB. This is independent of the normal (SERIAL_8250) driver + for this chipset. endchoice + +config KGDB_8250 + tristate "KGDB: On generic serial port (8250)" if !KGDB_8250_NOMODULE + depends on m && KGDB_ONLY_MODULES + help + Uses generic serial port (8250) to communicate with the host + GDB. This is independent of the normal (SERIAL_8250) driver + for this chipset. + +config KGDB_SIMPLE_SERIAL + bool "Simple selection of KGDB serial port" + depends on KGDB_8250_NOMODULE + default y + help + If you say Y here, you will only have to pick the baud rate + and port number that you wish to use for KGDB. Note that this + only works on architectures that register known serial ports + early on. If you say N, you will have to provide, either here + or on the command line, the type (I/O or MMIO), IRQ and + address to use. If in doubt, say Y. + +config KGDB_BAUDRATE + int "Debug serial port baud rate" + depends on (KGDB_8250 && KGDB_SIMPLE_SERIAL) + default "115200" + help + gdb and the kernel stub need to agree on the baud rate to be + used. Standard rates from 9600 to 115200 are allowed, and this + may be overridden via the commandline. + +config KGDB_PORT_NUM + int "Serial port number for KGDB" + range 0 1 if KGDB_MPSC + range 0 3 + depends on (KGDB_8250 && KGDB_SIMPLE_SERIAL) || KGDB_MPSC + default "1" + help + Pick the port number (0 based) for KGDB to use. + +config KGDB_8250_CONF_STRING + string "Configuration string for KGDB" + depends on KGDB_8250_NOMODULE && !KGDB_SIMPLE_SERIAL + default "io,2f8,115200,3" if X86 + help + The format of this string should be ,
,,. For example, to use the + serial port on an i386 box located at 0x2f8 and 115200 baud + on IRQ 3 at use: + io,2f8,115200,3