[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.