static void gdb_smp_pause(void);
static void gdb_smp_resume(void);
-static char opt_gdb[30] = "none";
+static char opt_gdb[30];
string_param("gdb", opt_gdb);
static void gdbstub_console_puts(const char *str);
void __init
initialise_gdb(void)
{
+ if ( *opt_gdb == '\0' )
+ return;
+
gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
- if ( gdb_ctx->serhnd != -1 )
- printk("GDB stub initialised.\n");
+ if ( gdb_ctx->serhnd == -1 )
+ {
+ printk("Bad gdb= option '%s'\n", opt_gdb);
+ return;
+ }
+
serial_start_sync(gdb_ctx->serhnd);
+
+ printk("GDB stub initialised.\n");
}
static void gdb_pause_this_cpu(void *unused)
{
if ( *p == ',' )
p++;
- if ( strncmp(p, "com", 3) == 0 )
- sercon_handle = serial_parse_handle(p);
- else if ( strncmp(p, "vga", 3) == 0 )
+ if ( !strncmp(p, "vga", 3) )
vga_init();
+ else if ( strncmp(p, "com", 3) ||
+ (sercon_handle = serial_parse_handle(p)) == -1 )
+ {
+ char *q = strchr(p, ',');
+ if ( q != NULL )
+ *q = '\0';
+ printk("Bad console= option '%s'\n", p);
+ if ( q != NULL )
+ *q = ',';
+ }
}
serial_set_rx_handler(sercon_handle, serial_rx);
#define MCR_DTR 0x01 /* Data Terminal Ready */
#define MCR_RTS 0x02 /* Request to Send */
#define MCR_OUT2 0x08 /* OUT2: interrupt mask */
+#define MCR_LOOP 0x10 /* Enable loopback test mode */
/* Line Status Register */
#define LSR_DR 0x01 /* Data ready */
return 0;
}
+static int check_existence(struct ns16550 *uart)
+{
+ unsigned char status, scratch, scratch2, scratch3;
+
+ /*
+ * Do a simple existence test first; if we fail this,
+ * there's no point trying anything else.
+ */
+ scratch = ns_read_reg(uart, IER);
+ ns_write_reg(uart, IER, 0);
+
+ /*
+ * Mask out IER[7:4] bits for test as some UARTs (e.g. TL
+ * 16C754B) allow only to modify them if an EFR bit is set.
+ */
+ scratch2 = ns_read_reg(uart, IER) & 0x0f;
+ ns_write_reg(uart, IER, 0x0F);
+ scratch3 = ns_read_reg(uart, IER) & 0x0f;
+ ns_write_reg(uart, IER, scratch);
+ if ( (scratch2 != 0) || (scratch3 != 0x0F) )
+ return 0;
+
+ /*
+ * Check to see if a UART is really there.
+ * Use loopback test mode.
+ */
+ ns_write_reg(uart, MCR, MCR_LOOP | 0x0A);
+ status = ns_read_reg(uart, MSR) & 0xF0;
+ return (status == 0x90);
+}
+
#define PARSE_ERR(_f, _a...) \
do { \
printk( "ERROR: " _f "\n" , ## _a ); \
PARSE_ERR("%d stop bits are unsupported.", uart->stop_bits);
if ( uart->io_base == 0 )
PARSE_ERR("I/O base address must be specified.");
+ if ( !check_existence(uart) )
+ PARSE_ERR("16550-compatible serial UART not present");
/* Register with generic serial driver. */
serial_register_uart(uart - ns16550_com, &ns16550_driver, uart);
{
int handle;
- /* Silently fail if user has explicitly requested no serial I/O. */
- if ( strcmp(conf, "none") == 0 )
- return -1;
-
- if ( strncmp(conf, "com", 3) != 0 )
+ if ( strncmp(conf, "com", 3) )
goto fail;
switch ( conf[3] )
goto fail;
}
+ if ( !com[handle].driver )
+ goto fail;
+
if ( conf[4] == 'H' )
handle |= SERHND_HI;
else if ( conf[4] == 'L' )
return handle;
fail:
- printk("ERROR: bad serial-interface specification '%s'\n", conf);
return -1;
}