[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-ia64-devel] [PATCH] implemented input-side of hpsimserial driver on xen
Hi. Implemented xen hpsimsieral input routine. To use this CONFIG_XEN_CONSOLE_INPUT should be defined. NOTE: The modification of xen_do_IRQ() is a temporal work around. I think ns16550 driver also have similar problem on IA-64. diff -r 0255f48b757f -r 7f581d389113 xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Sun Dec 4 20:12:00 2005 +0100 +++ b/xen/arch/ia64/xen/domain.c Wed Dec 14 21:00:58 2005 +0900 @@ -961,7 +961,6 @@ #ifdef CLONE_DOMAIN0 if (d == dom0) #endif - serial_input_init(); if (d == dom0) { VCPU(v, delivery_mask[0]) = -1L; VCPU(v, delivery_mask[1]) = -1L; diff -r 0255f48b757f -r 7f581d389113 xen/arch/ia64/xen/hpsimserial.c --- a/xen/arch/ia64/xen/hpsimserial.c Sun Dec 4 20:12:00 2005 +0100 +++ b/xen/arch/ia64/xen/hpsimserial.c Wed Dec 14 21:00:58 2005 +0900 @@ -3,21 +3,158 @@ * * Copyright (C) 2004 Hewlett-Packard Co * Dan Magenheimer <dan.magenheimer@xxxxxx> + * Copyright (C) 2005 VA Linux Systema Japan K.K. + * Isaku Yamahata <yamahata at valinux.co.jp> */ #include <linux/config.h> #include <xen/sched.h> #include <xen/serial.h> +#include <xen/irq.h> +#include <asm/linux/asm/hw_irq.h> + #include "hpsim_ssc.h" -static void hp_ski_putc(struct serial_port *port, char c) +static struct hpsimserial { + int is_saved; + unsigned char save; + + int irq; + struct irqaction irqaction; +} hpsimserial; + +static char opt_hpsimserial[30] = ""; +string_param("hpsimserial", opt_hpsimserial); + +// return value +// 0: there is no char left. +// !0: there is char to be get. +static int +hp_ski_peek(struct hpsimserial* uart) +{ + if (!uart->is_saved) { + uart->save = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR); + if (uart->save) { + uart->is_saved = 1; + } + } + return uart->is_saved; +} + +static void +hp_ski_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs) +{ + struct serial_port *port = dev_id; + struct hpsimserial *uart = port->uart; + + while (hp_ski_peek(uart)) { + serial_rx_interrupt(port, regs); + } +} + +static void +hp_ski_init_preirq(struct serial_port *port) +{ + // nothing +} + +static void +hp_ski_init_postirq(struct serial_port *port) +{ + int rc; + struct hpsimserial* uart = port->uart; + + uart->irqaction.handler = hp_ski_interrupt; + uart->irqaction.name = "hpsimserial"; + uart->irqaction.dev_id = port; + if (uart->irq == 0) { + uart->irq = assign_irq_vector(AUTO_ASSIGN); + if (uart->irq < 0) { + panic("%s: out of interrupt vectors!\n", __func__); + } + } + + printk("hpsimserial: irq = %d 0x%x\n", uart->irq, uart->irq); + rc = setup_irq(uart->irq, &uart->irqaction); + if (rc) { + printk("ERROR: Failed to allocate hpsimserial IRQ %d 0x%x\n", + uart->irq, uart->irq); + } else { + port->rx = serial_rx; +#define KEYBOARD_INTR 3 /* must match with simulator! */ + ia64_ssc(KEYBOARD_INTR, uart->irq, 0, 0, SSC_CONNECT_INTERRUPT); + } +} + +static void +hp_ski_endboot(struct serial_port* port) +{ + // nothing +} + +static int +hp_ski_tx_empty() +{ + return 1; +} + +// return value +// 0: no char left +// !0: success to read char +static int +hp_ski_getc(struct serial_port *port, char *pc) +{ + struct hpsimserial* uart = port->uart; + + if (!uart->is_saved) { + uart->save = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR); + if (!uart->save) { + return 0; + } + } + + *pc = uart->save; + uart->is_saved = 0; + return 1; +} + +static void +hp_ski_putc(struct serial_port *port, char c) { ia64_ssc(c,0,0,0,SSC_PUTCHAR); } -static struct uart_driver hp_ski = { .putc = hp_ski_putc }; +static struct uart_driver hp_ski = { + .init_preirq = hp_ski_init_preirq, + .init_postirq = hp_ski_init_postirq, + .endboot = hp_ski_endboot, + .tx_empty = hp_ski_tx_empty, + .putc = hp_ski_putc, + .getc = hp_ski_getc +}; -void hpsim_serial_init(void) +static void +hp_ski_parse_config(struct hpsimserial* uart, const char* conf) { - serial_register_uart(0, &hp_ski, 0); + if (conf == NULL || *conf == '\0') { + return; + } + uart->irq = simple_strtoul(conf, &conf, 0); } + +void +hpsim_serial_init(void) +{ + hpsimserial.is_saved = 0; + hp_ski_parse_config(&hpsimserial, opt_hpsimserial); + serial_register_uart(0, &hp_ski, &hpsimserial); +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff -r 0255f48b757f -r 7f581d389113 xen/arch/ia64/xen/irq.c --- a/xen/arch/ia64/xen/irq.c Sun Dec 4 20:12:00 2005 +0100 +++ b/xen/arch/ia64/xen/irq.c Wed Dec 14 21:00:58 2005 +0900 @@ -1479,25 +1479,3 @@ } #endif - -#ifdef XEN -#ifdef IA64 -// this is a temporary hack until real console input is implemented -irqreturn_t guest_forward_keyboard_input(int irq, void *nada, struct pt_regs *regs) -{ - domain_pend_keyboard_interrupt(irq); -} - -void serial_input_init(void) -{ - int retval; - int irq = 0x30; // FIXME - - retval = request_irq(irq,guest_forward_keyboard_input,SA_INTERRUPT,"siminput",NULL); - if (retval) { - printk("serial_input_init: broken request_irq call\n"); - while(1); - } -} -#endif -#endif diff -r 0255f48b757f -r 7f581d389113 xen/arch/ia64/xen/xenirq.c --- a/xen/arch/ia64/xen/xenirq.c Sun Dec 4 20:12:00 2005 +0100 +++ b/xen/arch/ia64/xen/xenirq.c Wed Dec 14 21:00:58 2005 +0900 @@ -35,7 +35,8 @@ int xen_do_IRQ(ia64_vector vector) { - if (vector != IA64_TIMER_VECTOR && vector != IA64_IPI_VECTOR) { + if (vector != IA64_TIMER_VECTOR && vector != IA64_IPI_VECTOR && + vector != 0x30) {//XXX extern void vcpu_pend_interrupt(void *, int); #if 0 if (firsttime[vector]) { diff -r 0255f48b757f -r 7f581d389113 xen/drivers/char/console.c --- a/xen/drivers/char/console.c Sun Dec 4 20:12:00 2005 +0100 +++ b/xen/drivers/char/console.c Wed Dec 14 21:00:58 2005 +0900 @@ -286,7 +286,7 @@ send_guest_virq(dom0->vcpu[0], VIRQ_CONSOLE); } -static void serial_rx(char c, struct cpu_user_regs *regs) +void serial_rx(char c, struct cpu_user_regs *regs) { static int switch_code_count = 0; diff -r 0255f48b757f -r 7f581d389113 xen/include/xen/serial.h --- a/xen/include/xen/serial.h Sun Dec 4 20:12:00 2005 +0100 +++ b/xen/include/xen/serial.h Wed Dec 14 21:00:58 2005 +0900 @@ -14,6 +14,7 @@ /* Register a character-receive hook on the specified COM port. */ typedef void (*serial_rx_fn)(char, struct cpu_user_regs *); void serial_set_rx_handler(int handle, serial_rx_fn fn); +void serial_rx(char c, struct cpu_user_regs *regs);// default rx handler /* Number of characters we buffer for a polling receiver. */ #define SERIAL_RXBUFSZ 32 -- yamahata _______________________________________________ Xen-ia64-devel mailing list Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-ia64-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |