multiple serial port support - terminal init fix
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Tue, 24 Aug 2004 21:13:40 +0000 (21:13 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Tue, 24 Aug 2004 21:13:40 +0000 (21:13 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1048 c046a42c-6fe2-441c-8c8c-71466251a162

hw/pc.c
hw/ppc_chrp.c
hw/ppc_prep.c
vl.c
vl.h

diff --git a/hw/pc.c b/hw/pc.c
index 0fd7b87b26a960e388bfd0db675b87b7e717a0d0..f59ea2397fb5d52aa9816c3ab4795680e5b70ecf 100644 (file)
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -314,9 +314,12 @@ static const int ide_irq[2] = { 14, 15 };
 
 #define NE2000_NB_MAX 6
 
-static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
+static int ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
 static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
 
+static int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
+static int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
+
 /* PC hardware initialisation */
 void pc_init(int ram_size, int vga_ram_size, int boot_device,
              DisplayState *ds, const char **fd_filename, int snapshot,
@@ -471,7 +474,11 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
     pic_init();
     pit = pit_init(0x40, 0);
 
-    serial_init(0x3f8, 4, serial_hd);
+    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
+        if (serial_hds[i]) {
+            serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
+        }
+    }
 
     if (pci_enabled) {
         for(i = 0; i < nb_nics; i++) {
index f532fe101926381f8a0bdbc9f4baeffc2faf1856..cf3a5f32fa7dba9bfa658b9754ca66d9eb11b592 100644 (file)
@@ -200,7 +200,7 @@ void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
     pic_init();
 
     /* XXX: use Mac Serial port */
-    serial_init(0x3f8, 4, serial_hd);
+    serial_init(0x3f8, 4, serial_hds[0]);
 
     for(i = 0; i < nb_nics; i++) {
         pci_ne2000_init(pci_bus, &nd_table[i]);
index eeb5a36095a55fbd5ea601b8ce575fe46a495765..c93b72faeb5526dd3b754e0cebfd4df152f41c27 100644 (file)
@@ -492,7 +492,7 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
     pic_init();
     //    pit = pit_init(0x40, 0);
 
-    serial_init(0x3f8, 4, serial_hd);
+    serial_init(0x3f8, 4, serial_hds[0]);
     nb_nics1 = nb_nics;
     if (nb_nics1 > NE2000_NB_MAX)
         nb_nics1 = NE2000_NB_MAX;
diff --git a/vl.c b/vl.c
index 646d1ff94753aac251b25686f766028c2f251857..4d274478eba0a2bae60b7aa19489d879214c30e2 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -128,6 +128,7 @@ int graphic_width = 800;
 int graphic_height = 600;
 int graphic_depth = 15;
 TextConsole *vga_console;
+CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 
 /***********************************************************/
 /* x86 ISA bus support */
@@ -1166,6 +1167,43 @@ static void stdio_read(void *opaque, const uint8_t *buf, int size)
         stdio_received_byte(buf[i]);
 }
 
+/* init terminal so that we can grab keys */
+static struct termios oldtty;
+static int old_fd0_flags;
+
+static void term_exit(void)
+{
+    tcsetattr (0, TCSANOW, &oldtty);
+    fcntl(0, F_SETFL, old_fd0_flags);
+}
+
+static void term_init(void)
+{
+    struct termios tty;
+
+    tcgetattr (0, &tty);
+    oldtty = tty;
+    old_fd0_flags = fcntl(0, F_GETFL);
+
+    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
+                          |INLCR|IGNCR|ICRNL|IXON);
+    tty.c_oflag |= OPOST;
+    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
+    /* if graphical mode, we allow Ctrl-C handling */
+    if (nographic)
+        tty.c_lflag &= ~ISIG;
+    tty.c_cflag &= ~(CSIZE|PARENB);
+    tty.c_cflag |= CS8;
+    tty.c_cc[VMIN] = 1;
+    tty.c_cc[VTIME] = 0;
+    
+    tcsetattr (0, TCSANOW, &tty);
+
+    atexit(term_exit);
+
+    fcntl(0, F_SETFL, O_NONBLOCK);
+}
+
 CharDriverState *qemu_chr_open_stdio(void)
 {
     CharDriverState *chr;
@@ -1183,6 +1221,10 @@ CharDriverState *qemu_chr_open_stdio(void)
         chr = qemu_chr_open_fd(0, 1);
     }
     stdio_clients[stdio_nb_clients++] = chr;
+    if (stdio_nb_clients == 1) {
+        /* set the terminal in raw mode */
+        term_init();
+    }
     return chr;
 }
 
@@ -1449,57 +1491,6 @@ static int net_fd_init(NetDriverState *nd, int fd)
 /***********************************************************/
 /* dumb display */
 
-#ifdef _WIN32
-
-static void term_exit(void)
-{
-}
-
-static void term_init(void)
-{
-}
-
-#else
-
-/* init terminal so that we can grab keys */
-static struct termios oldtty;
-static int old_fd0_flags;
-
-static void term_exit(void)
-{
-    tcsetattr (0, TCSANOW, &oldtty);
-    fcntl(0, F_SETFL, old_fd0_flags);
-}
-
-static void term_init(void)
-{
-    struct termios tty;
-
-    tcgetattr (0, &tty);
-    oldtty = tty;
-    old_fd0_flags = fcntl(0, F_GETFL);
-
-    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
-                          |INLCR|IGNCR|ICRNL|IXON);
-    tty.c_oflag |= OPOST;
-    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
-    /* if graphical mode, we allow Ctrl-C handling */
-    if (nographic)
-        tty.c_lflag &= ~ISIG;
-    tty.c_cflag &= ~(CSIZE|PARENB);
-    tty.c_cflag |= CS8;
-    tty.c_cc[VMIN] = 1;
-    tty.c_cc[VTIME] = 0;
-    
-    tcsetattr (0, TCSANOW, &tty);
-
-    atexit(term_exit);
-
-    fcntl(0, F_SETFL, O_NONBLOCK);
-}
-
-#endif
-
 static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
 {
 }
@@ -1531,7 +1522,8 @@ static void host_segv_handler(int host_signum, siginfo_t *info,
 {
     if (cpu_signal_handler(host_signum, info, puc))
         return;
-    term_exit();
+    if (stdio_nb_clients > 0)
+        term_exit();
     abort();
 }
 #endif
@@ -2568,8 +2560,9 @@ int main(int argc, char **argv)
     const char *r, *optarg;
     CharDriverState *monitor_hd;
     char monitor_device[128];
-    char serial_device[128];
-
+    char serial_devices[MAX_SERIAL_PORTS][128];
+    int serial_device_index;
+    
 #if !defined(CONFIG_SOFTMMU)
     /* we never want that malloc() uses mmap() */
     mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
@@ -2594,8 +2587,12 @@ int main(int argc, char **argv)
     has_cdrom = 1;
     cyls = heads = secs = 0;
     pstrcpy(monitor_device, sizeof(monitor_device), "vc");
-    pstrcpy(serial_device, sizeof(serial_device), "vc");
 
+    pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
+    for(i = 1; i < MAX_SERIAL_PORTS; i++)
+        serial_devices[i][0] = '\0';
+    serial_device_index = 0;
+    
     nb_tun_fds = 0;
     net_if_type = -1;
     nb_nics = 1;
@@ -2674,7 +2671,7 @@ int main(int argc, char **argv)
                 break;
             case QEMU_OPTION_nographic:
                 pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
-                pstrcpy(serial_device, sizeof(serial_device), "stdio");
+                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
                 nographic = 1;
                 break;
             case QEMU_OPTION_kernel:
@@ -2865,7 +2862,13 @@ int main(int argc, char **argv)
                 pstrcpy(monitor_device, sizeof(monitor_device), optarg);
                 break;
             case QEMU_OPTION_serial:
-                pstrcpy(serial_device, sizeof(serial_device), optarg);
+                if (serial_device_index >= MAX_SERIAL_PORTS) {
+                    fprintf(stderr, "qemu: too many serial ports\n");
+                    exit(1);
+                }
+                pstrcpy(serial_devices[serial_device_index], 
+                        sizeof(serial_devices[0]), optarg);
+                serial_device_index++;
                 break;
             }
         }
@@ -3066,14 +3069,18 @@ int main(int argc, char **argv)
     }
     monitor_init(monitor_hd, !nographic);
 
-    serial_hd = qemu_chr_open(serial_device);
-    if (!serial_hd) {
-        fprintf(stderr, "qemu: could not open serial device '%s'\n", serial_device);
-        exit(1);
+    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
+        if (serial_devices[i][0] != '\0') {
+            serial_hds[i] = qemu_chr_open(serial_devices[i]);
+            if (!serial_hds[i]) {
+                fprintf(stderr, "qemu: could not open serial device '%s'\n", 
+                        serial_devices[i]);
+                exit(1);
+            }
+            if (!strcmp(serial_devices[i], "vc"))
+                qemu_chr_printf(serial_hds[i], "serial%d console\n", i);
+        }
     }
-    if (!strcmp(serial_device, "vc"))
-        qemu_chr_printf(serial_hd, "serial0 console\n");
-    
 
     /* setup cpu signal handlers for MMU / self modifying code handling */
 #if !defined(CONFIG_SOFTMMU)
@@ -3142,11 +3149,9 @@ int main(int argc, char **argv)
         } else {
             printf("Waiting gdb connection on port %d\n", gdbstub_port);
         }
-        term_init();
     } else 
 #endif
     {
-        term_init();
         /* XXX: simplify init */
         read_passwords();
         if (start_emulation) {
diff --git a/vl.h b/vl.h
index 485ccc020c69e8ad11b96b15d7d517a0d5e70ab9..1f1e9e4242f4073b9878aa6024bac197c5adf67d 100644 (file)
--- a/vl.h
+++ b/vl.h
@@ -200,8 +200,6 @@ void qemu_chr_add_read_handler(CharDriverState *s,
                                IOReadHandler *fd_read, void *opaque);
 void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event);
                                
-CharDriverState *serial_hd;
-
 /* consoles */
 
 typedef struct DisplayState DisplayState;
@@ -214,6 +212,12 @@ int is_active_console(TextConsole *s);
 CharDriverState *text_console_init(DisplayState *ds);
 void console_select(unsigned int index);
 
+/* serial ports */
+
+#define MAX_SERIAL_PORTS 4
+
+extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
+
 /* network redirectors support */
 
 #define MAX_NICS 8