diff -r 47ca1724b31c xen/drivers/char/console.c --- a/xen/drivers/char/console.c Wed Jul 13 19:12:39 2005 +++ b/xen/drivers/char/console.c Wed Jul 13 17:07:27 2005 @@ -441,6 +441,22 @@ strcpy(printk_prefix, prefix); } +void use_serial_console(unsigned int index, char flag) +{ + if (index > 1) { + printk("ERROR: bad serial-interface index %d\n", index); + return; + } + sercon_handle = index; + + if (flag == 'H') + sercon_handle |= SERHND_HI; + else if (flag == 'L') + sercon_handle |= SERHND_LO; + + sercon_handle |= SERHND_COOKED; +} + void init_console(void) { char *p; diff -r 47ca1724b31c xen/drivers/char/ns16550.c --- a/xen/drivers/char/ns16550.c Wed Jul 13 19:12:39 2005 +++ b/xen/drivers/char/ns16550.c Wed Jul 13 17:07:27 2005 @@ -19,16 +19,6 @@ 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, irq; - unsigned long io_base; /* I/O port or memory-mapped I/O address. */ - char *remapped_io_base; /* Remapped virtual address of mmap I/O. */ - struct irqaction irqaction; -} ns16550_com[2] = { - { 0, 0, 0, 0, 4, 0x3f8 }, - { 0, 0, 0, 0, 3, 0x2f8 } -}; /* Register offsets */ #define RBR 0x00 /* receive buffer */ @@ -92,6 +82,30 @@ #define PARITY_MARK (5<<3) #define PARITY_SPACE (7<<3) +static struct ns16550 { + int baud, data_bits, parity, stop_bits, irq; + unsigned long io_base; /* I/O port or memory-mapped I/O address. */ + char *remapped_io_base; /* Remapped virtual address of mmap I/O. */ + struct irqaction irqaction; +} ns16550_com[2] = { + { + .baud = 0, + .data_bits = 8, + .parity = PARITY_NONE, + .stop_bits = 1, + .irq = 4, + .io_base = 0x3f8 + }, + { + .baud = 0, + .data_bits = 8, + .parity = PARITY_NONE, + .stop_bits = 1, + .irq = 3, + .io_base = 0x2f8 + }, +}; + static char ns_read_reg(struct ns16550 *uart, int reg) { if ( uart->remapped_io_base == NULL ) @@ -158,8 +172,10 @@ /* Line control and baud-rate generator. */ ns_write_reg(uart, LCR, lcr | LCR_DLAB); - ns_write_reg(uart, DLL, 115200/uart->baud); /* baud lo */ - ns_write_reg(uart, DLM, 0); /* baud hi */ + if (uart->baud) { + ns_write_reg(uart, DLL, 115200/uart->baud); /* baud lo */ + ns_write_reg(uart, DLM, 0); /* baud hi */ + } ns_write_reg(uart, LCR, lcr); /* parity, data, stop */ /* No flow ctrl: DTR and RTS are both wedged high to keep remote happy. */ @@ -213,6 +229,11 @@ .getc = ns16550_getc }; +void ns16550_port_register(unsigned int index) +{ + serial_register_uart(index, &ns16550_driver, &ns16550_com[index]); +} + #define PARSE_ERR(_f, _a...) \ do { \ printk( "ERROR: " _f "\n" , ## _a ); \ @@ -277,7 +298,48 @@ } } - serial_register_uart(uart - ns16550_com, &ns16550_driver, uart); + ns16550_port_register(uart - ns16550_com); +} + +void ns16550_port_config(unsigned int index, int baud, int data_bits, + char parity, int stop_bits, int irq, + ulong io_base) +{ + struct ns16550 *uart = &ns16550_com[index]; + + if (baud) + uart->baud = baud; + + if (data_bits) + uart->data_bits = data_bits; + + switch (parity) + { + case 'n': + uart->parity = PARITY_NONE; + break; + case 'o': + uart->parity = PARITY_ODD; + break; + case 'e': + uart->parity = PARITY_EVEN; + break; + case 'm': + uart->parity = PARITY_MARK; + break; + case 's': + uart->parity = PARITY_SPACE; + break; + } + + if (stop_bits) + uart->stop_bits = stop_bits; + + if (irq) + uart->irq = irq; + + if (io_base) + uart->io_base = io_base; } void ns16550_init(void) diff -r 47ca1724b31c xen/include/xen/console.h --- a/xen/include/xen/console.h Wed Jul 13 19:12:39 2005 +++ b/xen/include/xen/console.h Wed Jul 13 17:07:27 2005 @@ -16,6 +16,7 @@ long read_console_ring(char **, u32 *, int); void init_console(void); +void use_serial_console(unsigned int index, char flag); void console_endboot(int disable_vga); void console_force_unlock(void); diff -r 47ca1724b31c xen/include/xen/serial.h --- a/xen/include/xen/serial.h Wed Jul 13 19:12:39 2005 +++ b/xen/include/xen/serial.h Wed Jul 13 17:07:27 2005 @@ -114,6 +114,10 @@ * Initialisers for individual uart drivers. */ void ns16550_init(void); +void ns16550_port_register(unsigned int index); +void ns16550_port_config(unsigned int index, int baud, int data_bits, + char parity, int stop_bits, int irq, + ulong io_base); #endif /* __XEN_SERIAL_H__ */ diff -r 47ca1724b31c xen/arch/ppc/boot_of.c --- a/xen/arch/ppc/boot_of.c Wed Jul 13 19:12:39 2005 +++ b/xen/arch/ppc/boot_of.c Wed Jul 13 17:07:27 2005 @@ -22,8 +22,11 @@ #include #include #include +#include +#include #include #include +#include static ulong of_vec; static ulong of_msr; @@ -346,8 +349,6 @@ if (rc <= 0) { strcpy(cmdline, "xen console=com1"); } - /* Should really fidn this in OF tree add ",irq" when ready */ - strcat(cmdline, " com1=115200,8n1,0xf40003f8"); mbi->flags |= MBI_CMDLINE; mbi->cmdline = (u32)cmdline; @@ -655,9 +656,13 @@ int __init boot_of_serial(void) { - /* right now we are punting and using mambo writes which is the - * hardcoded setup */ - + /* XXX get base from ISA node in device tree */ + isa_io_base = 0xf4000000; + + /* XXX get values from serial node in device tree */ + ns16550_port_config(0, 0, 0, 0, 0, 10, 0); /* override irq */ + ns16550_port_register(0); + use_serial_console(0, 0); return 1; }