add virtio-console support (Christian Ehrhardt)
[qemu] / vl.c
diff --git a/vl.c b/vl.c
index a1a9cf4..2379986 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -209,6 +209,7 @@ static int no_frame = 0;
 int no_quit = 0;
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
+CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
 #ifdef TARGET_I386
 int win2k_install_hack = 0;
 #endif
@@ -231,7 +232,7 @@ int old_param = 0;
 #endif
 const char *qemu_name;
 int alt_grab = 0;
-#ifdef TARGET_SPARC
+#if defined(TARGET_SPARC) || defined(TARGET_PPC)
 unsigned int nb_prom_envs = 0;
 const char *prom_envs[MAX_PROM_ENVS];
 #endif
@@ -2196,6 +2197,17 @@ int drive_get_max_bus(BlockInterfaceType type)
     return max_bus;
 }
 
+const char *drive_get_serial(BlockDriverState *bdrv)
+{
+    int index;
+
+    for (index = 0; index < nb_drives; index++)
+        if (drives_table[index].bdrv == bdrv)
+            return drives_table[index].serial;
+
+    return "\0";
+}
+
 static void bdrv_format_print(void *opaque, const char *name)
 {
     fprintf(stderr, " %s", name);
@@ -2207,6 +2219,7 @@ static int drive_init(struct drive_opt *arg, int snapshot,
     char buf[128];
     char file[1024];
     char devname[128];
+    char serial[21];
     const char *mediastr = "";
     BlockInterfaceType type;
     enum { MEDIA_DISK, MEDIA_CDROM } media;
@@ -2222,7 +2235,7 @@ static int drive_init(struct drive_opt *arg, int snapshot,
     static const char * const params[] = { "bus", "unit", "if", "index",
                                            "cyls", "heads", "secs", "trans",
                                            "media", "snapshot", "file",
-                                           "cache", "format", NULL };
+                                           "cache", "format", "serial", NULL };
 
     if (check_params(buf, sizeof(buf), params, str) < 0) {
          fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
@@ -2409,6 +2422,9 @@ static int drive_init(struct drive_opt *arg, int snapshot,
     else
         pstrcpy(file, sizeof(file), arg->file);
 
+    if (!get_param_value(serial, sizeof(serial), "serial", str))
+           memset(serial, 0,  sizeof(serial));
+
     /* compute bus and unit according index */
 
     if (index != -1) {
@@ -2472,6 +2488,7 @@ static int drive_init(struct drive_opt *arg, int snapshot,
     drives_table[nb_drives].type = type;
     drives_table[nb_drives].bus = bus_id;
     drives_table[nb_drives].unit = unit_id;
+    strncpy(drives_table[nb_drives].serial, serial, sizeof(serial));
     nb_drives++;
 
     switch(type) {
@@ -3826,7 +3843,7 @@ static void help(int exitcode)
            "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
           "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
            "       [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
-           "       [,cache=writethrough|writeback|none][,format=f]\n"
+           "       [,cache=writethrough|writeback|none][,format=f][,serial=s]\n"
           "                use 'file' as a drive image\n"
            "-mtdblock file  use 'file' as on-board Flash memory image\n"
            "-sd file        use 'file' as SecureDigital card image\n"
@@ -3871,30 +3888,30 @@ static void help(int exitcode)
            "-uuid %%08x-%%04x-%%04x-%%04x-%%012x specify machine UUID\n"
            "\n"
            "Network options:\n"
-           "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
+           "-net nic[,vlan=n][,macaddr=addr][,model=type][,name=str]\n"
            "                create a new Network Interface Card and connect it to VLAN 'n'\n"
 #ifdef CONFIG_SLIRP
-           "-net user[,vlan=n][,hostname=host]\n"
+           "-net user[,vlan=n][,name=str][,hostname=host]\n"
            "                connect the user mode network stack to VLAN 'n' and send\n"
            "                hostname 'host' to DHCP clients\n"
 #endif
 #ifdef _WIN32
-           "-net tap[,vlan=n],ifname=name\n"
+           "-net tap[,vlan=n][,name=str],ifname=name\n"
            "                connect the host TAP network interface to VLAN 'n'\n"
 #else
-           "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,downscript=dfile]\n"
+           "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile]\n"
            "                connect the host TAP network interface to VLAN 'n' and use the\n"
            "                network scripts 'file' (default=%s)\n"
            "                and 'dfile' (default=%s);\n"
            "                use '[down]script=no' to disable script execution;\n"
            "                use 'fd=h' to connect to an already opened TAP interface\n"
 #endif
-           "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
+           "-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
            "                connect the vlan 'n' to another VLAN using a socket connection\n"
-           "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
+           "-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port]\n"
            "                connect the vlan 'n' to multicast maddr and port\n"
 #ifdef CONFIG_VDE
-           "-net vde[,vlan=n][,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n"
+           "-net vde[,vlan=n][,name=str][,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n"
            "                connect the vlan 'n' to port 'n' of a vde switch running\n"
            "                on host and listening for incoming connections on 'socketpath'.\n"
            "                Use group 'groupname' and mode 'octalmode' to change default\n"
@@ -4185,7 +4202,7 @@ static const QEMUOption qemu_options[] = {
     { "semihosting", 0, QEMU_OPTION_semihosting },
 #endif
     { "name", HAS_ARG, QEMU_OPTION_name },
-#if defined(TARGET_SPARC)
+#if defined(TARGET_SPARC) || defined(TARGET_PPC)
     { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
 #endif
 #if defined(TARGET_ARM)
@@ -4250,6 +4267,8 @@ struct soundhw soundhw[] = {
         { .init_isa = pcspk_audio_init }
     },
 #endif
+
+#ifdef CONFIG_SB16
     {
         "sb16",
         "Creative Sound Blaster 16",
@@ -4257,6 +4276,7 @@ struct soundhw soundhw[] = {
         1,
         { .init_isa = SB16_init }
     },
+#endif
 
 #ifdef CONFIG_CS4231A
     {
@@ -4302,6 +4322,7 @@ struct soundhw soundhw[] = {
     },
 #endif
 
+#ifdef CONFIG_ES1370
     {
         "es1370",
         "ENSONIQ AudioPCI ES1370",
@@ -4311,6 +4332,8 @@ struct soundhw soundhw[] = {
     },
 #endif
 
+#endif /* HAS_AUDIO_CHOICE */
+
     { NULL, NULL, 0, 0, { NULL } }
 };
 
@@ -4480,6 +4503,8 @@ int main(int argc, char **argv, char **envp)
     int serial_device_index;
     const char *parallel_devices[MAX_PARALLEL_PORTS];
     int parallel_device_index;
+    const char *virtio_consoles[MAX_VIRTIO_CONSOLES];
+    int virtio_console_index;
     const char *loadvm = NULL;
     QEMUMachine *machine;
     const char *cpu_model;
@@ -4553,6 +4578,11 @@ int main(int argc, char **argv, char **envp)
         parallel_devices[i] = NULL;
     parallel_device_index = 0;
 
+    virtio_consoles[0] = "vc:80Cx24C";
+    for(i = 1; i < MAX_VIRTIO_CONSOLES; i++)
+        virtio_consoles[i] = NULL;
+    virtio_console_index = 0;
+
     usb_devices_index = 0;
 
     nb_net_clients = 0;
@@ -5049,7 +5079,7 @@ int main(int argc, char **argv, char **envp)
             case QEMU_OPTION_name:
                 qemu_name = optarg;
                 break;
-#ifdef TARGET_SPARC
+#if defined(TARGET_SPARC) || defined(TARGET_PPC)
             case QEMU_OPTION_prom_env:
                 if (nb_prom_envs >= MAX_PROM_ENVS) {
                     fprintf(stderr, "Too many prom variables\n");
@@ -5148,6 +5178,8 @@ int main(int argc, char **argv, char **envp)
            parallel_devices[0] = "null";
        if (strncmp(monitor_device, "vc", 2) == 0)
            monitor_device = "stdio";
+       if (virtio_console_index == 0)
+           virtio_consoles[0] = "null";
     }
 
 #ifndef _WIN32
@@ -5442,6 +5474,22 @@ int main(int argc, char **argv, char **envp)
         }
     }
 
+    for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
+        const char *devname = virtio_consoles[i];
+        if (devname && strcmp(devname, "none")) {
+            char label[32];
+            snprintf(label, sizeof(label), "virtcon%d", i);
+            virtcon_hds[i] = qemu_chr_open(label, devname);
+            if (!virtcon_hds[i]) {
+                fprintf(stderr, "qemu: could not open virtio console '%s'\n",
+                        devname);
+                exit(1);
+            }
+            if (strstart(devname, "vc", 0))
+                qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);
+        }
+    }
+
     if (kvm_enabled()) {
         int ret;