ChangeSet 1.1586, 2005/05/28 22:18:17+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx
Clean up serial driver in Xen: separate ns16550 driver from generic
serial code.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
b/xen/arch/ia64/xensetup.c | 3
b/xen/arch/x86/cdb.c | 12 -
b/xen/arch/x86/setup.c | 5
b/xen/drivers/char/console.c | 21 --
b/xen/drivers/char/ns16550.c | 263 ++++++++++++++++++++++++++
b/xen/drivers/char/serial.c | 404 ++++++++++------------------------------
b/xen/include/asm-ia64/config.h | 3
b/xen/include/asm-ia64/serial.h | 14 -
b/xen/include/xen/console.h | 4
b/xen/include/xen/serial.h | 129 ++++--------
xen/include/asm-x86/serial.h | 22 --
11 files changed, 437 insertions(+), 443 deletions(-)
diff -Nru a/xen/arch/ia64/xensetup.c b/xen/arch/ia64/xensetup.c
--- a/xen/arch/ia64/xensetup.c 2005-05-28 18:03:19 -04:00
+++ b/xen/arch/ia64/xensetup.c 2005-05-28 18:03:19 -04:00
@@ -154,7 +154,8 @@
early_setup_arch(&cmdline);
/* We initialise the serial devices very early so we can get debugging. */
- serial_init_stage1();
+ ns16550_init();
+ serial_init_preirq();
init_console();
set_printk_prefix("(XEN) ");
diff -Nru a/xen/arch/x86/cdb.c b/xen/arch/x86/cdb.c
--- a/xen/arch/x86/cdb.c 2005-05-28 18:03:19 -04:00
+++ b/xen/arch/x86/cdb.c 2005-05-28 18:03:19 -04:00
@@ -91,11 +91,11 @@
u8 ch;
/* Skip over everything up to the first '$' */
- while ((ch = irq_serial_getc(ctx->serhnd)) != '$')
+ while ((ch = serial_getc(ctx->serhnd)) != '$')
;
csum = 0;
for (count = 0; count < 4096; count++) {
- ch = irq_serial_getc(ctx->serhnd);
+ ch = serial_getc(ctx->serhnd);
if (ch == '#')
break;
recv_buf[count] = ch;
@@ -106,8 +106,8 @@
return -1;
}
recv_buf[count] = 0;
- received_csum = hex_char_val(irq_serial_getc(ctx->serhnd)) * 16 +
- hex_char_val(irq_serial_getc(ctx->serhnd));
+ received_csum = hex_char_val(serial_getc(ctx->serhnd)) * 16 +
+ hex_char_val(serial_getc(ctx->serhnd));
if (received_csum == csum) {
return 0;
} else {
@@ -163,7 +163,7 @@
xendbg_put_char('#', ctx);
xendbg_send(buf, 2, ctx);
- ch = irq_serial_getc(ctx->serhnd);
+ ch = serial_getc(ctx->serhnd);
if (ch == '+')
return 0;
else
@@ -394,7 +394,7 @@
{
if (!strcmp(opt_cdb, "none"))
return 0;
- xdb_ctx.serhnd = parse_serial_handle(opt_cdb);
+ xdb_ctx.serhnd = serial_parse_handle(opt_cdb);
if (xdb_ctx.serhnd == -1)
panic("Can't parse %s as CDB serial info.\n", opt_cdb);
diff -Nru a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c 2005-05-28 18:03:19 -04:00
+++ b/xen/arch/x86/setup.c 2005-05-28 18:03:19 -04:00
@@ -216,7 +216,7 @@
initialize_keytable();
- serial_init_stage2();
+ serial_init_postirq();
init_xen_time();
@@ -263,7 +263,8 @@
smp_prepare_boot_cpu();
/* We initialise the serial devices very early so we can get debugging. */
- serial_init_stage1();
+ ns16550_init();
+ serial_init_preirq();
init_console();
diff -Nru a/xen/drivers/char/console.c b/xen/drivers/char/console.c
--- a/xen/drivers/char/console.c 2005-05-28 18:03:19 -04:00
+++ b/xen/drivers/char/console.c 2005-05-28 18:03:19 -04:00
@@ -260,7 +260,7 @@
}
}
-static void __serial_rx(unsigned char c, struct cpu_user_regs *regs)
+static void __serial_rx(char c, struct cpu_user_regs *regs)
{
if ( xen_rx )
return handle_keypress(c, regs);
@@ -272,7 +272,7 @@
send_guest_virq(dom0->exec_domain[0], VIRQ_CONSOLE);
}
-static void serial_rx(unsigned char c, struct cpu_user_regs *regs)
+static void serial_rx(char c, struct cpu_user_regs *regs)
{
static int switch_code_count = 0;
@@ -416,7 +416,7 @@
if ( *p == ',' )
p++;
if ( strncmp(p, "com", 3) == 0 )
- sercon_handle = parse_serial_handle(p);
+ sercon_handle = serial_parse_handle(p);
else if ( strncmp(p, "vga", 3) == 0 )
vgacon_enabled = 1;
}
@@ -463,21 +463,6 @@
void console_force_lock(void)
{
spin_lock(&console_lock);
-}
-
-void console_putc(char c)
-{
- serial_putc(sercon_handle, c);
-}
-
-int console_getc(void)
-{
- return serial_getc(sercon_handle);
-}
-
-int irq_console_getc(void)
-{
- return irq_serial_getc(sercon_handle);
}
diff -Nru a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/xen/drivers/char/ns16550.c 2005-05-28 18:03:19 -04:00
@@ -0,0 +1,263 @@
+/******************************************************************************
+ * ns16550.c
+ *
+ * Driver for 16550-series UARTs. This driver is to be kept within Xen as
+ * it permits debugging of seriously-toasted machines (e.g., in situations
+ * where a device driver within a guest OS would be inaccessible).
+ *
+ * Copyright (c) 2003-2005, K A Fraser
+ */
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/irq.h>
+#include <xen/sched.h>
+#include <xen/serial.h>
+#include <asm/io.h>
+
+/* Config serial port with a string <baud>,DPS,<io-base>,<irq>. */
+static char opt_com1[30] = "", opt_com2[30] = "";
+string_param("com1", opt_com1);
+string_param("com2", opt_com2);
+
+static struct ns16550 {
+ int baud, data_bits, parity, stop_bits, io_base, irq;
+ struct irqaction irqaction;
+} ns16550_com[2] = {
+ { 0, 0, 0, 0, 0x3f8, 4 },
+ { 0, 0, 0, 0, 0x2f8, 3 }
+};
+
+/* Register offsets */
+#define RBR 0x00 /* receive buffer */
+#define THR 0x00 /* transmit holding */
+#define IER 0x01 /* interrupt enable */
+#define IIR 0x02 /* interrupt identity */
+#define FCR 0x02 /* FIFO control */
+#define LCR 0x03 /* line control */
+#define MCR 0x04 /* Modem control */
+#define LSR 0x05 /* line status */
+#define MSR 0x06 /* Modem status */
+#define DLL 0x00 /* divisor latch (ls) (DLAB=1) */
+#define DLM 0x01 /* divisor latch (ms) (DLAB=1) */
+
+/* Interrupt Enable Register */
+#define IER_ERDAI 0x01 /* rx data recv'd */
+#define IER_ETHREI 0x02 /* tx reg. empty */
+#define IER_ELSI 0x04 /* rx line status */
+#define IER_EMSI 0x08 /* MODEM status */
+
+/* FIFO control register */
+#define FCR_ENABLE 0x01 /* enable FIFO */
+#define FCR_CLRX 0x02 /* clear Rx FIFO */
+#define FCR_CLTX 0x04 /* clear Tx FIFO */
+#define FCR_DMA 0x10 /* enter DMA mode */
+#define FCR_TRG1 0x00 /* Rx FIFO trig lev 1 */
+#define FCR_TRG4 0x40 /* Rx FIFO trig lev 4 */
+#define FCR_TRG8 0x80 /* Rx FIFO trig lev 8 */
+#define FCR_TRG14 0xc0 /* Rx FIFO trig lev 14 */
+
+/* Line control register */
+#define LCR_DLAB 0x80 /* Divisor Latch Access */
+
+/* Modem Control Register */
+#define MCR_DTR 0x01 /* Data Terminal Ready */
+#define MCR_RTS 0x02 /* Request to Send */
+#define MCR_OUT2 0x08 /* OUT2: interrupt mask */
+
+/* Line Status Register */
+#define LSR_DR 0x01 /* Data ready */
+#define LSR_OE 0x02 /* Overrun */
+#define LSR_PE 0x04 /* Parity error */
+#define LSR_FE 0x08 /* Framing error */
+#define LSR_BI 0x10 /* Break */
+#define LSR_THRE 0x20 /* Xmit hold reg empty */
+#define LSR_TEMT 0x40 /* Xmitter empty */
+#define LSR_ERR 0x80 /* Error */
+
+/* These parity settings can be ORed directly into the LCR. */
+#define PARITY_NONE (0<<3)
+#define PARITY_ODD (1<<3)
+#define PARITY_EVEN (3<<3)
+#define PARITY_MARK (5<<3)
+#define PARITY_SPACE (7<<3)
+
+static void ns16550_interrupt(
+ int irq, void *dev_id, struct cpu_user_regs *regs)
+{
+ serial_rx_interrupt(dev_id, regs);
+}
+
+static void ns16550_putc(struct serial_port *port, char c)
+{
+ struct ns16550 *uart = port->uart;
+
+ while ( !(inb(uart->io_base + LSR) & LSR_THRE) )
+ cpu_relax();
+
+ outb(c, uart->io_base + THR);
+}
+
+static int ns16550_getc(struct serial_port *port, char *pc)
+{
+ struct ns16550 *uart = port->uart;
+
+ if ( !(inb(uart->io_base + LSR) & LSR_DR) )
+ return 0;
+
+ *pc = inb(uart->io_base + RBR);
+ return 1;
+}
+
+static void ns16550_init_preirq(struct serial_port *port)
+{
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|