qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] Serial port hacking -- Fix verified for Windows Guest (


From: Fabrice Bellard
Subject: Re: [Qemu-devel] Serial port hacking -- Fix verified for Windows Guest (kindof ;)
Date: Mon, 23 Aug 2004 21:00:38 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624

OK for the idea of several serial ports, but for consistency I prefer to add several '-serial' options. I'll make an implementation soon.

Fabrice.

Darryl Dixon wrote:
  Hi All,

I concur with Nile and Hampa (thanks Hampa!) that Hampa's patch works successfully for a Windows guest, however I will add the rider that whatever the guest OS is expecting in the form of Hardware Flow Control from the UART still does not work, but No Flow Control and Software Flow Control (Xon/Xoff) DO both work now with this patch. Hurray! :) Unfortunately this means that the guest OS still can't quite drive the Host's modem ;) Ahh well :)

I have rewritten my *original* patch to make it fit more nicely with the other command line options that qemu provides and attach it below. It adds the ability to add up to a possible 4 guest com ports at the normal memory addresses and fairly standard IRQs (I have integrated the changes with the ppc stuff for the first, builtin, com port, but because I am unfamiliar with ppc hardware I didn't want to add the other three extra ports until someone had verified that they'll be OK; if someone can confirm that the three extra ports as defined for the pc will be OK in the ppc machine I'll add them there, too.). This patch cleans up the command line options for serial devices also: -serial1 'dev' <------ serial1 is always connected regardless, so this option is only to redirect it if you want it to go somewhere other than the vc -serial2 'dev' -serial3 'dev' -serial4 'dev' <--- these options will turn on the designated guest com port and connect it to char device 'dev'


Enjoy,
D





On Fri, 2004-08-20 at 05:15, Nile Geisinger wrote:

/Thanks Hampa!

I tested the patch with Darryl's patch, a Linux host and Linux guest, and the test programs that were posted earlier (with some slight modifications to poll for file events to prevent data loss). All tests passed perfectly.

great work,

Nile




_______________________________________________
Qemu-devel mailing list
address@hidden/ / http://lists.nongnu.org/mailman/listinfo/qemu-devel <http://lists.nongnu.org/mailman/listinfo/qemu-devel>/

--
Darryl Dixon < address@hidden <mailto:address@hidden>>



------------------------------------------------------------------------

diff -ru qemu-snapshot-2004-08-16_23/hw/pc.c 
qemu-snapshot-2004-08-16_23-testserial/hw/pc.c
--- qemu-snapshot-2004-08-16_23/hw/pc.c 2004-07-15 05:28:12.000000000 +1200
+++ qemu-snapshot-2004-08-16_23-testserial/hw/pc.c      2004-08-20 
14:19:50.830140666 +1200
@@ -471,7 +471,21 @@
     pic_init();
     pit = pit_init(0x40, 0);
- serial_init(0x3f8, 4, serial_hd);
+    /* register each com port:
+     * the memory address are Well Defined but
+     * the IRQs are a matter of preference and
+     * general consensus
+     */
+    serial_init(0x3f8, 4, serial1_hd); /* serial1 is always on */
+    if (init_serial2_device) {
+        serial_init(0x2f8, 3, serial2_hd);
+    }
+    if (init_serial3_device) {
+        serial_init(0x3e8, 5, serial3_hd);
+    }
+    if (init_serial4_device) {
+        serial_init(0x2e8, 9, serial4_hd);
+    }
if (pci_enabled) {
         for(i = 0; i < nb_nics; i++) {
diff -ru qemu-snapshot-2004-08-16_23/hw/ppc_chrp.c 
qemu-snapshot-2004-08-16_23-testserial/hw/ppc_chrp.c
--- qemu-snapshot-2004-08-16_23/hw/ppc_chrp.c   2004-07-15 05:28:13.000000000 
+1200
+++ qemu-snapshot-2004-08-16_23-testserial/hw/ppc_chrp.c        2004-08-20 
14:50:41.827364816 +1200
@@ -200,7 +200,7 @@
     pic_init();
/* XXX: use Mac Serial port */
-    serial_init(0x3f8, 4, serial_hd);
+    serial_init(0x3f8, 4, serial1_hd);
for(i = 0; i < nb_nics; i++) {
         pci_ne2000_init(pci_bus, &nd_table[i]);
diff -ru qemu-snapshot-2004-08-16_23/hw/ppc_prep.c 
qemu-snapshot-2004-08-16_23-testserial/hw/ppc_prep.c
--- qemu-snapshot-2004-08-16_23/hw/ppc_prep.c   2004-07-15 05:28:13.000000000 
+1200
+++ qemu-snapshot-2004-08-16_23-testserial/hw/ppc_prep.c        2004-08-20 
14:49:47.155402748 +1200
@@ -492,7 +492,7 @@
     pic_init();
     //    pit = pit_init(0x40, 0);
- serial_init(0x3f8, 4, serial_hd);
+    serial_init(0x3f8, 4, serial1_hd);
     nb_nics1 = nb_nics;
     if (nb_nics1 > NE2000_NB_MAX)
         nb_nics1 = NE2000_NB_MAX;
Only in qemu-snapshot-2004-08-16_23-testserial: qemu.1
Only in qemu-snapshot-2004-08-16_23-testserial: qemu-doc.html
Only in qemu-snapshot-2004-08-16_23-testserial: qemu-tech.html
diff -ru qemu-snapshot-2004-08-16_23/vl.c 
qemu-snapshot-2004-08-16_23-testserial/vl.c
--- qemu-snapshot-2004-08-16_23/vl.c    2004-08-04 10:09:30.000000000 +1200
+++ qemu-snapshot-2004-08-16_23-testserial/vl.c 2004-08-20 14:56:17.390009809 
+1200
@@ -1222,8 +1222,17 @@
         return qemu_chr_open_stdio();
} else #endif
-    {
+    if (!strcmp(filename, "NULL")) {
+        /* Shouldn't ever end up in here */
         return NULL;
+    } else {
+        int fdesc;
+        fdesc = open(filename, O_RDWR);
+        if (fdesc >= 0) {
+            return qemu_chr_open_fd(fdesc, fdesc);
+        } else {
+            return NULL;
+        }
     }
 }
@@ -2352,7 +2361,10 @@
            "\n"
            "Debug/Expert options:\n"
            "-monitor dev    redirect the monitor to char device 'dev'\n"
-           "-serial dev     redirect the serial port to char device 'dev'\n"
+           "-serial1 dev     redirect the guest com1 port to char device 
'dev'\n"
+           "-serial2 dev     initialise and redirect the guest com2 port to char 
device 'dev'\n"
+           "-serial3 dev     initialise and redirect the guest com3 port to char 
device 'dev'\n"
+           "-serial4 dev     initialise and redirect the guest com4 port to char 
device 'dev'\n"
            "-S              freeze CPU at startup (use 'c' to start 
execution)\n"
            "-s              wait gdb connection to port %d\n"
            "-p port         change gdb connection port\n"
@@ -2437,7 +2449,10 @@
     QEMU_OPTION_g,
     QEMU_OPTION_std_vga,
     QEMU_OPTION_monitor,
-    QEMU_OPTION_serial,
+    QEMU_OPTION_serial1,
+    QEMU_OPTION_serial2,
+    QEMU_OPTION_serial3,
+    QEMU_OPTION_serial4,
 };
typedef struct QEMUOption {
@@ -2490,7 +2505,10 @@
     { "isa", 0, QEMU_OPTION_isa },
     { "std-vga", 0, QEMU_OPTION_std_vga },
     { "monitor", 1, QEMU_OPTION_monitor },
-    { "serial", 1, QEMU_OPTION_serial },
+    { "serial1", HAS_ARG, QEMU_OPTION_serial1 },
+    { "serial2", HAS_ARG, QEMU_OPTION_serial2 },
+    { "serial3", HAS_ARG, QEMU_OPTION_serial3 },
+    { "serial4", HAS_ARG, QEMU_OPTION_serial4 },
/* temporary options */
     { "pci", 0, QEMU_OPTION_pci },
@@ -2568,8 +2586,11 @@
     const char *r, *optarg;
     CharDriverState *monitor_hd;
     char monitor_device[128];
-    char serial_device[128];
-
+    char serial1_device[128];
+    char serial2_device[128];
+    char serial3_device[128];
+    char serial4_device[128];
+ #if !defined(CONFIG_SOFTMMU)
     /* we never want that malloc() uses mmap() */
     mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
@@ -2594,7 +2615,14 @@
     has_cdrom = 1;
     cyls = heads = secs = 0;
     pstrcpy(monitor_device, sizeof(monitor_device), "vc");
-    pstrcpy(serial_device, sizeof(serial_device), "vc");
+    /* Because serial1 is on by default we initialise it to the vc */
+    pstrcpy(serial1_device, sizeof(serial1_device), "vc");
+    pstrcpy(serial2_device, sizeof(serial2_device), "NULL");
+    pstrcpy(serial3_device, sizeof(serial3_device), "NULL");
+    pstrcpy(serial4_device, sizeof(serial4_device), "NULL");
+    init_serial2_device = 0;
+    init_serial3_device = 0;
+    init_serial4_device = 0;
nb_tun_fds = 0;
     net_if_type = -1;
@@ -2674,7 +2702,7 @@
                 break;
             case QEMU_OPTION_nographic:
                 pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
-                pstrcpy(serial_device, sizeof(serial_device), "stdio");
+                pstrcpy(serial1_device, sizeof(serial1_device), "stdio");
                 nographic = 1;
                 break;
             case QEMU_OPTION_kernel:
@@ -2864,8 +2892,20 @@
             case QEMU_OPTION_monitor:
                 pstrcpy(monitor_device, sizeof(monitor_device), optarg);
                 break;
-            case QEMU_OPTION_serial:
-                pstrcpy(serial_device, sizeof(serial_device), optarg);
+            case QEMU_OPTION_serial1:
+                pstrcpy(serial1_device, sizeof(serial1_device), optarg);
+                break;
+            case QEMU_OPTION_serial2:
+                pstrcpy(serial2_device, sizeof(serial2_device), optarg);
+                init_serial2_device = 1;
+                break;
+            case QEMU_OPTION_serial3:
+                pstrcpy(serial3_device, sizeof(serial3_device), optarg);
+                init_serial3_device = 1;
+                break;
+            case QEMU_OPTION_serial4:
+                pstrcpy(serial4_device, sizeof(serial4_device), optarg);
+                init_serial4_device = 1;
                 break;
             }
         }
@@ -3065,15 +3105,41 @@
         exit(1);
     }
     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);
+ + /* Initialise all relevant serial ports */
+    /* serial1 is always connected by default */
+    serial1_hd = qemu_chr_open(serial1_device);
+    if (!serial1_hd) {
+        fprintf(stderr, "qemu: could not open serial1 device '%s'\n", 
serial1_device);
         exit(1);
     }
-    if (!strcmp(serial_device, "vc"))
-        qemu_chr_printf(serial_hd, "serial0 console\n");
+    if (!strcmp(serial1_device, "vc"))
+        qemu_chr_printf(serial1_hd, "serial1 console\n");
+ if (init_serial2_device) {
+        serial2_hd = qemu_chr_open(serial2_device);
+        if (!serial2_hd) {
+            fprintf(stderr, "qemu: could not open serial2 device '%s'\n", 
serial2_device);
+            exit(1);
+        }
+    }
+
+    if (init_serial3_device) {
+        serial3_hd = qemu_chr_open(serial3_device);
+        if (!serial3_hd) {
+            fprintf(stderr, "qemu: could not open serial3 device '%s'\n", 
serial3_device);
+            exit(1);
+        }
+    }
+
+    if (init_serial4_device) {
+        serial4_hd = qemu_chr_open(serial4_device);
+        if (!serial4_hd) {
+            fprintf(stderr, "qemu: could not open serial4 device '%s'\n", 
serial4_device);
+            exit(1);
+        }
+    }
+
/* setup cpu signal handlers for MMU / self modifying code handling */
 #if !defined(CONFIG_SOFTMMU)
diff -ru qemu-snapshot-2004-08-16_23/vl.h 
qemu-snapshot-2004-08-16_23-testserial/vl.h
--- qemu-snapshot-2004-08-16_23/vl.h    2004-08-04 09:15:11.000000000 +1200
+++ qemu-snapshot-2004-08-16_23-testserial/vl.h 2004-08-20 13:59:59.110132869 
+1200
@@ -200,7 +200,14 @@
                                IOReadHandler *fd_read, void *opaque);
 void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event);
-CharDriverState *serial_hd;
+CharDriverState *serial1_hd;
+CharDriverState *serial2_hd;
+CharDriverState *serial3_hd;
+CharDriverState *serial4_hd;
+int init_serial2_device;
+int init_serial3_device;
+int init_serial4_device;
+
/* consoles */

------------------------------------------------------------------------

_______________________________________________
Qemu-devel mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/qemu-devel






reply via email to

[Prev in Thread] Current Thread [Next in Thread]