xref: /qemu/system/vl.c (revision 6261164b)
18d7f2e76SPhilippe Mathieu-Daudé /*
28d7f2e76SPhilippe Mathieu-Daudé  * QEMU System Emulator
38d7f2e76SPhilippe Mathieu-Daudé  *
48d7f2e76SPhilippe Mathieu-Daudé  * Copyright (c) 2003-2008 Fabrice Bellard
58d7f2e76SPhilippe Mathieu-Daudé  *
68d7f2e76SPhilippe Mathieu-Daudé  * Permission is hereby granted, free of charge, to any person obtaining a copy
78d7f2e76SPhilippe Mathieu-Daudé  * of this software and associated documentation files (the "Software"), to deal
88d7f2e76SPhilippe Mathieu-Daudé  * in the Software without restriction, including without limitation the rights
98d7f2e76SPhilippe Mathieu-Daudé  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
108d7f2e76SPhilippe Mathieu-Daudé  * copies of the Software, and to permit persons to whom the Software is
118d7f2e76SPhilippe Mathieu-Daudé  * furnished to do so, subject to the following conditions:
128d7f2e76SPhilippe Mathieu-Daudé  *
138d7f2e76SPhilippe Mathieu-Daudé  * The above copyright notice and this permission notice shall be included in
148d7f2e76SPhilippe Mathieu-Daudé  * all copies or substantial portions of the Software.
158d7f2e76SPhilippe Mathieu-Daudé  *
168d7f2e76SPhilippe Mathieu-Daudé  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
178d7f2e76SPhilippe Mathieu-Daudé  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
188d7f2e76SPhilippe Mathieu-Daudé  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
198d7f2e76SPhilippe Mathieu-Daudé  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
208d7f2e76SPhilippe Mathieu-Daudé  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
218d7f2e76SPhilippe Mathieu-Daudé  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
228d7f2e76SPhilippe Mathieu-Daudé  * THE SOFTWARE.
238d7f2e76SPhilippe Mathieu-Daudé  */
248d7f2e76SPhilippe Mathieu-Daudé 
258d7f2e76SPhilippe Mathieu-Daudé #include "qemu/osdep.h"
268d7f2e76SPhilippe Mathieu-Daudé #include "qemu/help-texts.h"
278d7f2e76SPhilippe Mathieu-Daudé #include "qemu/datadir.h"
288d7f2e76SPhilippe Mathieu-Daudé #include "qemu/units.h"
298d7f2e76SPhilippe Mathieu-Daudé #include "exec/cpu-common.h"
308d7f2e76SPhilippe Mathieu-Daudé #include "exec/page-vary.h"
318d7f2e76SPhilippe Mathieu-Daudé #include "hw/qdev-properties.h"
328d7f2e76SPhilippe Mathieu-Daudé #include "qapi/compat-policy.h"
338d7f2e76SPhilippe Mathieu-Daudé #include "qapi/error.h"
348d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qmp/qdict.h"
358d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qmp/qstring.h"
368d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qmp/qjson.h"
378d7f2e76SPhilippe Mathieu-Daudé #include "qemu-version.h"
388d7f2e76SPhilippe Mathieu-Daudé #include "qemu/cutils.h"
398d7f2e76SPhilippe Mathieu-Daudé #include "qemu/help_option.h"
408d7f2e76SPhilippe Mathieu-Daudé #include "qemu/hw-version.h"
418d7f2e76SPhilippe Mathieu-Daudé #include "qemu/uuid.h"
428d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/reset.h"
438d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/runstate.h"
448d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/runstate-action.h"
458d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/seccomp.h"
468d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/tcg.h"
478d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/xen.h"
488d7f2e76SPhilippe Mathieu-Daudé 
498d7f2e76SPhilippe Mathieu-Daudé #include "qemu/error-report.h"
508d7f2e76SPhilippe Mathieu-Daudé #include "qemu/sockets.h"
518d7f2e76SPhilippe Mathieu-Daudé #include "qemu/accel.h"
528d7f2e76SPhilippe Mathieu-Daudé #include "qemu/async-teardown.h"
538d7f2e76SPhilippe Mathieu-Daudé #include "hw/usb.h"
548d7f2e76SPhilippe Mathieu-Daudé #include "hw/isa/isa.h"
558d7f2e76SPhilippe Mathieu-Daudé #include "hw/scsi/scsi.h"
568d7f2e76SPhilippe Mathieu-Daudé #include "hw/display/vga.h"
578d7f2e76SPhilippe Mathieu-Daudé #include "hw/firmware/smbios.h"
588d7f2e76SPhilippe Mathieu-Daudé #include "hw/acpi/acpi.h"
598d7f2e76SPhilippe Mathieu-Daudé #include "hw/xen/xen.h"
608d7f2e76SPhilippe Mathieu-Daudé #include "hw/loader.h"
618d7f2e76SPhilippe Mathieu-Daudé #include "monitor/qdev.h"
628d7f2e76SPhilippe Mathieu-Daudé #include "net/net.h"
638d7f2e76SPhilippe Mathieu-Daudé #include "net/slirp.h"
648d7f2e76SPhilippe Mathieu-Daudé #include "monitor/monitor.h"
658d7f2e76SPhilippe Mathieu-Daudé #include "ui/console.h"
668d7f2e76SPhilippe Mathieu-Daudé #include "ui/input.h"
678d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/sysemu.h"
688d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/numa.h"
698d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/hostmem.h"
708d7f2e76SPhilippe Mathieu-Daudé #include "exec/gdbstub.h"
718d7f2e76SPhilippe Mathieu-Daudé #include "qemu/timer.h"
728d7f2e76SPhilippe Mathieu-Daudé #include "chardev/char.h"
738d7f2e76SPhilippe Mathieu-Daudé #include "qemu/bitmap.h"
748d7f2e76SPhilippe Mathieu-Daudé #include "qemu/log.h"
758d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/blockdev.h"
768d7f2e76SPhilippe Mathieu-Daudé #include "hw/block/block.h"
778d7f2e76SPhilippe Mathieu-Daudé #include "hw/i386/x86.h"
788d7f2e76SPhilippe Mathieu-Daudé #include "hw/i386/pc.h"
798d7f2e76SPhilippe Mathieu-Daudé #include "migration/misc.h"
808d7f2e76SPhilippe Mathieu-Daudé #include "migration/snapshot.h"
818d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/tpm.h"
828d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/dma.h"
838d7f2e76SPhilippe Mathieu-Daudé #include "hw/audio/soundhw.h"
848d7f2e76SPhilippe Mathieu-Daudé #include "audio/audio.h"
858d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/cpus.h"
868d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/cpu-timers.h"
878d7f2e76SPhilippe Mathieu-Daudé #include "migration/colo.h"
888d7f2e76SPhilippe Mathieu-Daudé #include "migration/postcopy-ram.h"
898d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/kvm.h"
908d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qobject-input-visitor.h"
918d7f2e76SPhilippe Mathieu-Daudé #include "qemu/option.h"
928d7f2e76SPhilippe Mathieu-Daudé #include "qemu/config-file.h"
938d7f2e76SPhilippe Mathieu-Daudé #include "qemu/main-loop.h"
948d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTFS
958d7f2e76SPhilippe Mathieu-Daudé #include "fsdev/qemu-fsdev.h"
968d7f2e76SPhilippe Mathieu-Daudé #endif
978d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/qtest.h"
988d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_TCG
998d7f2e76SPhilippe Mathieu-Daudé #include "accel/tcg/perf.h"
1008d7f2e76SPhilippe Mathieu-Daudé #endif
1018d7f2e76SPhilippe Mathieu-Daudé 
1028d7f2e76SPhilippe Mathieu-Daudé #include "disas/disas.h"
1038d7f2e76SPhilippe Mathieu-Daudé 
1048d7f2e76SPhilippe Mathieu-Daudé #include "trace.h"
1058d7f2e76SPhilippe Mathieu-Daudé #include "trace/control.h"
1068d7f2e76SPhilippe Mathieu-Daudé #include "qemu/plugin.h"
1078d7f2e76SPhilippe Mathieu-Daudé #include "qemu/queue.h"
1088d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/arch_init.h"
1098d7f2e76SPhilippe Mathieu-Daudé #include "exec/confidential-guest-support.h"
1108d7f2e76SPhilippe Mathieu-Daudé 
1118d7f2e76SPhilippe Mathieu-Daudé #include "ui/qemu-spice.h"
1128d7f2e76SPhilippe Mathieu-Daudé #include "qapi/string-input-visitor.h"
1138d7f2e76SPhilippe Mathieu-Daudé #include "qapi/opts-visitor.h"
1148d7f2e76SPhilippe Mathieu-Daudé #include "qapi/clone-visitor.h"
1158d7f2e76SPhilippe Mathieu-Daudé #include "qom/object_interfaces.h"
1168d7f2e76SPhilippe Mathieu-Daudé #include "semihosting/semihost.h"
1178d7f2e76SPhilippe Mathieu-Daudé #include "crypto/init.h"
1188d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/replay.h"
1198d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-events-run-state.h"
1208d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-types-audio.h"
1218d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-visit-audio.h"
1228d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-visit-block-core.h"
1238d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-visit-compat.h"
1248d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-visit-machine.h"
1258d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-visit-ui.h"
1268d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-commands-block-core.h"
1278d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-commands-migration.h"
1288d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-commands-misc.h"
1298d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-visit-qom.h"
1308d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-commands-ui.h"
1318d7f2e76SPhilippe Mathieu-Daudé #include "block/qdict.h"
1328d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qmp/qerror.h"
1338d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/iothread.h"
1348d7f2e76SPhilippe Mathieu-Daudé #include "qemu/guest-random.h"
1358d7f2e76SPhilippe Mathieu-Daudé #include "qemu/keyval.h"
1368d7f2e76SPhilippe Mathieu-Daudé 
1378d7f2e76SPhilippe Mathieu-Daudé #define MAX_VIRTIO_CONSOLES 1
1388d7f2e76SPhilippe Mathieu-Daudé 
1398d7f2e76SPhilippe Mathieu-Daudé typedef struct BlockdevOptionsQueueEntry {
1408d7f2e76SPhilippe Mathieu-Daudé     BlockdevOptions *bdo;
1418d7f2e76SPhilippe Mathieu-Daudé     Location loc;
1428d7f2e76SPhilippe Mathieu-Daudé     QSIMPLEQ_ENTRY(BlockdevOptionsQueueEntry) entry;
1438d7f2e76SPhilippe Mathieu-Daudé } BlockdevOptionsQueueEntry;
1448d7f2e76SPhilippe Mathieu-Daudé 
1458d7f2e76SPhilippe Mathieu-Daudé typedef QSIMPLEQ_HEAD(, BlockdevOptionsQueueEntry) BlockdevOptionsQueue;
1468d7f2e76SPhilippe Mathieu-Daudé 
1478d7f2e76SPhilippe Mathieu-Daudé typedef struct ObjectOption {
1488d7f2e76SPhilippe Mathieu-Daudé     ObjectOptions *opts;
1498d7f2e76SPhilippe Mathieu-Daudé     QTAILQ_ENTRY(ObjectOption) next;
1508d7f2e76SPhilippe Mathieu-Daudé } ObjectOption;
1518d7f2e76SPhilippe Mathieu-Daudé 
1528d7f2e76SPhilippe Mathieu-Daudé typedef struct DeviceOption {
1538d7f2e76SPhilippe Mathieu-Daudé     QDict *opts;
1548d7f2e76SPhilippe Mathieu-Daudé     Location loc;
1558d7f2e76SPhilippe Mathieu-Daudé     QTAILQ_ENTRY(DeviceOption) next;
1568d7f2e76SPhilippe Mathieu-Daudé } DeviceOption;
1578d7f2e76SPhilippe Mathieu-Daudé 
1588d7f2e76SPhilippe Mathieu-Daudé static const char *cpu_option;
1598d7f2e76SPhilippe Mathieu-Daudé static const char *mem_path;
1608d7f2e76SPhilippe Mathieu-Daudé static const char *incoming;
1618d7f2e76SPhilippe Mathieu-Daudé static const char *loadvm;
1628d7f2e76SPhilippe Mathieu-Daudé static const char *accelerators;
1638d7f2e76SPhilippe Mathieu-Daudé static bool have_custom_ram_size;
1648d7f2e76SPhilippe Mathieu-Daudé static const char *ram_memdev_id;
1658d7f2e76SPhilippe Mathieu-Daudé static QDict *machine_opts_dict;
1668d7f2e76SPhilippe Mathieu-Daudé static QTAILQ_HEAD(, ObjectOption) object_opts = QTAILQ_HEAD_INITIALIZER(object_opts);
1678d7f2e76SPhilippe Mathieu-Daudé static QTAILQ_HEAD(, DeviceOption) device_opts = QTAILQ_HEAD_INITIALIZER(device_opts);
1688d7f2e76SPhilippe Mathieu-Daudé static int display_remote;
1698d7f2e76SPhilippe Mathieu-Daudé static int snapshot;
1708d7f2e76SPhilippe Mathieu-Daudé static bool preconfig_requested;
1718d7f2e76SPhilippe Mathieu-Daudé static QemuPluginList plugin_list = QTAILQ_HEAD_INITIALIZER(plugin_list);
1728d7f2e76SPhilippe Mathieu-Daudé static BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
1738d7f2e76SPhilippe Mathieu-Daudé static bool nographic = false;
1748d7f2e76SPhilippe Mathieu-Daudé static int mem_prealloc; /* force preallocation of physical target memory */
1758d7f2e76SPhilippe Mathieu-Daudé static const char *vga_model = NULL;
1768d7f2e76SPhilippe Mathieu-Daudé static DisplayOptions dpy;
1778d7f2e76SPhilippe Mathieu-Daudé static int num_serial_hds;
1788d7f2e76SPhilippe Mathieu-Daudé static Chardev **serial_hds;
1798d7f2e76SPhilippe Mathieu-Daudé static const char *log_mask;
1808d7f2e76SPhilippe Mathieu-Daudé static const char *log_file;
1818d7f2e76SPhilippe Mathieu-Daudé static bool list_data_dirs;
1828d7f2e76SPhilippe Mathieu-Daudé static const char *qtest_chrdev;
1838d7f2e76SPhilippe Mathieu-Daudé static const char *qtest_log;
1848d7f2e76SPhilippe Mathieu-Daudé static bool opt_one_insn_per_tb;
1858d7f2e76SPhilippe Mathieu-Daudé 
1868d7f2e76SPhilippe Mathieu-Daudé static int has_defaults = 1;
187c753bf47SPaolo Bonzini static int default_audio = 1;
1888d7f2e76SPhilippe Mathieu-Daudé static int default_serial = 1;
1898d7f2e76SPhilippe Mathieu-Daudé static int default_parallel = 1;
1908d7f2e76SPhilippe Mathieu-Daudé static int default_monitor = 1;
1918d7f2e76SPhilippe Mathieu-Daudé static int default_floppy = 1;
1928d7f2e76SPhilippe Mathieu-Daudé static int default_cdrom = 1;
1938d7f2e76SPhilippe Mathieu-Daudé static int default_sdcard = 1;
1948d7f2e76SPhilippe Mathieu-Daudé static int default_vga = 1;
1958d7f2e76SPhilippe Mathieu-Daudé static int default_net = 1;
1968d7f2e76SPhilippe Mathieu-Daudé 
1978d7f2e76SPhilippe Mathieu-Daudé static struct {
1988d7f2e76SPhilippe Mathieu-Daudé     const char *driver;
1998d7f2e76SPhilippe Mathieu-Daudé     int *flag;
2008d7f2e76SPhilippe Mathieu-Daudé } default_list[] = {
2018d7f2e76SPhilippe Mathieu-Daudé     { .driver = "isa-serial",           .flag = &default_serial    },
2028d7f2e76SPhilippe Mathieu-Daudé     { .driver = "isa-parallel",         .flag = &default_parallel  },
2038d7f2e76SPhilippe Mathieu-Daudé     { .driver = "isa-fdc",              .flag = &default_floppy    },
2048d7f2e76SPhilippe Mathieu-Daudé     { .driver = "floppy",               .flag = &default_floppy    },
2058d7f2e76SPhilippe Mathieu-Daudé     { .driver = "ide-cd",               .flag = &default_cdrom     },
2068d7f2e76SPhilippe Mathieu-Daudé     { .driver = "ide-hd",               .flag = &default_cdrom     },
2078d7f2e76SPhilippe Mathieu-Daudé     { .driver = "scsi-cd",              .flag = &default_cdrom     },
2088d7f2e76SPhilippe Mathieu-Daudé     { .driver = "scsi-hd",              .flag = &default_cdrom     },
2098d7f2e76SPhilippe Mathieu-Daudé     { .driver = "VGA",                  .flag = &default_vga       },
2108d7f2e76SPhilippe Mathieu-Daudé     { .driver = "isa-vga",              .flag = &default_vga       },
2118d7f2e76SPhilippe Mathieu-Daudé     { .driver = "cirrus-vga",           .flag = &default_vga       },
2128d7f2e76SPhilippe Mathieu-Daudé     { .driver = "isa-cirrus-vga",       .flag = &default_vga       },
2138d7f2e76SPhilippe Mathieu-Daudé     { .driver = "vmware-svga",          .flag = &default_vga       },
2148d7f2e76SPhilippe Mathieu-Daudé     { .driver = "qxl-vga",              .flag = &default_vga       },
2158d7f2e76SPhilippe Mathieu-Daudé     { .driver = "virtio-vga",           .flag = &default_vga       },
2168d7f2e76SPhilippe Mathieu-Daudé     { .driver = "ati-vga",              .flag = &default_vga       },
2178d7f2e76SPhilippe Mathieu-Daudé     { .driver = "vhost-user-vga",       .flag = &default_vga       },
2188d7f2e76SPhilippe Mathieu-Daudé     { .driver = "virtio-vga-gl",        .flag = &default_vga       },
2198e7b21caSGurchetan Singh     { .driver = "virtio-vga-rutabaga",  .flag = &default_vga       },
2208d7f2e76SPhilippe Mathieu-Daudé };
2218d7f2e76SPhilippe Mathieu-Daudé 
2228d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_rtc_opts = {
2238d7f2e76SPhilippe Mathieu-Daudé     .name = "rtc",
2248d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
2258d7f2e76SPhilippe Mathieu-Daudé     .merge_lists = true,
2268d7f2e76SPhilippe Mathieu-Daudé     .desc = {
2278d7f2e76SPhilippe Mathieu-Daudé         {
2288d7f2e76SPhilippe Mathieu-Daudé             .name = "base",
2298d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
2308d7f2e76SPhilippe Mathieu-Daudé         },{
2318d7f2e76SPhilippe Mathieu-Daudé             .name = "clock",
2328d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
2338d7f2e76SPhilippe Mathieu-Daudé         },{
2348d7f2e76SPhilippe Mathieu-Daudé             .name = "driftfix",
2358d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
2368d7f2e76SPhilippe Mathieu-Daudé         },
2378d7f2e76SPhilippe Mathieu-Daudé         { /* end of list */ }
2388d7f2e76SPhilippe Mathieu-Daudé     },
2398d7f2e76SPhilippe Mathieu-Daudé };
2408d7f2e76SPhilippe Mathieu-Daudé 
2418d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_option_rom_opts = {
2428d7f2e76SPhilippe Mathieu-Daudé     .name = "option-rom",
2438d7f2e76SPhilippe Mathieu-Daudé     .implied_opt_name = "romfile",
2448d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_option_rom_opts.head),
2458d7f2e76SPhilippe Mathieu-Daudé     .desc = {
2468d7f2e76SPhilippe Mathieu-Daudé         {
2478d7f2e76SPhilippe Mathieu-Daudé             .name = "bootindex",
2488d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_NUMBER,
2498d7f2e76SPhilippe Mathieu-Daudé         }, {
2508d7f2e76SPhilippe Mathieu-Daudé             .name = "romfile",
2518d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
2528d7f2e76SPhilippe Mathieu-Daudé         },
2538d7f2e76SPhilippe Mathieu-Daudé         { /* end of list */ }
2548d7f2e76SPhilippe Mathieu-Daudé     },
2558d7f2e76SPhilippe Mathieu-Daudé };
2568d7f2e76SPhilippe Mathieu-Daudé 
2578d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_accel_opts = {
2588d7f2e76SPhilippe Mathieu-Daudé     .name = "accel",
2598d7f2e76SPhilippe Mathieu-Daudé     .implied_opt_name = "accel",
2608d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_accel_opts.head),
2618d7f2e76SPhilippe Mathieu-Daudé     .desc = {
2628d7f2e76SPhilippe Mathieu-Daudé         /*
2638d7f2e76SPhilippe Mathieu-Daudé          * no elements => accept any
2648d7f2e76SPhilippe Mathieu-Daudé          * sanity checking will happen later
2658d7f2e76SPhilippe Mathieu-Daudé          * when setting accelerator properties
2668d7f2e76SPhilippe Mathieu-Daudé          */
2678d7f2e76SPhilippe Mathieu-Daudé         { }
2688d7f2e76SPhilippe Mathieu-Daudé     },
2698d7f2e76SPhilippe Mathieu-Daudé };
2708d7f2e76SPhilippe Mathieu-Daudé 
2718d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_boot_opts = {
2728d7f2e76SPhilippe Mathieu-Daudé     .name = "boot-opts",
2738d7f2e76SPhilippe Mathieu-Daudé     .implied_opt_name = "order",
2748d7f2e76SPhilippe Mathieu-Daudé     .merge_lists = true,
2758d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_boot_opts.head),
2768d7f2e76SPhilippe Mathieu-Daudé     .desc = {
2778d7f2e76SPhilippe Mathieu-Daudé         {
2788d7f2e76SPhilippe Mathieu-Daudé             .name = "order",
2798d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
2808d7f2e76SPhilippe Mathieu-Daudé         }, {
2818d7f2e76SPhilippe Mathieu-Daudé             .name = "once",
2828d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
2838d7f2e76SPhilippe Mathieu-Daudé         }, {
2848d7f2e76SPhilippe Mathieu-Daudé             .name = "menu",
2858d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_BOOL,
2868d7f2e76SPhilippe Mathieu-Daudé         }, {
2878d7f2e76SPhilippe Mathieu-Daudé             .name = "splash",
2888d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
2898d7f2e76SPhilippe Mathieu-Daudé         }, {
2908d7f2e76SPhilippe Mathieu-Daudé             .name = "splash-time",
2918d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_NUMBER,
2928d7f2e76SPhilippe Mathieu-Daudé         }, {
2938d7f2e76SPhilippe Mathieu-Daudé             .name = "reboot-timeout",
2948d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_NUMBER,
2958d7f2e76SPhilippe Mathieu-Daudé         }, {
2968d7f2e76SPhilippe Mathieu-Daudé             .name = "strict",
2978d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_BOOL,
2988d7f2e76SPhilippe Mathieu-Daudé         },
2998d7f2e76SPhilippe Mathieu-Daudé         { /*End of list */ }
3008d7f2e76SPhilippe Mathieu-Daudé     },
3018d7f2e76SPhilippe Mathieu-Daudé };
3028d7f2e76SPhilippe Mathieu-Daudé 
3038d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_add_fd_opts = {
3048d7f2e76SPhilippe Mathieu-Daudé     .name = "add-fd",
3058d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_add_fd_opts.head),
3068d7f2e76SPhilippe Mathieu-Daudé     .desc = {
3078d7f2e76SPhilippe Mathieu-Daudé         {
3088d7f2e76SPhilippe Mathieu-Daudé             .name = "fd",
3098d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_NUMBER,
3108d7f2e76SPhilippe Mathieu-Daudé             .help = "file descriptor of which a duplicate is added to fd set",
3118d7f2e76SPhilippe Mathieu-Daudé         },{
3128d7f2e76SPhilippe Mathieu-Daudé             .name = "set",
3138d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_NUMBER,
3148d7f2e76SPhilippe Mathieu-Daudé             .help = "ID of the fd set to add fd to",
3158d7f2e76SPhilippe Mathieu-Daudé         },{
3168d7f2e76SPhilippe Mathieu-Daudé             .name = "opaque",
3178d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
3188d7f2e76SPhilippe Mathieu-Daudé             .help = "free-form string used to describe fd",
3198d7f2e76SPhilippe Mathieu-Daudé         },
3208d7f2e76SPhilippe Mathieu-Daudé         { /* end of list */ }
3218d7f2e76SPhilippe Mathieu-Daudé     },
3228d7f2e76SPhilippe Mathieu-Daudé };
3238d7f2e76SPhilippe Mathieu-Daudé 
3248d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_object_opts = {
3258d7f2e76SPhilippe Mathieu-Daudé     .name = "object",
3268d7f2e76SPhilippe Mathieu-Daudé     .implied_opt_name = "qom-type",
3278d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
3288d7f2e76SPhilippe Mathieu-Daudé     .desc = {
3298d7f2e76SPhilippe Mathieu-Daudé         { }
3308d7f2e76SPhilippe Mathieu-Daudé     },
3318d7f2e76SPhilippe Mathieu-Daudé };
3328d7f2e76SPhilippe Mathieu-Daudé 
3338d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_tpmdev_opts = {
3348d7f2e76SPhilippe Mathieu-Daudé     .name = "tpmdev",
3358d7f2e76SPhilippe Mathieu-Daudé     .implied_opt_name = "type",
3368d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_tpmdev_opts.head),
3378d7f2e76SPhilippe Mathieu-Daudé     .desc = {
3388d7f2e76SPhilippe Mathieu-Daudé         /* options are defined in the TPM backends */
3398d7f2e76SPhilippe Mathieu-Daudé         { /* end of list */ }
3408d7f2e76SPhilippe Mathieu-Daudé     },
3418d7f2e76SPhilippe Mathieu-Daudé };
3428d7f2e76SPhilippe Mathieu-Daudé 
3438d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_overcommit_opts = {
3448d7f2e76SPhilippe Mathieu-Daudé     .name = "overcommit",
3458d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_overcommit_opts.head),
3468d7f2e76SPhilippe Mathieu-Daudé     .desc = {
3478d7f2e76SPhilippe Mathieu-Daudé         {
3488d7f2e76SPhilippe Mathieu-Daudé             .name = "mem-lock",
3498d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_BOOL,
3508d7f2e76SPhilippe Mathieu-Daudé         },
3518d7f2e76SPhilippe Mathieu-Daudé         {
3528d7f2e76SPhilippe Mathieu-Daudé             .name = "cpu-pm",
3538d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_BOOL,
3548d7f2e76SPhilippe Mathieu-Daudé         },
3558d7f2e76SPhilippe Mathieu-Daudé         { /* end of list */ }
3568d7f2e76SPhilippe Mathieu-Daudé     },
3578d7f2e76SPhilippe Mathieu-Daudé };
3588d7f2e76SPhilippe Mathieu-Daudé 
3598d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_msg_opts = {
3608d7f2e76SPhilippe Mathieu-Daudé     .name = "msg",
3618d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_msg_opts.head),
3628d7f2e76SPhilippe Mathieu-Daudé     .desc = {
3638d7f2e76SPhilippe Mathieu-Daudé         {
3648d7f2e76SPhilippe Mathieu-Daudé             .name = "timestamp",
3658d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_BOOL,
3668d7f2e76SPhilippe Mathieu-Daudé         },
3678d7f2e76SPhilippe Mathieu-Daudé         {
3688d7f2e76SPhilippe Mathieu-Daudé             .name = "guest-name",
3698d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_BOOL,
3708d7f2e76SPhilippe Mathieu-Daudé             .help = "Prepends guest name for error messages but only if "
3718d7f2e76SPhilippe Mathieu-Daudé                     "-name guest is set otherwise option is ignored\n",
3728d7f2e76SPhilippe Mathieu-Daudé         },
3738d7f2e76SPhilippe Mathieu-Daudé         { /* end of list */ }
3748d7f2e76SPhilippe Mathieu-Daudé     },
3758d7f2e76SPhilippe Mathieu-Daudé };
3768d7f2e76SPhilippe Mathieu-Daudé 
3778d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_name_opts = {
3788d7f2e76SPhilippe Mathieu-Daudé     .name = "name",
3798d7f2e76SPhilippe Mathieu-Daudé     .implied_opt_name = "guest",
3808d7f2e76SPhilippe Mathieu-Daudé     .merge_lists = true,
3818d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_name_opts.head),
3828d7f2e76SPhilippe Mathieu-Daudé     .desc = {
3838d7f2e76SPhilippe Mathieu-Daudé         {
3848d7f2e76SPhilippe Mathieu-Daudé             .name = "guest",
3858d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
3868d7f2e76SPhilippe Mathieu-Daudé             .help = "Sets the name of the guest.\n"
3878d7f2e76SPhilippe Mathieu-Daudé                     "This name will be displayed in the SDL window caption.\n"
3888d7f2e76SPhilippe Mathieu-Daudé                     "The name will also be used for the VNC server",
3898d7f2e76SPhilippe Mathieu-Daudé         }, {
3908d7f2e76SPhilippe Mathieu-Daudé             .name = "process",
3918d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
3928d7f2e76SPhilippe Mathieu-Daudé             .help = "Sets the name of the QEMU process, as shown in top etc",
3938d7f2e76SPhilippe Mathieu-Daudé         }, {
3948d7f2e76SPhilippe Mathieu-Daudé             .name = "debug-threads",
3958d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_BOOL,
3968d7f2e76SPhilippe Mathieu-Daudé             .help = "When enabled, name the individual threads; defaults off.\n"
3978d7f2e76SPhilippe Mathieu-Daudé                     "NOTE: The thread names are for debugging and not a\n"
3988d7f2e76SPhilippe Mathieu-Daudé                     "stable API.",
3998d7f2e76SPhilippe Mathieu-Daudé         },
4008d7f2e76SPhilippe Mathieu-Daudé         { /* End of list */ }
4018d7f2e76SPhilippe Mathieu-Daudé     },
4028d7f2e76SPhilippe Mathieu-Daudé };
4038d7f2e76SPhilippe Mathieu-Daudé 
4048d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_mem_opts = {
4058d7f2e76SPhilippe Mathieu-Daudé     .name = "memory",
4068d7f2e76SPhilippe Mathieu-Daudé     .implied_opt_name = "size",
4078d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
4088d7f2e76SPhilippe Mathieu-Daudé     .merge_lists = true,
4098d7f2e76SPhilippe Mathieu-Daudé     .desc = {
4108d7f2e76SPhilippe Mathieu-Daudé         {
4118d7f2e76SPhilippe Mathieu-Daudé             .name = "size",
4128d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_SIZE,
4138d7f2e76SPhilippe Mathieu-Daudé         },
4148d7f2e76SPhilippe Mathieu-Daudé         {
4158d7f2e76SPhilippe Mathieu-Daudé             .name = "slots",
4168d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_NUMBER,
4178d7f2e76SPhilippe Mathieu-Daudé         },
4188d7f2e76SPhilippe Mathieu-Daudé         {
4198d7f2e76SPhilippe Mathieu-Daudé             .name = "maxmem",
4208d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_SIZE,
4218d7f2e76SPhilippe Mathieu-Daudé         },
4228d7f2e76SPhilippe Mathieu-Daudé         { /* end of list */ }
4238d7f2e76SPhilippe Mathieu-Daudé     },
4248d7f2e76SPhilippe Mathieu-Daudé };
4258d7f2e76SPhilippe Mathieu-Daudé 
4268d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_icount_opts = {
4278d7f2e76SPhilippe Mathieu-Daudé     .name = "icount",
4288d7f2e76SPhilippe Mathieu-Daudé     .implied_opt_name = "shift",
4298d7f2e76SPhilippe Mathieu-Daudé     .merge_lists = true,
4308d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_icount_opts.head),
4318d7f2e76SPhilippe Mathieu-Daudé     .desc = {
4328d7f2e76SPhilippe Mathieu-Daudé         {
4338d7f2e76SPhilippe Mathieu-Daudé             .name = "shift",
4348d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
4358d7f2e76SPhilippe Mathieu-Daudé         }, {
4368d7f2e76SPhilippe Mathieu-Daudé             .name = "align",
4378d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_BOOL,
4388d7f2e76SPhilippe Mathieu-Daudé         }, {
4398d7f2e76SPhilippe Mathieu-Daudé             .name = "sleep",
4408d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_BOOL,
4418d7f2e76SPhilippe Mathieu-Daudé         }, {
4428d7f2e76SPhilippe Mathieu-Daudé             .name = "rr",
4438d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
4448d7f2e76SPhilippe Mathieu-Daudé         }, {
4458d7f2e76SPhilippe Mathieu-Daudé             .name = "rrfile",
4468d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
4478d7f2e76SPhilippe Mathieu-Daudé         }, {
4488d7f2e76SPhilippe Mathieu-Daudé             .name = "rrsnapshot",
4498d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
4508d7f2e76SPhilippe Mathieu-Daudé         },
4518d7f2e76SPhilippe Mathieu-Daudé         { /* end of list */ }
4528d7f2e76SPhilippe Mathieu-Daudé     },
4538d7f2e76SPhilippe Mathieu-Daudé };
4548d7f2e76SPhilippe Mathieu-Daudé 
4558d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_fw_cfg_opts = {
4568d7f2e76SPhilippe Mathieu-Daudé     .name = "fw_cfg",
4578d7f2e76SPhilippe Mathieu-Daudé     .implied_opt_name = "name",
4588d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_fw_cfg_opts.head),
4598d7f2e76SPhilippe Mathieu-Daudé     .desc = {
4608d7f2e76SPhilippe Mathieu-Daudé         {
4618d7f2e76SPhilippe Mathieu-Daudé             .name = "name",
4628d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
4638d7f2e76SPhilippe Mathieu-Daudé             .help = "Sets the fw_cfg name of the blob to be inserted",
4648d7f2e76SPhilippe Mathieu-Daudé         }, {
4658d7f2e76SPhilippe Mathieu-Daudé             .name = "file",
4668d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
4678d7f2e76SPhilippe Mathieu-Daudé             .help = "Sets the name of the file from which "
4688d7f2e76SPhilippe Mathieu-Daudé                     "the fw_cfg blob will be loaded",
4698d7f2e76SPhilippe Mathieu-Daudé         }, {
4708d7f2e76SPhilippe Mathieu-Daudé             .name = "string",
4718d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
4728d7f2e76SPhilippe Mathieu-Daudé             .help = "Sets content of the blob to be inserted from a string",
4738d7f2e76SPhilippe Mathieu-Daudé         }, {
4748d7f2e76SPhilippe Mathieu-Daudé             .name = "gen_id",
4758d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
4768d7f2e76SPhilippe Mathieu-Daudé             .help = "Sets id of the object generating the fw_cfg blob "
4778d7f2e76SPhilippe Mathieu-Daudé                     "to be inserted",
4788d7f2e76SPhilippe Mathieu-Daudé         },
4798d7f2e76SPhilippe Mathieu-Daudé         { /* end of list */ }
4808d7f2e76SPhilippe Mathieu-Daudé     },
4818d7f2e76SPhilippe Mathieu-Daudé };
4828d7f2e76SPhilippe Mathieu-Daudé 
4838d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_action_opts = {
4848d7f2e76SPhilippe Mathieu-Daudé     .name = "action",
4858d7f2e76SPhilippe Mathieu-Daudé     .merge_lists = true,
4868d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_action_opts.head),
4878d7f2e76SPhilippe Mathieu-Daudé     .desc = {
4888d7f2e76SPhilippe Mathieu-Daudé         {
4898d7f2e76SPhilippe Mathieu-Daudé             .name = "shutdown",
4908d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
4918d7f2e76SPhilippe Mathieu-Daudé         },{
4928d7f2e76SPhilippe Mathieu-Daudé             .name = "reboot",
4938d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
4948d7f2e76SPhilippe Mathieu-Daudé         },{
4958d7f2e76SPhilippe Mathieu-Daudé             .name = "panic",
4968d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
4978d7f2e76SPhilippe Mathieu-Daudé         },{
4988d7f2e76SPhilippe Mathieu-Daudé             .name = "watchdog",
4998d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
5008d7f2e76SPhilippe Mathieu-Daudé         },
5018d7f2e76SPhilippe Mathieu-Daudé         { /* end of list */ }
5028d7f2e76SPhilippe Mathieu-Daudé     },
5038d7f2e76SPhilippe Mathieu-Daudé };
5048d7f2e76SPhilippe Mathieu-Daudé 
5058d7f2e76SPhilippe Mathieu-Daudé const char *qemu_get_vm_name(void)
5068d7f2e76SPhilippe Mathieu-Daudé {
5078d7f2e76SPhilippe Mathieu-Daudé     return qemu_name;
5088d7f2e76SPhilippe Mathieu-Daudé }
5098d7f2e76SPhilippe Mathieu-Daudé 
5108d7f2e76SPhilippe Mathieu-Daudé static void default_driver_disable(const char *driver)
5118d7f2e76SPhilippe Mathieu-Daudé {
5128d7f2e76SPhilippe Mathieu-Daudé     int i;
5138d7f2e76SPhilippe Mathieu-Daudé 
5148d7f2e76SPhilippe Mathieu-Daudé     if (!driver) {
5158d7f2e76SPhilippe Mathieu-Daudé         return;
5168d7f2e76SPhilippe Mathieu-Daudé     }
5178d7f2e76SPhilippe Mathieu-Daudé 
5188d7f2e76SPhilippe Mathieu-Daudé     for (i = 0; i < ARRAY_SIZE(default_list); i++) {
5198d7f2e76SPhilippe Mathieu-Daudé         if (strcmp(default_list[i].driver, driver) != 0)
5208d7f2e76SPhilippe Mathieu-Daudé             continue;
5218d7f2e76SPhilippe Mathieu-Daudé         *(default_list[i].flag) = 0;
5228d7f2e76SPhilippe Mathieu-Daudé     }
5238d7f2e76SPhilippe Mathieu-Daudé }
5248d7f2e76SPhilippe Mathieu-Daudé 
5258d7f2e76SPhilippe Mathieu-Daudé static int default_driver_check(void *opaque, QemuOpts *opts, Error **errp)
5268d7f2e76SPhilippe Mathieu-Daudé {
5278d7f2e76SPhilippe Mathieu-Daudé     const char *driver = qemu_opt_get(opts, "driver");
5288d7f2e76SPhilippe Mathieu-Daudé 
5298d7f2e76SPhilippe Mathieu-Daudé     default_driver_disable(driver);
5308d7f2e76SPhilippe Mathieu-Daudé     return 0;
5318d7f2e76SPhilippe Mathieu-Daudé }
5328d7f2e76SPhilippe Mathieu-Daudé 
5338d7f2e76SPhilippe Mathieu-Daudé static void default_driver_check_json(void)
5348d7f2e76SPhilippe Mathieu-Daudé {
5358d7f2e76SPhilippe Mathieu-Daudé     DeviceOption *opt;
5368d7f2e76SPhilippe Mathieu-Daudé 
5378d7f2e76SPhilippe Mathieu-Daudé     QTAILQ_FOREACH(opt, &device_opts, next) {
5388d7f2e76SPhilippe Mathieu-Daudé         const char *driver = qdict_get_try_str(opt->opts, "driver");
5398d7f2e76SPhilippe Mathieu-Daudé         default_driver_disable(driver);
5408d7f2e76SPhilippe Mathieu-Daudé     }
5418d7f2e76SPhilippe Mathieu-Daudé }
5428d7f2e76SPhilippe Mathieu-Daudé 
5438d7f2e76SPhilippe Mathieu-Daudé static int parse_name(void *opaque, QemuOpts *opts, Error **errp)
5448d7f2e76SPhilippe Mathieu-Daudé {
5458d7f2e76SPhilippe Mathieu-Daudé     const char *proc_name;
5468d7f2e76SPhilippe Mathieu-Daudé 
5478d7f2e76SPhilippe Mathieu-Daudé     if (qemu_opt_get(opts, "debug-threads")) {
5488d7f2e76SPhilippe Mathieu-Daudé         qemu_thread_naming(qemu_opt_get_bool(opts, "debug-threads", false));
5498d7f2e76SPhilippe Mathieu-Daudé     }
5508d7f2e76SPhilippe Mathieu-Daudé     qemu_name = qemu_opt_get(opts, "guest");
5518d7f2e76SPhilippe Mathieu-Daudé 
5528d7f2e76SPhilippe Mathieu-Daudé     proc_name = qemu_opt_get(opts, "process");
5538d7f2e76SPhilippe Mathieu-Daudé     if (proc_name) {
5548d7f2e76SPhilippe Mathieu-Daudé         os_set_proc_name(proc_name);
5558d7f2e76SPhilippe Mathieu-Daudé     }
5568d7f2e76SPhilippe Mathieu-Daudé 
5578d7f2e76SPhilippe Mathieu-Daudé     return 0;
5588d7f2e76SPhilippe Mathieu-Daudé }
5598d7f2e76SPhilippe Mathieu-Daudé 
5608d7f2e76SPhilippe Mathieu-Daudé bool defaults_enabled(void)
5618d7f2e76SPhilippe Mathieu-Daudé {
5628d7f2e76SPhilippe Mathieu-Daudé     return has_defaults;
5638d7f2e76SPhilippe Mathieu-Daudé }
5648d7f2e76SPhilippe Mathieu-Daudé 
5658d7f2e76SPhilippe Mathieu-Daudé #ifndef _WIN32
5668d7f2e76SPhilippe Mathieu-Daudé static int parse_add_fd(void *opaque, QemuOpts *opts, Error **errp)
5678d7f2e76SPhilippe Mathieu-Daudé {
5688d7f2e76SPhilippe Mathieu-Daudé     int fd, dupfd, flags;
5698d7f2e76SPhilippe Mathieu-Daudé     int64_t fdset_id;
5708d7f2e76SPhilippe Mathieu-Daudé     const char *fd_opaque = NULL;
5718d7f2e76SPhilippe Mathieu-Daudé     AddfdInfo *fdinfo;
5728d7f2e76SPhilippe Mathieu-Daudé 
5738d7f2e76SPhilippe Mathieu-Daudé     fd = qemu_opt_get_number(opts, "fd", -1);
5748d7f2e76SPhilippe Mathieu-Daudé     fdset_id = qemu_opt_get_number(opts, "set", -1);
5758d7f2e76SPhilippe Mathieu-Daudé     fd_opaque = qemu_opt_get(opts, "opaque");
5768d7f2e76SPhilippe Mathieu-Daudé 
5778d7f2e76SPhilippe Mathieu-Daudé     if (fd < 0) {
5788d7f2e76SPhilippe Mathieu-Daudé         error_setg(errp, "fd option is required and must be non-negative");
5798d7f2e76SPhilippe Mathieu-Daudé         return -1;
5808d7f2e76SPhilippe Mathieu-Daudé     }
5818d7f2e76SPhilippe Mathieu-Daudé 
5828d7f2e76SPhilippe Mathieu-Daudé     if (fd <= STDERR_FILENO) {
5838d7f2e76SPhilippe Mathieu-Daudé         error_setg(errp, "fd cannot be a standard I/O stream");
5848d7f2e76SPhilippe Mathieu-Daudé         return -1;
5858d7f2e76SPhilippe Mathieu-Daudé     }
5868d7f2e76SPhilippe Mathieu-Daudé 
5878d7f2e76SPhilippe Mathieu-Daudé     /*
5888d7f2e76SPhilippe Mathieu-Daudé      * All fds inherited across exec() necessarily have FD_CLOEXEC
5898d7f2e76SPhilippe Mathieu-Daudé      * clear, while qemu sets FD_CLOEXEC on all other fds used internally.
5908d7f2e76SPhilippe Mathieu-Daudé      */
5918d7f2e76SPhilippe Mathieu-Daudé     flags = fcntl(fd, F_GETFD);
5928d7f2e76SPhilippe Mathieu-Daudé     if (flags == -1 || (flags & FD_CLOEXEC)) {
5938d7f2e76SPhilippe Mathieu-Daudé         error_setg(errp, "fd is not valid or already in use");
5948d7f2e76SPhilippe Mathieu-Daudé         return -1;
5958d7f2e76SPhilippe Mathieu-Daudé     }
5968d7f2e76SPhilippe Mathieu-Daudé 
5978d7f2e76SPhilippe Mathieu-Daudé     if (fdset_id < 0) {
5988d7f2e76SPhilippe Mathieu-Daudé         error_setg(errp, "set option is required and must be non-negative");
5998d7f2e76SPhilippe Mathieu-Daudé         return -1;
6008d7f2e76SPhilippe Mathieu-Daudé     }
6018d7f2e76SPhilippe Mathieu-Daudé 
6028d7f2e76SPhilippe Mathieu-Daudé #ifdef F_DUPFD_CLOEXEC
6038d7f2e76SPhilippe Mathieu-Daudé     dupfd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
6048d7f2e76SPhilippe Mathieu-Daudé #else
6058d7f2e76SPhilippe Mathieu-Daudé     dupfd = dup(fd);
6068d7f2e76SPhilippe Mathieu-Daudé     if (dupfd != -1) {
6078d7f2e76SPhilippe Mathieu-Daudé         qemu_set_cloexec(dupfd);
6088d7f2e76SPhilippe Mathieu-Daudé     }
6098d7f2e76SPhilippe Mathieu-Daudé #endif
6108d7f2e76SPhilippe Mathieu-Daudé     if (dupfd == -1) {
6118d7f2e76SPhilippe Mathieu-Daudé         error_setg(errp, "error duplicating fd: %s", strerror(errno));
6128d7f2e76SPhilippe Mathieu-Daudé         return -1;
6138d7f2e76SPhilippe Mathieu-Daudé     }
6148d7f2e76SPhilippe Mathieu-Daudé 
6158d7f2e76SPhilippe Mathieu-Daudé     /* add the duplicate fd, and optionally the opaque string, to the fd set */
6168d7f2e76SPhilippe Mathieu-Daudé     fdinfo = monitor_fdset_add_fd(dupfd, true, fdset_id, fd_opaque,
6178d7f2e76SPhilippe Mathieu-Daudé                                   &error_abort);
6188d7f2e76SPhilippe Mathieu-Daudé     g_free(fdinfo);
6198d7f2e76SPhilippe Mathieu-Daudé 
6208d7f2e76SPhilippe Mathieu-Daudé     return 0;
6218d7f2e76SPhilippe Mathieu-Daudé }
6228d7f2e76SPhilippe Mathieu-Daudé 
6238d7f2e76SPhilippe Mathieu-Daudé static int cleanup_add_fd(void *opaque, QemuOpts *opts, Error **errp)
6248d7f2e76SPhilippe Mathieu-Daudé {
6258d7f2e76SPhilippe Mathieu-Daudé     int fd;
6268d7f2e76SPhilippe Mathieu-Daudé 
6278d7f2e76SPhilippe Mathieu-Daudé     fd = qemu_opt_get_number(opts, "fd", -1);
6288d7f2e76SPhilippe Mathieu-Daudé     close(fd);
6298d7f2e76SPhilippe Mathieu-Daudé 
6308d7f2e76SPhilippe Mathieu-Daudé     return 0;
6318d7f2e76SPhilippe Mathieu-Daudé }
6328d7f2e76SPhilippe Mathieu-Daudé #endif
6338d7f2e76SPhilippe Mathieu-Daudé 
6348d7f2e76SPhilippe Mathieu-Daudé /***********************************************************/
6358d7f2e76SPhilippe Mathieu-Daudé /* QEMU Block devices */
6368d7f2e76SPhilippe Mathieu-Daudé 
6378d7f2e76SPhilippe Mathieu-Daudé #define HD_OPTS "media=disk"
6388d7f2e76SPhilippe Mathieu-Daudé #define CDROM_OPTS "media=cdrom"
6398d7f2e76SPhilippe Mathieu-Daudé #define FD_OPTS ""
6408d7f2e76SPhilippe Mathieu-Daudé #define PFLASH_OPTS ""
6418d7f2e76SPhilippe Mathieu-Daudé #define MTD_OPTS ""
6428d7f2e76SPhilippe Mathieu-Daudé #define SD_OPTS ""
6438d7f2e76SPhilippe Mathieu-Daudé 
6448d7f2e76SPhilippe Mathieu-Daudé static int drive_init_func(void *opaque, QemuOpts *opts, Error **errp)
6458d7f2e76SPhilippe Mathieu-Daudé {
6468d7f2e76SPhilippe Mathieu-Daudé     BlockInterfaceType *block_default_type = opaque;
6478d7f2e76SPhilippe Mathieu-Daudé 
6488d7f2e76SPhilippe Mathieu-Daudé     return drive_new(opts, *block_default_type, errp) == NULL;
6498d7f2e76SPhilippe Mathieu-Daudé }
6508d7f2e76SPhilippe Mathieu-Daudé 
6518d7f2e76SPhilippe Mathieu-Daudé static int drive_enable_snapshot(void *opaque, QemuOpts *opts, Error **errp)
6528d7f2e76SPhilippe Mathieu-Daudé {
6538d7f2e76SPhilippe Mathieu-Daudé     if (qemu_opt_get(opts, "snapshot") == NULL) {
6548d7f2e76SPhilippe Mathieu-Daudé         qemu_opt_set(opts, "snapshot", "on", &error_abort);
6558d7f2e76SPhilippe Mathieu-Daudé     }
6568d7f2e76SPhilippe Mathieu-Daudé     return 0;
6578d7f2e76SPhilippe Mathieu-Daudé }
6588d7f2e76SPhilippe Mathieu-Daudé 
6598d7f2e76SPhilippe Mathieu-Daudé static void default_drive(int enable, int snapshot, BlockInterfaceType type,
6608d7f2e76SPhilippe Mathieu-Daudé                           int index, const char *optstr)
6618d7f2e76SPhilippe Mathieu-Daudé {
6628d7f2e76SPhilippe Mathieu-Daudé     QemuOpts *opts;
6638d7f2e76SPhilippe Mathieu-Daudé     DriveInfo *dinfo;
6648d7f2e76SPhilippe Mathieu-Daudé 
6658d7f2e76SPhilippe Mathieu-Daudé     if (!enable || drive_get_by_index(type, index)) {
6668d7f2e76SPhilippe Mathieu-Daudé         return;
6678d7f2e76SPhilippe Mathieu-Daudé     }
6688d7f2e76SPhilippe Mathieu-Daudé 
6698d7f2e76SPhilippe Mathieu-Daudé     opts = drive_add(type, index, NULL, optstr);
6708d7f2e76SPhilippe Mathieu-Daudé     if (snapshot) {
6718d7f2e76SPhilippe Mathieu-Daudé         drive_enable_snapshot(NULL, opts, NULL);
6728d7f2e76SPhilippe Mathieu-Daudé     }
6738d7f2e76SPhilippe Mathieu-Daudé 
6748d7f2e76SPhilippe Mathieu-Daudé     dinfo = drive_new(opts, type, &error_abort);
6758d7f2e76SPhilippe Mathieu-Daudé     dinfo->is_default = true;
6768d7f2e76SPhilippe Mathieu-Daudé 
6778d7f2e76SPhilippe Mathieu-Daudé }
6788d7f2e76SPhilippe Mathieu-Daudé 
6798d7f2e76SPhilippe Mathieu-Daudé static void configure_blockdev(BlockdevOptionsQueue *bdo_queue,
6808d7f2e76SPhilippe Mathieu-Daudé                                MachineClass *machine_class, int snapshot)
6818d7f2e76SPhilippe Mathieu-Daudé {
6828d7f2e76SPhilippe Mathieu-Daudé     /*
6838d7f2e76SPhilippe Mathieu-Daudé      * If the currently selected machine wishes to override the
6848d7f2e76SPhilippe Mathieu-Daudé      * units-per-bus property of its default HBA interface type, do so
6858d7f2e76SPhilippe Mathieu-Daudé      * now.
6868d7f2e76SPhilippe Mathieu-Daudé      */
6878d7f2e76SPhilippe Mathieu-Daudé     if (machine_class->units_per_default_bus) {
6888d7f2e76SPhilippe Mathieu-Daudé         override_max_devs(machine_class->block_default_type,
6898d7f2e76SPhilippe Mathieu-Daudé                           machine_class->units_per_default_bus);
6908d7f2e76SPhilippe Mathieu-Daudé     }
6918d7f2e76SPhilippe Mathieu-Daudé 
6928d7f2e76SPhilippe Mathieu-Daudé     /* open the virtual block devices */
6938d7f2e76SPhilippe Mathieu-Daudé     while (!QSIMPLEQ_EMPTY(bdo_queue)) {
6948d7f2e76SPhilippe Mathieu-Daudé         BlockdevOptionsQueueEntry *bdo = QSIMPLEQ_FIRST(bdo_queue);
6958d7f2e76SPhilippe Mathieu-Daudé 
6968d7f2e76SPhilippe Mathieu-Daudé         QSIMPLEQ_REMOVE_HEAD(bdo_queue, entry);
6978d7f2e76SPhilippe Mathieu-Daudé         loc_push_restore(&bdo->loc);
6988d7f2e76SPhilippe Mathieu-Daudé         qmp_blockdev_add(bdo->bdo, &error_fatal);
6998d7f2e76SPhilippe Mathieu-Daudé         loc_pop(&bdo->loc);
7008d7f2e76SPhilippe Mathieu-Daudé         qapi_free_BlockdevOptions(bdo->bdo);
7018d7f2e76SPhilippe Mathieu-Daudé         g_free(bdo);
7028d7f2e76SPhilippe Mathieu-Daudé     }
7038d7f2e76SPhilippe Mathieu-Daudé     if (snapshot) {
7048d7f2e76SPhilippe Mathieu-Daudé         qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot,
7058d7f2e76SPhilippe Mathieu-Daudé                           NULL, NULL);
7068d7f2e76SPhilippe Mathieu-Daudé     }
7078d7f2e76SPhilippe Mathieu-Daudé     if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func,
7088d7f2e76SPhilippe Mathieu-Daudé                           &machine_class->block_default_type, &error_fatal)) {
7098d7f2e76SPhilippe Mathieu-Daudé         /* We printed help */
7108d7f2e76SPhilippe Mathieu-Daudé         exit(0);
7118d7f2e76SPhilippe Mathieu-Daudé     }
7128d7f2e76SPhilippe Mathieu-Daudé 
7138d7f2e76SPhilippe Mathieu-Daudé     default_drive(default_cdrom, snapshot, machine_class->block_default_type, 2,
7148d7f2e76SPhilippe Mathieu-Daudé                   CDROM_OPTS);
7158d7f2e76SPhilippe Mathieu-Daudé     default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS);
7168d7f2e76SPhilippe Mathieu-Daudé     default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS);
7178d7f2e76SPhilippe Mathieu-Daudé 
7188d7f2e76SPhilippe Mathieu-Daudé }
7198d7f2e76SPhilippe Mathieu-Daudé 
7208d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_smp_opts = {
7218d7f2e76SPhilippe Mathieu-Daudé     .name = "smp-opts",
7228d7f2e76SPhilippe Mathieu-Daudé     .implied_opt_name = "cpus",
7238d7f2e76SPhilippe Mathieu-Daudé     .merge_lists = true,
7248d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_smp_opts.head),
7258d7f2e76SPhilippe Mathieu-Daudé     .desc = {
7268d7f2e76SPhilippe Mathieu-Daudé         {
7278d7f2e76SPhilippe Mathieu-Daudé             .name = "cpus",
7288d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_NUMBER,
7298d7f2e76SPhilippe Mathieu-Daudé         }, {
7305de1aff2SPierre Morel             .name = "drawers",
7315de1aff2SPierre Morel             .type = QEMU_OPT_NUMBER,
7325de1aff2SPierre Morel         }, {
7335de1aff2SPierre Morel             .name = "books",
7345de1aff2SPierre Morel             .type = QEMU_OPT_NUMBER,
7355de1aff2SPierre Morel         }, {
7368d7f2e76SPhilippe Mathieu-Daudé             .name = "sockets",
7378d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_NUMBER,
7388d7f2e76SPhilippe Mathieu-Daudé         }, {
7398d7f2e76SPhilippe Mathieu-Daudé             .name = "dies",
7408d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_NUMBER,
7418d7f2e76SPhilippe Mathieu-Daudé         }, {
7428d7f2e76SPhilippe Mathieu-Daudé             .name = "clusters",
7438d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_NUMBER,
7448d7f2e76SPhilippe Mathieu-Daudé         }, {
7458d7f2e76SPhilippe Mathieu-Daudé             .name = "cores",
7468d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_NUMBER,
7478d7f2e76SPhilippe Mathieu-Daudé         }, {
7488d7f2e76SPhilippe Mathieu-Daudé             .name = "threads",
7498d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_NUMBER,
7508d7f2e76SPhilippe Mathieu-Daudé         }, {
7518d7f2e76SPhilippe Mathieu-Daudé             .name = "maxcpus",
7528d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_NUMBER,
7538d7f2e76SPhilippe Mathieu-Daudé         },
7548d7f2e76SPhilippe Mathieu-Daudé         { /*End of list */ }
7558d7f2e76SPhilippe Mathieu-Daudé     },
7568d7f2e76SPhilippe Mathieu-Daudé };
7578d7f2e76SPhilippe Mathieu-Daudé 
7588d7f2e76SPhilippe Mathieu-Daudé #if defined(CONFIG_POSIX)
7598d7f2e76SPhilippe Mathieu-Daudé static QemuOptsList qemu_run_with_opts = {
7608d7f2e76SPhilippe Mathieu-Daudé     .name = "run-with",
7618d7f2e76SPhilippe Mathieu-Daudé     .head = QTAILQ_HEAD_INITIALIZER(qemu_run_with_opts.head),
7628d7f2e76SPhilippe Mathieu-Daudé     .desc = {
7638d7f2e76SPhilippe Mathieu-Daudé #if defined(CONFIG_LINUX)
7648d7f2e76SPhilippe Mathieu-Daudé         {
7658d7f2e76SPhilippe Mathieu-Daudé             .name = "async-teardown",
7668d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_BOOL,
7678d7f2e76SPhilippe Mathieu-Daudé         },
7688d7f2e76SPhilippe Mathieu-Daudé #endif
7698d7f2e76SPhilippe Mathieu-Daudé         {
7708d7f2e76SPhilippe Mathieu-Daudé             .name = "chroot",
7718d7f2e76SPhilippe Mathieu-Daudé             .type = QEMU_OPT_STRING,
7728d7f2e76SPhilippe Mathieu-Daudé         },
7738d7f2e76SPhilippe Mathieu-Daudé         { /* end of list */ }
7748d7f2e76SPhilippe Mathieu-Daudé     },
7758d7f2e76SPhilippe Mathieu-Daudé };
7768d7f2e76SPhilippe Mathieu-Daudé 
7778d7f2e76SPhilippe Mathieu-Daudé #define qemu_add_run_with_opts() qemu_add_opts(&qemu_run_with_opts)
7788d7f2e76SPhilippe Mathieu-Daudé 
7798d7f2e76SPhilippe Mathieu-Daudé #else
7808d7f2e76SPhilippe Mathieu-Daudé 
7818d7f2e76SPhilippe Mathieu-Daudé #define qemu_add_run_with_opts()
7828d7f2e76SPhilippe Mathieu-Daudé 
7838d7f2e76SPhilippe Mathieu-Daudé #endif /* CONFIG_POSIX */
7848d7f2e76SPhilippe Mathieu-Daudé 
7858d7f2e76SPhilippe Mathieu-Daudé static void realtime_init(void)
7868d7f2e76SPhilippe Mathieu-Daudé {
7878d7f2e76SPhilippe Mathieu-Daudé     if (enable_mlock) {
7888d7f2e76SPhilippe Mathieu-Daudé         if (os_mlock() < 0) {
7898d7f2e76SPhilippe Mathieu-Daudé             error_report("locking memory failed");
7908d7f2e76SPhilippe Mathieu-Daudé             exit(1);
7918d7f2e76SPhilippe Mathieu-Daudé         }
7928d7f2e76SPhilippe Mathieu-Daudé     }
7938d7f2e76SPhilippe Mathieu-Daudé }
7948d7f2e76SPhilippe Mathieu-Daudé 
7958d7f2e76SPhilippe Mathieu-Daudé 
7968d7f2e76SPhilippe Mathieu-Daudé static void configure_msg(QemuOpts *opts)
7978d7f2e76SPhilippe Mathieu-Daudé {
7988d7f2e76SPhilippe Mathieu-Daudé     message_with_timestamp = qemu_opt_get_bool(opts, "timestamp", false);
7998d7f2e76SPhilippe Mathieu-Daudé     error_with_guestname = qemu_opt_get_bool(opts, "guest-name", false);
8008d7f2e76SPhilippe Mathieu-Daudé }
8018d7f2e76SPhilippe Mathieu-Daudé 
8028d7f2e76SPhilippe Mathieu-Daudé 
8038d7f2e76SPhilippe Mathieu-Daudé /***********************************************************/
8048d7f2e76SPhilippe Mathieu-Daudé /* USB devices */
8058d7f2e76SPhilippe Mathieu-Daudé 
8068d7f2e76SPhilippe Mathieu-Daudé static int usb_device_add(const char *devname)
8078d7f2e76SPhilippe Mathieu-Daudé {
8088d7f2e76SPhilippe Mathieu-Daudé     USBDevice *dev = NULL;
8098d7f2e76SPhilippe Mathieu-Daudé 
8108d7f2e76SPhilippe Mathieu-Daudé     if (!machine_usb(current_machine)) {
8118d7f2e76SPhilippe Mathieu-Daudé         return -1;
8128d7f2e76SPhilippe Mathieu-Daudé     }
8138d7f2e76SPhilippe Mathieu-Daudé 
8148d7f2e76SPhilippe Mathieu-Daudé     dev = usbdevice_create(devname);
8158d7f2e76SPhilippe Mathieu-Daudé     if (!dev)
8168d7f2e76SPhilippe Mathieu-Daudé         return -1;
8178d7f2e76SPhilippe Mathieu-Daudé 
8188d7f2e76SPhilippe Mathieu-Daudé     return 0;
8198d7f2e76SPhilippe Mathieu-Daudé }
8208d7f2e76SPhilippe Mathieu-Daudé 
8218d7f2e76SPhilippe Mathieu-Daudé static int usb_parse(const char *cmdline)
8228d7f2e76SPhilippe Mathieu-Daudé {
8238d7f2e76SPhilippe Mathieu-Daudé     int r;
8248d7f2e76SPhilippe Mathieu-Daudé     r = usb_device_add(cmdline);
8258d7f2e76SPhilippe Mathieu-Daudé     if (r < 0) {
8268d7f2e76SPhilippe Mathieu-Daudé         error_report("could not add USB device '%s'", cmdline);
8278d7f2e76SPhilippe Mathieu-Daudé     }
8288d7f2e76SPhilippe Mathieu-Daudé     return r;
8298d7f2e76SPhilippe Mathieu-Daudé }
8308d7f2e76SPhilippe Mathieu-Daudé 
8318d7f2e76SPhilippe Mathieu-Daudé /***********************************************************/
8328d7f2e76SPhilippe Mathieu-Daudé /* machine registration */
8338d7f2e76SPhilippe Mathieu-Daudé 
8348d7f2e76SPhilippe Mathieu-Daudé static MachineClass *find_machine(const char *name, GSList *machines)
8358d7f2e76SPhilippe Mathieu-Daudé {
8368d7f2e76SPhilippe Mathieu-Daudé     GSList *el;
8378d7f2e76SPhilippe Mathieu-Daudé 
8388d7f2e76SPhilippe Mathieu-Daudé     for (el = machines; el; el = el->next) {
8398d7f2e76SPhilippe Mathieu-Daudé         MachineClass *mc = el->data;
8408d7f2e76SPhilippe Mathieu-Daudé 
8418d7f2e76SPhilippe Mathieu-Daudé         if (!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) {
8428d7f2e76SPhilippe Mathieu-Daudé             return mc;
8438d7f2e76SPhilippe Mathieu-Daudé         }
8448d7f2e76SPhilippe Mathieu-Daudé     }
8458d7f2e76SPhilippe Mathieu-Daudé 
8468d7f2e76SPhilippe Mathieu-Daudé     return NULL;
8478d7f2e76SPhilippe Mathieu-Daudé }
8488d7f2e76SPhilippe Mathieu-Daudé 
8498d7f2e76SPhilippe Mathieu-Daudé static MachineClass *find_default_machine(GSList *machines)
8508d7f2e76SPhilippe Mathieu-Daudé {
8518d7f2e76SPhilippe Mathieu-Daudé     GSList *el;
8528d7f2e76SPhilippe Mathieu-Daudé     MachineClass *default_machineclass = NULL;
8538d7f2e76SPhilippe Mathieu-Daudé 
8548d7f2e76SPhilippe Mathieu-Daudé     for (el = machines; el; el = el->next) {
8558d7f2e76SPhilippe Mathieu-Daudé         MachineClass *mc = el->data;
8568d7f2e76SPhilippe Mathieu-Daudé 
8578d7f2e76SPhilippe Mathieu-Daudé         if (mc->is_default) {
8588d7f2e76SPhilippe Mathieu-Daudé             assert(default_machineclass == NULL && "Multiple default machines");
8598d7f2e76SPhilippe Mathieu-Daudé             default_machineclass = mc;
8608d7f2e76SPhilippe Mathieu-Daudé         }
8618d7f2e76SPhilippe Mathieu-Daudé     }
8628d7f2e76SPhilippe Mathieu-Daudé 
8638d7f2e76SPhilippe Mathieu-Daudé     return default_machineclass;
8648d7f2e76SPhilippe Mathieu-Daudé }
8658d7f2e76SPhilippe Mathieu-Daudé 
8668d7f2e76SPhilippe Mathieu-Daudé static void version(void)
8678d7f2e76SPhilippe Mathieu-Daudé {
8688d7f2e76SPhilippe Mathieu-Daudé     printf("QEMU emulator version " QEMU_FULL_VERSION "\n"
8698d7f2e76SPhilippe Mathieu-Daudé            QEMU_COPYRIGHT "\n");
8708d7f2e76SPhilippe Mathieu-Daudé }
8718d7f2e76SPhilippe Mathieu-Daudé 
8728d7f2e76SPhilippe Mathieu-Daudé static void help(int exitcode)
8738d7f2e76SPhilippe Mathieu-Daudé {
8748d7f2e76SPhilippe Mathieu-Daudé     version();
8758d7f2e76SPhilippe Mathieu-Daudé     printf("usage: %s [options] [disk_image]\n\n"
8768d7f2e76SPhilippe Mathieu-Daudé            "'disk_image' is a raw hard disk image for IDE hard disk 0\n\n",
8778d7f2e76SPhilippe Mathieu-Daudé             g_get_prgname());
8788d7f2e76SPhilippe Mathieu-Daudé 
8798d7f2e76SPhilippe Mathieu-Daudé #define DEF(option, opt_arg, opt_enum, opt_help, arch_mask)    \
8808d7f2e76SPhilippe Mathieu-Daudé     if ((arch_mask) & arch_type)                               \
8818d7f2e76SPhilippe Mathieu-Daudé         fputs(opt_help, stdout);
8828d7f2e76SPhilippe Mathieu-Daudé 
8838d7f2e76SPhilippe Mathieu-Daudé #define ARCHHEADING(text, arch_mask) \
8848d7f2e76SPhilippe Mathieu-Daudé     if ((arch_mask) & arch_type)    \
8858d7f2e76SPhilippe Mathieu-Daudé         puts(stringify(text));
8868d7f2e76SPhilippe Mathieu-Daudé 
8878d7f2e76SPhilippe Mathieu-Daudé #define DEFHEADING(text) ARCHHEADING(text, QEMU_ARCH_ALL)
8888d7f2e76SPhilippe Mathieu-Daudé 
8898d7f2e76SPhilippe Mathieu-Daudé #include "qemu-options.def"
8908d7f2e76SPhilippe Mathieu-Daudé 
8918d7f2e76SPhilippe Mathieu-Daudé     printf("\nDuring emulation, the following keys are useful:\n"
8928d7f2e76SPhilippe Mathieu-Daudé            "ctrl-alt-f      toggle full screen\n"
8938d7f2e76SPhilippe Mathieu-Daudé            "ctrl-alt-n      switch to virtual console 'n'\n"
8948d7f2e76SPhilippe Mathieu-Daudé            "ctrl-alt        toggle mouse and keyboard grab\n"
8958d7f2e76SPhilippe Mathieu-Daudé            "\n"
8968d7f2e76SPhilippe Mathieu-Daudé            "When using -nographic, press 'ctrl-a h' to get some help.\n"
8978d7f2e76SPhilippe Mathieu-Daudé            "\n"
8988d7f2e76SPhilippe Mathieu-Daudé            QEMU_HELP_BOTTOM "\n");
8998d7f2e76SPhilippe Mathieu-Daudé 
9008d7f2e76SPhilippe Mathieu-Daudé     exit(exitcode);
9018d7f2e76SPhilippe Mathieu-Daudé }
9028d7f2e76SPhilippe Mathieu-Daudé 
9038d7f2e76SPhilippe Mathieu-Daudé enum {
9048d7f2e76SPhilippe Mathieu-Daudé 
9058d7f2e76SPhilippe Mathieu-Daudé #define DEF(option, opt_arg, opt_enum, opt_help, arch_mask)     \
9068d7f2e76SPhilippe Mathieu-Daudé     opt_enum,
9078d7f2e76SPhilippe Mathieu-Daudé #define DEFHEADING(text)
9088d7f2e76SPhilippe Mathieu-Daudé #define ARCHHEADING(text, arch_mask)
9098d7f2e76SPhilippe Mathieu-Daudé 
9108d7f2e76SPhilippe Mathieu-Daudé #include "qemu-options.def"
9118d7f2e76SPhilippe Mathieu-Daudé };
9128d7f2e76SPhilippe Mathieu-Daudé 
9138d7f2e76SPhilippe Mathieu-Daudé #define HAS_ARG 0x0001
9148d7f2e76SPhilippe Mathieu-Daudé 
9158d7f2e76SPhilippe Mathieu-Daudé typedef struct QEMUOption {
9168d7f2e76SPhilippe Mathieu-Daudé     const char *name;
9178d7f2e76SPhilippe Mathieu-Daudé     int flags;
9188d7f2e76SPhilippe Mathieu-Daudé     int index;
9198d7f2e76SPhilippe Mathieu-Daudé     uint32_t arch_mask;
9208d7f2e76SPhilippe Mathieu-Daudé } QEMUOption;
9218d7f2e76SPhilippe Mathieu-Daudé 
9228d7f2e76SPhilippe Mathieu-Daudé static const QEMUOption qemu_options[] = {
9238d7f2e76SPhilippe Mathieu-Daudé     { "h", 0, QEMU_OPTION_h, QEMU_ARCH_ALL },
9248d7f2e76SPhilippe Mathieu-Daudé 
9258d7f2e76SPhilippe Mathieu-Daudé #define DEF(option, opt_arg, opt_enum, opt_help, arch_mask)     \
9268d7f2e76SPhilippe Mathieu-Daudé     { option, opt_arg, opt_enum, arch_mask },
9278d7f2e76SPhilippe Mathieu-Daudé #define DEFHEADING(text)
9288d7f2e76SPhilippe Mathieu-Daudé #define ARCHHEADING(text, arch_mask)
9298d7f2e76SPhilippe Mathieu-Daudé 
9308d7f2e76SPhilippe Mathieu-Daudé #include "qemu-options.def"
9318d7f2e76SPhilippe Mathieu-Daudé     { /* end of list */ }
9328d7f2e76SPhilippe Mathieu-Daudé };
9338d7f2e76SPhilippe Mathieu-Daudé 
9348d7f2e76SPhilippe Mathieu-Daudé typedef struct VGAInterfaceInfo {
9358d7f2e76SPhilippe Mathieu-Daudé     const char *opt_name;    /* option name */
9368d7f2e76SPhilippe Mathieu-Daudé     const char *name;        /* human-readable name */
9378d7f2e76SPhilippe Mathieu-Daudé     /* Class names indicating that support is available.
9388d7f2e76SPhilippe Mathieu-Daudé      * If no class is specified, the interface is always available */
9398d7f2e76SPhilippe Mathieu-Daudé     const char *class_names[2];
9408d7f2e76SPhilippe Mathieu-Daudé } VGAInterfaceInfo;
9418d7f2e76SPhilippe Mathieu-Daudé 
9428d7f2e76SPhilippe Mathieu-Daudé static const VGAInterfaceInfo vga_interfaces[VGA_TYPE_MAX] = {
9438d7f2e76SPhilippe Mathieu-Daudé     [VGA_NONE] = {
9448d7f2e76SPhilippe Mathieu-Daudé         .opt_name = "none",
9458d7f2e76SPhilippe Mathieu-Daudé         .name = "no graphic card",
9468d7f2e76SPhilippe Mathieu-Daudé     },
9478d7f2e76SPhilippe Mathieu-Daudé     [VGA_STD] = {
9488d7f2e76SPhilippe Mathieu-Daudé         .opt_name = "std",
9498d7f2e76SPhilippe Mathieu-Daudé         .name = "standard VGA",
9508d7f2e76SPhilippe Mathieu-Daudé         .class_names = { "VGA", "isa-vga" },
9518d7f2e76SPhilippe Mathieu-Daudé     },
9528d7f2e76SPhilippe Mathieu-Daudé     [VGA_CIRRUS] = {
9538d7f2e76SPhilippe Mathieu-Daudé         .opt_name = "cirrus",
9548d7f2e76SPhilippe Mathieu-Daudé         .name = "Cirrus VGA",
9558d7f2e76SPhilippe Mathieu-Daudé         .class_names = { "cirrus-vga", "isa-cirrus-vga" },
9568d7f2e76SPhilippe Mathieu-Daudé     },
9578d7f2e76SPhilippe Mathieu-Daudé     [VGA_VMWARE] = {
9588d7f2e76SPhilippe Mathieu-Daudé         .opt_name = "vmware",
9598d7f2e76SPhilippe Mathieu-Daudé         .name = "VMWare SVGA",
9608d7f2e76SPhilippe Mathieu-Daudé         .class_names = { "vmware-svga" },
9618d7f2e76SPhilippe Mathieu-Daudé     },
9628d7f2e76SPhilippe Mathieu-Daudé     [VGA_VIRTIO] = {
9638d7f2e76SPhilippe Mathieu-Daudé         .opt_name = "virtio",
9648d7f2e76SPhilippe Mathieu-Daudé         .name = "Virtio VGA",
9658d7f2e76SPhilippe Mathieu-Daudé         .class_names = { "virtio-vga" },
9668d7f2e76SPhilippe Mathieu-Daudé     },
9678d7f2e76SPhilippe Mathieu-Daudé     [VGA_QXL] = {
9688d7f2e76SPhilippe Mathieu-Daudé         .opt_name = "qxl",
9698d7f2e76SPhilippe Mathieu-Daudé         .name = "QXL VGA",
9708d7f2e76SPhilippe Mathieu-Daudé         .class_names = { "qxl-vga" },
9718d7f2e76SPhilippe Mathieu-Daudé     },
9728d7f2e76SPhilippe Mathieu-Daudé     [VGA_TCX] = {
9738d7f2e76SPhilippe Mathieu-Daudé         .opt_name = "tcx",
9748d7f2e76SPhilippe Mathieu-Daudé         .name = "TCX framebuffer",
9758d7f2e76SPhilippe Mathieu-Daudé         .class_names = { "sun-tcx" },
9768d7f2e76SPhilippe Mathieu-Daudé     },
9778d7f2e76SPhilippe Mathieu-Daudé     [VGA_CG3] = {
9788d7f2e76SPhilippe Mathieu-Daudé         .opt_name = "cg3",
9798d7f2e76SPhilippe Mathieu-Daudé         .name = "CG3 framebuffer",
9808d7f2e76SPhilippe Mathieu-Daudé         .class_names = { "cgthree" },
9818d7f2e76SPhilippe Mathieu-Daudé     },
9828d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_XEN_BACKEND
9838d7f2e76SPhilippe Mathieu-Daudé     [VGA_XENFB] = {
9848d7f2e76SPhilippe Mathieu-Daudé         .opt_name = "xenfb",
9858d7f2e76SPhilippe Mathieu-Daudé         .name = "Xen paravirtualized framebuffer",
9868d7f2e76SPhilippe Mathieu-Daudé     },
9878d7f2e76SPhilippe Mathieu-Daudé #endif
9888d7f2e76SPhilippe Mathieu-Daudé };
9898d7f2e76SPhilippe Mathieu-Daudé 
9908d7f2e76SPhilippe Mathieu-Daudé static bool vga_interface_available(VGAInterfaceType t)
9918d7f2e76SPhilippe Mathieu-Daudé {
9928d7f2e76SPhilippe Mathieu-Daudé     const VGAInterfaceInfo *ti = &vga_interfaces[t];
9938d7f2e76SPhilippe Mathieu-Daudé 
9948d7f2e76SPhilippe Mathieu-Daudé     assert(t < VGA_TYPE_MAX);
9958d7f2e76SPhilippe Mathieu-Daudé     return !ti->class_names[0] ||
9968d7f2e76SPhilippe Mathieu-Daudé            module_object_class_by_name(ti->class_names[0]) ||
9978d7f2e76SPhilippe Mathieu-Daudé            module_object_class_by_name(ti->class_names[1]);
9988d7f2e76SPhilippe Mathieu-Daudé }
9998d7f2e76SPhilippe Mathieu-Daudé 
10008d7f2e76SPhilippe Mathieu-Daudé static const char *
10018d7f2e76SPhilippe Mathieu-Daudé get_default_vga_model(const MachineClass *machine_class)
10028d7f2e76SPhilippe Mathieu-Daudé {
10038d7f2e76SPhilippe Mathieu-Daudé     if (machine_class->default_display) {
10048d7f2e76SPhilippe Mathieu-Daudé         for (int t = 0; t < VGA_TYPE_MAX; t++) {
10058d7f2e76SPhilippe Mathieu-Daudé             const VGAInterfaceInfo *ti = &vga_interfaces[t];
10068d7f2e76SPhilippe Mathieu-Daudé 
10078d7f2e76SPhilippe Mathieu-Daudé             if (ti->opt_name && vga_interface_available(t) &&
10088d7f2e76SPhilippe Mathieu-Daudé                 g_str_equal(ti->opt_name, machine_class->default_display)) {
10098d7f2e76SPhilippe Mathieu-Daudé                 return machine_class->default_display;
10108d7f2e76SPhilippe Mathieu-Daudé             }
10118d7f2e76SPhilippe Mathieu-Daudé         }
10128d7f2e76SPhilippe Mathieu-Daudé 
10138d7f2e76SPhilippe Mathieu-Daudé         warn_report_once("Default display '%s' is not available in this binary",
10148d7f2e76SPhilippe Mathieu-Daudé                          machine_class->default_display);
10158d7f2e76SPhilippe Mathieu-Daudé         return NULL;
10168d7f2e76SPhilippe Mathieu-Daudé     } else if (vga_interface_available(VGA_CIRRUS)) {
10178d7f2e76SPhilippe Mathieu-Daudé         return "cirrus";
10188d7f2e76SPhilippe Mathieu-Daudé     } else if (vga_interface_available(VGA_STD)) {
10198d7f2e76SPhilippe Mathieu-Daudé         return "std";
10208d7f2e76SPhilippe Mathieu-Daudé     }
10218d7f2e76SPhilippe Mathieu-Daudé 
10228d7f2e76SPhilippe Mathieu-Daudé     return NULL;
10238d7f2e76SPhilippe Mathieu-Daudé }
10248d7f2e76SPhilippe Mathieu-Daudé 
10258d7f2e76SPhilippe Mathieu-Daudé static void select_vgahw(const MachineClass *machine_class, const char *p)
10268d7f2e76SPhilippe Mathieu-Daudé {
10278d7f2e76SPhilippe Mathieu-Daudé     const char *opts;
10288d7f2e76SPhilippe Mathieu-Daudé     int t;
10298d7f2e76SPhilippe Mathieu-Daudé 
10308d7f2e76SPhilippe Mathieu-Daudé     if (g_str_equal(p, "help")) {
10318d7f2e76SPhilippe Mathieu-Daudé         const char *def = get_default_vga_model(machine_class);
10328d7f2e76SPhilippe Mathieu-Daudé 
10338d7f2e76SPhilippe Mathieu-Daudé         for (t = 0; t < VGA_TYPE_MAX; t++) {
10348d7f2e76SPhilippe Mathieu-Daudé             const VGAInterfaceInfo *ti = &vga_interfaces[t];
10358d7f2e76SPhilippe Mathieu-Daudé 
10368d7f2e76SPhilippe Mathieu-Daudé             if (vga_interface_available(t) && ti->opt_name) {
10378d7f2e76SPhilippe Mathieu-Daudé                 printf("%-20s %s%s\n", ti->opt_name, ti->name ?: "",
10388d7f2e76SPhilippe Mathieu-Daudé                         (def && g_str_equal(ti->opt_name, def)) ?
10398d7f2e76SPhilippe Mathieu-Daudé                         " (default)" : "");
10408d7f2e76SPhilippe Mathieu-Daudé             }
10418d7f2e76SPhilippe Mathieu-Daudé         }
10428d7f2e76SPhilippe Mathieu-Daudé         exit(0);
10438d7f2e76SPhilippe Mathieu-Daudé     }
10448d7f2e76SPhilippe Mathieu-Daudé 
10458d7f2e76SPhilippe Mathieu-Daudé     assert(vga_interface_type == VGA_NONE);
10468d7f2e76SPhilippe Mathieu-Daudé     for (t = 0; t < VGA_TYPE_MAX; t++) {
10478d7f2e76SPhilippe Mathieu-Daudé         const VGAInterfaceInfo *ti = &vga_interfaces[t];
10488d7f2e76SPhilippe Mathieu-Daudé         if (ti->opt_name && strstart(p, ti->opt_name, &opts)) {
10498d7f2e76SPhilippe Mathieu-Daudé             if (!vga_interface_available(t)) {
10508d7f2e76SPhilippe Mathieu-Daudé                 error_report("%s not available", ti->name);
10518d7f2e76SPhilippe Mathieu-Daudé                 exit(1);
10528d7f2e76SPhilippe Mathieu-Daudé             }
10538d7f2e76SPhilippe Mathieu-Daudé             vga_interface_type = t;
10548d7f2e76SPhilippe Mathieu-Daudé             break;
10558d7f2e76SPhilippe Mathieu-Daudé         }
10568d7f2e76SPhilippe Mathieu-Daudé     }
10578d7f2e76SPhilippe Mathieu-Daudé     if (t == VGA_TYPE_MAX) {
10588d7f2e76SPhilippe Mathieu-Daudé     invalid_vga:
10598d7f2e76SPhilippe Mathieu-Daudé         error_report("unknown vga type: %s", p);
10608d7f2e76SPhilippe Mathieu-Daudé         exit(1);
10618d7f2e76SPhilippe Mathieu-Daudé     }
10628d7f2e76SPhilippe Mathieu-Daudé     while (*opts) {
10638d7f2e76SPhilippe Mathieu-Daudé         const char *nextopt;
10648d7f2e76SPhilippe Mathieu-Daudé 
10658d7f2e76SPhilippe Mathieu-Daudé         if (strstart(opts, ",retrace=", &nextopt)) {
10668d7f2e76SPhilippe Mathieu-Daudé             opts = nextopt;
10678d7f2e76SPhilippe Mathieu-Daudé             if (strstart(opts, "dumb", &nextopt))
10688d7f2e76SPhilippe Mathieu-Daudé                 vga_retrace_method = VGA_RETRACE_DUMB;
10698d7f2e76SPhilippe Mathieu-Daudé             else if (strstart(opts, "precise", &nextopt))
10708d7f2e76SPhilippe Mathieu-Daudé                 vga_retrace_method = VGA_RETRACE_PRECISE;
10718d7f2e76SPhilippe Mathieu-Daudé             else goto invalid_vga;
10728d7f2e76SPhilippe Mathieu-Daudé         } else goto invalid_vga;
10738d7f2e76SPhilippe Mathieu-Daudé         opts = nextopt;
10748d7f2e76SPhilippe Mathieu-Daudé     }
10758d7f2e76SPhilippe Mathieu-Daudé }
10768d7f2e76SPhilippe Mathieu-Daudé 
10771527c6b6SStefan Hajnoczi static void parse_display_qapi(const char *str)
10788d7f2e76SPhilippe Mathieu-Daudé {
10798d7f2e76SPhilippe Mathieu-Daudé     DisplayOptions *opts;
10808d7f2e76SPhilippe Mathieu-Daudé     Visitor *v;
10818d7f2e76SPhilippe Mathieu-Daudé 
10821527c6b6SStefan Hajnoczi     v = qobject_input_visitor_new_str(str, "type", &error_fatal);
10838d7f2e76SPhilippe Mathieu-Daudé 
10848d7f2e76SPhilippe Mathieu-Daudé     visit_type_DisplayOptions(v, NULL, &opts, &error_fatal);
10858d7f2e76SPhilippe Mathieu-Daudé     QAPI_CLONE_MEMBERS(DisplayOptions, &dpy, opts);
10868d7f2e76SPhilippe Mathieu-Daudé 
10878d7f2e76SPhilippe Mathieu-Daudé     qapi_free_DisplayOptions(opts);
10888d7f2e76SPhilippe Mathieu-Daudé     visit_free(v);
10898d7f2e76SPhilippe Mathieu-Daudé }
10908d7f2e76SPhilippe Mathieu-Daudé 
10918d7f2e76SPhilippe Mathieu-Daudé DisplayOptions *qmp_query_display_options(Error **errp)
10928d7f2e76SPhilippe Mathieu-Daudé {
10938d7f2e76SPhilippe Mathieu-Daudé     return QAPI_CLONE(DisplayOptions, &dpy);
10948d7f2e76SPhilippe Mathieu-Daudé }
10958d7f2e76SPhilippe Mathieu-Daudé 
10968d7f2e76SPhilippe Mathieu-Daudé static void parse_display(const char *p)
10978d7f2e76SPhilippe Mathieu-Daudé {
10988d7f2e76SPhilippe Mathieu-Daudé     if (is_help_option(p)) {
10998d7f2e76SPhilippe Mathieu-Daudé         qemu_display_help();
11008d7f2e76SPhilippe Mathieu-Daudé         exit(0);
11018d7f2e76SPhilippe Mathieu-Daudé     }
11028d7f2e76SPhilippe Mathieu-Daudé 
1103*6261164bSMarc-André Lureau #ifdef CONFIG_VNC
1104*6261164bSMarc-André Lureau     const char *opts;
1105*6261164bSMarc-André Lureau 
11068d7f2e76SPhilippe Mathieu-Daudé     if (strstart(p, "vnc", &opts)) {
11078d7f2e76SPhilippe Mathieu-Daudé         /*
11088d7f2e76SPhilippe Mathieu-Daudé          * vnc isn't a (local) DisplayType but a protocol for remote
11098d7f2e76SPhilippe Mathieu-Daudé          * display access.
11108d7f2e76SPhilippe Mathieu-Daudé          */
11118d7f2e76SPhilippe Mathieu-Daudé         if (*opts == '=') {
11128d7f2e76SPhilippe Mathieu-Daudé             vnc_parse(opts + 1);
11138d7f2e76SPhilippe Mathieu-Daudé         } else {
11148d7f2e76SPhilippe Mathieu-Daudé             error_report("VNC requires a display argument vnc=<display>");
11158d7f2e76SPhilippe Mathieu-Daudé             exit(1);
11168d7f2e76SPhilippe Mathieu-Daudé         }
1117*6261164bSMarc-André Lureau         return;
11188d7f2e76SPhilippe Mathieu-Daudé     }
1119*6261164bSMarc-André Lureau #endif
1120*6261164bSMarc-André Lureau 
1121*6261164bSMarc-André Lureau     parse_display_qapi(p);
11228d7f2e76SPhilippe Mathieu-Daudé }
11238d7f2e76SPhilippe Mathieu-Daudé 
11248d7f2e76SPhilippe Mathieu-Daudé static inline bool nonempty_str(const char *str)
11258d7f2e76SPhilippe Mathieu-Daudé {
11268d7f2e76SPhilippe Mathieu-Daudé     return str && *str;
11278d7f2e76SPhilippe Mathieu-Daudé }
11288d7f2e76SPhilippe Mathieu-Daudé 
11298d7f2e76SPhilippe Mathieu-Daudé static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
11308d7f2e76SPhilippe Mathieu-Daudé {
11318d7f2e76SPhilippe Mathieu-Daudé     gchar *buf;
11328d7f2e76SPhilippe Mathieu-Daudé     size_t size;
11338d7f2e76SPhilippe Mathieu-Daudé     const char *name, *file, *str, *gen_id;
11348d7f2e76SPhilippe Mathieu-Daudé     FWCfgState *fw_cfg = (FWCfgState *) opaque;
11358d7f2e76SPhilippe Mathieu-Daudé 
11368d7f2e76SPhilippe Mathieu-Daudé     if (fw_cfg == NULL) {
11378d7f2e76SPhilippe Mathieu-Daudé         error_setg(errp, "fw_cfg device not available");
11388d7f2e76SPhilippe Mathieu-Daudé         return -1;
11398d7f2e76SPhilippe Mathieu-Daudé     }
11408d7f2e76SPhilippe Mathieu-Daudé     name = qemu_opt_get(opts, "name");
11418d7f2e76SPhilippe Mathieu-Daudé     file = qemu_opt_get(opts, "file");
11428d7f2e76SPhilippe Mathieu-Daudé     str = qemu_opt_get(opts, "string");
11438d7f2e76SPhilippe Mathieu-Daudé     gen_id = qemu_opt_get(opts, "gen_id");
11448d7f2e76SPhilippe Mathieu-Daudé 
11458d7f2e76SPhilippe Mathieu-Daudé     /* we need the name, and exactly one of: file, content string, gen_id */
11468d7f2e76SPhilippe Mathieu-Daudé     if (!nonempty_str(name) ||
11478d7f2e76SPhilippe Mathieu-Daudé         nonempty_str(file) + nonempty_str(str) + nonempty_str(gen_id) != 1) {
11488d7f2e76SPhilippe Mathieu-Daudé         error_setg(errp, "name, plus exactly one of file,"
11498d7f2e76SPhilippe Mathieu-Daudé                          " string and gen_id, are needed");
11508d7f2e76SPhilippe Mathieu-Daudé         return -1;
11518d7f2e76SPhilippe Mathieu-Daudé     }
11528d7f2e76SPhilippe Mathieu-Daudé     if (strlen(name) > FW_CFG_MAX_FILE_PATH - 1) {
11538d7f2e76SPhilippe Mathieu-Daudé         error_setg(errp, "name too long (max. %d char)",
11548d7f2e76SPhilippe Mathieu-Daudé                    FW_CFG_MAX_FILE_PATH - 1);
11558d7f2e76SPhilippe Mathieu-Daudé         return -1;
11568d7f2e76SPhilippe Mathieu-Daudé     }
11578d7f2e76SPhilippe Mathieu-Daudé     if (nonempty_str(gen_id)) {
11588d7f2e76SPhilippe Mathieu-Daudé         /*
11598d7f2e76SPhilippe Mathieu-Daudé          * In this particular case where the content is populated
11608d7f2e76SPhilippe Mathieu-Daudé          * internally, the "etc/" namespace protection is relaxed,
11618d7f2e76SPhilippe Mathieu-Daudé          * so do not emit a warning.
11628d7f2e76SPhilippe Mathieu-Daudé          */
11638d7f2e76SPhilippe Mathieu-Daudé     } else if (strncmp(name, "opt/", 4) != 0) {
11648d7f2e76SPhilippe Mathieu-Daudé         warn_report("externally provided fw_cfg item names "
11658d7f2e76SPhilippe Mathieu-Daudé                     "should be prefixed with \"opt/\"");
11668d7f2e76SPhilippe Mathieu-Daudé     }
11678d7f2e76SPhilippe Mathieu-Daudé     if (nonempty_str(str)) {
11688d7f2e76SPhilippe Mathieu-Daudé         size = strlen(str); /* NUL terminator NOT included in fw_cfg blob */
11698d7f2e76SPhilippe Mathieu-Daudé         buf = g_memdup(str, size);
11708d7f2e76SPhilippe Mathieu-Daudé     } else if (nonempty_str(gen_id)) {
11718d7f2e76SPhilippe Mathieu-Daudé         if (!fw_cfg_add_from_generator(fw_cfg, name, gen_id, errp)) {
11728d7f2e76SPhilippe Mathieu-Daudé             return -1;
11738d7f2e76SPhilippe Mathieu-Daudé         }
11748d7f2e76SPhilippe Mathieu-Daudé         return 0;
11758d7f2e76SPhilippe Mathieu-Daudé     } else {
11768d7f2e76SPhilippe Mathieu-Daudé         GError *err = NULL;
11778d7f2e76SPhilippe Mathieu-Daudé         if (!g_file_get_contents(file, &buf, &size, &err)) {
11788d7f2e76SPhilippe Mathieu-Daudé             error_setg(errp, "can't load %s: %s", file, err->message);
11798d7f2e76SPhilippe Mathieu-Daudé             g_error_free(err);
11808d7f2e76SPhilippe Mathieu-Daudé             return -1;
11818d7f2e76SPhilippe Mathieu-Daudé         }
11828d7f2e76SPhilippe Mathieu-Daudé     }
11838d7f2e76SPhilippe Mathieu-Daudé     /* For legacy, keep user files in a specific global order. */
11848d7f2e76SPhilippe Mathieu-Daudé     fw_cfg_set_order_override(fw_cfg, FW_CFG_ORDER_OVERRIDE_USER);
11858d7f2e76SPhilippe Mathieu-Daudé     fw_cfg_add_file(fw_cfg, name, buf, size);
11868d7f2e76SPhilippe Mathieu-Daudé     fw_cfg_reset_order_override(fw_cfg);
11878d7f2e76SPhilippe Mathieu-Daudé     return 0;
11888d7f2e76SPhilippe Mathieu-Daudé }
11898d7f2e76SPhilippe Mathieu-Daudé 
11908d7f2e76SPhilippe Mathieu-Daudé static int device_help_func(void *opaque, QemuOpts *opts, Error **errp)
11918d7f2e76SPhilippe Mathieu-Daudé {
11928d7f2e76SPhilippe Mathieu-Daudé     return qdev_device_help(opts);
11938d7f2e76SPhilippe Mathieu-Daudé }
11948d7f2e76SPhilippe Mathieu-Daudé 
11958d7f2e76SPhilippe Mathieu-Daudé static int device_init_func(void *opaque, QemuOpts *opts, Error **errp)
11968d7f2e76SPhilippe Mathieu-Daudé {
11978d7f2e76SPhilippe Mathieu-Daudé     DeviceState *dev;
11988d7f2e76SPhilippe Mathieu-Daudé 
11998d7f2e76SPhilippe Mathieu-Daudé     dev = qdev_device_add(opts, errp);
12008d7f2e76SPhilippe Mathieu-Daudé     if (!dev && *errp) {
12018d7f2e76SPhilippe Mathieu-Daudé         error_report_err(*errp);
12028d7f2e76SPhilippe Mathieu-Daudé         return -1;
12038d7f2e76SPhilippe Mathieu-Daudé     } else if (dev) {
12048d7f2e76SPhilippe Mathieu-Daudé         object_unref(OBJECT(dev));
12058d7f2e76SPhilippe Mathieu-Daudé     }
12068d7f2e76SPhilippe Mathieu-Daudé     return 0;
12078d7f2e76SPhilippe Mathieu-Daudé }
12088d7f2e76SPhilippe Mathieu-Daudé 
12098d7f2e76SPhilippe Mathieu-Daudé static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp)
12108d7f2e76SPhilippe Mathieu-Daudé {
12118d7f2e76SPhilippe Mathieu-Daudé     Error *local_err = NULL;
12128d7f2e76SPhilippe Mathieu-Daudé 
12138d7f2e76SPhilippe Mathieu-Daudé     if (!qemu_chr_new_from_opts(opts, NULL, &local_err)) {
12148d7f2e76SPhilippe Mathieu-Daudé         if (local_err) {
12158d7f2e76SPhilippe Mathieu-Daudé             error_propagate(errp, local_err);
12168d7f2e76SPhilippe Mathieu-Daudé             return -1;
12178d7f2e76SPhilippe Mathieu-Daudé         }
12188d7f2e76SPhilippe Mathieu-Daudé         exit(0);
12198d7f2e76SPhilippe Mathieu-Daudé     }
12208d7f2e76SPhilippe Mathieu-Daudé     return 0;
12218d7f2e76SPhilippe Mathieu-Daudé }
12228d7f2e76SPhilippe Mathieu-Daudé 
12238d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTFS
12248d7f2e76SPhilippe Mathieu-Daudé static int fsdev_init_func(void *opaque, QemuOpts *opts, Error **errp)
12258d7f2e76SPhilippe Mathieu-Daudé {
12268d7f2e76SPhilippe Mathieu-Daudé     return qemu_fsdev_add(opts, errp);
12278d7f2e76SPhilippe Mathieu-Daudé }
12288d7f2e76SPhilippe Mathieu-Daudé #endif
12298d7f2e76SPhilippe Mathieu-Daudé 
12308d7f2e76SPhilippe Mathieu-Daudé static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)
12318d7f2e76SPhilippe Mathieu-Daudé {
12328d7f2e76SPhilippe Mathieu-Daudé     return monitor_init_opts(opts, errp);
12338d7f2e76SPhilippe Mathieu-Daudé }
12348d7f2e76SPhilippe Mathieu-Daudé 
12351527c6b6SStefan Hajnoczi static void monitor_parse(const char *str, const char *mode, bool pretty)
12368d7f2e76SPhilippe Mathieu-Daudé {
12378d7f2e76SPhilippe Mathieu-Daudé     static int monitor_device_index = 0;
12388d7f2e76SPhilippe Mathieu-Daudé     QemuOpts *opts;
12398d7f2e76SPhilippe Mathieu-Daudé     const char *p;
12408d7f2e76SPhilippe Mathieu-Daudé     char label[32];
12418d7f2e76SPhilippe Mathieu-Daudé 
12421527c6b6SStefan Hajnoczi     if (strstart(str, "chardev:", &p)) {
12438d7f2e76SPhilippe Mathieu-Daudé         snprintf(label, sizeof(label), "%s", p);
12448d7f2e76SPhilippe Mathieu-Daudé     } else {
12458d7f2e76SPhilippe Mathieu-Daudé         snprintf(label, sizeof(label), "compat_monitor%d",
12468d7f2e76SPhilippe Mathieu-Daudé                  monitor_device_index);
12471527c6b6SStefan Hajnoczi         opts = qemu_chr_parse_compat(label, str, true);
12488d7f2e76SPhilippe Mathieu-Daudé         if (!opts) {
12491527c6b6SStefan Hajnoczi             error_report("parse error: %s", str);
12508d7f2e76SPhilippe Mathieu-Daudé             exit(1);
12518d7f2e76SPhilippe Mathieu-Daudé         }
12528d7f2e76SPhilippe Mathieu-Daudé     }
12538d7f2e76SPhilippe Mathieu-Daudé 
12548d7f2e76SPhilippe Mathieu-Daudé     opts = qemu_opts_create(qemu_find_opts("mon"), label, 1, &error_fatal);
12558d7f2e76SPhilippe Mathieu-Daudé     qemu_opt_set(opts, "mode", mode, &error_abort);
12568d7f2e76SPhilippe Mathieu-Daudé     qemu_opt_set(opts, "chardev", label, &error_abort);
12578d7f2e76SPhilippe Mathieu-Daudé     if (!strcmp(mode, "control")) {
12588d7f2e76SPhilippe Mathieu-Daudé         qemu_opt_set_bool(opts, "pretty", pretty, &error_abort);
12598d7f2e76SPhilippe Mathieu-Daudé     } else {
12608d7f2e76SPhilippe Mathieu-Daudé         assert(pretty == false);
12618d7f2e76SPhilippe Mathieu-Daudé     }
12628d7f2e76SPhilippe Mathieu-Daudé     monitor_device_index++;
12638d7f2e76SPhilippe Mathieu-Daudé }
12648d7f2e76SPhilippe Mathieu-Daudé 
12658d7f2e76SPhilippe Mathieu-Daudé struct device_config {
12668d7f2e76SPhilippe Mathieu-Daudé     enum {
12678d7f2e76SPhilippe Mathieu-Daudé         DEV_USB,       /* -usbdevice     */
12688d7f2e76SPhilippe Mathieu-Daudé         DEV_SERIAL,    /* -serial        */
12698d7f2e76SPhilippe Mathieu-Daudé         DEV_PARALLEL,  /* -parallel      */
12708d7f2e76SPhilippe Mathieu-Daudé         DEV_DEBUGCON,  /* -debugcon */
12718d7f2e76SPhilippe Mathieu-Daudé         DEV_GDB,       /* -gdb, -s */
12728d7f2e76SPhilippe Mathieu-Daudé         DEV_SCLP,      /* s390 sclp */
12738d7f2e76SPhilippe Mathieu-Daudé     } type;
12748d7f2e76SPhilippe Mathieu-Daudé     const char *cmdline;
12758d7f2e76SPhilippe Mathieu-Daudé     Location loc;
12768d7f2e76SPhilippe Mathieu-Daudé     QTAILQ_ENTRY(device_config) next;
12778d7f2e76SPhilippe Mathieu-Daudé };
12788d7f2e76SPhilippe Mathieu-Daudé 
12798d7f2e76SPhilippe Mathieu-Daudé static QTAILQ_HEAD(, device_config) device_configs =
12808d7f2e76SPhilippe Mathieu-Daudé     QTAILQ_HEAD_INITIALIZER(device_configs);
12818d7f2e76SPhilippe Mathieu-Daudé 
12828d7f2e76SPhilippe Mathieu-Daudé static void add_device_config(int type, const char *cmdline)
12838d7f2e76SPhilippe Mathieu-Daudé {
12848d7f2e76SPhilippe Mathieu-Daudé     struct device_config *conf;
12858d7f2e76SPhilippe Mathieu-Daudé 
12868d7f2e76SPhilippe Mathieu-Daudé     conf = g_malloc0(sizeof(*conf));
12878d7f2e76SPhilippe Mathieu-Daudé     conf->type = type;
12888d7f2e76SPhilippe Mathieu-Daudé     conf->cmdline = cmdline;
12898d7f2e76SPhilippe Mathieu-Daudé     loc_save(&conf->loc);
12908d7f2e76SPhilippe Mathieu-Daudé     QTAILQ_INSERT_TAIL(&device_configs, conf, next);
12918d7f2e76SPhilippe Mathieu-Daudé }
12928d7f2e76SPhilippe Mathieu-Daudé 
12938d7f2e76SPhilippe Mathieu-Daudé static int foreach_device_config(int type, int (*func)(const char *cmdline))
12948d7f2e76SPhilippe Mathieu-Daudé {
12958d7f2e76SPhilippe Mathieu-Daudé     struct device_config *conf;
12968d7f2e76SPhilippe Mathieu-Daudé     int rc;
12978d7f2e76SPhilippe Mathieu-Daudé 
12988d7f2e76SPhilippe Mathieu-Daudé     QTAILQ_FOREACH(conf, &device_configs, next) {
12998d7f2e76SPhilippe Mathieu-Daudé         if (conf->type != type)
13008d7f2e76SPhilippe Mathieu-Daudé             continue;
13018d7f2e76SPhilippe Mathieu-Daudé         loc_push_restore(&conf->loc);
13028d7f2e76SPhilippe Mathieu-Daudé         rc = func(conf->cmdline);
13038d7f2e76SPhilippe Mathieu-Daudé         loc_pop(&conf->loc);
13048d7f2e76SPhilippe Mathieu-Daudé         if (rc) {
13058d7f2e76SPhilippe Mathieu-Daudé             return rc;
13068d7f2e76SPhilippe Mathieu-Daudé         }
13078d7f2e76SPhilippe Mathieu-Daudé     }
13088d7f2e76SPhilippe Mathieu-Daudé     return 0;
13098d7f2e76SPhilippe Mathieu-Daudé }
13108d7f2e76SPhilippe Mathieu-Daudé 
13118d7f2e76SPhilippe Mathieu-Daudé static void qemu_disable_default_devices(void)
13128d7f2e76SPhilippe Mathieu-Daudé {
13138d7f2e76SPhilippe Mathieu-Daudé     MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
13148d7f2e76SPhilippe Mathieu-Daudé 
13158d7f2e76SPhilippe Mathieu-Daudé     default_driver_check_json();
13168d7f2e76SPhilippe Mathieu-Daudé     qemu_opts_foreach(qemu_find_opts("device"),
13178d7f2e76SPhilippe Mathieu-Daudé                       default_driver_check, NULL, NULL);
13188d7f2e76SPhilippe Mathieu-Daudé     qemu_opts_foreach(qemu_find_opts("global"),
13198d7f2e76SPhilippe Mathieu-Daudé                       default_driver_check, NULL, NULL);
13208d7f2e76SPhilippe Mathieu-Daudé 
13218d7f2e76SPhilippe Mathieu-Daudé     if (!vga_model && !default_vga) {
13228d7f2e76SPhilippe Mathieu-Daudé         vga_interface_type = VGA_DEVICE;
13238d7f2e76SPhilippe Mathieu-Daudé         vga_interface_created = true;
13248d7f2e76SPhilippe Mathieu-Daudé     }
13258d7f2e76SPhilippe Mathieu-Daudé     if (!has_defaults || machine_class->no_serial) {
13268d7f2e76SPhilippe Mathieu-Daudé         default_serial = 0;
13278d7f2e76SPhilippe Mathieu-Daudé     }
13288d7f2e76SPhilippe Mathieu-Daudé     if (!has_defaults || machine_class->no_parallel) {
13298d7f2e76SPhilippe Mathieu-Daudé         default_parallel = 0;
13308d7f2e76SPhilippe Mathieu-Daudé     }
13318d7f2e76SPhilippe Mathieu-Daudé     if (!has_defaults || machine_class->no_floppy) {
13328d7f2e76SPhilippe Mathieu-Daudé         default_floppy = 0;
13338d7f2e76SPhilippe Mathieu-Daudé     }
13348d7f2e76SPhilippe Mathieu-Daudé     if (!has_defaults || machine_class->no_cdrom) {
13358d7f2e76SPhilippe Mathieu-Daudé         default_cdrom = 0;
13368d7f2e76SPhilippe Mathieu-Daudé     }
13378d7f2e76SPhilippe Mathieu-Daudé     if (!has_defaults || machine_class->no_sdcard) {
13388d7f2e76SPhilippe Mathieu-Daudé         default_sdcard = 0;
13398d7f2e76SPhilippe Mathieu-Daudé     }
13408d7f2e76SPhilippe Mathieu-Daudé     if (!has_defaults) {
1341c753bf47SPaolo Bonzini         default_audio = 0;
13428d7f2e76SPhilippe Mathieu-Daudé         default_monitor = 0;
13438d7f2e76SPhilippe Mathieu-Daudé         default_net = 0;
13448d7f2e76SPhilippe Mathieu-Daudé         default_vga = 0;
13458d7f2e76SPhilippe Mathieu-Daudé     } else {
13468d7f2e76SPhilippe Mathieu-Daudé         if (default_net && machine_class->default_nic &&
13478d7f2e76SPhilippe Mathieu-Daudé             !module_object_class_by_name(machine_class->default_nic)) {
13488d7f2e76SPhilippe Mathieu-Daudé             warn_report("Default NIC '%s' is not available in this binary",
13498d7f2e76SPhilippe Mathieu-Daudé                         machine_class->default_nic);
13508d7f2e76SPhilippe Mathieu-Daudé             default_net = 0;
13518d7f2e76SPhilippe Mathieu-Daudé         }
13528d7f2e76SPhilippe Mathieu-Daudé     }
13538d7f2e76SPhilippe Mathieu-Daudé }
13548d7f2e76SPhilippe Mathieu-Daudé 
13558d7f2e76SPhilippe Mathieu-Daudé static void qemu_create_default_devices(void)
13568d7f2e76SPhilippe Mathieu-Daudé {
13578d7f2e76SPhilippe Mathieu-Daudé     MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
13588d7f2e76SPhilippe Mathieu-Daudé 
13598d7f2e76SPhilippe Mathieu-Daudé     if (is_daemonized()) {
13608d7f2e76SPhilippe Mathieu-Daudé         /* According to documentation and historically, -nographic redirects
13618d7f2e76SPhilippe Mathieu-Daudé          * serial port, parallel port and monitor to stdio, which does not work
13628d7f2e76SPhilippe Mathieu-Daudé          * with -daemonize.  We can redirect these to null instead, but since
13638d7f2e76SPhilippe Mathieu-Daudé          * -nographic is legacy, let's just error out.
13648d7f2e76SPhilippe Mathieu-Daudé          * We disallow -nographic only if all other ports are not redirected
13658d7f2e76SPhilippe Mathieu-Daudé          * explicitly, to not break existing legacy setups which uses
13668d7f2e76SPhilippe Mathieu-Daudé          * -nographic _and_ redirects all ports explicitly - this is valid
13678d7f2e76SPhilippe Mathieu-Daudé          * usage, -nographic is just a no-op in this case.
13688d7f2e76SPhilippe Mathieu-Daudé          */
13698d7f2e76SPhilippe Mathieu-Daudé         if (nographic
13708d7f2e76SPhilippe Mathieu-Daudé             && (default_parallel || default_serial || default_monitor)) {
13718d7f2e76SPhilippe Mathieu-Daudé             error_report("-nographic cannot be used with -daemonize");
13728d7f2e76SPhilippe Mathieu-Daudé             exit(1);
13738d7f2e76SPhilippe Mathieu-Daudé         }
13748d7f2e76SPhilippe Mathieu-Daudé     }
13758d7f2e76SPhilippe Mathieu-Daudé 
13768d7f2e76SPhilippe Mathieu-Daudé     if (nographic) {
13778d7f2e76SPhilippe Mathieu-Daudé         if (default_parallel)
13788d7f2e76SPhilippe Mathieu-Daudé             add_device_config(DEV_PARALLEL, "null");
13798d7f2e76SPhilippe Mathieu-Daudé         if (default_serial && default_monitor) {
13808d7f2e76SPhilippe Mathieu-Daudé             add_device_config(DEV_SERIAL, "mon:stdio");
13818d7f2e76SPhilippe Mathieu-Daudé         } else {
13828d7f2e76SPhilippe Mathieu-Daudé             if (default_serial)
13838d7f2e76SPhilippe Mathieu-Daudé                 add_device_config(DEV_SERIAL, "stdio");
13848d7f2e76SPhilippe Mathieu-Daudé             if (default_monitor)
13858d7f2e76SPhilippe Mathieu-Daudé                 monitor_parse("stdio", "readline", false);
13868d7f2e76SPhilippe Mathieu-Daudé         }
13878d7f2e76SPhilippe Mathieu-Daudé     } else {
13888d7f2e76SPhilippe Mathieu-Daudé         if (default_serial)
13898d7f2e76SPhilippe Mathieu-Daudé             add_device_config(DEV_SERIAL, "vc:80Cx24C");
13908d7f2e76SPhilippe Mathieu-Daudé         if (default_parallel)
13918d7f2e76SPhilippe Mathieu-Daudé             add_device_config(DEV_PARALLEL, "vc:80Cx24C");
13928d7f2e76SPhilippe Mathieu-Daudé         if (default_monitor)
13938d7f2e76SPhilippe Mathieu-Daudé             monitor_parse("vc:80Cx24C", "readline", false);
13948d7f2e76SPhilippe Mathieu-Daudé     }
13958d7f2e76SPhilippe Mathieu-Daudé 
13968d7f2e76SPhilippe Mathieu-Daudé     if (default_net) {
13978d7f2e76SPhilippe Mathieu-Daudé         QemuOptsList *net = qemu_find_opts("net");
13988d7f2e76SPhilippe Mathieu-Daudé         qemu_opts_parse(net, "nic", true, &error_abort);
13998d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_SLIRP
14008d7f2e76SPhilippe Mathieu-Daudé         qemu_opts_parse(net, "user", true, &error_abort);
14018d7f2e76SPhilippe Mathieu-Daudé #endif
14028d7f2e76SPhilippe Mathieu-Daudé     }
14038d7f2e76SPhilippe Mathieu-Daudé 
14048d7f2e76SPhilippe Mathieu-Daudé #if defined(CONFIG_VNC)
14058d7f2e76SPhilippe Mathieu-Daudé     if (!QTAILQ_EMPTY(&(qemu_find_opts("vnc")->head))) {
14068d7f2e76SPhilippe Mathieu-Daudé         display_remote++;
14078d7f2e76SPhilippe Mathieu-Daudé     }
14088d7f2e76SPhilippe Mathieu-Daudé #endif
14098d7f2e76SPhilippe Mathieu-Daudé     if (dpy.type == DISPLAY_TYPE_DEFAULT && !display_remote) {
14108d7f2e76SPhilippe Mathieu-Daudé         if (!qemu_display_find_default(&dpy)) {
14118d7f2e76SPhilippe Mathieu-Daudé             dpy.type = DISPLAY_TYPE_NONE;
14128d7f2e76SPhilippe Mathieu-Daudé #if defined(CONFIG_VNC)
14138d7f2e76SPhilippe Mathieu-Daudé             vnc_parse("localhost:0,to=99,id=default");
14148d7f2e76SPhilippe Mathieu-Daudé #endif
14158d7f2e76SPhilippe Mathieu-Daudé         }
14168d7f2e76SPhilippe Mathieu-Daudé     }
14178d7f2e76SPhilippe Mathieu-Daudé     if (dpy.type == DISPLAY_TYPE_DEFAULT) {
14188d7f2e76SPhilippe Mathieu-Daudé         dpy.type = DISPLAY_TYPE_NONE;
14198d7f2e76SPhilippe Mathieu-Daudé     }
14208d7f2e76SPhilippe Mathieu-Daudé 
14218d7f2e76SPhilippe Mathieu-Daudé     /* If no default VGA is requested, the default is "none".  */
14228d7f2e76SPhilippe Mathieu-Daudé     if (default_vga) {
14238d7f2e76SPhilippe Mathieu-Daudé         vga_model = get_default_vga_model(machine_class);
14248d7f2e76SPhilippe Mathieu-Daudé     }
14258d7f2e76SPhilippe Mathieu-Daudé     if (vga_model) {
14268d7f2e76SPhilippe Mathieu-Daudé         select_vgahw(machine_class, vga_model);
14278d7f2e76SPhilippe Mathieu-Daudé     }
14288d7f2e76SPhilippe Mathieu-Daudé }
14298d7f2e76SPhilippe Mathieu-Daudé 
14308d7f2e76SPhilippe Mathieu-Daudé static int serial_parse(const char *devname)
14318d7f2e76SPhilippe Mathieu-Daudé {
14328d7f2e76SPhilippe Mathieu-Daudé     int index = num_serial_hds;
14338d7f2e76SPhilippe Mathieu-Daudé     char label[32];
14348d7f2e76SPhilippe Mathieu-Daudé 
14358d7f2e76SPhilippe Mathieu-Daudé     if (strcmp(devname, "none") == 0)
14368d7f2e76SPhilippe Mathieu-Daudé         return 0;
14378d7f2e76SPhilippe Mathieu-Daudé     snprintf(label, sizeof(label), "serial%d", index);
14388d7f2e76SPhilippe Mathieu-Daudé     serial_hds = g_renew(Chardev *, serial_hds, index + 1);
14398d7f2e76SPhilippe Mathieu-Daudé 
14408d7f2e76SPhilippe Mathieu-Daudé     serial_hds[index] = qemu_chr_new_mux_mon(label, devname, NULL);
14418d7f2e76SPhilippe Mathieu-Daudé     if (!serial_hds[index]) {
14428d7f2e76SPhilippe Mathieu-Daudé         error_report("could not connect serial device"
14438d7f2e76SPhilippe Mathieu-Daudé                      " to character backend '%s'", devname);
14448d7f2e76SPhilippe Mathieu-Daudé         return -1;
14458d7f2e76SPhilippe Mathieu-Daudé     }
14468d7f2e76SPhilippe Mathieu-Daudé     num_serial_hds++;
14478d7f2e76SPhilippe Mathieu-Daudé     return 0;
14488d7f2e76SPhilippe Mathieu-Daudé }
14498d7f2e76SPhilippe Mathieu-Daudé 
14508d7f2e76SPhilippe Mathieu-Daudé Chardev *serial_hd(int i)
14518d7f2e76SPhilippe Mathieu-Daudé {
14528d7f2e76SPhilippe Mathieu-Daudé     assert(i >= 0);
14538d7f2e76SPhilippe Mathieu-Daudé     if (i < num_serial_hds) {
14548d7f2e76SPhilippe Mathieu-Daudé         return serial_hds[i];
14558d7f2e76SPhilippe Mathieu-Daudé     }
14568d7f2e76SPhilippe Mathieu-Daudé     return NULL;
14578d7f2e76SPhilippe Mathieu-Daudé }
14588d7f2e76SPhilippe Mathieu-Daudé 
14598d7f2e76SPhilippe Mathieu-Daudé static int parallel_parse(const char *devname)
14608d7f2e76SPhilippe Mathieu-Daudé {
14618d7f2e76SPhilippe Mathieu-Daudé     static int index = 0;
14628d7f2e76SPhilippe Mathieu-Daudé     char label[32];
14638d7f2e76SPhilippe Mathieu-Daudé 
14648d7f2e76SPhilippe Mathieu-Daudé     if (strcmp(devname, "none") == 0)
14658d7f2e76SPhilippe Mathieu-Daudé         return 0;
14668d7f2e76SPhilippe Mathieu-Daudé     if (index == MAX_PARALLEL_PORTS) {
14678d7f2e76SPhilippe Mathieu-Daudé         error_report("too many parallel ports");
14688d7f2e76SPhilippe Mathieu-Daudé         exit(1);
14698d7f2e76SPhilippe Mathieu-Daudé     }
14708d7f2e76SPhilippe Mathieu-Daudé     snprintf(label, sizeof(label), "parallel%d", index);
14718d7f2e76SPhilippe Mathieu-Daudé     parallel_hds[index] = qemu_chr_new_mux_mon(label, devname, NULL);
14728d7f2e76SPhilippe Mathieu-Daudé     if (!parallel_hds[index]) {
14738d7f2e76SPhilippe Mathieu-Daudé         error_report("could not connect parallel device"
14748d7f2e76SPhilippe Mathieu-Daudé                      " to character backend '%s'", devname);
14758d7f2e76SPhilippe Mathieu-Daudé         return -1;
14768d7f2e76SPhilippe Mathieu-Daudé     }
14778d7f2e76SPhilippe Mathieu-Daudé     index++;
14788d7f2e76SPhilippe Mathieu-Daudé     return 0;
14798d7f2e76SPhilippe Mathieu-Daudé }
14808d7f2e76SPhilippe Mathieu-Daudé 
14818d7f2e76SPhilippe Mathieu-Daudé static int debugcon_parse(const char *devname)
14828d7f2e76SPhilippe Mathieu-Daudé {
14838d7f2e76SPhilippe Mathieu-Daudé     QemuOpts *opts;
14848d7f2e76SPhilippe Mathieu-Daudé 
14858d7f2e76SPhilippe Mathieu-Daudé     if (!qemu_chr_new_mux_mon("debugcon", devname, NULL)) {
14868d7f2e76SPhilippe Mathieu-Daudé         error_report("invalid character backend '%s'", devname);
14878d7f2e76SPhilippe Mathieu-Daudé         exit(1);
14888d7f2e76SPhilippe Mathieu-Daudé     }
14898d7f2e76SPhilippe Mathieu-Daudé     opts = qemu_opts_create(qemu_find_opts("device"), "debugcon", 1, NULL);
14908d7f2e76SPhilippe Mathieu-Daudé     if (!opts) {
14918d7f2e76SPhilippe Mathieu-Daudé         error_report("already have a debugcon device");
14928d7f2e76SPhilippe Mathieu-Daudé         exit(1);
14938d7f2e76SPhilippe Mathieu-Daudé     }
14948d7f2e76SPhilippe Mathieu-Daudé     qemu_opt_set(opts, "driver", "isa-debugcon", &error_abort);
14958d7f2e76SPhilippe Mathieu-Daudé     qemu_opt_set(opts, "chardev", "debugcon", &error_abort);
14968d7f2e76SPhilippe Mathieu-Daudé     return 0;
14978d7f2e76SPhilippe Mathieu-Daudé }
14988d7f2e76SPhilippe Mathieu-Daudé 
14998d7f2e76SPhilippe Mathieu-Daudé static gint machine_class_cmp(gconstpointer a, gconstpointer b)
15008d7f2e76SPhilippe Mathieu-Daudé {
15018d7f2e76SPhilippe Mathieu-Daudé     const MachineClass *mc1 = a, *mc2 = b;
15028d7f2e76SPhilippe Mathieu-Daudé     int res;
15038d7f2e76SPhilippe Mathieu-Daudé 
15048d7f2e76SPhilippe Mathieu-Daudé     if (mc1->family == NULL) {
15058d7f2e76SPhilippe Mathieu-Daudé         if (mc2->family == NULL) {
15068d7f2e76SPhilippe Mathieu-Daudé             /* Compare standalone machine types against each other; they sort
15078d7f2e76SPhilippe Mathieu-Daudé              * in increasing order.
15088d7f2e76SPhilippe Mathieu-Daudé              */
15098d7f2e76SPhilippe Mathieu-Daudé             return strcmp(object_class_get_name(OBJECT_CLASS(mc1)),
15108d7f2e76SPhilippe Mathieu-Daudé                           object_class_get_name(OBJECT_CLASS(mc2)));
15118d7f2e76SPhilippe Mathieu-Daudé         }
15128d7f2e76SPhilippe Mathieu-Daudé 
15138d7f2e76SPhilippe Mathieu-Daudé         /* Standalone machine types sort after families. */
15148d7f2e76SPhilippe Mathieu-Daudé         return 1;
15158d7f2e76SPhilippe Mathieu-Daudé     }
15168d7f2e76SPhilippe Mathieu-Daudé 
15178d7f2e76SPhilippe Mathieu-Daudé     if (mc2->family == NULL) {
15188d7f2e76SPhilippe Mathieu-Daudé         /* Families sort before standalone machine types. */
15198d7f2e76SPhilippe Mathieu-Daudé         return -1;
15208d7f2e76SPhilippe Mathieu-Daudé     }
15218d7f2e76SPhilippe Mathieu-Daudé 
15228d7f2e76SPhilippe Mathieu-Daudé     /* Families sort between each other alphabetically increasingly. */
15238d7f2e76SPhilippe Mathieu-Daudé     res = strcmp(mc1->family, mc2->family);
15248d7f2e76SPhilippe Mathieu-Daudé     if (res != 0) {
15258d7f2e76SPhilippe Mathieu-Daudé         return res;
15268d7f2e76SPhilippe Mathieu-Daudé     }
15278d7f2e76SPhilippe Mathieu-Daudé 
15288d7f2e76SPhilippe Mathieu-Daudé     /* Within the same family, machine types sort in decreasing order. */
15298d7f2e76SPhilippe Mathieu-Daudé     return strcmp(object_class_get_name(OBJECT_CLASS(mc2)),
15308d7f2e76SPhilippe Mathieu-Daudé                   object_class_get_name(OBJECT_CLASS(mc1)));
15318d7f2e76SPhilippe Mathieu-Daudé }
15328d7f2e76SPhilippe Mathieu-Daudé 
15338d7f2e76SPhilippe Mathieu-Daudé static void machine_help_func(const QDict *qdict)
15348d7f2e76SPhilippe Mathieu-Daudé {
15358d7f2e76SPhilippe Mathieu-Daudé     GSList *machines, *el;
15368d7f2e76SPhilippe Mathieu-Daudé     const char *type = qdict_get_try_str(qdict, "type");
15378d7f2e76SPhilippe Mathieu-Daudé 
15388d7f2e76SPhilippe Mathieu-Daudé     machines = object_class_get_list(TYPE_MACHINE, false);
15398d7f2e76SPhilippe Mathieu-Daudé     if (type) {
15408d7f2e76SPhilippe Mathieu-Daudé         ObjectClass *machine_class = OBJECT_CLASS(find_machine(type, machines));
15418d7f2e76SPhilippe Mathieu-Daudé         if (machine_class) {
15428d7f2e76SPhilippe Mathieu-Daudé             type_print_class_properties(object_class_get_name(machine_class));
15438d7f2e76SPhilippe Mathieu-Daudé             return;
15448d7f2e76SPhilippe Mathieu-Daudé         }
15458d7f2e76SPhilippe Mathieu-Daudé     }
15468d7f2e76SPhilippe Mathieu-Daudé 
15478d7f2e76SPhilippe Mathieu-Daudé     printf("Supported machines are:\n");
15488d7f2e76SPhilippe Mathieu-Daudé     machines = g_slist_sort(machines, machine_class_cmp);
15498d7f2e76SPhilippe Mathieu-Daudé     for (el = machines; el; el = el->next) {
15508d7f2e76SPhilippe Mathieu-Daudé         MachineClass *mc = el->data;
15518d7f2e76SPhilippe Mathieu-Daudé         if (mc->alias) {
15528d7f2e76SPhilippe Mathieu-Daudé             printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
15538d7f2e76SPhilippe Mathieu-Daudé         }
15548d7f2e76SPhilippe Mathieu-Daudé         printf("%-20s %s%s%s\n", mc->name, mc->desc,
15558d7f2e76SPhilippe Mathieu-Daudé                mc->is_default ? " (default)" : "",
15568d7f2e76SPhilippe Mathieu-Daudé                mc->deprecation_reason ? " (deprecated)" : "");
15578d7f2e76SPhilippe Mathieu-Daudé     }
15588d7f2e76SPhilippe Mathieu-Daudé }
15598d7f2e76SPhilippe Mathieu-Daudé 
15608d7f2e76SPhilippe Mathieu-Daudé static void
15618d7f2e76SPhilippe Mathieu-Daudé machine_merge_property(const char *propname, QDict *prop, Error **errp)
15628d7f2e76SPhilippe Mathieu-Daudé {
15638d7f2e76SPhilippe Mathieu-Daudé     QDict *opts;
15648d7f2e76SPhilippe Mathieu-Daudé 
15658d7f2e76SPhilippe Mathieu-Daudé     opts = qdict_new();
15668d7f2e76SPhilippe Mathieu-Daudé     /* Preserve the caller's reference to prop.  */
15678d7f2e76SPhilippe Mathieu-Daudé     qobject_ref(prop);
15688d7f2e76SPhilippe Mathieu-Daudé     qdict_put(opts, propname, prop);
15698d7f2e76SPhilippe Mathieu-Daudé     keyval_merge(machine_opts_dict, opts, errp);
15708d7f2e76SPhilippe Mathieu-Daudé     qobject_unref(opts);
15718d7f2e76SPhilippe Mathieu-Daudé }
15728d7f2e76SPhilippe Mathieu-Daudé 
15738d7f2e76SPhilippe Mathieu-Daudé static void
15748d7f2e76SPhilippe Mathieu-Daudé machine_parse_property_opt(QemuOptsList *opts_list, const char *propname,
15758d7f2e76SPhilippe Mathieu-Daudé                            const char *arg)
15768d7f2e76SPhilippe Mathieu-Daudé {
15778d7f2e76SPhilippe Mathieu-Daudé     QDict *prop = NULL;
15788d7f2e76SPhilippe Mathieu-Daudé     bool help = false;
15798d7f2e76SPhilippe Mathieu-Daudé 
15808d7f2e76SPhilippe Mathieu-Daudé     prop = keyval_parse(arg, opts_list->implied_opt_name, &help, &error_fatal);
15818d7f2e76SPhilippe Mathieu-Daudé     if (help) {
15828d7f2e76SPhilippe Mathieu-Daudé         qemu_opts_print_help(opts_list, true);
15838d7f2e76SPhilippe Mathieu-Daudé         exit(0);
15848d7f2e76SPhilippe Mathieu-Daudé     }
15858d7f2e76SPhilippe Mathieu-Daudé     machine_merge_property(propname, prop, &error_fatal);
15868d7f2e76SPhilippe Mathieu-Daudé     qobject_unref(prop);
15878d7f2e76SPhilippe Mathieu-Daudé }
15888d7f2e76SPhilippe Mathieu-Daudé 
15898d7f2e76SPhilippe Mathieu-Daudé static const char *pid_file;
15908d7f2e76SPhilippe Mathieu-Daudé struct UnlinkPidfileNotifier {
15918d7f2e76SPhilippe Mathieu-Daudé     Notifier notifier;
15928d7f2e76SPhilippe Mathieu-Daudé     char *pid_file_realpath;
15938d7f2e76SPhilippe Mathieu-Daudé };
15948d7f2e76SPhilippe Mathieu-Daudé static struct UnlinkPidfileNotifier qemu_unlink_pidfile_notifier;
15958d7f2e76SPhilippe Mathieu-Daudé 
15968d7f2e76SPhilippe Mathieu-Daudé static void qemu_unlink_pidfile(Notifier *n, void *data)
15978d7f2e76SPhilippe Mathieu-Daudé {
15988d7f2e76SPhilippe Mathieu-Daudé     struct UnlinkPidfileNotifier *upn;
15998d7f2e76SPhilippe Mathieu-Daudé 
16008d7f2e76SPhilippe Mathieu-Daudé     upn = DO_UPCAST(struct UnlinkPidfileNotifier, notifier, n);
16018d7f2e76SPhilippe Mathieu-Daudé     unlink(upn->pid_file_realpath);
16028d7f2e76SPhilippe Mathieu-Daudé }
16038d7f2e76SPhilippe Mathieu-Daudé 
16048d7f2e76SPhilippe Mathieu-Daudé static const QEMUOption *lookup_opt(int argc, char **argv,
16058d7f2e76SPhilippe Mathieu-Daudé                                     const char **poptarg, int *poptind)
16068d7f2e76SPhilippe Mathieu-Daudé {
16078d7f2e76SPhilippe Mathieu-Daudé     const QEMUOption *popt;
16088d7f2e76SPhilippe Mathieu-Daudé     int optind = *poptind;
16098d7f2e76SPhilippe Mathieu-Daudé     char *r = argv[optind];
16108d7f2e76SPhilippe Mathieu-Daudé     const char *optarg;
16118d7f2e76SPhilippe Mathieu-Daudé 
16128d7f2e76SPhilippe Mathieu-Daudé     loc_set_cmdline(argv, optind, 1);
16138d7f2e76SPhilippe Mathieu-Daudé     optind++;
16148d7f2e76SPhilippe Mathieu-Daudé     /* Treat --foo the same as -foo.  */
16158d7f2e76SPhilippe Mathieu-Daudé     if (r[1] == '-')
16168d7f2e76SPhilippe Mathieu-Daudé         r++;
16178d7f2e76SPhilippe Mathieu-Daudé     popt = qemu_options;
16188d7f2e76SPhilippe Mathieu-Daudé     for(;;) {
16198d7f2e76SPhilippe Mathieu-Daudé         if (!popt->name) {
16208d7f2e76SPhilippe Mathieu-Daudé             error_report("invalid option");
16218d7f2e76SPhilippe Mathieu-Daudé             exit(1);
16228d7f2e76SPhilippe Mathieu-Daudé         }
16238d7f2e76SPhilippe Mathieu-Daudé         if (!strcmp(popt->name, r + 1))
16248d7f2e76SPhilippe Mathieu-Daudé             break;
16258d7f2e76SPhilippe Mathieu-Daudé         popt++;
16268d7f2e76SPhilippe Mathieu-Daudé     }
16278d7f2e76SPhilippe Mathieu-Daudé     if (popt->flags & HAS_ARG) {
16288d7f2e76SPhilippe Mathieu-Daudé         if (optind >= argc) {
16298d7f2e76SPhilippe Mathieu-Daudé             error_report("requires an argument");
16308d7f2e76SPhilippe Mathieu-Daudé             exit(1);
16318d7f2e76SPhilippe Mathieu-Daudé         }
16328d7f2e76SPhilippe Mathieu-Daudé         optarg = argv[optind++];
16338d7f2e76SPhilippe Mathieu-Daudé         loc_set_cmdline(argv, optind - 2, 2);
16348d7f2e76SPhilippe Mathieu-Daudé     } else {
16358d7f2e76SPhilippe Mathieu-Daudé         optarg = NULL;
16368d7f2e76SPhilippe Mathieu-Daudé     }
16378d7f2e76SPhilippe Mathieu-Daudé 
16388d7f2e76SPhilippe Mathieu-Daudé     *poptarg = optarg;
16398d7f2e76SPhilippe Mathieu-Daudé     *poptind = optind;
16408d7f2e76SPhilippe Mathieu-Daudé 
16418d7f2e76SPhilippe Mathieu-Daudé     return popt;
16428d7f2e76SPhilippe Mathieu-Daudé }
16438d7f2e76SPhilippe Mathieu-Daudé 
16448d7f2e76SPhilippe Mathieu-Daudé static MachineClass *select_machine(QDict *qdict, Error **errp)
16458d7f2e76SPhilippe Mathieu-Daudé {
16461527c6b6SStefan Hajnoczi     const char *machine_type = qdict_get_try_str(qdict, "type");
16478d7f2e76SPhilippe Mathieu-Daudé     GSList *machines = object_class_get_list(TYPE_MACHINE, false);
16488d7f2e76SPhilippe Mathieu-Daudé     MachineClass *machine_class;
16498d7f2e76SPhilippe Mathieu-Daudé     Error *local_err = NULL;
16508d7f2e76SPhilippe Mathieu-Daudé 
16511527c6b6SStefan Hajnoczi     if (machine_type) {
16521527c6b6SStefan Hajnoczi         machine_class = find_machine(machine_type, machines);
16538d7f2e76SPhilippe Mathieu-Daudé         qdict_del(qdict, "type");
16548d7f2e76SPhilippe Mathieu-Daudé         if (!machine_class) {
16558d7f2e76SPhilippe Mathieu-Daudé             error_setg(&local_err, "unsupported machine type");
16568d7f2e76SPhilippe Mathieu-Daudé         }
16578d7f2e76SPhilippe Mathieu-Daudé     } else {
16588d7f2e76SPhilippe Mathieu-Daudé         machine_class = find_default_machine(machines);
16598d7f2e76SPhilippe Mathieu-Daudé         if (!machine_class) {
16608d7f2e76SPhilippe Mathieu-Daudé             error_setg(&local_err, "No machine specified, and there is no default");
16618d7f2e76SPhilippe Mathieu-Daudé         }
16628d7f2e76SPhilippe Mathieu-Daudé     }
16638d7f2e76SPhilippe Mathieu-Daudé 
16648d7f2e76SPhilippe Mathieu-Daudé     g_slist_free(machines);
16658d7f2e76SPhilippe Mathieu-Daudé     if (local_err) {
16668d7f2e76SPhilippe Mathieu-Daudé         error_append_hint(&local_err, "Use -machine help to list supported machines\n");
16678d7f2e76SPhilippe Mathieu-Daudé         error_propagate(errp, local_err);
16688d7f2e76SPhilippe Mathieu-Daudé     }
16698d7f2e76SPhilippe Mathieu-Daudé     return machine_class;
16708d7f2e76SPhilippe Mathieu-Daudé }
16718d7f2e76SPhilippe Mathieu-Daudé 
16728d7f2e76SPhilippe Mathieu-Daudé static int object_parse_property_opt(Object *obj,
16738d7f2e76SPhilippe Mathieu-Daudé                                      const char *name, const char *value,
16748d7f2e76SPhilippe Mathieu-Daudé                                      const char *skip, Error **errp)
16758d7f2e76SPhilippe Mathieu-Daudé {
16768d7f2e76SPhilippe Mathieu-Daudé     if (g_str_equal(name, skip)) {
16778d7f2e76SPhilippe Mathieu-Daudé         return 0;
16788d7f2e76SPhilippe Mathieu-Daudé     }
16798d7f2e76SPhilippe Mathieu-Daudé 
16808d7f2e76SPhilippe Mathieu-Daudé     if (!object_property_parse(obj, name, value, errp)) {
16818d7f2e76SPhilippe Mathieu-Daudé         return -1;
16828d7f2e76SPhilippe Mathieu-Daudé     }
16838d7f2e76SPhilippe Mathieu-Daudé 
16848d7f2e76SPhilippe Mathieu-Daudé     return 0;
16858d7f2e76SPhilippe Mathieu-Daudé }
16868d7f2e76SPhilippe Mathieu-Daudé 
16878d7f2e76SPhilippe Mathieu-Daudé /* *Non*recursively replace underscores with dashes in QDict keys.  */
16888d7f2e76SPhilippe Mathieu-Daudé static void keyval_dashify(QDict *qdict, Error **errp)
16898d7f2e76SPhilippe Mathieu-Daudé {
16908d7f2e76SPhilippe Mathieu-Daudé     const QDictEntry *ent, *next;
16918d7f2e76SPhilippe Mathieu-Daudé     char *p;
16928d7f2e76SPhilippe Mathieu-Daudé 
16938d7f2e76SPhilippe Mathieu-Daudé     for (ent = qdict_first(qdict); ent; ent = next) {
16948d7f2e76SPhilippe Mathieu-Daudé         g_autofree char *new_key = NULL;
16958d7f2e76SPhilippe Mathieu-Daudé 
16968d7f2e76SPhilippe Mathieu-Daudé         next = qdict_next(qdict, ent);
16978d7f2e76SPhilippe Mathieu-Daudé         if (!strchr(ent->key, '_')) {
16988d7f2e76SPhilippe Mathieu-Daudé             continue;
16998d7f2e76SPhilippe Mathieu-Daudé         }
17008d7f2e76SPhilippe Mathieu-Daudé         new_key = g_strdup(ent->key);
17018d7f2e76SPhilippe Mathieu-Daudé         for (p = new_key; *p; p++) {
17028d7f2e76SPhilippe Mathieu-Daudé             if (*p == '_') {
17038d7f2e76SPhilippe Mathieu-Daudé                 *p = '-';
17048d7f2e76SPhilippe Mathieu-Daudé             }
17058d7f2e76SPhilippe Mathieu-Daudé         }
17068d7f2e76SPhilippe Mathieu-Daudé         if (qdict_haskey(qdict, new_key)) {
17078d7f2e76SPhilippe Mathieu-Daudé             error_setg(errp, "Conflict between '%s' and '%s'", ent->key, new_key);
17088d7f2e76SPhilippe Mathieu-Daudé             return;
17098d7f2e76SPhilippe Mathieu-Daudé         }
17108d7f2e76SPhilippe Mathieu-Daudé         qobject_ref(ent->value);
17118d7f2e76SPhilippe Mathieu-Daudé         qdict_put_obj(qdict, new_key, ent->value);
17128d7f2e76SPhilippe Mathieu-Daudé         qdict_del(qdict, ent->key);
17138d7f2e76SPhilippe Mathieu-Daudé     }
17148d7f2e76SPhilippe Mathieu-Daudé }
17158d7f2e76SPhilippe Mathieu-Daudé 
17168d7f2e76SPhilippe Mathieu-Daudé static void qemu_apply_legacy_machine_options(QDict *qdict)
17178d7f2e76SPhilippe Mathieu-Daudé {
17188d7f2e76SPhilippe Mathieu-Daudé     const char *value;
17198d7f2e76SPhilippe Mathieu-Daudé     QObject *prop;
17208d7f2e76SPhilippe Mathieu-Daudé 
17218d7f2e76SPhilippe Mathieu-Daudé     keyval_dashify(qdict, &error_fatal);
17228d7f2e76SPhilippe Mathieu-Daudé 
17238d7f2e76SPhilippe Mathieu-Daudé     /* Legacy options do not correspond to MachineState properties.  */
17248d7f2e76SPhilippe Mathieu-Daudé     value = qdict_get_try_str(qdict, "accel");
17258d7f2e76SPhilippe Mathieu-Daudé     if (value) {
17268d7f2e76SPhilippe Mathieu-Daudé         accelerators = g_strdup(value);
17278d7f2e76SPhilippe Mathieu-Daudé         qdict_del(qdict, "accel");
17288d7f2e76SPhilippe Mathieu-Daudé     }
17298d7f2e76SPhilippe Mathieu-Daudé 
17308d7f2e76SPhilippe Mathieu-Daudé     value = qdict_get_try_str(qdict, "igd-passthru");
17318d7f2e76SPhilippe Mathieu-Daudé     if (value) {
17328d7f2e76SPhilippe Mathieu-Daudé         object_register_sugar_prop(ACCEL_CLASS_NAME("xen"), "igd-passthru", value,
17338d7f2e76SPhilippe Mathieu-Daudé                                    false);
17348d7f2e76SPhilippe Mathieu-Daudé         qdict_del(qdict, "igd-passthru");
17358d7f2e76SPhilippe Mathieu-Daudé     }
17368d7f2e76SPhilippe Mathieu-Daudé 
17378d7f2e76SPhilippe Mathieu-Daudé     value = qdict_get_try_str(qdict, "kvm-shadow-mem");
17388d7f2e76SPhilippe Mathieu-Daudé     if (value) {
17398d7f2e76SPhilippe Mathieu-Daudé         object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), "kvm-shadow-mem", value,
17408d7f2e76SPhilippe Mathieu-Daudé                                    false);
17418d7f2e76SPhilippe Mathieu-Daudé         qdict_del(qdict, "kvm-shadow-mem");
17428d7f2e76SPhilippe Mathieu-Daudé     }
17438d7f2e76SPhilippe Mathieu-Daudé 
17448d7f2e76SPhilippe Mathieu-Daudé     value = qdict_get_try_str(qdict, "kernel-irqchip");
17458d7f2e76SPhilippe Mathieu-Daudé     if (value) {
17468d7f2e76SPhilippe Mathieu-Daudé         object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), "kernel-irqchip", value,
17478d7f2e76SPhilippe Mathieu-Daudé                                    false);
17488d7f2e76SPhilippe Mathieu-Daudé         object_register_sugar_prop(ACCEL_CLASS_NAME("whpx"), "kernel-irqchip", value,
17498d7f2e76SPhilippe Mathieu-Daudé                                    false);
17508d7f2e76SPhilippe Mathieu-Daudé         qdict_del(qdict, "kernel-irqchip");
17518d7f2e76SPhilippe Mathieu-Daudé     }
17528d7f2e76SPhilippe Mathieu-Daudé 
17538d7f2e76SPhilippe Mathieu-Daudé     value = qdict_get_try_str(qdict, "memory-backend");
17548d7f2e76SPhilippe Mathieu-Daudé     if (value) {
17558d7f2e76SPhilippe Mathieu-Daudé         if (mem_path) {
17568d7f2e76SPhilippe Mathieu-Daudé             error_report("'-mem-path' can't be used together with"
17578d7f2e76SPhilippe Mathieu-Daudé                          "'-machine memory-backend'");
17588d7f2e76SPhilippe Mathieu-Daudé             exit(EXIT_FAILURE);
17598d7f2e76SPhilippe Mathieu-Daudé         }
17608d7f2e76SPhilippe Mathieu-Daudé 
17618d7f2e76SPhilippe Mathieu-Daudé         /* Resolved later.  */
17628d7f2e76SPhilippe Mathieu-Daudé         ram_memdev_id = g_strdup(value);
17638d7f2e76SPhilippe Mathieu-Daudé         qdict_del(qdict, "memory-backend");
17648d7f2e76SPhilippe Mathieu-Daudé     }
17658d7f2e76SPhilippe Mathieu-Daudé 
17668d7f2e76SPhilippe Mathieu-Daudé     prop = qdict_get(qdict, "memory");
17678d7f2e76SPhilippe Mathieu-Daudé     if (prop) {
17688d7f2e76SPhilippe Mathieu-Daudé         have_custom_ram_size =
17698d7f2e76SPhilippe Mathieu-Daudé             qobject_type(prop) == QTYPE_QDICT &&
17708d7f2e76SPhilippe Mathieu-Daudé             qdict_haskey(qobject_to(QDict, prop), "size");
17718d7f2e76SPhilippe Mathieu-Daudé     }
17728d7f2e76SPhilippe Mathieu-Daudé }
17738d7f2e76SPhilippe Mathieu-Daudé 
17748d7f2e76SPhilippe Mathieu-Daudé static void object_option_foreach_add(bool (*type_opt_predicate)(const char *))
17758d7f2e76SPhilippe Mathieu-Daudé {
17768d7f2e76SPhilippe Mathieu-Daudé     ObjectOption *opt, *next;
17778d7f2e76SPhilippe Mathieu-Daudé 
17788d7f2e76SPhilippe Mathieu-Daudé     QTAILQ_FOREACH_SAFE(opt, &object_opts, next, next) {
17798d7f2e76SPhilippe Mathieu-Daudé         const char *type = ObjectType_str(opt->opts->qom_type);
17808d7f2e76SPhilippe Mathieu-Daudé         if (type_opt_predicate(type)) {
17818d7f2e76SPhilippe Mathieu-Daudé             user_creatable_add_qapi(opt->opts, &error_fatal);
17828d7f2e76SPhilippe Mathieu-Daudé             qapi_free_ObjectOptions(opt->opts);
17838d7f2e76SPhilippe Mathieu-Daudé             QTAILQ_REMOVE(&object_opts, opt, next);
17848d7f2e76SPhilippe Mathieu-Daudé             g_free(opt);
17858d7f2e76SPhilippe Mathieu-Daudé         }
17868d7f2e76SPhilippe Mathieu-Daudé     }
17878d7f2e76SPhilippe Mathieu-Daudé }
17888d7f2e76SPhilippe Mathieu-Daudé 
17898d7f2e76SPhilippe Mathieu-Daudé static void object_option_add_visitor(Visitor *v)
17908d7f2e76SPhilippe Mathieu-Daudé {
17918d7f2e76SPhilippe Mathieu-Daudé     ObjectOption *opt = g_new0(ObjectOption, 1);
17928d7f2e76SPhilippe Mathieu-Daudé     visit_type_ObjectOptions(v, NULL, &opt->opts, &error_fatal);
17938d7f2e76SPhilippe Mathieu-Daudé     QTAILQ_INSERT_TAIL(&object_opts, opt, next);
17948d7f2e76SPhilippe Mathieu-Daudé }
17958d7f2e76SPhilippe Mathieu-Daudé 
17961527c6b6SStefan Hajnoczi static void object_option_parse(const char *str)
17978d7f2e76SPhilippe Mathieu-Daudé {
17988d7f2e76SPhilippe Mathieu-Daudé     QemuOpts *opts;
17998d7f2e76SPhilippe Mathieu-Daudé     const char *type;
18008d7f2e76SPhilippe Mathieu-Daudé     Visitor *v;
18018d7f2e76SPhilippe Mathieu-Daudé 
18021527c6b6SStefan Hajnoczi     if (str[0] == '{') {
18031527c6b6SStefan Hajnoczi         QObject *obj = qobject_from_json(str, &error_fatal);
18048d7f2e76SPhilippe Mathieu-Daudé 
18058d7f2e76SPhilippe Mathieu-Daudé         v = qobject_input_visitor_new(obj);
18068d7f2e76SPhilippe Mathieu-Daudé         qobject_unref(obj);
18078d7f2e76SPhilippe Mathieu-Daudé     } else {
18088d7f2e76SPhilippe Mathieu-Daudé         opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
18091527c6b6SStefan Hajnoczi                                        str, true);
18108d7f2e76SPhilippe Mathieu-Daudé         if (!opts) {
18118d7f2e76SPhilippe Mathieu-Daudé             exit(1);
18128d7f2e76SPhilippe Mathieu-Daudé         }
18138d7f2e76SPhilippe Mathieu-Daudé 
18148d7f2e76SPhilippe Mathieu-Daudé         type = qemu_opt_get(opts, "qom-type");
18158d7f2e76SPhilippe Mathieu-Daudé         if (!type) {
18168d7f2e76SPhilippe Mathieu-Daudé             error_setg(&error_fatal, QERR_MISSING_PARAMETER, "qom-type");
18178d7f2e76SPhilippe Mathieu-Daudé         }
18188d7f2e76SPhilippe Mathieu-Daudé         if (user_creatable_print_help(type, opts)) {
18198d7f2e76SPhilippe Mathieu-Daudé             exit(0);
18208d7f2e76SPhilippe Mathieu-Daudé         }
18218d7f2e76SPhilippe Mathieu-Daudé 
18228d7f2e76SPhilippe Mathieu-Daudé         v = opts_visitor_new(opts);
18238d7f2e76SPhilippe Mathieu-Daudé     }
18248d7f2e76SPhilippe Mathieu-Daudé 
18258d7f2e76SPhilippe Mathieu-Daudé     object_option_add_visitor(v);
18268d7f2e76SPhilippe Mathieu-Daudé     visit_free(v);
18278d7f2e76SPhilippe Mathieu-Daudé }
18288d7f2e76SPhilippe Mathieu-Daudé 
18298d7f2e76SPhilippe Mathieu-Daudé /*
18308d7f2e76SPhilippe Mathieu-Daudé  * Very early object creation, before the sandbox options have been activated.
18318d7f2e76SPhilippe Mathieu-Daudé  */
18328d7f2e76SPhilippe Mathieu-Daudé static bool object_create_pre_sandbox(const char *type)
18338d7f2e76SPhilippe Mathieu-Daudé {
18348d7f2e76SPhilippe Mathieu-Daudé     /*
18358d7f2e76SPhilippe Mathieu-Daudé      * Objects should in general not get initialized "too early" without
18368d7f2e76SPhilippe Mathieu-Daudé      * a reason. If you add one, state the reason in a comment!
18378d7f2e76SPhilippe Mathieu-Daudé      */
18388d7f2e76SPhilippe Mathieu-Daudé 
18398d7f2e76SPhilippe Mathieu-Daudé     /*
18408d7f2e76SPhilippe Mathieu-Daudé      * Reason: -sandbox on,resourcecontrol=deny disallows setting CPU
18418d7f2e76SPhilippe Mathieu-Daudé      * affinity of threads.
18428d7f2e76SPhilippe Mathieu-Daudé      */
18438d7f2e76SPhilippe Mathieu-Daudé     if (g_str_equal(type, "thread-context")) {
18448d7f2e76SPhilippe Mathieu-Daudé         return true;
18458d7f2e76SPhilippe Mathieu-Daudé     }
18468d7f2e76SPhilippe Mathieu-Daudé 
18478d7f2e76SPhilippe Mathieu-Daudé     return false;
18488d7f2e76SPhilippe Mathieu-Daudé }
18498d7f2e76SPhilippe Mathieu-Daudé 
18508d7f2e76SPhilippe Mathieu-Daudé /*
18518d7f2e76SPhilippe Mathieu-Daudé  * Initial object creation happens before all other
18528d7f2e76SPhilippe Mathieu-Daudé  * QEMU data types are created. The majority of objects
18538d7f2e76SPhilippe Mathieu-Daudé  * can be created at this point. The rng-egd object
18548d7f2e76SPhilippe Mathieu-Daudé  * cannot be created here, as it depends on the chardev
18558d7f2e76SPhilippe Mathieu-Daudé  * already existing.
18568d7f2e76SPhilippe Mathieu-Daudé  */
18578d7f2e76SPhilippe Mathieu-Daudé static bool object_create_early(const char *type)
18588d7f2e76SPhilippe Mathieu-Daudé {
18598d7f2e76SPhilippe Mathieu-Daudé     /*
18608d7f2e76SPhilippe Mathieu-Daudé      * Objects should not be made "delayed" without a reason.  If you
18618d7f2e76SPhilippe Mathieu-Daudé      * add one, state the reason in a comment!
18628d7f2e76SPhilippe Mathieu-Daudé      */
18638d7f2e76SPhilippe Mathieu-Daudé 
18648d7f2e76SPhilippe Mathieu-Daudé     /* Reason: already created. */
18658d7f2e76SPhilippe Mathieu-Daudé     if (object_create_pre_sandbox(type)) {
18668d7f2e76SPhilippe Mathieu-Daudé         return false;
18678d7f2e76SPhilippe Mathieu-Daudé     }
18688d7f2e76SPhilippe Mathieu-Daudé 
18698d7f2e76SPhilippe Mathieu-Daudé     /* Reason: property "chardev" */
18708d7f2e76SPhilippe Mathieu-Daudé     if (g_str_equal(type, "rng-egd") ||
18718d7f2e76SPhilippe Mathieu-Daudé         g_str_equal(type, "qtest")) {
18728d7f2e76SPhilippe Mathieu-Daudé         return false;
18738d7f2e76SPhilippe Mathieu-Daudé     }
18748d7f2e76SPhilippe Mathieu-Daudé 
18758d7f2e76SPhilippe Mathieu-Daudé #if defined(CONFIG_VHOST_USER) && defined(CONFIG_LINUX)
18768d7f2e76SPhilippe Mathieu-Daudé     /* Reason: cryptodev-vhost-user property "chardev" */
18778d7f2e76SPhilippe Mathieu-Daudé     if (g_str_equal(type, "cryptodev-vhost-user")) {
18788d7f2e76SPhilippe Mathieu-Daudé         return false;
18798d7f2e76SPhilippe Mathieu-Daudé     }
18808d7f2e76SPhilippe Mathieu-Daudé #endif
18818d7f2e76SPhilippe Mathieu-Daudé 
18828d7f2e76SPhilippe Mathieu-Daudé     /* Reason: vhost-user-blk-server property "node-name" */
18838d7f2e76SPhilippe Mathieu-Daudé     if (g_str_equal(type, "vhost-user-blk-server")) {
18848d7f2e76SPhilippe Mathieu-Daudé         return false;
18858d7f2e76SPhilippe Mathieu-Daudé     }
18868d7f2e76SPhilippe Mathieu-Daudé     /*
18878d7f2e76SPhilippe Mathieu-Daudé      * Reason: filter-* property "netdev" etc.
18888d7f2e76SPhilippe Mathieu-Daudé      */
18898d7f2e76SPhilippe Mathieu-Daudé     if (g_str_equal(type, "filter-buffer") ||
18908d7f2e76SPhilippe Mathieu-Daudé         g_str_equal(type, "filter-dump") ||
18918d7f2e76SPhilippe Mathieu-Daudé         g_str_equal(type, "filter-mirror") ||
18928d7f2e76SPhilippe Mathieu-Daudé         g_str_equal(type, "filter-redirector") ||
18938d7f2e76SPhilippe Mathieu-Daudé         g_str_equal(type, "colo-compare") ||
18948d7f2e76SPhilippe Mathieu-Daudé         g_str_equal(type, "filter-rewriter") ||
18958d7f2e76SPhilippe Mathieu-Daudé         g_str_equal(type, "filter-replay")) {
18968d7f2e76SPhilippe Mathieu-Daudé         return false;
18978d7f2e76SPhilippe Mathieu-Daudé     }
18988d7f2e76SPhilippe Mathieu-Daudé 
18998d7f2e76SPhilippe Mathieu-Daudé     /*
19008d7f2e76SPhilippe Mathieu-Daudé      * Allocation of large amounts of memory may delay
19018d7f2e76SPhilippe Mathieu-Daudé      * chardev initialization for too long, and trigger timeouts
19028d7f2e76SPhilippe Mathieu-Daudé      * on software that waits for a monitor socket to be created
19038d7f2e76SPhilippe Mathieu-Daudé      * (e.g. libvirt).
19048d7f2e76SPhilippe Mathieu-Daudé      */
19058d7f2e76SPhilippe Mathieu-Daudé     if (g_str_has_prefix(type, "memory-backend-")) {
19068d7f2e76SPhilippe Mathieu-Daudé         return false;
19078d7f2e76SPhilippe Mathieu-Daudé     }
19088d7f2e76SPhilippe Mathieu-Daudé 
19098d7f2e76SPhilippe Mathieu-Daudé     return true;
19108d7f2e76SPhilippe Mathieu-Daudé }
19118d7f2e76SPhilippe Mathieu-Daudé 
19128d7f2e76SPhilippe Mathieu-Daudé static void qemu_apply_machine_options(QDict *qdict)
19138d7f2e76SPhilippe Mathieu-Daudé {
19148d7f2e76SPhilippe Mathieu-Daudé     object_set_properties_from_keyval(OBJECT(current_machine), qdict, false, &error_fatal);
19158d7f2e76SPhilippe Mathieu-Daudé 
19168d7f2e76SPhilippe Mathieu-Daudé     if (semihosting_enabled(false) && !semihosting_get_argc()) {
19178d7f2e76SPhilippe Mathieu-Daudé         /* fall back to the -kernel/-append */
19188d7f2e76SPhilippe Mathieu-Daudé         semihosting_arg_fallback(current_machine->kernel_filename, current_machine->kernel_cmdline);
19198d7f2e76SPhilippe Mathieu-Daudé     }
19208d7f2e76SPhilippe Mathieu-Daudé 
19218d7f2e76SPhilippe Mathieu-Daudé     if (current_machine->smp.cpus > 1) {
19228d7f2e76SPhilippe Mathieu-Daudé         replay_add_blocker("smp");
19238d7f2e76SPhilippe Mathieu-Daudé     }
19248d7f2e76SPhilippe Mathieu-Daudé }
19258d7f2e76SPhilippe Mathieu-Daudé 
19268d7f2e76SPhilippe Mathieu-Daudé static void qemu_create_early_backends(void)
19278d7f2e76SPhilippe Mathieu-Daudé {
19288d7f2e76SPhilippe Mathieu-Daudé     MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
19298d7f2e76SPhilippe Mathieu-Daudé #if defined(CONFIG_SDL)
19308d7f2e76SPhilippe Mathieu-Daudé     const bool use_sdl = (dpy.type == DISPLAY_TYPE_SDL);
19318d7f2e76SPhilippe Mathieu-Daudé #else
19328d7f2e76SPhilippe Mathieu-Daudé     const bool use_sdl = false;
19338d7f2e76SPhilippe Mathieu-Daudé #endif
19348d7f2e76SPhilippe Mathieu-Daudé #if defined(CONFIG_GTK)
19358d7f2e76SPhilippe Mathieu-Daudé     const bool use_gtk = (dpy.type == DISPLAY_TYPE_GTK);
19368d7f2e76SPhilippe Mathieu-Daudé #else
19378d7f2e76SPhilippe Mathieu-Daudé     const bool use_gtk = false;
19388d7f2e76SPhilippe Mathieu-Daudé #endif
19398d7f2e76SPhilippe Mathieu-Daudé 
19408d7f2e76SPhilippe Mathieu-Daudé     if (dpy.has_window_close && !use_gtk && !use_sdl) {
19418d7f2e76SPhilippe Mathieu-Daudé         error_report("window-close is only valid for GTK and SDL, "
19428d7f2e76SPhilippe Mathieu-Daudé                      "ignoring option");
19438d7f2e76SPhilippe Mathieu-Daudé     }
19448d7f2e76SPhilippe Mathieu-Daudé 
19458d7f2e76SPhilippe Mathieu-Daudé     qemu_display_early_init(&dpy);
19468d7f2e76SPhilippe Mathieu-Daudé     qemu_console_early_init();
19478d7f2e76SPhilippe Mathieu-Daudé 
19488d7f2e76SPhilippe Mathieu-Daudé     if (dpy.has_gl && dpy.gl != DISPLAYGL_MODE_OFF && display_opengl == 0) {
19498d7f2e76SPhilippe Mathieu-Daudé #if defined(CONFIG_OPENGL)
19508d7f2e76SPhilippe Mathieu-Daudé         error_report("OpenGL is not supported by the display");
19518d7f2e76SPhilippe Mathieu-Daudé #else
19528d7f2e76SPhilippe Mathieu-Daudé         error_report("OpenGL support is disabled");
19538d7f2e76SPhilippe Mathieu-Daudé #endif
19548d7f2e76SPhilippe Mathieu-Daudé         exit(1);
19558d7f2e76SPhilippe Mathieu-Daudé     }
19568d7f2e76SPhilippe Mathieu-Daudé 
19578d7f2e76SPhilippe Mathieu-Daudé     object_option_foreach_add(object_create_early);
19588d7f2e76SPhilippe Mathieu-Daudé 
19598d7f2e76SPhilippe Mathieu-Daudé     /* spice needs the timers to be initialized by this point */
19608d7f2e76SPhilippe Mathieu-Daudé     /* spice must initialize before audio as it changes the default audiodev */
19618d7f2e76SPhilippe Mathieu-Daudé     /* spice must initialize before chardevs (for spicevmc and spiceport) */
19628d7f2e76SPhilippe Mathieu-Daudé     qemu_spice.init();
19638d7f2e76SPhilippe Mathieu-Daudé 
19648d7f2e76SPhilippe Mathieu-Daudé     qemu_opts_foreach(qemu_find_opts("chardev"),
19658d7f2e76SPhilippe Mathieu-Daudé                       chardev_init_func, NULL, &error_fatal);
19668d7f2e76SPhilippe Mathieu-Daudé 
19678d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_VIRTFS
19688d7f2e76SPhilippe Mathieu-Daudé     qemu_opts_foreach(qemu_find_opts("fsdev"),
19698d7f2e76SPhilippe Mathieu-Daudé                       fsdev_init_func, NULL, &error_fatal);
19708d7f2e76SPhilippe Mathieu-Daudé #endif
19718d7f2e76SPhilippe Mathieu-Daudé 
19728d7f2e76SPhilippe Mathieu-Daudé     /*
19738d7f2e76SPhilippe Mathieu-Daudé      * Note: we need to create audio and block backends before
19748d7f2e76SPhilippe Mathieu-Daudé      * setting machine properties, so they can be referred to.
19758d7f2e76SPhilippe Mathieu-Daudé      */
19768d7f2e76SPhilippe Mathieu-Daudé     configure_blockdev(&bdo_queue, machine_class, snapshot);
19778d7f2e76SPhilippe Mathieu-Daudé     audio_init_audiodevs();
1978c753bf47SPaolo Bonzini     if (default_audio) {
1979c753bf47SPaolo Bonzini         audio_create_default_audiodevs();
1980c753bf47SPaolo Bonzini     }
19818d7f2e76SPhilippe Mathieu-Daudé }
19828d7f2e76SPhilippe Mathieu-Daudé 
19838d7f2e76SPhilippe Mathieu-Daudé 
19848d7f2e76SPhilippe Mathieu-Daudé /*
19858d7f2e76SPhilippe Mathieu-Daudé  * The remainder of object creation happens after the
19868d7f2e76SPhilippe Mathieu-Daudé  * creation of chardev, fsdev, net clients and device data types.
19878d7f2e76SPhilippe Mathieu-Daudé  */
19888d7f2e76SPhilippe Mathieu-Daudé static bool object_create_late(const char *type)
19898d7f2e76SPhilippe Mathieu-Daudé {
19908d7f2e76SPhilippe Mathieu-Daudé     return !object_create_early(type) && !object_create_pre_sandbox(type);
19918d7f2e76SPhilippe Mathieu-Daudé }
19928d7f2e76SPhilippe Mathieu-Daudé 
19938d7f2e76SPhilippe Mathieu-Daudé static void qemu_create_late_backends(void)
19948d7f2e76SPhilippe Mathieu-Daudé {
19958d7f2e76SPhilippe Mathieu-Daudé     if (qtest_chrdev) {
19968d7f2e76SPhilippe Mathieu-Daudé         qtest_server_init(qtest_chrdev, qtest_log, &error_fatal);
19978d7f2e76SPhilippe Mathieu-Daudé     }
19988d7f2e76SPhilippe Mathieu-Daudé 
19998d7f2e76SPhilippe Mathieu-Daudé     net_init_clients();
20008d7f2e76SPhilippe Mathieu-Daudé 
20018d7f2e76SPhilippe Mathieu-Daudé     object_option_foreach_add(object_create_late);
20028d7f2e76SPhilippe Mathieu-Daudé 
20038d7f2e76SPhilippe Mathieu-Daudé     if (tpm_init() < 0) {
20048d7f2e76SPhilippe Mathieu-Daudé         exit(1);
20058d7f2e76SPhilippe Mathieu-Daudé     }
20068d7f2e76SPhilippe Mathieu-Daudé 
20078d7f2e76SPhilippe Mathieu-Daudé     qemu_opts_foreach(qemu_find_opts("mon"),
20088d7f2e76SPhilippe Mathieu-Daudé                       mon_init_func, NULL, &error_fatal);
20098d7f2e76SPhilippe Mathieu-Daudé 
20108d7f2e76SPhilippe Mathieu-Daudé     if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
20118d7f2e76SPhilippe Mathieu-Daudé         exit(1);
20128d7f2e76SPhilippe Mathieu-Daudé     if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)
20138d7f2e76SPhilippe Mathieu-Daudé         exit(1);
20148d7f2e76SPhilippe Mathieu-Daudé     if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
20158d7f2e76SPhilippe Mathieu-Daudé         exit(1);
20168d7f2e76SPhilippe Mathieu-Daudé 
20178d7f2e76SPhilippe Mathieu-Daudé     /* now chardevs have been created we may have semihosting to connect */
20188d7f2e76SPhilippe Mathieu-Daudé     qemu_semihosting_chardev_init();
20198d7f2e76SPhilippe Mathieu-Daudé }
20208d7f2e76SPhilippe Mathieu-Daudé 
20218d7f2e76SPhilippe Mathieu-Daudé static void qemu_resolve_machine_memdev(void)
20228d7f2e76SPhilippe Mathieu-Daudé {
20238d7f2e76SPhilippe Mathieu-Daudé     if (ram_memdev_id) {
20248d7f2e76SPhilippe Mathieu-Daudé         Object *backend;
20258d7f2e76SPhilippe Mathieu-Daudé         ram_addr_t backend_size;
20268d7f2e76SPhilippe Mathieu-Daudé 
20278d7f2e76SPhilippe Mathieu-Daudé         backend = object_resolve_path_type(ram_memdev_id,
20288d7f2e76SPhilippe Mathieu-Daudé                                            TYPE_MEMORY_BACKEND, NULL);
20298d7f2e76SPhilippe Mathieu-Daudé         if (!backend) {
20308d7f2e76SPhilippe Mathieu-Daudé             error_report("Memory backend '%s' not found", ram_memdev_id);
20318d7f2e76SPhilippe Mathieu-Daudé             exit(EXIT_FAILURE);
20328d7f2e76SPhilippe Mathieu-Daudé         }
20338d7f2e76SPhilippe Mathieu-Daudé         if (!have_custom_ram_size) {
20348d7f2e76SPhilippe Mathieu-Daudé             backend_size = object_property_get_uint(backend, "size",  &error_abort);
20358d7f2e76SPhilippe Mathieu-Daudé             current_machine->ram_size = backend_size;
20368d7f2e76SPhilippe Mathieu-Daudé         }
20378d7f2e76SPhilippe Mathieu-Daudé         object_property_set_link(OBJECT(current_machine),
20388d7f2e76SPhilippe Mathieu-Daudé                                  "memory-backend", backend, &error_fatal);
20398d7f2e76SPhilippe Mathieu-Daudé     }
20408d7f2e76SPhilippe Mathieu-Daudé }
20418d7f2e76SPhilippe Mathieu-Daudé 
20428d7f2e76SPhilippe Mathieu-Daudé static void parse_memory_options(void)
20438d7f2e76SPhilippe Mathieu-Daudé {
20448d7f2e76SPhilippe Mathieu-Daudé     QemuOpts *opts = qemu_find_opts_singleton("memory");
20458d7f2e76SPhilippe Mathieu-Daudé     QDict *dict, *prop;
20468d7f2e76SPhilippe Mathieu-Daudé     const char *mem_str;
20478d7f2e76SPhilippe Mathieu-Daudé     Location loc;
20488d7f2e76SPhilippe Mathieu-Daudé 
20498d7f2e76SPhilippe Mathieu-Daudé     loc_push_none(&loc);
20508d7f2e76SPhilippe Mathieu-Daudé     qemu_opts_loc_restore(opts);
20518d7f2e76SPhilippe Mathieu-Daudé 
20528d7f2e76SPhilippe Mathieu-Daudé     prop = qdict_new();
20538d7f2e76SPhilippe Mathieu-Daudé 
20548d7f2e76SPhilippe Mathieu-Daudé     if (qemu_opt_get_size(opts, "size", 0) != 0) {
20558d7f2e76SPhilippe Mathieu-Daudé         /* Fix up legacy suffix-less format */
20568d7f2e76SPhilippe Mathieu-Daudé         mem_str = qemu_opt_get(opts, "size");
20578d7f2e76SPhilippe Mathieu-Daudé         if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
20588d7f2e76SPhilippe Mathieu-Daudé             g_autofree char *mib_str = g_strdup_printf("%sM", mem_str);
20598d7f2e76SPhilippe Mathieu-Daudé             qdict_put_str(prop, "size", mib_str);
20608d7f2e76SPhilippe Mathieu-Daudé         } else {
20618d7f2e76SPhilippe Mathieu-Daudé             qdict_put_str(prop, "size", mem_str);
20628d7f2e76SPhilippe Mathieu-Daudé         }
20638d7f2e76SPhilippe Mathieu-Daudé     }
20648d7f2e76SPhilippe Mathieu-Daudé 
20658d7f2e76SPhilippe Mathieu-Daudé     if (qemu_opt_get(opts, "maxmem")) {
20668d7f2e76SPhilippe Mathieu-Daudé         qdict_put_str(prop, "max-size", qemu_opt_get(opts, "maxmem"));
20678d7f2e76SPhilippe Mathieu-Daudé     }
20688d7f2e76SPhilippe Mathieu-Daudé     if (qemu_opt_get(opts, "slots")) {
20698d7f2e76SPhilippe Mathieu-Daudé         qdict_put_str(prop, "slots", qemu_opt_get(opts, "slots"));
20708d7f2e76SPhilippe Mathieu-Daudé     }
20718d7f2e76SPhilippe Mathieu-Daudé 
20728d7f2e76SPhilippe Mathieu-Daudé     dict = qdict_new();
20738d7f2e76SPhilippe Mathieu-Daudé     qdict_put(dict, "memory", prop);
20748d7f2e76SPhilippe Mathieu-Daudé     keyval_merge(machine_opts_dict, dict, &error_fatal);
20758d7f2e76SPhilippe Mathieu-Daudé     qobject_unref(dict);
20768d7f2e76SPhilippe Mathieu-Daudé     loc_pop(&loc);
20778d7f2e76SPhilippe Mathieu-Daudé }
20788d7f2e76SPhilippe Mathieu-Daudé 
20798d7f2e76SPhilippe Mathieu-Daudé static void qemu_create_machine(QDict *qdict)
20808d7f2e76SPhilippe Mathieu-Daudé {
20818d7f2e76SPhilippe Mathieu-Daudé     MachineClass *machine_class = select_machine(qdict, &error_fatal);
20828d7f2e76SPhilippe Mathieu-Daudé     object_set_machine_compat_props(machine_class->compat_props);
20838d7f2e76SPhilippe Mathieu-Daudé 
20848d7f2e76SPhilippe Mathieu-Daudé     current_machine = MACHINE(object_new_with_class(OBJECT_CLASS(machine_class)));
20858d7f2e76SPhilippe Mathieu-Daudé     object_property_add_child(object_get_root(), "machine",
20868d7f2e76SPhilippe Mathieu-Daudé                               OBJECT(current_machine));
20878d7f2e76SPhilippe Mathieu-Daudé     object_property_add_child(container_get(OBJECT(current_machine),
20888d7f2e76SPhilippe Mathieu-Daudé                                             "/unattached"),
20898d7f2e76SPhilippe Mathieu-Daudé                               "sysbus", OBJECT(sysbus_get_default()));
20908d7f2e76SPhilippe Mathieu-Daudé 
20918d7f2e76SPhilippe Mathieu-Daudé     if (machine_class->minimum_page_bits) {
20928d7f2e76SPhilippe Mathieu-Daudé         if (!set_preferred_target_page_bits(machine_class->minimum_page_bits)) {
20938d7f2e76SPhilippe Mathieu-Daudé             /* This would be a board error: specifying a minimum smaller than
20948d7f2e76SPhilippe Mathieu-Daudé              * a target's compile-time fixed setting.
20958d7f2e76SPhilippe Mathieu-Daudé              */
20968d7f2e76SPhilippe Mathieu-Daudé             g_assert_not_reached();
20978d7f2e76SPhilippe Mathieu-Daudé         }
20988d7f2e76SPhilippe Mathieu-Daudé     }
20998d7f2e76SPhilippe Mathieu-Daudé 
21008d7f2e76SPhilippe Mathieu-Daudé     cpu_exec_init_all();
21018d7f2e76SPhilippe Mathieu-Daudé     page_size_init();
21028d7f2e76SPhilippe Mathieu-Daudé 
21038d7f2e76SPhilippe Mathieu-Daudé     if (machine_class->hw_version) {
21048d7f2e76SPhilippe Mathieu-Daudé         qemu_set_hw_version(machine_class->hw_version);
21058d7f2e76SPhilippe Mathieu-Daudé     }
21068d7f2e76SPhilippe Mathieu-Daudé 
21078d7f2e76SPhilippe Mathieu-Daudé     /*
21088d7f2e76SPhilippe Mathieu-Daudé      * Get the default machine options from the machine if it is not already
21098d7f2e76SPhilippe Mathieu-Daudé      * specified either by the configuration file or by the command line.
21108d7f2e76SPhilippe Mathieu-Daudé      */
21118d7f2e76SPhilippe Mathieu-Daudé     if (machine_class->default_machine_opts) {
21128d7f2e76SPhilippe Mathieu-Daudé         QDict *default_opts =
21138d7f2e76SPhilippe Mathieu-Daudé             keyval_parse(machine_class->default_machine_opts, NULL, NULL,
21148d7f2e76SPhilippe Mathieu-Daudé                          &error_abort);
21158d7f2e76SPhilippe Mathieu-Daudé         qemu_apply_legacy_machine_options(default_opts);
21168d7f2e76SPhilippe Mathieu-Daudé         object_set_properties_from_keyval(OBJECT(current_machine), default_opts,
21178d7f2e76SPhilippe Mathieu-Daudé                                           false, &error_abort);
21188d7f2e76SPhilippe Mathieu-Daudé         qobject_unref(default_opts);
21198d7f2e76SPhilippe Mathieu-Daudé     }
21208d7f2e76SPhilippe Mathieu-Daudé }
21218d7f2e76SPhilippe Mathieu-Daudé 
21228d7f2e76SPhilippe Mathieu-Daudé static int global_init_func(void *opaque, QemuOpts *opts, Error **errp)
21238d7f2e76SPhilippe Mathieu-Daudé {
21248d7f2e76SPhilippe Mathieu-Daudé     GlobalProperty *g;
21258d7f2e76SPhilippe Mathieu-Daudé 
21268d7f2e76SPhilippe Mathieu-Daudé     g = g_malloc0(sizeof(*g));
21278d7f2e76SPhilippe Mathieu-Daudé     g->driver   = qemu_opt_get(opts, "driver");
21288d7f2e76SPhilippe Mathieu-Daudé     g->property = qemu_opt_get(opts, "property");
21298d7f2e76SPhilippe Mathieu-Daudé     g->value    = qemu_opt_get(opts, "value");
21308d7f2e76SPhilippe Mathieu-Daudé     qdev_prop_register_global(g);
21318d7f2e76SPhilippe Mathieu-Daudé     return 0;
21328d7f2e76SPhilippe Mathieu-Daudé }
21338d7f2e76SPhilippe Mathieu-Daudé 
21348d7f2e76SPhilippe Mathieu-Daudé /*
21358d7f2e76SPhilippe Mathieu-Daudé  * Return whether configuration group @group is stored in QemuOpts, or
21368d7f2e76SPhilippe Mathieu-Daudé  * recorded as one or more QDicts by qemu_record_config_group.
21378d7f2e76SPhilippe Mathieu-Daudé  */
21388d7f2e76SPhilippe Mathieu-Daudé static bool is_qemuopts_group(const char *group)
21398d7f2e76SPhilippe Mathieu-Daudé {
21408d7f2e76SPhilippe Mathieu-Daudé     if (g_str_equal(group, "object") ||
21418d7f2e76SPhilippe Mathieu-Daudé         g_str_equal(group, "audiodev") ||
21428d7f2e76SPhilippe Mathieu-Daudé         g_str_equal(group, "machine") ||
21438d7f2e76SPhilippe Mathieu-Daudé         g_str_equal(group, "smp-opts") ||
21448d7f2e76SPhilippe Mathieu-Daudé         g_str_equal(group, "boot-opts")) {
21458d7f2e76SPhilippe Mathieu-Daudé         return false;
21468d7f2e76SPhilippe Mathieu-Daudé     }
21478d7f2e76SPhilippe Mathieu-Daudé     return true;
21488d7f2e76SPhilippe Mathieu-Daudé }
21498d7f2e76SPhilippe Mathieu-Daudé 
21508d7f2e76SPhilippe Mathieu-Daudé static void qemu_record_config_group(const char *group, QDict *dict,
21518d7f2e76SPhilippe Mathieu-Daudé                                      bool from_json, Error **errp)
21528d7f2e76SPhilippe Mathieu-Daudé {
21538d7f2e76SPhilippe Mathieu-Daudé     if (g_str_equal(group, "object")) {
21548d7f2e76SPhilippe Mathieu-Daudé         Visitor *v = qobject_input_visitor_new_keyval(QOBJECT(dict));
21558d7f2e76SPhilippe Mathieu-Daudé         object_option_add_visitor(v);
21568d7f2e76SPhilippe Mathieu-Daudé         visit_free(v);
21578d7f2e76SPhilippe Mathieu-Daudé 
21588d7f2e76SPhilippe Mathieu-Daudé     } else if (g_str_equal(group, "audiodev")) {
21598d7f2e76SPhilippe Mathieu-Daudé         Audiodev *dev = NULL;
21608d7f2e76SPhilippe Mathieu-Daudé         Visitor *v = qobject_input_visitor_new_keyval(QOBJECT(dict));
21618d7f2e76SPhilippe Mathieu-Daudé         if (visit_type_Audiodev(v, NULL, &dev, errp)) {
21628d7f2e76SPhilippe Mathieu-Daudé             audio_define(dev);
21638d7f2e76SPhilippe Mathieu-Daudé         }
21648d7f2e76SPhilippe Mathieu-Daudé         visit_free(v);
21658d7f2e76SPhilippe Mathieu-Daudé 
21668d7f2e76SPhilippe Mathieu-Daudé     } else if (g_str_equal(group, "machine")) {
21678d7f2e76SPhilippe Mathieu-Daudé         /*
21688d7f2e76SPhilippe Mathieu-Daudé          * Cannot merge string-valued and type-safe dictionaries, so JSON
21698d7f2e76SPhilippe Mathieu-Daudé          * is not accepted yet for -M.
21708d7f2e76SPhilippe Mathieu-Daudé          */
21718d7f2e76SPhilippe Mathieu-Daudé         assert(!from_json);
21728d7f2e76SPhilippe Mathieu-Daudé         keyval_merge(machine_opts_dict, dict, errp);
21738d7f2e76SPhilippe Mathieu-Daudé     } else if (g_str_equal(group, "smp-opts")) {
21748d7f2e76SPhilippe Mathieu-Daudé         machine_merge_property("smp", dict, &error_fatal);
21758d7f2e76SPhilippe Mathieu-Daudé     } else if (g_str_equal(group, "boot-opts")) {
21768d7f2e76SPhilippe Mathieu-Daudé         machine_merge_property("boot", dict, &error_fatal);
21778d7f2e76SPhilippe Mathieu-Daudé     } else {
21788d7f2e76SPhilippe Mathieu-Daudé         abort();
21798d7f2e76SPhilippe Mathieu-Daudé     }
21808d7f2e76SPhilippe Mathieu-Daudé }
21818d7f2e76SPhilippe Mathieu-Daudé 
21828d7f2e76SPhilippe Mathieu-Daudé /*
21838d7f2e76SPhilippe Mathieu-Daudé  * Parse non-QemuOpts config file groups, pass the rest to
21848d7f2e76SPhilippe Mathieu-Daudé  * qemu_config_do_parse.
21858d7f2e76SPhilippe Mathieu-Daudé  */
21868d7f2e76SPhilippe Mathieu-Daudé static void qemu_parse_config_group(const char *group, QDict *qdict,
21878d7f2e76SPhilippe Mathieu-Daudé                                     void *opaque, Error **errp)
21888d7f2e76SPhilippe Mathieu-Daudé {
21898d7f2e76SPhilippe Mathieu-Daudé     QObject *crumpled;
21908d7f2e76SPhilippe Mathieu-Daudé     if (is_qemuopts_group(group)) {
21918d7f2e76SPhilippe Mathieu-Daudé         qemu_config_do_parse(group, qdict, opaque, errp);
21928d7f2e76SPhilippe Mathieu-Daudé         return;
21938d7f2e76SPhilippe Mathieu-Daudé     }
21948d7f2e76SPhilippe Mathieu-Daudé 
21958d7f2e76SPhilippe Mathieu-Daudé     crumpled = qdict_crumple(qdict, errp);
21968d7f2e76SPhilippe Mathieu-Daudé     if (!crumpled) {
21978d7f2e76SPhilippe Mathieu-Daudé         return;
21988d7f2e76SPhilippe Mathieu-Daudé     }
21998d7f2e76SPhilippe Mathieu-Daudé     switch (qobject_type(crumpled)) {
22008d7f2e76SPhilippe Mathieu-Daudé     case QTYPE_QDICT:
22018d7f2e76SPhilippe Mathieu-Daudé         qemu_record_config_group(group, qobject_to(QDict, crumpled), false, errp);
22028d7f2e76SPhilippe Mathieu-Daudé         break;
22038d7f2e76SPhilippe Mathieu-Daudé     case QTYPE_QLIST:
22048d7f2e76SPhilippe Mathieu-Daudé         error_setg(errp, "Lists cannot be at top level of a configuration section");
22058d7f2e76SPhilippe Mathieu-Daudé         break;
22068d7f2e76SPhilippe Mathieu-Daudé     default:
22078d7f2e76SPhilippe Mathieu-Daudé         g_assert_not_reached();
22088d7f2e76SPhilippe Mathieu-Daudé     }
22098d7f2e76SPhilippe Mathieu-Daudé     qobject_unref(crumpled);
22108d7f2e76SPhilippe Mathieu-Daudé }
22118d7f2e76SPhilippe Mathieu-Daudé 
22128d7f2e76SPhilippe Mathieu-Daudé static void qemu_read_default_config_file(Error **errp)
22138d7f2e76SPhilippe Mathieu-Daudé {
22148d7f2e76SPhilippe Mathieu-Daudé     ERRP_GUARD();
22158d7f2e76SPhilippe Mathieu-Daudé     int ret;
22168d7f2e76SPhilippe Mathieu-Daudé     g_autofree char *file = get_relocated_path(CONFIG_QEMU_CONFDIR "/qemu.conf");
22178d7f2e76SPhilippe Mathieu-Daudé 
22188d7f2e76SPhilippe Mathieu-Daudé     ret = qemu_read_config_file(file, qemu_parse_config_group, errp);
22198d7f2e76SPhilippe Mathieu-Daudé     if (ret < 0) {
22208d7f2e76SPhilippe Mathieu-Daudé         if (ret == -ENOENT) {
22218d7f2e76SPhilippe Mathieu-Daudé             error_free(*errp);
22228d7f2e76SPhilippe Mathieu-Daudé             *errp = NULL;
22238d7f2e76SPhilippe Mathieu-Daudé         }
22248d7f2e76SPhilippe Mathieu-Daudé     }
22258d7f2e76SPhilippe Mathieu-Daudé }
22268d7f2e76SPhilippe Mathieu-Daudé 
22278d7f2e76SPhilippe Mathieu-Daudé static void qemu_set_option(const char *str, Error **errp)
22288d7f2e76SPhilippe Mathieu-Daudé {
22298d7f2e76SPhilippe Mathieu-Daudé     char group[64], id[64], arg[64];
22308d7f2e76SPhilippe Mathieu-Daudé     QemuOptsList *list;
22318d7f2e76SPhilippe Mathieu-Daudé     QemuOpts *opts;
22328d7f2e76SPhilippe Mathieu-Daudé     int rc, offset;
22338d7f2e76SPhilippe Mathieu-Daudé 
22348d7f2e76SPhilippe Mathieu-Daudé     rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset);
22358d7f2e76SPhilippe Mathieu-Daudé     if (rc < 3 || str[offset] != '=') {
22368d7f2e76SPhilippe Mathieu-Daudé         error_setg(errp, "can't parse: \"%s\"", str);
22378d7f2e76SPhilippe Mathieu-Daudé         return;
22388d7f2e76SPhilippe Mathieu-Daudé     }
22398d7f2e76SPhilippe Mathieu-Daudé 
22408d7f2e76SPhilippe Mathieu-Daudé     if (!is_qemuopts_group(group)) {
22418d7f2e76SPhilippe Mathieu-Daudé         error_setg(errp, "-set is not supported with %s", group);
22428d7f2e76SPhilippe Mathieu-Daudé     } else {
22438d7f2e76SPhilippe Mathieu-Daudé         list = qemu_find_opts_err(group, errp);
22448d7f2e76SPhilippe Mathieu-Daudé         if (list) {
22458d7f2e76SPhilippe Mathieu-Daudé             opts = qemu_opts_find(list, id);
22468d7f2e76SPhilippe Mathieu-Daudé             if (!opts) {
22478d7f2e76SPhilippe Mathieu-Daudé                 error_setg(errp, "there is no %s \"%s\" defined", group, id);
22488d7f2e76SPhilippe Mathieu-Daudé                 return;
22498d7f2e76SPhilippe Mathieu-Daudé             }
22508d7f2e76SPhilippe Mathieu-Daudé             qemu_opt_set(opts, arg, str + offset + 1, errp);
22518d7f2e76SPhilippe Mathieu-Daudé         }
22528d7f2e76SPhilippe Mathieu-Daudé     }
22538d7f2e76SPhilippe Mathieu-Daudé }
22548d7f2e76SPhilippe Mathieu-Daudé 
22558d7f2e76SPhilippe Mathieu-Daudé static void user_register_global_props(void)
22568d7f2e76SPhilippe Mathieu-Daudé {
22578d7f2e76SPhilippe Mathieu-Daudé     qemu_opts_foreach(qemu_find_opts("global"),
22588d7f2e76SPhilippe Mathieu-Daudé                       global_init_func, NULL, NULL);
22598d7f2e76SPhilippe Mathieu-Daudé }
22608d7f2e76SPhilippe Mathieu-Daudé 
22618d7f2e76SPhilippe Mathieu-Daudé static int do_configure_icount(void *opaque, QemuOpts *opts, Error **errp)
22628d7f2e76SPhilippe Mathieu-Daudé {
22638d7f2e76SPhilippe Mathieu-Daudé     icount_configure(opts, errp);
22648d7f2e76SPhilippe Mathieu-Daudé     return 0;
22658d7f2e76SPhilippe Mathieu-Daudé }
22668d7f2e76SPhilippe Mathieu-Daudé 
22678d7f2e76SPhilippe Mathieu-Daudé static int accelerator_set_property(void *opaque,
22688d7f2e76SPhilippe Mathieu-Daudé                                 const char *name, const char *value,
22698d7f2e76SPhilippe Mathieu-Daudé                                 Error **errp)
22708d7f2e76SPhilippe Mathieu-Daudé {
22718d7f2e76SPhilippe Mathieu-Daudé     return object_parse_property_opt(opaque, name, value, "accel", errp);
22728d7f2e76SPhilippe Mathieu-Daudé }
22738d7f2e76SPhilippe Mathieu-Daudé 
22748d7f2e76SPhilippe Mathieu-Daudé static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
22758d7f2e76SPhilippe Mathieu-Daudé {
22768d7f2e76SPhilippe Mathieu-Daudé     bool *p_init_failed = opaque;
22778d7f2e76SPhilippe Mathieu-Daudé     const char *acc = qemu_opt_get(opts, "accel");
22788d7f2e76SPhilippe Mathieu-Daudé     AccelClass *ac = accel_find(acc);
22798d7f2e76SPhilippe Mathieu-Daudé     AccelState *accel;
22808d7f2e76SPhilippe Mathieu-Daudé     int ret;
22818d7f2e76SPhilippe Mathieu-Daudé     bool qtest_with_kvm;
22828d7f2e76SPhilippe Mathieu-Daudé 
22838d7f2e76SPhilippe Mathieu-Daudé     if (!acc) {
22848d7f2e76SPhilippe Mathieu-Daudé         error_setg(errp, QERR_MISSING_PARAMETER, "accel");
22858d7f2e76SPhilippe Mathieu-Daudé         goto bad;
22868d7f2e76SPhilippe Mathieu-Daudé     }
22878d7f2e76SPhilippe Mathieu-Daudé 
22888d7f2e76SPhilippe Mathieu-Daudé     qtest_with_kvm = g_str_equal(acc, "kvm") && qtest_chrdev != NULL;
22898d7f2e76SPhilippe Mathieu-Daudé 
22908d7f2e76SPhilippe Mathieu-Daudé     if (!ac) {
22918d7f2e76SPhilippe Mathieu-Daudé         if (!qtest_with_kvm) {
22928d7f2e76SPhilippe Mathieu-Daudé             error_report("invalid accelerator %s", acc);
22938d7f2e76SPhilippe Mathieu-Daudé         }
22948d7f2e76SPhilippe Mathieu-Daudé         goto bad;
22958d7f2e76SPhilippe Mathieu-Daudé     }
22968d7f2e76SPhilippe Mathieu-Daudé     accel = ACCEL(object_new_with_class(OBJECT_CLASS(ac)));
22978d7f2e76SPhilippe Mathieu-Daudé     object_apply_compat_props(OBJECT(accel));
22988d7f2e76SPhilippe Mathieu-Daudé     qemu_opt_foreach(opts, accelerator_set_property,
22998d7f2e76SPhilippe Mathieu-Daudé                      accel,
23008d7f2e76SPhilippe Mathieu-Daudé                      &error_fatal);
23018d7f2e76SPhilippe Mathieu-Daudé     /*
23028d7f2e76SPhilippe Mathieu-Daudé      * If legacy -singlestep option is set, honour it for TCG and
23038d7f2e76SPhilippe Mathieu-Daudé      * silently ignore for any other accelerator (which is how this
23048d7f2e76SPhilippe Mathieu-Daudé      * option has always behaved).
23058d7f2e76SPhilippe Mathieu-Daudé      */
23068d7f2e76SPhilippe Mathieu-Daudé     if (opt_one_insn_per_tb) {
23078d7f2e76SPhilippe Mathieu-Daudé         /*
23088d7f2e76SPhilippe Mathieu-Daudé          * This will always succeed for TCG, and we want to ignore
23098d7f2e76SPhilippe Mathieu-Daudé          * the error from trying to set a nonexistent property
23108d7f2e76SPhilippe Mathieu-Daudé          * on any other accelerator.
23118d7f2e76SPhilippe Mathieu-Daudé          */
23128d7f2e76SPhilippe Mathieu-Daudé         object_property_set_bool(OBJECT(accel), "one-insn-per-tb", true, NULL);
23138d7f2e76SPhilippe Mathieu-Daudé     }
23148d7f2e76SPhilippe Mathieu-Daudé     ret = accel_init_machine(accel, current_machine);
23158d7f2e76SPhilippe Mathieu-Daudé     if (ret < 0) {
23168d7f2e76SPhilippe Mathieu-Daudé         if (!qtest_with_kvm || ret != -ENOENT) {
23178d7f2e76SPhilippe Mathieu-Daudé             error_report("failed to initialize %s: %s", acc, strerror(-ret));
23188d7f2e76SPhilippe Mathieu-Daudé         }
23198d7f2e76SPhilippe Mathieu-Daudé         goto bad;
23208d7f2e76SPhilippe Mathieu-Daudé     }
23218d7f2e76SPhilippe Mathieu-Daudé 
23228d7f2e76SPhilippe Mathieu-Daudé     return 1;
23238d7f2e76SPhilippe Mathieu-Daudé 
23248d7f2e76SPhilippe Mathieu-Daudé bad:
23258d7f2e76SPhilippe Mathieu-Daudé     *p_init_failed = true;
23268d7f2e76SPhilippe Mathieu-Daudé     return 0;
23278d7f2e76SPhilippe Mathieu-Daudé }
23288d7f2e76SPhilippe Mathieu-Daudé 
23298d7f2e76SPhilippe Mathieu-Daudé static void configure_accelerators(const char *progname)
23308d7f2e76SPhilippe Mathieu-Daudé {
23318d7f2e76SPhilippe Mathieu-Daudé     bool init_failed = false;
23328d7f2e76SPhilippe Mathieu-Daudé 
23338d7f2e76SPhilippe Mathieu-Daudé     qemu_opts_foreach(qemu_find_opts("icount"),
23348d7f2e76SPhilippe Mathieu-Daudé                       do_configure_icount, NULL, &error_fatal);
23358d7f2e76SPhilippe Mathieu-Daudé 
23368d7f2e76SPhilippe Mathieu-Daudé     if (QTAILQ_EMPTY(&qemu_accel_opts.head)) {
23378d7f2e76SPhilippe Mathieu-Daudé         char **accel_list, **tmp;
23388d7f2e76SPhilippe Mathieu-Daudé 
23398d7f2e76SPhilippe Mathieu-Daudé         if (accelerators == NULL) {
23408d7f2e76SPhilippe Mathieu-Daudé             /* Select the default accelerator */
23418d7f2e76SPhilippe Mathieu-Daudé             bool have_tcg = accel_find("tcg");
23428d7f2e76SPhilippe Mathieu-Daudé             bool have_kvm = accel_find("kvm");
23438d7f2e76SPhilippe Mathieu-Daudé 
23448d7f2e76SPhilippe Mathieu-Daudé             if (have_tcg && have_kvm) {
23458d7f2e76SPhilippe Mathieu-Daudé                 if (g_str_has_suffix(progname, "kvm")) {
23468d7f2e76SPhilippe Mathieu-Daudé                     /* If the program name ends with "kvm", we prefer KVM */
23478d7f2e76SPhilippe Mathieu-Daudé                     accelerators = "kvm:tcg";
23488d7f2e76SPhilippe Mathieu-Daudé                 } else {
23498d7f2e76SPhilippe Mathieu-Daudé                     accelerators = "tcg:kvm";
23508d7f2e76SPhilippe Mathieu-Daudé                 }
23518d7f2e76SPhilippe Mathieu-Daudé             } else if (have_kvm) {
23528d7f2e76SPhilippe Mathieu-Daudé                 accelerators = "kvm";
23538d7f2e76SPhilippe Mathieu-Daudé             } else if (have_tcg) {
23548d7f2e76SPhilippe Mathieu-Daudé                 accelerators = "tcg";
23558d7f2e76SPhilippe Mathieu-Daudé             } else {
23568d7f2e76SPhilippe Mathieu-Daudé                 error_report("No accelerator selected and"
23578d7f2e76SPhilippe Mathieu-Daudé                              " no default accelerator available");
23588d7f2e76SPhilippe Mathieu-Daudé                 exit(1);
23598d7f2e76SPhilippe Mathieu-Daudé             }
23608d7f2e76SPhilippe Mathieu-Daudé         }
23618d7f2e76SPhilippe Mathieu-Daudé         accel_list = g_strsplit(accelerators, ":", 0);
23628d7f2e76SPhilippe Mathieu-Daudé 
23638d7f2e76SPhilippe Mathieu-Daudé         for (tmp = accel_list; *tmp; tmp++) {
23648d7f2e76SPhilippe Mathieu-Daudé             /*
23658d7f2e76SPhilippe Mathieu-Daudé              * Filter invalid accelerators here, to prevent obscenities
23668d7f2e76SPhilippe Mathieu-Daudé              * such as "-machine accel=tcg,,thread=single".
23678d7f2e76SPhilippe Mathieu-Daudé              */
23688d7f2e76SPhilippe Mathieu-Daudé             if (accel_find(*tmp)) {
23698d7f2e76SPhilippe Mathieu-Daudé                 qemu_opts_parse_noisily(qemu_find_opts("accel"), *tmp, true);
23708d7f2e76SPhilippe Mathieu-Daudé             } else {
23718d7f2e76SPhilippe Mathieu-Daudé                 init_failed = true;
23728d7f2e76SPhilippe Mathieu-Daudé                 error_report("invalid accelerator %s", *tmp);
23738d7f2e76SPhilippe Mathieu-Daudé             }
23748d7f2e76SPhilippe Mathieu-Daudé         }
23758d7f2e76SPhilippe Mathieu-Daudé         g_strfreev(accel_list);
23768d7f2e76SPhilippe Mathieu-Daudé     } else {
23778d7f2e76SPhilippe Mathieu-Daudé         if (accelerators != NULL) {
23788d7f2e76SPhilippe Mathieu-Daudé             error_report("The -accel and \"-machine accel=\" options are incompatible");
23798d7f2e76SPhilippe Mathieu-Daudé             exit(1);
23808d7f2e76SPhilippe Mathieu-Daudé         }
23818d7f2e76SPhilippe Mathieu-Daudé     }
23828d7f2e76SPhilippe Mathieu-Daudé 
23838d7f2e76SPhilippe Mathieu-Daudé     if (!qemu_opts_foreach(qemu_find_opts("accel"),
23848d7f2e76SPhilippe Mathieu-Daudé                            do_configure_accelerator, &init_failed, &error_fatal)) {
23858d7f2e76SPhilippe Mathieu-Daudé         if (!init_failed) {
23868d7f2e76SPhilippe Mathieu-Daudé             error_report("no accelerator found");
23878d7f2e76SPhilippe Mathieu-Daudé         }
23888d7f2e76SPhilippe Mathieu-Daudé         exit(1);
23898d7f2e76SPhilippe Mathieu-Daudé     }
23908d7f2e76SPhilippe Mathieu-Daudé 
23918d7f2e76SPhilippe Mathieu-Daudé     if (init_failed && !qtest_chrdev) {
23928d7f2e76SPhilippe Mathieu-Daudé         error_report("falling back to %s", current_accel_name());
23938d7f2e76SPhilippe Mathieu-Daudé     }
23948d7f2e76SPhilippe Mathieu-Daudé 
23958d7f2e76SPhilippe Mathieu-Daudé     if (icount_enabled() && !tcg_enabled()) {
23968d7f2e76SPhilippe Mathieu-Daudé         error_report("-icount is not allowed with hardware virtualization");
23978d7f2e76SPhilippe Mathieu-Daudé         exit(1);
23988d7f2e76SPhilippe Mathieu-Daudé     }
23998d7f2e76SPhilippe Mathieu-Daudé }
24008d7f2e76SPhilippe Mathieu-Daudé 
24018d7f2e76SPhilippe Mathieu-Daudé static void qemu_validate_options(const QDict *machine_opts)
24028d7f2e76SPhilippe Mathieu-Daudé {
24038d7f2e76SPhilippe Mathieu-Daudé     const char *kernel_filename = qdict_get_try_str(machine_opts, "kernel");
24048d7f2e76SPhilippe Mathieu-Daudé     const char *initrd_filename = qdict_get_try_str(machine_opts, "initrd");
24058d7f2e76SPhilippe Mathieu-Daudé     const char *kernel_cmdline = qdict_get_try_str(machine_opts, "append");
24068d7f2e76SPhilippe Mathieu-Daudé 
24078d7f2e76SPhilippe Mathieu-Daudé     if (kernel_filename == NULL) {
24088d7f2e76SPhilippe Mathieu-Daudé          if (kernel_cmdline != NULL) {
24098d7f2e76SPhilippe Mathieu-Daudé               error_report("-append only allowed with -kernel option");
24108d7f2e76SPhilippe Mathieu-Daudé               exit(1);
24118d7f2e76SPhilippe Mathieu-Daudé           }
24128d7f2e76SPhilippe Mathieu-Daudé 
24138d7f2e76SPhilippe Mathieu-Daudé           if (initrd_filename != NULL) {
24148d7f2e76SPhilippe Mathieu-Daudé               error_report("-initrd only allowed with -kernel option");
24158d7f2e76SPhilippe Mathieu-Daudé               exit(1);
24168d7f2e76SPhilippe Mathieu-Daudé           }
24178d7f2e76SPhilippe Mathieu-Daudé     }
24188d7f2e76SPhilippe Mathieu-Daudé 
24198d7f2e76SPhilippe Mathieu-Daudé     if (loadvm && preconfig_requested) {
24208d7f2e76SPhilippe Mathieu-Daudé         error_report("'preconfig' and 'loadvm' options are "
24218d7f2e76SPhilippe Mathieu-Daudé                      "mutually exclusive");
24228d7f2e76SPhilippe Mathieu-Daudé         exit(EXIT_FAILURE);
24238d7f2e76SPhilippe Mathieu-Daudé     }
24248d7f2e76SPhilippe Mathieu-Daudé     if (incoming && preconfig_requested && strcmp(incoming, "defer") != 0) {
24258d7f2e76SPhilippe Mathieu-Daudé         error_report("'preconfig' supports '-incoming defer' only");
24268d7f2e76SPhilippe Mathieu-Daudé         exit(EXIT_FAILURE);
24278d7f2e76SPhilippe Mathieu-Daudé     }
24288d7f2e76SPhilippe Mathieu-Daudé 
24298d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_CURSES
24308d7f2e76SPhilippe Mathieu-Daudé     if (is_daemonized() && dpy.type == DISPLAY_TYPE_CURSES) {
24318d7f2e76SPhilippe Mathieu-Daudé         error_report("curses display cannot be used with -daemonize");
24328d7f2e76SPhilippe Mathieu-Daudé         exit(1);
24338d7f2e76SPhilippe Mathieu-Daudé     }
24348d7f2e76SPhilippe Mathieu-Daudé #endif
24358d7f2e76SPhilippe Mathieu-Daudé }
24368d7f2e76SPhilippe Mathieu-Daudé 
24378d7f2e76SPhilippe Mathieu-Daudé static void qemu_process_sugar_options(void)
24388d7f2e76SPhilippe Mathieu-Daudé {
24398d7f2e76SPhilippe Mathieu-Daudé     if (mem_prealloc) {
24408d7f2e76SPhilippe Mathieu-Daudé         QObject *smp = qdict_get(machine_opts_dict, "smp");
24418d7f2e76SPhilippe Mathieu-Daudé         if (smp && qobject_type(smp) == QTYPE_QDICT) {
24428d7f2e76SPhilippe Mathieu-Daudé             QObject *cpus = qdict_get(qobject_to(QDict, smp), "cpus");
24438d7f2e76SPhilippe Mathieu-Daudé             if (cpus && qobject_type(cpus) == QTYPE_QSTRING) {
24448d7f2e76SPhilippe Mathieu-Daudé                 const char *val = qstring_get_str(qobject_to(QString, cpus));
24458d7f2e76SPhilippe Mathieu-Daudé                 object_register_sugar_prop("memory-backend", "prealloc-threads",
24468d7f2e76SPhilippe Mathieu-Daudé                                            val, false);
24478d7f2e76SPhilippe Mathieu-Daudé             }
24488d7f2e76SPhilippe Mathieu-Daudé         }
24498d7f2e76SPhilippe Mathieu-Daudé         object_register_sugar_prop("memory-backend", "prealloc", "on", false);
24508d7f2e76SPhilippe Mathieu-Daudé     }
24518d7f2e76SPhilippe Mathieu-Daudé }
24528d7f2e76SPhilippe Mathieu-Daudé 
24538d7f2e76SPhilippe Mathieu-Daudé /* -action processing */
24548d7f2e76SPhilippe Mathieu-Daudé 
24558d7f2e76SPhilippe Mathieu-Daudé /*
24568d7f2e76SPhilippe Mathieu-Daudé  * Process all the -action parameters parsed from cmdline.
24578d7f2e76SPhilippe Mathieu-Daudé  */
24588d7f2e76SPhilippe Mathieu-Daudé static int process_runstate_actions(void *opaque, QemuOpts *opts, Error **errp)
24598d7f2e76SPhilippe Mathieu-Daudé {
24608d7f2e76SPhilippe Mathieu-Daudé     Error *local_err = NULL;
24618d7f2e76SPhilippe Mathieu-Daudé     QDict *qdict = qemu_opts_to_qdict(opts, NULL);
24628d7f2e76SPhilippe Mathieu-Daudé     QObject *ret = NULL;
24638d7f2e76SPhilippe Mathieu-Daudé     qmp_marshal_set_action(qdict, &ret, &local_err);
24648d7f2e76SPhilippe Mathieu-Daudé     qobject_unref(ret);
24658d7f2e76SPhilippe Mathieu-Daudé     qobject_unref(qdict);
24668d7f2e76SPhilippe Mathieu-Daudé     if (local_err) {
24678d7f2e76SPhilippe Mathieu-Daudé         error_propagate(errp, local_err);
24688d7f2e76SPhilippe Mathieu-Daudé         return 1;
24698d7f2e76SPhilippe Mathieu-Daudé     }
24708d7f2e76SPhilippe Mathieu-Daudé     return 0;
24718d7f2e76SPhilippe Mathieu-Daudé }
24728d7f2e76SPhilippe Mathieu-Daudé 
24738d7f2e76SPhilippe Mathieu-Daudé static void qemu_process_early_options(void)
24748d7f2e76SPhilippe Mathieu-Daudé {
24758d7f2e76SPhilippe Mathieu-Daudé     qemu_opts_foreach(qemu_find_opts("name"),
24768d7f2e76SPhilippe Mathieu-Daudé                       parse_name, NULL, &error_fatal);
24778d7f2e76SPhilippe Mathieu-Daudé 
24788d7f2e76SPhilippe Mathieu-Daudé     object_option_foreach_add(object_create_pre_sandbox);
24798d7f2e76SPhilippe Mathieu-Daudé 
24808d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_SECCOMP
24818d7f2e76SPhilippe Mathieu-Daudé     QemuOptsList *olist = qemu_find_opts_err("sandbox", NULL);
24828d7f2e76SPhilippe Mathieu-Daudé     if (olist) {
24838d7f2e76SPhilippe Mathieu-Daudé         qemu_opts_foreach(olist, parse_sandbox, NULL, &error_fatal);
24848d7f2e76SPhilippe Mathieu-Daudé     }
24858d7f2e76SPhilippe Mathieu-Daudé #endif
24868d7f2e76SPhilippe Mathieu-Daudé 
24878d7f2e76SPhilippe Mathieu-Daudé     if (qemu_opts_foreach(qemu_find_opts("action"),
24888d7f2e76SPhilippe Mathieu-Daudé                           process_runstate_actions, NULL, &error_fatal)) {
24898d7f2e76SPhilippe Mathieu-Daudé         exit(1);
24908d7f2e76SPhilippe Mathieu-Daudé     }
24918d7f2e76SPhilippe Mathieu-Daudé 
24928d7f2e76SPhilippe Mathieu-Daudé #ifndef _WIN32
24938d7f2e76SPhilippe Mathieu-Daudé     qemu_opts_foreach(qemu_find_opts("add-fd"),
24948d7f2e76SPhilippe Mathieu-Daudé                       parse_add_fd, NULL, &error_fatal);
24958d7f2e76SPhilippe Mathieu-Daudé 
24968d7f2e76SPhilippe Mathieu-Daudé     qemu_opts_foreach(qemu_find_opts("add-fd"),
24978d7f2e76SPhilippe Mathieu-Daudé                       cleanup_add_fd, NULL, &error_fatal);
24988d7f2e76SPhilippe Mathieu-Daudé #endif
24998d7f2e76SPhilippe Mathieu-Daudé 
25008d7f2e76SPhilippe Mathieu-Daudé     /* Open the logfile at this point and set the log mask if necessary.  */
25018d7f2e76SPhilippe Mathieu-Daudé     {
25028d7f2e76SPhilippe Mathieu-Daudé         int mask = 0;
25038d7f2e76SPhilippe Mathieu-Daudé         if (log_mask) {
25048d7f2e76SPhilippe Mathieu-Daudé             mask = qemu_str_to_log_mask(log_mask);
25058d7f2e76SPhilippe Mathieu-Daudé             if (!mask) {
25068d7f2e76SPhilippe Mathieu-Daudé                 qemu_print_log_usage(stdout);
25078d7f2e76SPhilippe Mathieu-Daudé                 exit(1);
25088d7f2e76SPhilippe Mathieu-Daudé             }
25098d7f2e76SPhilippe Mathieu-Daudé         }
25108d7f2e76SPhilippe Mathieu-Daudé         qemu_set_log_filename_flags(log_file, mask, &error_fatal);
25118d7f2e76SPhilippe Mathieu-Daudé     }
25128d7f2e76SPhilippe Mathieu-Daudé 
25138d7f2e76SPhilippe Mathieu-Daudé     qemu_add_default_firmwarepath();
25148d7f2e76SPhilippe Mathieu-Daudé }
25158d7f2e76SPhilippe Mathieu-Daudé 
25168d7f2e76SPhilippe Mathieu-Daudé static void qemu_process_help_options(void)
25178d7f2e76SPhilippe Mathieu-Daudé {
25188d7f2e76SPhilippe Mathieu-Daudé     /*
25198d7f2e76SPhilippe Mathieu-Daudé      * Check for -cpu help and -device help before we call select_machine(),
25208d7f2e76SPhilippe Mathieu-Daudé      * which will return an error if the architecture has no default machine
25218d7f2e76SPhilippe Mathieu-Daudé      * type and the user did not specify one, so that the user doesn't need
25228d7f2e76SPhilippe Mathieu-Daudé      * to say '-cpu help -machine something'.
25238d7f2e76SPhilippe Mathieu-Daudé      */
25248d7f2e76SPhilippe Mathieu-Daudé     if (cpu_option && is_help_option(cpu_option)) {
25258d7f2e76SPhilippe Mathieu-Daudé         list_cpus();
25268d7f2e76SPhilippe Mathieu-Daudé         exit(0);
25278d7f2e76SPhilippe Mathieu-Daudé     }
25288d7f2e76SPhilippe Mathieu-Daudé 
25298d7f2e76SPhilippe Mathieu-Daudé     if (qemu_opts_foreach(qemu_find_opts("device"),
25308d7f2e76SPhilippe Mathieu-Daudé                           device_help_func, NULL, NULL)) {
25318d7f2e76SPhilippe Mathieu-Daudé         exit(0);
25328d7f2e76SPhilippe Mathieu-Daudé     }
25338d7f2e76SPhilippe Mathieu-Daudé 
25348d7f2e76SPhilippe Mathieu-Daudé     /* -L help lists the data directories and exits. */
25358d7f2e76SPhilippe Mathieu-Daudé     if (list_data_dirs) {
25368d7f2e76SPhilippe Mathieu-Daudé         qemu_list_data_dirs();
25378d7f2e76SPhilippe Mathieu-Daudé         exit(0);
25388d7f2e76SPhilippe Mathieu-Daudé     }
25398d7f2e76SPhilippe Mathieu-Daudé }
25408d7f2e76SPhilippe Mathieu-Daudé 
25418d7f2e76SPhilippe Mathieu-Daudé static void qemu_maybe_daemonize(const char *pid_file)
25428d7f2e76SPhilippe Mathieu-Daudé {
25438d7f2e76SPhilippe Mathieu-Daudé     Error *err = NULL;
25448d7f2e76SPhilippe Mathieu-Daudé 
25458d7f2e76SPhilippe Mathieu-Daudé     os_daemonize();
25468d7f2e76SPhilippe Mathieu-Daudé     rcu_disable_atfork();
25478d7f2e76SPhilippe Mathieu-Daudé 
25488d7f2e76SPhilippe Mathieu-Daudé     if (pid_file) {
25498d7f2e76SPhilippe Mathieu-Daudé         char *pid_file_realpath = NULL;
25508d7f2e76SPhilippe Mathieu-Daudé 
25518d7f2e76SPhilippe Mathieu-Daudé         if (!qemu_write_pidfile(pid_file, &err)) {
25528d7f2e76SPhilippe Mathieu-Daudé             error_reportf_err(err, "cannot create PID file: ");
25538d7f2e76SPhilippe Mathieu-Daudé             exit(1);
25548d7f2e76SPhilippe Mathieu-Daudé         }
25558d7f2e76SPhilippe Mathieu-Daudé 
25568d7f2e76SPhilippe Mathieu-Daudé         pid_file_realpath = g_malloc0(PATH_MAX);
25578d7f2e76SPhilippe Mathieu-Daudé         if (!realpath(pid_file, pid_file_realpath)) {
25588d7f2e76SPhilippe Mathieu-Daudé             if (errno != ENOENT) {
25598d7f2e76SPhilippe Mathieu-Daudé                 warn_report("not removing PID file on exit: cannot resolve PID "
25608d7f2e76SPhilippe Mathieu-Daudé                             "file path: %s: %s", pid_file, strerror(errno));
25618d7f2e76SPhilippe Mathieu-Daudé             }
25628d7f2e76SPhilippe Mathieu-Daudé             return;
25638d7f2e76SPhilippe Mathieu-Daudé         }
25648d7f2e76SPhilippe Mathieu-Daudé 
25658d7f2e76SPhilippe Mathieu-Daudé         qemu_unlink_pidfile_notifier = (struct UnlinkPidfileNotifier) {
25668d7f2e76SPhilippe Mathieu-Daudé             .notifier = {
25678d7f2e76SPhilippe Mathieu-Daudé                 .notify = qemu_unlink_pidfile,
25688d7f2e76SPhilippe Mathieu-Daudé             },
25698d7f2e76SPhilippe Mathieu-Daudé             .pid_file_realpath = pid_file_realpath,
25708d7f2e76SPhilippe Mathieu-Daudé         };
25718d7f2e76SPhilippe Mathieu-Daudé         qemu_add_exit_notifier(&qemu_unlink_pidfile_notifier.notifier);
25728d7f2e76SPhilippe Mathieu-Daudé     }
25738d7f2e76SPhilippe Mathieu-Daudé }
25748d7f2e76SPhilippe Mathieu-Daudé 
25758d7f2e76SPhilippe Mathieu-Daudé static void qemu_init_displays(void)
25768d7f2e76SPhilippe Mathieu-Daudé {
25778d7f2e76SPhilippe Mathieu-Daudé     DisplayState *ds;
25788d7f2e76SPhilippe Mathieu-Daudé 
25798d7f2e76SPhilippe Mathieu-Daudé     /* init local displays */
25808d7f2e76SPhilippe Mathieu-Daudé     ds = init_displaystate();
25818d7f2e76SPhilippe Mathieu-Daudé     qemu_display_init(ds, &dpy);
25828d7f2e76SPhilippe Mathieu-Daudé 
25838d7f2e76SPhilippe Mathieu-Daudé     /* must be after terminal init, SDL library changes signal handlers */
25848d7f2e76SPhilippe Mathieu-Daudé     os_setup_signal_handling();
25858d7f2e76SPhilippe Mathieu-Daudé 
25868d7f2e76SPhilippe Mathieu-Daudé     /* init remote displays */
25878d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_VNC
25888d7f2e76SPhilippe Mathieu-Daudé     qemu_opts_foreach(qemu_find_opts("vnc"),
25898d7f2e76SPhilippe Mathieu-Daudé                       vnc_init_func, NULL, &error_fatal);
25908d7f2e76SPhilippe Mathieu-Daudé #endif
25918d7f2e76SPhilippe Mathieu-Daudé 
25928d7f2e76SPhilippe Mathieu-Daudé     if (using_spice) {
25938d7f2e76SPhilippe Mathieu-Daudé         qemu_spice.display_init();
25948d7f2e76SPhilippe Mathieu-Daudé     }
25958d7f2e76SPhilippe Mathieu-Daudé }
25968d7f2e76SPhilippe Mathieu-Daudé 
25978d7f2e76SPhilippe Mathieu-Daudé static void qemu_init_board(void)
25988d7f2e76SPhilippe Mathieu-Daudé {
25998d7f2e76SPhilippe Mathieu-Daudé     /* process plugin before CPUs are created, but once -smp has been parsed */
26008d7f2e76SPhilippe Mathieu-Daudé     qemu_plugin_load_list(&plugin_list, &error_fatal);
26018d7f2e76SPhilippe Mathieu-Daudé 
26028d7f2e76SPhilippe Mathieu-Daudé     /* From here on we enter MACHINE_PHASE_INITIALIZED.  */
26038d7f2e76SPhilippe Mathieu-Daudé     machine_run_board_init(current_machine, mem_path, &error_fatal);
26048d7f2e76SPhilippe Mathieu-Daudé 
26058d7f2e76SPhilippe Mathieu-Daudé     drive_check_orphaned();
26068d7f2e76SPhilippe Mathieu-Daudé 
26078d7f2e76SPhilippe Mathieu-Daudé     realtime_init();
26088d7f2e76SPhilippe Mathieu-Daudé }
26098d7f2e76SPhilippe Mathieu-Daudé 
26108d7f2e76SPhilippe Mathieu-Daudé static void qemu_create_cli_devices(void)
26118d7f2e76SPhilippe Mathieu-Daudé {
26128d7f2e76SPhilippe Mathieu-Daudé     DeviceOption *opt;
26138d7f2e76SPhilippe Mathieu-Daudé 
26148d7f2e76SPhilippe Mathieu-Daudé     soundhw_init();
26158d7f2e76SPhilippe Mathieu-Daudé 
26168d7f2e76SPhilippe Mathieu-Daudé     qemu_opts_foreach(qemu_find_opts("fw_cfg"),
26178d7f2e76SPhilippe Mathieu-Daudé                       parse_fw_cfg, fw_cfg_find(), &error_fatal);
26188d7f2e76SPhilippe Mathieu-Daudé 
26198d7f2e76SPhilippe Mathieu-Daudé     /* init USB devices */
26208d7f2e76SPhilippe Mathieu-Daudé     if (machine_usb(current_machine)) {
26218d7f2e76SPhilippe Mathieu-Daudé         if (foreach_device_config(DEV_USB, usb_parse) < 0)
26228d7f2e76SPhilippe Mathieu-Daudé             exit(1);
26238d7f2e76SPhilippe Mathieu-Daudé     }
26248d7f2e76SPhilippe Mathieu-Daudé 
26258d7f2e76SPhilippe Mathieu-Daudé     /* init generic devices */
26268d7f2e76SPhilippe Mathieu-Daudé     rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE);
26278d7f2e76SPhilippe Mathieu-Daudé     qemu_opts_foreach(qemu_find_opts("device"),
26288d7f2e76SPhilippe Mathieu-Daudé                       device_init_func, NULL, &error_fatal);
26298d7f2e76SPhilippe Mathieu-Daudé     QTAILQ_FOREACH(opt, &device_opts, next) {
26308d7f2e76SPhilippe Mathieu-Daudé         DeviceState *dev;
26318d7f2e76SPhilippe Mathieu-Daudé         loc_push_restore(&opt->loc);
26328d7f2e76SPhilippe Mathieu-Daudé         /*
26338d7f2e76SPhilippe Mathieu-Daudé          * TODO Eventually we should call qmp_device_add() here to make sure it
26348d7f2e76SPhilippe Mathieu-Daudé          * behaves the same, but QMP still has to accept incorrectly typed
26358d7f2e76SPhilippe Mathieu-Daudé          * options until libvirt is fixed and we want to be strict on the CLI
26368d7f2e76SPhilippe Mathieu-Daudé          * from the start, so call qdev_device_add_from_qdict() directly for
26378d7f2e76SPhilippe Mathieu-Daudé          * now.
26388d7f2e76SPhilippe Mathieu-Daudé          */
26398d7f2e76SPhilippe Mathieu-Daudé         dev = qdev_device_add_from_qdict(opt->opts, true, &error_fatal);
26408d7f2e76SPhilippe Mathieu-Daudé         object_unref(OBJECT(dev));
26418d7f2e76SPhilippe Mathieu-Daudé         loc_pop(&opt->loc);
26428d7f2e76SPhilippe Mathieu-Daudé     }
26438d7f2e76SPhilippe Mathieu-Daudé     rom_reset_order_override();
26448d7f2e76SPhilippe Mathieu-Daudé }
26458d7f2e76SPhilippe Mathieu-Daudé 
26468d7f2e76SPhilippe Mathieu-Daudé static void qemu_machine_creation_done(void)
26478d7f2e76SPhilippe Mathieu-Daudé {
26488d7f2e76SPhilippe Mathieu-Daudé     MachineState *machine = MACHINE(qdev_get_machine());
26498d7f2e76SPhilippe Mathieu-Daudé 
26508d7f2e76SPhilippe Mathieu-Daudé     /* Did we create any drives that we failed to create a device for? */
26518d7f2e76SPhilippe Mathieu-Daudé     drive_check_orphaned();
26528d7f2e76SPhilippe Mathieu-Daudé 
26538d7f2e76SPhilippe Mathieu-Daudé     /* Don't warn about the default network setup that you get if
26548d7f2e76SPhilippe Mathieu-Daudé      * no command line -net or -netdev options are specified. There
26558d7f2e76SPhilippe Mathieu-Daudé      * are two cases that we would otherwise complain about:
26568d7f2e76SPhilippe Mathieu-Daudé      * (1) board doesn't support a NIC but the implicit "-net nic"
26578d7f2e76SPhilippe Mathieu-Daudé      * requested one
26588d7f2e76SPhilippe Mathieu-Daudé      * (2) CONFIG_SLIRP not set, in which case the implicit "-net nic"
26598d7f2e76SPhilippe Mathieu-Daudé      * sets up a nic that isn't connected to anything.
26608d7f2e76SPhilippe Mathieu-Daudé      */
26618d7f2e76SPhilippe Mathieu-Daudé     if (!default_net && (!qtest_enabled() || has_defaults)) {
26628d7f2e76SPhilippe Mathieu-Daudé         net_check_clients();
26638d7f2e76SPhilippe Mathieu-Daudé     }
26648d7f2e76SPhilippe Mathieu-Daudé 
26658d7f2e76SPhilippe Mathieu-Daudé     qdev_prop_check_globals();
26668d7f2e76SPhilippe Mathieu-Daudé 
26678d7f2e76SPhilippe Mathieu-Daudé     qdev_machine_creation_done();
26688d7f2e76SPhilippe Mathieu-Daudé 
26698d7f2e76SPhilippe Mathieu-Daudé     if (machine->cgs) {
26708d7f2e76SPhilippe Mathieu-Daudé         /*
26718d7f2e76SPhilippe Mathieu-Daudé          * Verify that Confidential Guest Support has actually been initialized
26728d7f2e76SPhilippe Mathieu-Daudé          */
26738d7f2e76SPhilippe Mathieu-Daudé         assert(machine->cgs->ready);
26748d7f2e76SPhilippe Mathieu-Daudé     }
26758d7f2e76SPhilippe Mathieu-Daudé 
26768d7f2e76SPhilippe Mathieu-Daudé     if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
26778d7f2e76SPhilippe Mathieu-Daudé         exit(1);
26788d7f2e76SPhilippe Mathieu-Daudé     }
26798d7f2e76SPhilippe Mathieu-Daudé     if (!vga_interface_created && !default_vga &&
26808d7f2e76SPhilippe Mathieu-Daudé         vga_interface_type != VGA_NONE) {
26818d7f2e76SPhilippe Mathieu-Daudé         warn_report("A -vga option was passed but this machine "
26828d7f2e76SPhilippe Mathieu-Daudé                     "type does not use that option; "
26838d7f2e76SPhilippe Mathieu-Daudé                     "No VGA device has been created");
26848d7f2e76SPhilippe Mathieu-Daudé     }
26858d7f2e76SPhilippe Mathieu-Daudé }
26868d7f2e76SPhilippe Mathieu-Daudé 
26878d7f2e76SPhilippe Mathieu-Daudé void qmp_x_exit_preconfig(Error **errp)
26888d7f2e76SPhilippe Mathieu-Daudé {
26898d7f2e76SPhilippe Mathieu-Daudé     if (phase_check(PHASE_MACHINE_INITIALIZED)) {
26908d7f2e76SPhilippe Mathieu-Daudé         error_setg(errp, "The command is permitted only before machine initialization");
26918d7f2e76SPhilippe Mathieu-Daudé         return;
26928d7f2e76SPhilippe Mathieu-Daudé     }
26938d7f2e76SPhilippe Mathieu-Daudé 
26948d7f2e76SPhilippe Mathieu-Daudé     qemu_init_board();
26958d7f2e76SPhilippe Mathieu-Daudé     qemu_create_cli_devices();
26968d7f2e76SPhilippe Mathieu-Daudé     qemu_machine_creation_done();
26978d7f2e76SPhilippe Mathieu-Daudé 
26988d7f2e76SPhilippe Mathieu-Daudé     if (loadvm) {
26998d7f2e76SPhilippe Mathieu-Daudé         load_snapshot(loadvm, NULL, false, NULL, &error_fatal);
27008d7f2e76SPhilippe Mathieu-Daudé     }
27018d7f2e76SPhilippe Mathieu-Daudé     if (replay_mode != REPLAY_MODE_NONE) {
27028d7f2e76SPhilippe Mathieu-Daudé         replay_vmstate_init();
27038d7f2e76SPhilippe Mathieu-Daudé     }
27048d7f2e76SPhilippe Mathieu-Daudé 
27058d7f2e76SPhilippe Mathieu-Daudé     if (incoming) {
27068d7f2e76SPhilippe Mathieu-Daudé         Error *local_err = NULL;
27078d7f2e76SPhilippe Mathieu-Daudé         if (strcmp(incoming, "defer") != 0) {
2708074dbce5SHet Gala             qmp_migrate_incoming(incoming, false, NULL, &local_err);
27098d7f2e76SPhilippe Mathieu-Daudé             if (local_err) {
27108d7f2e76SPhilippe Mathieu-Daudé                 error_reportf_err(local_err, "-incoming %s: ", incoming);
27118d7f2e76SPhilippe Mathieu-Daudé                 exit(1);
27128d7f2e76SPhilippe Mathieu-Daudé             }
27138d7f2e76SPhilippe Mathieu-Daudé         }
27148d7f2e76SPhilippe Mathieu-Daudé     } else if (autostart) {
27158d7f2e76SPhilippe Mathieu-Daudé         qmp_cont(NULL);
27168d7f2e76SPhilippe Mathieu-Daudé     }
27178d7f2e76SPhilippe Mathieu-Daudé }
27188d7f2e76SPhilippe Mathieu-Daudé 
27198d7f2e76SPhilippe Mathieu-Daudé void qemu_init(int argc, char **argv)
27208d7f2e76SPhilippe Mathieu-Daudé {
27218d7f2e76SPhilippe Mathieu-Daudé     QemuOpts *opts;
27228d7f2e76SPhilippe Mathieu-Daudé     QemuOpts *icount_opts = NULL, *accel_opts = NULL;
27238d7f2e76SPhilippe Mathieu-Daudé     QemuOptsList *olist;
27248d7f2e76SPhilippe Mathieu-Daudé     int optind;
27258d7f2e76SPhilippe Mathieu-Daudé     const char *optarg;
27268d7f2e76SPhilippe Mathieu-Daudé     MachineClass *machine_class;
27278d7f2e76SPhilippe Mathieu-Daudé     bool userconfig = true;
27288d7f2e76SPhilippe Mathieu-Daudé     FILE *vmstate_dump_file = NULL;
27298d7f2e76SPhilippe Mathieu-Daudé 
27308d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_drive_opts);
27318d7f2e76SPhilippe Mathieu-Daudé     qemu_add_drive_opts(&qemu_legacy_drive_opts);
27328d7f2e76SPhilippe Mathieu-Daudé     qemu_add_drive_opts(&qemu_common_drive_opts);
27338d7f2e76SPhilippe Mathieu-Daudé     qemu_add_drive_opts(&qemu_drive_opts);
27348d7f2e76SPhilippe Mathieu-Daudé     qemu_add_drive_opts(&bdrv_runtime_opts);
27358d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_chardev_opts);
27368d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_device_opts);
27378d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_netdev_opts);
27388d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_nic_opts);
27398d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_net_opts);
27408d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_rtc_opts);
27418d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_global_opts);
27428d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_mon_opts);
27438d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_trace_opts);
27448d7f2e76SPhilippe Mathieu-Daudé     qemu_plugin_add_opts();
27458d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_option_rom_opts);
27468d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_accel_opts);
27478d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_mem_opts);
27488d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_smp_opts);
27498d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_boot_opts);
27508d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_add_fd_opts);
27518d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_object_opts);
27528d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_tpmdev_opts);
27538d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_overcommit_opts);
27548d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_msg_opts);
27558d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_name_opts);
27568d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_numa_opts);
27578d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_icount_opts);
27588d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_semihosting_config_opts);
27598d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_fw_cfg_opts);
27608d7f2e76SPhilippe Mathieu-Daudé     qemu_add_opts(&qemu_action_opts);
27618d7f2e76SPhilippe Mathieu-Daudé     qemu_add_run_with_opts();
27628d7f2e76SPhilippe Mathieu-Daudé     module_call_init(MODULE_INIT_OPTS);
27638d7f2e76SPhilippe Mathieu-Daudé 
27648d7f2e76SPhilippe Mathieu-Daudé     error_init(argv[0]);
27658d7f2e76SPhilippe Mathieu-Daudé     qemu_init_exec_dir(argv[0]);
27668d7f2e76SPhilippe Mathieu-Daudé 
27678d7f2e76SPhilippe Mathieu-Daudé     qemu_init_arch_modules();
27688d7f2e76SPhilippe Mathieu-Daudé 
27698d7f2e76SPhilippe Mathieu-Daudé     qemu_init_subsystems();
27708d7f2e76SPhilippe Mathieu-Daudé 
27718d7f2e76SPhilippe Mathieu-Daudé     /* first pass of option parsing */
27728d7f2e76SPhilippe Mathieu-Daudé     optind = 1;
27738d7f2e76SPhilippe Mathieu-Daudé     while (optind < argc) {
27748d7f2e76SPhilippe Mathieu-Daudé         if (argv[optind][0] != '-') {
27758d7f2e76SPhilippe Mathieu-Daudé             /* disk image */
27768d7f2e76SPhilippe Mathieu-Daudé             optind++;
27778d7f2e76SPhilippe Mathieu-Daudé         } else {
27788d7f2e76SPhilippe Mathieu-Daudé             const QEMUOption *popt;
27798d7f2e76SPhilippe Mathieu-Daudé 
27808d7f2e76SPhilippe Mathieu-Daudé             popt = lookup_opt(argc, argv, &optarg, &optind);
27818d7f2e76SPhilippe Mathieu-Daudé             switch (popt->index) {
27828d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_nouserconfig:
27838d7f2e76SPhilippe Mathieu-Daudé                 userconfig = false;
27848d7f2e76SPhilippe Mathieu-Daudé                 break;
27858d7f2e76SPhilippe Mathieu-Daudé             }
27868d7f2e76SPhilippe Mathieu-Daudé         }
27878d7f2e76SPhilippe Mathieu-Daudé     }
27888d7f2e76SPhilippe Mathieu-Daudé 
27898d7f2e76SPhilippe Mathieu-Daudé     machine_opts_dict = qdict_new();
27908d7f2e76SPhilippe Mathieu-Daudé     if (userconfig) {
27918d7f2e76SPhilippe Mathieu-Daudé         qemu_read_default_config_file(&error_fatal);
27928d7f2e76SPhilippe Mathieu-Daudé     }
27938d7f2e76SPhilippe Mathieu-Daudé 
27948d7f2e76SPhilippe Mathieu-Daudé     /* second pass of option parsing */
27958d7f2e76SPhilippe Mathieu-Daudé     optind = 1;
27968d7f2e76SPhilippe Mathieu-Daudé     for(;;) {
27978d7f2e76SPhilippe Mathieu-Daudé         if (optind >= argc)
27988d7f2e76SPhilippe Mathieu-Daudé             break;
27998d7f2e76SPhilippe Mathieu-Daudé         if (argv[optind][0] != '-') {
28008d7f2e76SPhilippe Mathieu-Daudé             loc_set_cmdline(argv, optind, 1);
28018d7f2e76SPhilippe Mathieu-Daudé             drive_add(IF_DEFAULT, 0, argv[optind++], HD_OPTS);
28028d7f2e76SPhilippe Mathieu-Daudé         } else {
28038d7f2e76SPhilippe Mathieu-Daudé             const QEMUOption *popt;
28048d7f2e76SPhilippe Mathieu-Daudé 
28058d7f2e76SPhilippe Mathieu-Daudé             popt = lookup_opt(argc, argv, &optarg, &optind);
28068d7f2e76SPhilippe Mathieu-Daudé             if (!(popt->arch_mask & arch_type)) {
28078d7f2e76SPhilippe Mathieu-Daudé                 error_report("Option not supported for this target");
28088d7f2e76SPhilippe Mathieu-Daudé                 exit(1);
28098d7f2e76SPhilippe Mathieu-Daudé             }
28108d7f2e76SPhilippe Mathieu-Daudé             switch(popt->index) {
28118d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_cpu:
28128d7f2e76SPhilippe Mathieu-Daudé                 /* hw initialization will check this */
28138d7f2e76SPhilippe Mathieu-Daudé                 cpu_option = optarg;
28148d7f2e76SPhilippe Mathieu-Daudé                 break;
28158d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_hda:
28168d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_hdb:
28178d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_hdc:
28188d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_hdd:
28198d7f2e76SPhilippe Mathieu-Daudé                 drive_add(IF_DEFAULT, popt->index - QEMU_OPTION_hda, optarg,
28208d7f2e76SPhilippe Mathieu-Daudé                           HD_OPTS);
28218d7f2e76SPhilippe Mathieu-Daudé                 break;
28228d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_blockdev:
28238d7f2e76SPhilippe Mathieu-Daudé                 {
28248d7f2e76SPhilippe Mathieu-Daudé                     Visitor *v;
28258d7f2e76SPhilippe Mathieu-Daudé                     BlockdevOptionsQueueEntry *bdo;
28268d7f2e76SPhilippe Mathieu-Daudé 
28278d7f2e76SPhilippe Mathieu-Daudé                     v = qobject_input_visitor_new_str(optarg, "driver",
28288d7f2e76SPhilippe Mathieu-Daudé                                                       &error_fatal);
28298d7f2e76SPhilippe Mathieu-Daudé 
28308d7f2e76SPhilippe Mathieu-Daudé                     bdo = g_new(BlockdevOptionsQueueEntry, 1);
28318d7f2e76SPhilippe Mathieu-Daudé                     visit_type_BlockdevOptions(v, NULL, &bdo->bdo,
28328d7f2e76SPhilippe Mathieu-Daudé                                                &error_fatal);
28338d7f2e76SPhilippe Mathieu-Daudé                     visit_free(v);
28348d7f2e76SPhilippe Mathieu-Daudé                     loc_save(&bdo->loc);
28358d7f2e76SPhilippe Mathieu-Daudé                     QSIMPLEQ_INSERT_TAIL(&bdo_queue, bdo, entry);
28368d7f2e76SPhilippe Mathieu-Daudé                     break;
28378d7f2e76SPhilippe Mathieu-Daudé                 }
28388d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_drive:
28398d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("drive"),
28408d7f2e76SPhilippe Mathieu-Daudé                                                optarg, false);
28418d7f2e76SPhilippe Mathieu-Daudé                 if (opts == NULL) {
28428d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
28438d7f2e76SPhilippe Mathieu-Daudé                 }
28448d7f2e76SPhilippe Mathieu-Daudé                 break;
28458d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_set:
28468d7f2e76SPhilippe Mathieu-Daudé                 qemu_set_option(optarg, &error_fatal);
28478d7f2e76SPhilippe Mathieu-Daudé                 break;
28488d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_global:
28498d7f2e76SPhilippe Mathieu-Daudé                 if (qemu_global_option(optarg) != 0)
28508d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
28518d7f2e76SPhilippe Mathieu-Daudé                 break;
28528d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_mtdblock:
28538d7f2e76SPhilippe Mathieu-Daudé                 drive_add(IF_MTD, -1, optarg, MTD_OPTS);
28548d7f2e76SPhilippe Mathieu-Daudé                 break;
28558d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_sd:
28568d7f2e76SPhilippe Mathieu-Daudé                 drive_add(IF_SD, -1, optarg, SD_OPTS);
28578d7f2e76SPhilippe Mathieu-Daudé                 break;
28588d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_pflash:
28598d7f2e76SPhilippe Mathieu-Daudé                 drive_add(IF_PFLASH, -1, optarg, PFLASH_OPTS);
28608d7f2e76SPhilippe Mathieu-Daudé                 break;
28618d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_snapshot:
28628d7f2e76SPhilippe Mathieu-Daudé                 snapshot = 1;
28638d7f2e76SPhilippe Mathieu-Daudé                 replay_add_blocker("-snapshot");
28648d7f2e76SPhilippe Mathieu-Daudé                 break;
28658d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_numa:
28668d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("numa"),
28678d7f2e76SPhilippe Mathieu-Daudé                                                optarg, true);
28688d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
28698d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
28708d7f2e76SPhilippe Mathieu-Daudé                 }
28718d7f2e76SPhilippe Mathieu-Daudé                 break;
28728d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_display:
28738d7f2e76SPhilippe Mathieu-Daudé                 parse_display(optarg);
28748d7f2e76SPhilippe Mathieu-Daudé                 break;
28758d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_nographic:
28768d7f2e76SPhilippe Mathieu-Daudé                 qdict_put_str(machine_opts_dict, "graphics", "off");
28778d7f2e76SPhilippe Mathieu-Daudé                 nographic = true;
28788d7f2e76SPhilippe Mathieu-Daudé                 dpy.type = DISPLAY_TYPE_NONE;
28798d7f2e76SPhilippe Mathieu-Daudé                 break;
28808d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_portrait:
28818d7f2e76SPhilippe Mathieu-Daudé                 graphic_rotate = 90;
28828d7f2e76SPhilippe Mathieu-Daudé                 break;
28838d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_rotate:
28848d7f2e76SPhilippe Mathieu-Daudé                 graphic_rotate = strtol(optarg, (char **) &optarg, 10);
28858d7f2e76SPhilippe Mathieu-Daudé                 if (graphic_rotate != 0 && graphic_rotate != 90 &&
28868d7f2e76SPhilippe Mathieu-Daudé                     graphic_rotate != 180 && graphic_rotate != 270) {
28878d7f2e76SPhilippe Mathieu-Daudé                     error_report("only 90, 180, 270 deg rotation is available");
28888d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
28898d7f2e76SPhilippe Mathieu-Daudé                 }
28908d7f2e76SPhilippe Mathieu-Daudé                 break;
28918d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_kernel:
28928d7f2e76SPhilippe Mathieu-Daudé                 qdict_put_str(machine_opts_dict, "kernel", optarg);
28938d7f2e76SPhilippe Mathieu-Daudé                 break;
28948d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_initrd:
28958d7f2e76SPhilippe Mathieu-Daudé                 qdict_put_str(machine_opts_dict, "initrd", optarg);
28968d7f2e76SPhilippe Mathieu-Daudé                 break;
28978d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_append:
28988d7f2e76SPhilippe Mathieu-Daudé                 qdict_put_str(machine_opts_dict, "append", optarg);
28998d7f2e76SPhilippe Mathieu-Daudé                 break;
29008d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_dtb:
29018d7f2e76SPhilippe Mathieu-Daudé                 qdict_put_str(machine_opts_dict, "dtb", optarg);
29028d7f2e76SPhilippe Mathieu-Daudé                 break;
29038d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_cdrom:
29048d7f2e76SPhilippe Mathieu-Daudé                 drive_add(IF_DEFAULT, 2, optarg, CDROM_OPTS);
29058d7f2e76SPhilippe Mathieu-Daudé                 break;
29068d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_boot:
29078d7f2e76SPhilippe Mathieu-Daudé                 machine_parse_property_opt(qemu_find_opts("boot-opts"), "boot", optarg);
29088d7f2e76SPhilippe Mathieu-Daudé                 break;
29098d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_fda:
29108d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_fdb:
29118d7f2e76SPhilippe Mathieu-Daudé                 drive_add(IF_FLOPPY, popt->index - QEMU_OPTION_fda,
29128d7f2e76SPhilippe Mathieu-Daudé                           optarg, FD_OPTS);
29138d7f2e76SPhilippe Mathieu-Daudé                 break;
29148d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_no_fd_bootchk:
29158d7f2e76SPhilippe Mathieu-Daudé                 fd_bootchk = 0;
29168d7f2e76SPhilippe Mathieu-Daudé                 break;
29178d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_netdev:
29188d7f2e76SPhilippe Mathieu-Daudé                 default_net = 0;
29198d7f2e76SPhilippe Mathieu-Daudé                 if (netdev_is_modern(optarg)) {
29208d7f2e76SPhilippe Mathieu-Daudé                     netdev_parse_modern(optarg);
29218d7f2e76SPhilippe Mathieu-Daudé                 } else {
29228d7f2e76SPhilippe Mathieu-Daudé                     net_client_parse(qemu_find_opts("netdev"), optarg);
29238d7f2e76SPhilippe Mathieu-Daudé                 }
29248d7f2e76SPhilippe Mathieu-Daudé                 break;
29258d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_nic:
29268d7f2e76SPhilippe Mathieu-Daudé                 default_net = 0;
29278d7f2e76SPhilippe Mathieu-Daudé                 net_client_parse(qemu_find_opts("nic"), optarg);
29288d7f2e76SPhilippe Mathieu-Daudé                 break;
29298d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_net:
29308d7f2e76SPhilippe Mathieu-Daudé                 default_net = 0;
29318d7f2e76SPhilippe Mathieu-Daudé                 net_client_parse(qemu_find_opts("net"), optarg);
29328d7f2e76SPhilippe Mathieu-Daudé                 break;
29338d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_LIBISCSI
29348d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_iscsi:
29358d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("iscsi"),
29368d7f2e76SPhilippe Mathieu-Daudé                                                optarg, false);
29378d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
29388d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
29398d7f2e76SPhilippe Mathieu-Daudé                 }
29408d7f2e76SPhilippe Mathieu-Daudé                 break;
29418d7f2e76SPhilippe Mathieu-Daudé #endif
29428d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_audiodev:
2943c753bf47SPaolo Bonzini                 default_audio = 0;
29448d7f2e76SPhilippe Mathieu-Daudé                 audio_parse_option(optarg);
29458d7f2e76SPhilippe Mathieu-Daudé                 break;
29468d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_audio: {
29478d7f2e76SPhilippe Mathieu-Daudé                 bool help;
29481ebdbff4SPaolo Bonzini                 char *model = NULL;
29498d7f2e76SPhilippe Mathieu-Daudé                 Audiodev *dev = NULL;
29508d7f2e76SPhilippe Mathieu-Daudé                 Visitor *v;
29518d7f2e76SPhilippe Mathieu-Daudé                 QDict *dict = keyval_parse(optarg, "driver", &help, &error_fatal);
2952c753bf47SPaolo Bonzini                 default_audio = 0;
29538d7f2e76SPhilippe Mathieu-Daudé                 if (help || (qdict_haskey(dict, "driver") &&
29548d7f2e76SPhilippe Mathieu-Daudé                              is_help_option(qdict_get_str(dict, "driver")))) {
29558d7f2e76SPhilippe Mathieu-Daudé                     audio_help();
29568d7f2e76SPhilippe Mathieu-Daudé                     exit(EXIT_SUCCESS);
29578d7f2e76SPhilippe Mathieu-Daudé                 }
29588d7f2e76SPhilippe Mathieu-Daudé                 if (!qdict_haskey(dict, "id")) {
29598d7f2e76SPhilippe Mathieu-Daudé                     qdict_put_str(dict, "id", "audiodev0");
29608d7f2e76SPhilippe Mathieu-Daudé                 }
29611ebdbff4SPaolo Bonzini                 if (qdict_haskey(dict, "model")) {
29628d7f2e76SPhilippe Mathieu-Daudé                     model = g_strdup(qdict_get_str(dict, "model"));
29638d7f2e76SPhilippe Mathieu-Daudé                     qdict_del(dict, "model");
29648d7f2e76SPhilippe Mathieu-Daudé                     if (is_help_option(model)) {
29658d7f2e76SPhilippe Mathieu-Daudé                         show_valid_soundhw();
29668d7f2e76SPhilippe Mathieu-Daudé                         exit(0);
29678d7f2e76SPhilippe Mathieu-Daudé                     }
29681ebdbff4SPaolo Bonzini                 }
29698d7f2e76SPhilippe Mathieu-Daudé                 v = qobject_input_visitor_new_keyval(QOBJECT(dict));
29708d7f2e76SPhilippe Mathieu-Daudé                 qobject_unref(dict);
29718d7f2e76SPhilippe Mathieu-Daudé                 visit_type_Audiodev(v, NULL, &dev, &error_fatal);
29728d7f2e76SPhilippe Mathieu-Daudé                 visit_free(v);
29731ebdbff4SPaolo Bonzini                 if (model) {
29748d7f2e76SPhilippe Mathieu-Daudé                     audio_define(dev);
29758d7f2e76SPhilippe Mathieu-Daudé                     select_soundhw(model, dev->id);
29768d7f2e76SPhilippe Mathieu-Daudé                     g_free(model);
29771ebdbff4SPaolo Bonzini                 } else {
29781ebdbff4SPaolo Bonzini                     audio_define_default(dev, &error_fatal);
29791ebdbff4SPaolo Bonzini                 }
29808d7f2e76SPhilippe Mathieu-Daudé                 break;
29818d7f2e76SPhilippe Mathieu-Daudé             }
29828d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_h:
29838d7f2e76SPhilippe Mathieu-Daudé                 help(0);
29848d7f2e76SPhilippe Mathieu-Daudé                 break;
29858d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_version:
29868d7f2e76SPhilippe Mathieu-Daudé                 version();
29878d7f2e76SPhilippe Mathieu-Daudé                 exit(0);
29888d7f2e76SPhilippe Mathieu-Daudé                 break;
29898d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_m:
29908d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("memory"), optarg, true);
29918d7f2e76SPhilippe Mathieu-Daudé                 if (opts == NULL) {
29928d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
29938d7f2e76SPhilippe Mathieu-Daudé                 }
29948d7f2e76SPhilippe Mathieu-Daudé                 break;
29958d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_TPM
29968d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_tpmdev:
29978d7f2e76SPhilippe Mathieu-Daudé                 if (tpm_config_parse(qemu_find_opts("tpmdev"), optarg) < 0) {
29988d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
29998d7f2e76SPhilippe Mathieu-Daudé                 }
30008d7f2e76SPhilippe Mathieu-Daudé                 break;
30018d7f2e76SPhilippe Mathieu-Daudé #endif
30028d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_mempath:
30038d7f2e76SPhilippe Mathieu-Daudé                 mem_path = optarg;
30048d7f2e76SPhilippe Mathieu-Daudé                 break;
30058d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_mem_prealloc:
30068d7f2e76SPhilippe Mathieu-Daudé                 mem_prealloc = 1;
30078d7f2e76SPhilippe Mathieu-Daudé                 break;
30088d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_d:
30098d7f2e76SPhilippe Mathieu-Daudé                 log_mask = optarg;
30108d7f2e76SPhilippe Mathieu-Daudé                 break;
30118d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_D:
30128d7f2e76SPhilippe Mathieu-Daudé                 log_file = optarg;
30138d7f2e76SPhilippe Mathieu-Daudé                 break;
30148d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_DFILTER:
30158d7f2e76SPhilippe Mathieu-Daudé                 qemu_set_dfilter_ranges(optarg, &error_fatal);
30168d7f2e76SPhilippe Mathieu-Daudé                 break;
30178d7f2e76SPhilippe Mathieu-Daudé #if defined(CONFIG_TCG) && defined(CONFIG_LINUX)
30188d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_perfmap:
30198d7f2e76SPhilippe Mathieu-Daudé                 perf_enable_perfmap();
30208d7f2e76SPhilippe Mathieu-Daudé                 break;
30218d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_jitdump:
30228d7f2e76SPhilippe Mathieu-Daudé                 perf_enable_jitdump();
30238d7f2e76SPhilippe Mathieu-Daudé                 break;
30248d7f2e76SPhilippe Mathieu-Daudé #endif
30258d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_seed:
30268d7f2e76SPhilippe Mathieu-Daudé                 qemu_guest_random_seed_main(optarg, &error_fatal);
30278d7f2e76SPhilippe Mathieu-Daudé                 break;
30288d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_s:
30298d7f2e76SPhilippe Mathieu-Daudé                 add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT);
30308d7f2e76SPhilippe Mathieu-Daudé                 break;
30318d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_gdb:
30328d7f2e76SPhilippe Mathieu-Daudé                 add_device_config(DEV_GDB, optarg);
30338d7f2e76SPhilippe Mathieu-Daudé                 break;
30348d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_L:
30358d7f2e76SPhilippe Mathieu-Daudé                 if (is_help_option(optarg)) {
30368d7f2e76SPhilippe Mathieu-Daudé                     list_data_dirs = true;
30378d7f2e76SPhilippe Mathieu-Daudé                 } else {
30388d7f2e76SPhilippe Mathieu-Daudé                     qemu_add_data_dir(g_strdup(optarg));
30398d7f2e76SPhilippe Mathieu-Daudé                 }
30408d7f2e76SPhilippe Mathieu-Daudé                 break;
30418d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_bios:
30428d7f2e76SPhilippe Mathieu-Daudé                 qdict_put_str(machine_opts_dict, "firmware", optarg);
30438d7f2e76SPhilippe Mathieu-Daudé                 break;
30448d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_singlestep:
30458d7f2e76SPhilippe Mathieu-Daudé                 opt_one_insn_per_tb = true;
30468d7f2e76SPhilippe Mathieu-Daudé                 break;
30478d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_S:
30488d7f2e76SPhilippe Mathieu-Daudé                 autostart = 0;
30498d7f2e76SPhilippe Mathieu-Daudé                 break;
30508d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_k:
30518d7f2e76SPhilippe Mathieu-Daudé                 keyboard_layout = optarg;
30528d7f2e76SPhilippe Mathieu-Daudé                 break;
30538d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_vga:
30548d7f2e76SPhilippe Mathieu-Daudé                 vga_model = optarg;
30558d7f2e76SPhilippe Mathieu-Daudé                 default_vga = 0;
30568d7f2e76SPhilippe Mathieu-Daudé                 break;
30578d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_g:
30588d7f2e76SPhilippe Mathieu-Daudé                 {
30598d7f2e76SPhilippe Mathieu-Daudé                     const char *p;
30608d7f2e76SPhilippe Mathieu-Daudé                     int w, h, depth;
30618d7f2e76SPhilippe Mathieu-Daudé                     p = optarg;
30628d7f2e76SPhilippe Mathieu-Daudé                     w = strtol(p, (char **)&p, 10);
30638d7f2e76SPhilippe Mathieu-Daudé                     if (w <= 0) {
30648d7f2e76SPhilippe Mathieu-Daudé                     graphic_error:
30658d7f2e76SPhilippe Mathieu-Daudé                         error_report("invalid resolution or depth");
30668d7f2e76SPhilippe Mathieu-Daudé                         exit(1);
30678d7f2e76SPhilippe Mathieu-Daudé                     }
30688d7f2e76SPhilippe Mathieu-Daudé                     if (*p != 'x')
30698d7f2e76SPhilippe Mathieu-Daudé                         goto graphic_error;
30708d7f2e76SPhilippe Mathieu-Daudé                     p++;
30718d7f2e76SPhilippe Mathieu-Daudé                     h = strtol(p, (char **)&p, 10);
30728d7f2e76SPhilippe Mathieu-Daudé                     if (h <= 0)
30738d7f2e76SPhilippe Mathieu-Daudé                         goto graphic_error;
30748d7f2e76SPhilippe Mathieu-Daudé                     if (*p == 'x') {
30758d7f2e76SPhilippe Mathieu-Daudé                         p++;
30768d7f2e76SPhilippe Mathieu-Daudé                         depth = strtol(p, (char **)&p, 10);
30778d7f2e76SPhilippe Mathieu-Daudé                         if (depth != 1 && depth != 2 && depth != 4 &&
30788d7f2e76SPhilippe Mathieu-Daudé                             depth != 8 && depth != 15 && depth != 16 &&
30798d7f2e76SPhilippe Mathieu-Daudé                             depth != 24 && depth != 32)
30808d7f2e76SPhilippe Mathieu-Daudé                             goto graphic_error;
30818d7f2e76SPhilippe Mathieu-Daudé                     } else if (*p == '\0') {
30828d7f2e76SPhilippe Mathieu-Daudé                         depth = graphic_depth;
30838d7f2e76SPhilippe Mathieu-Daudé                     } else {
30848d7f2e76SPhilippe Mathieu-Daudé                         goto graphic_error;
30858d7f2e76SPhilippe Mathieu-Daudé                     }
30868d7f2e76SPhilippe Mathieu-Daudé 
30878d7f2e76SPhilippe Mathieu-Daudé                     graphic_width = w;
30888d7f2e76SPhilippe Mathieu-Daudé                     graphic_height = h;
30898d7f2e76SPhilippe Mathieu-Daudé                     graphic_depth = depth;
30908d7f2e76SPhilippe Mathieu-Daudé                 }
30918d7f2e76SPhilippe Mathieu-Daudé                 break;
30928d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_echr:
30938d7f2e76SPhilippe Mathieu-Daudé                 {
30948d7f2e76SPhilippe Mathieu-Daudé                     char *r;
30958d7f2e76SPhilippe Mathieu-Daudé                     term_escape_char = strtol(optarg, &r, 0);
30968d7f2e76SPhilippe Mathieu-Daudé                     if (r == optarg)
30978d7f2e76SPhilippe Mathieu-Daudé                         printf("Bad argument to echr\n");
30988d7f2e76SPhilippe Mathieu-Daudé                     break;
30998d7f2e76SPhilippe Mathieu-Daudé                 }
31008d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_monitor:
31018d7f2e76SPhilippe Mathieu-Daudé                 default_monitor = 0;
31028d7f2e76SPhilippe Mathieu-Daudé                 if (strncmp(optarg, "none", 4)) {
31038d7f2e76SPhilippe Mathieu-Daudé                     monitor_parse(optarg, "readline", false);
31048d7f2e76SPhilippe Mathieu-Daudé                 }
31058d7f2e76SPhilippe Mathieu-Daudé                 break;
31068d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_qmp:
31078d7f2e76SPhilippe Mathieu-Daudé                 monitor_parse(optarg, "control", false);
31088d7f2e76SPhilippe Mathieu-Daudé                 default_monitor = 0;
31098d7f2e76SPhilippe Mathieu-Daudé                 break;
31108d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_qmp_pretty:
31118d7f2e76SPhilippe Mathieu-Daudé                 monitor_parse(optarg, "control", true);
31128d7f2e76SPhilippe Mathieu-Daudé                 default_monitor = 0;
31138d7f2e76SPhilippe Mathieu-Daudé                 break;
31148d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_mon:
31158d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("mon"), optarg,
31168d7f2e76SPhilippe Mathieu-Daudé                                                true);
31178d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
31188d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
31198d7f2e76SPhilippe Mathieu-Daudé                 }
31208d7f2e76SPhilippe Mathieu-Daudé                 default_monitor = 0;
31218d7f2e76SPhilippe Mathieu-Daudé                 break;
31228d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_chardev:
31238d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
31248d7f2e76SPhilippe Mathieu-Daudé                                                optarg, true);
31258d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
31268d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
31278d7f2e76SPhilippe Mathieu-Daudé                 }
31288d7f2e76SPhilippe Mathieu-Daudé                 break;
31298d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_fsdev:
31308d7f2e76SPhilippe Mathieu-Daudé                 olist = qemu_find_opts("fsdev");
31318d7f2e76SPhilippe Mathieu-Daudé                 if (!olist) {
31328d7f2e76SPhilippe Mathieu-Daudé                     error_report("fsdev support is disabled");
31338d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
31348d7f2e76SPhilippe Mathieu-Daudé                 }
31358d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(olist, optarg, true);
31368d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
31378d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
31388d7f2e76SPhilippe Mathieu-Daudé                 }
31398d7f2e76SPhilippe Mathieu-Daudé                 break;
31408d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_virtfs: {
31418d7f2e76SPhilippe Mathieu-Daudé                 QemuOpts *fsdev;
31428d7f2e76SPhilippe Mathieu-Daudé                 QemuOpts *device;
31438d7f2e76SPhilippe Mathieu-Daudé                 const char *writeout, *sock_fd, *socket, *path, *security_model,
31448d7f2e76SPhilippe Mathieu-Daudé                            *multidevs;
31458d7f2e76SPhilippe Mathieu-Daudé 
31468d7f2e76SPhilippe Mathieu-Daudé                 olist = qemu_find_opts("virtfs");
31478d7f2e76SPhilippe Mathieu-Daudé                 if (!olist) {
31488d7f2e76SPhilippe Mathieu-Daudé                     error_report("virtfs support is disabled");
31498d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
31508d7f2e76SPhilippe Mathieu-Daudé                 }
31518d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(olist, optarg, true);
31528d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
31538d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
31548d7f2e76SPhilippe Mathieu-Daudé                 }
31558d7f2e76SPhilippe Mathieu-Daudé 
31568d7f2e76SPhilippe Mathieu-Daudé                 if (qemu_opt_get(opts, "fsdriver") == NULL ||
31578d7f2e76SPhilippe Mathieu-Daudé                     qemu_opt_get(opts, "mount_tag") == NULL) {
31588d7f2e76SPhilippe Mathieu-Daudé                     error_report("Usage: -virtfs fsdriver,mount_tag=tag");
31598d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
31608d7f2e76SPhilippe Mathieu-Daudé                 }
31618d7f2e76SPhilippe Mathieu-Daudé                 fsdev = qemu_opts_create(qemu_find_opts("fsdev"),
31628d7f2e76SPhilippe Mathieu-Daudé                                          qemu_opts_id(opts) ?:
31638d7f2e76SPhilippe Mathieu-Daudé                                          qemu_opt_get(opts, "mount_tag"),
31648d7f2e76SPhilippe Mathieu-Daudé                                          1, NULL);
31658d7f2e76SPhilippe Mathieu-Daudé                 if (!fsdev) {
31668d7f2e76SPhilippe Mathieu-Daudé                     error_report("duplicate or invalid fsdev id: %s",
31678d7f2e76SPhilippe Mathieu-Daudé                                  qemu_opt_get(opts, "mount_tag"));
31688d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
31698d7f2e76SPhilippe Mathieu-Daudé                 }
31708d7f2e76SPhilippe Mathieu-Daudé 
31718d7f2e76SPhilippe Mathieu-Daudé                 writeout = qemu_opt_get(opts, "writeout");
31728d7f2e76SPhilippe Mathieu-Daudé                 if (writeout) {
31738d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_SYNC_FILE_RANGE
31748d7f2e76SPhilippe Mathieu-Daudé                     qemu_opt_set(fsdev, "writeout", writeout, &error_abort);
31758d7f2e76SPhilippe Mathieu-Daudé #else
31768d7f2e76SPhilippe Mathieu-Daudé                     error_report("writeout=immediate not supported "
31778d7f2e76SPhilippe Mathieu-Daudé                                  "on this platform");
31788d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
31798d7f2e76SPhilippe Mathieu-Daudé #endif
31808d7f2e76SPhilippe Mathieu-Daudé                 }
31818d7f2e76SPhilippe Mathieu-Daudé                 qemu_opt_set(fsdev, "fsdriver",
31828d7f2e76SPhilippe Mathieu-Daudé                              qemu_opt_get(opts, "fsdriver"), &error_abort);
31838d7f2e76SPhilippe Mathieu-Daudé                 path = qemu_opt_get(opts, "path");
31848d7f2e76SPhilippe Mathieu-Daudé                 if (path) {
31858d7f2e76SPhilippe Mathieu-Daudé                     qemu_opt_set(fsdev, "path", path, &error_abort);
31868d7f2e76SPhilippe Mathieu-Daudé                 }
31878d7f2e76SPhilippe Mathieu-Daudé                 security_model = qemu_opt_get(opts, "security_model");
31888d7f2e76SPhilippe Mathieu-Daudé                 if (security_model) {
31898d7f2e76SPhilippe Mathieu-Daudé                     qemu_opt_set(fsdev, "security_model", security_model,
31908d7f2e76SPhilippe Mathieu-Daudé                                  &error_abort);
31918d7f2e76SPhilippe Mathieu-Daudé                 }
31928d7f2e76SPhilippe Mathieu-Daudé                 socket = qemu_opt_get(opts, "socket");
31938d7f2e76SPhilippe Mathieu-Daudé                 if (socket) {
31948d7f2e76SPhilippe Mathieu-Daudé                     qemu_opt_set(fsdev, "socket", socket, &error_abort);
31958d7f2e76SPhilippe Mathieu-Daudé                 }
31968d7f2e76SPhilippe Mathieu-Daudé                 sock_fd = qemu_opt_get(opts, "sock_fd");
31978d7f2e76SPhilippe Mathieu-Daudé                 if (sock_fd) {
31988d7f2e76SPhilippe Mathieu-Daudé                     qemu_opt_set(fsdev, "sock_fd", sock_fd, &error_abort);
31998d7f2e76SPhilippe Mathieu-Daudé                 }
32008d7f2e76SPhilippe Mathieu-Daudé 
32018d7f2e76SPhilippe Mathieu-Daudé                 qemu_opt_set_bool(fsdev, "readonly",
32028d7f2e76SPhilippe Mathieu-Daudé                                   qemu_opt_get_bool(opts, "readonly", 0),
32038d7f2e76SPhilippe Mathieu-Daudé                                   &error_abort);
32048d7f2e76SPhilippe Mathieu-Daudé                 multidevs = qemu_opt_get(opts, "multidevs");
32058d7f2e76SPhilippe Mathieu-Daudé                 if (multidevs) {
32068d7f2e76SPhilippe Mathieu-Daudé                     qemu_opt_set(fsdev, "multidevs", multidevs, &error_abort);
32078d7f2e76SPhilippe Mathieu-Daudé                 }
32088d7f2e76SPhilippe Mathieu-Daudé                 device = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
32098d7f2e76SPhilippe Mathieu-Daudé                                           &error_abort);
32108d7f2e76SPhilippe Mathieu-Daudé                 qemu_opt_set(device, "driver", "virtio-9p-pci", &error_abort);
32118d7f2e76SPhilippe Mathieu-Daudé                 qemu_opt_set(device, "fsdev",
32128d7f2e76SPhilippe Mathieu-Daudé                              qemu_opts_id(fsdev), &error_abort);
32138d7f2e76SPhilippe Mathieu-Daudé                 qemu_opt_set(device, "mount_tag",
32148d7f2e76SPhilippe Mathieu-Daudé                              qemu_opt_get(opts, "mount_tag"), &error_abort);
32158d7f2e76SPhilippe Mathieu-Daudé                 break;
32168d7f2e76SPhilippe Mathieu-Daudé             }
32178d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_serial:
32188d7f2e76SPhilippe Mathieu-Daudé                 add_device_config(DEV_SERIAL, optarg);
32198d7f2e76SPhilippe Mathieu-Daudé                 default_serial = 0;
32208d7f2e76SPhilippe Mathieu-Daudé                 if (strncmp(optarg, "mon:", 4) == 0) {
32218d7f2e76SPhilippe Mathieu-Daudé                     default_monitor = 0;
32228d7f2e76SPhilippe Mathieu-Daudé                 }
32238d7f2e76SPhilippe Mathieu-Daudé                 break;
32248d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_action:
32258d7f2e76SPhilippe Mathieu-Daudé                 olist = qemu_find_opts("action");
32268d7f2e76SPhilippe Mathieu-Daudé                 if (!qemu_opts_parse_noisily(olist, optarg, false)) {
32278d7f2e76SPhilippe Mathieu-Daudé                      exit(1);
32288d7f2e76SPhilippe Mathieu-Daudé                 }
32298d7f2e76SPhilippe Mathieu-Daudé                 break;
32308d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_watchdog_action: {
32318d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_create(qemu_find_opts("action"), NULL, 0, &error_abort);
32328d7f2e76SPhilippe Mathieu-Daudé                 qemu_opt_set(opts, "watchdog", optarg, &error_abort);
32338d7f2e76SPhilippe Mathieu-Daudé                 break;
32348d7f2e76SPhilippe Mathieu-Daudé             }
32358d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_parallel:
32368d7f2e76SPhilippe Mathieu-Daudé                 add_device_config(DEV_PARALLEL, optarg);
32378d7f2e76SPhilippe Mathieu-Daudé                 default_parallel = 0;
32388d7f2e76SPhilippe Mathieu-Daudé                 if (strncmp(optarg, "mon:", 4) == 0) {
32398d7f2e76SPhilippe Mathieu-Daudé                     default_monitor = 0;
32408d7f2e76SPhilippe Mathieu-Daudé                 }
32418d7f2e76SPhilippe Mathieu-Daudé                 break;
32428d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_debugcon:
32438d7f2e76SPhilippe Mathieu-Daudé                 add_device_config(DEV_DEBUGCON, optarg);
32448d7f2e76SPhilippe Mathieu-Daudé                 break;
32458d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_loadvm:
32468d7f2e76SPhilippe Mathieu-Daudé                 loadvm = optarg;
32478d7f2e76SPhilippe Mathieu-Daudé                 break;
32488d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_full_screen:
32498d7f2e76SPhilippe Mathieu-Daudé                 dpy.has_full_screen = true;
32508d7f2e76SPhilippe Mathieu-Daudé                 dpy.full_screen = true;
32518d7f2e76SPhilippe Mathieu-Daudé                 break;
32528d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_pidfile:
32538d7f2e76SPhilippe Mathieu-Daudé                 pid_file = optarg;
32548d7f2e76SPhilippe Mathieu-Daudé                 break;
32558d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_win2k_hack:
32568d7f2e76SPhilippe Mathieu-Daudé                 win2k_install_hack = 1;
32578d7f2e76SPhilippe Mathieu-Daudé                 break;
32588d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_acpitable:
32598d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("acpi"),
32608d7f2e76SPhilippe Mathieu-Daudé                                                optarg, true);
32618d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
32628d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
32638d7f2e76SPhilippe Mathieu-Daudé                 }
32648d7f2e76SPhilippe Mathieu-Daudé                 acpi_table_add(opts, &error_fatal);
32658d7f2e76SPhilippe Mathieu-Daudé                 break;
32668d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_smbios:
32678d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("smbios"),
32688d7f2e76SPhilippe Mathieu-Daudé                                                optarg, false);
32698d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
32708d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
32718d7f2e76SPhilippe Mathieu-Daudé                 }
32728d7f2e76SPhilippe Mathieu-Daudé                 smbios_entry_add(opts, &error_fatal);
32738d7f2e76SPhilippe Mathieu-Daudé                 break;
32748d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_fwcfg:
32758d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("fw_cfg"),
32768d7f2e76SPhilippe Mathieu-Daudé                                                optarg, true);
32778d7f2e76SPhilippe Mathieu-Daudé                 if (opts == NULL) {
32788d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
32798d7f2e76SPhilippe Mathieu-Daudé                 }
32808d7f2e76SPhilippe Mathieu-Daudé                 break;
32818d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_preconfig:
32828d7f2e76SPhilippe Mathieu-Daudé                 preconfig_requested = true;
32838d7f2e76SPhilippe Mathieu-Daudé                 break;
32848d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_enable_kvm:
32858d7f2e76SPhilippe Mathieu-Daudé                 qdict_put_str(machine_opts_dict, "accel", "kvm");
32868d7f2e76SPhilippe Mathieu-Daudé                 break;
32878d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_M:
32888d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_machine:
32898d7f2e76SPhilippe Mathieu-Daudé                 {
32908d7f2e76SPhilippe Mathieu-Daudé                     bool help;
32918d7f2e76SPhilippe Mathieu-Daudé 
32928d7f2e76SPhilippe Mathieu-Daudé                     keyval_parse_into(machine_opts_dict, optarg, "type", &help, &error_fatal);
32938d7f2e76SPhilippe Mathieu-Daudé                     if (help) {
32948d7f2e76SPhilippe Mathieu-Daudé                         machine_help_func(machine_opts_dict);
32958d7f2e76SPhilippe Mathieu-Daudé                         exit(EXIT_SUCCESS);
32968d7f2e76SPhilippe Mathieu-Daudé                     }
32978d7f2e76SPhilippe Mathieu-Daudé                     break;
32988d7f2e76SPhilippe Mathieu-Daudé                 }
32998d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_accel:
33008d7f2e76SPhilippe Mathieu-Daudé                 accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"),
33018d7f2e76SPhilippe Mathieu-Daudé                                                      optarg, true);
33028d7f2e76SPhilippe Mathieu-Daudé                 optarg = qemu_opt_get(accel_opts, "accel");
33038d7f2e76SPhilippe Mathieu-Daudé                 if (!optarg || is_help_option(optarg)) {
33048d7f2e76SPhilippe Mathieu-Daudé                     printf("Accelerators supported in QEMU binary:\n");
33058d7f2e76SPhilippe Mathieu-Daudé                     GSList *el, *accel_list = object_class_get_list(TYPE_ACCEL,
33068d7f2e76SPhilippe Mathieu-Daudé                                                                     false);
33078d7f2e76SPhilippe Mathieu-Daudé                     for (el = accel_list; el; el = el->next) {
33088d7f2e76SPhilippe Mathieu-Daudé                         gchar *typename = g_strdup(object_class_get_name(
33098d7f2e76SPhilippe Mathieu-Daudé                                                    OBJECT_CLASS(el->data)));
33108d7f2e76SPhilippe Mathieu-Daudé                         /* omit qtest which is used for tests only */
33118d7f2e76SPhilippe Mathieu-Daudé                         if (g_strcmp0(typename, ACCEL_CLASS_NAME("qtest")) &&
33128d7f2e76SPhilippe Mathieu-Daudé                             g_str_has_suffix(typename, ACCEL_CLASS_SUFFIX)) {
33138d7f2e76SPhilippe Mathieu-Daudé                             gchar **optname = g_strsplit(typename,
33148d7f2e76SPhilippe Mathieu-Daudé                                                          ACCEL_CLASS_SUFFIX, 0);
33158d7f2e76SPhilippe Mathieu-Daudé                             printf("%s\n", optname[0]);
33168d7f2e76SPhilippe Mathieu-Daudé                             g_strfreev(optname);
33178d7f2e76SPhilippe Mathieu-Daudé                         }
33188d7f2e76SPhilippe Mathieu-Daudé                         g_free(typename);
33198d7f2e76SPhilippe Mathieu-Daudé                     }
33208d7f2e76SPhilippe Mathieu-Daudé                     g_slist_free(accel_list);
33218d7f2e76SPhilippe Mathieu-Daudé                     exit(0);
33228d7f2e76SPhilippe Mathieu-Daudé                 }
33238d7f2e76SPhilippe Mathieu-Daudé                 break;
33248d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_usb:
33258d7f2e76SPhilippe Mathieu-Daudé                 qdict_put_str(machine_opts_dict, "usb", "on");
33268d7f2e76SPhilippe Mathieu-Daudé                 break;
33278d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_usbdevice:
33288d7f2e76SPhilippe Mathieu-Daudé                 qdict_put_str(machine_opts_dict, "usb", "on");
33298d7f2e76SPhilippe Mathieu-Daudé                 add_device_config(DEV_USB, optarg);
33308d7f2e76SPhilippe Mathieu-Daudé                 break;
33318d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_device:
33328d7f2e76SPhilippe Mathieu-Daudé                 if (optarg[0] == '{') {
33338d7f2e76SPhilippe Mathieu-Daudé                     QObject *obj = qobject_from_json(optarg, &error_fatal);
33348d7f2e76SPhilippe Mathieu-Daudé                     DeviceOption *opt = g_new0(DeviceOption, 1);
33358d7f2e76SPhilippe Mathieu-Daudé                     opt->opts = qobject_to(QDict, obj);
33368d7f2e76SPhilippe Mathieu-Daudé                     loc_save(&opt->loc);
33378d7f2e76SPhilippe Mathieu-Daudé                     assert(opt->opts != NULL);
33388d7f2e76SPhilippe Mathieu-Daudé                     QTAILQ_INSERT_TAIL(&device_opts, opt, next);
33398d7f2e76SPhilippe Mathieu-Daudé                 } else {
33408d7f2e76SPhilippe Mathieu-Daudé                     if (!qemu_opts_parse_noisily(qemu_find_opts("device"),
33418d7f2e76SPhilippe Mathieu-Daudé                                                  optarg, true)) {
33428d7f2e76SPhilippe Mathieu-Daudé                         exit(1);
33438d7f2e76SPhilippe Mathieu-Daudé                     }
33448d7f2e76SPhilippe Mathieu-Daudé                 }
33458d7f2e76SPhilippe Mathieu-Daudé                 break;
33468d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_smp:
33478d7f2e76SPhilippe Mathieu-Daudé                 machine_parse_property_opt(qemu_find_opts("smp-opts"),
33488d7f2e76SPhilippe Mathieu-Daudé                                            "smp", optarg);
33498d7f2e76SPhilippe Mathieu-Daudé                 break;
3350*6261164bSMarc-André Lureau #ifdef CONFIG_VNC
33518d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_vnc:
33528d7f2e76SPhilippe Mathieu-Daudé                 vnc_parse(optarg);
33538d7f2e76SPhilippe Mathieu-Daudé                 break;
3354*6261164bSMarc-André Lureau #endif
33558d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_no_acpi:
33568d7f2e76SPhilippe Mathieu-Daudé                 warn_report("-no-acpi is deprecated, use '-machine acpi=off' instead");
33578d7f2e76SPhilippe Mathieu-Daudé                 qdict_put_str(machine_opts_dict, "acpi", "off");
33588d7f2e76SPhilippe Mathieu-Daudé                 break;
33598d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_no_hpet:
33608d7f2e76SPhilippe Mathieu-Daudé                 warn_report("-no-hpet is deprecated, use '-machine hpet=off' instead");
33618d7f2e76SPhilippe Mathieu-Daudé                 qdict_put_str(machine_opts_dict, "hpet", "off");
33628d7f2e76SPhilippe Mathieu-Daudé                 break;
33638d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_no_reboot:
33648d7f2e76SPhilippe Mathieu-Daudé                 olist = qemu_find_opts("action");
33658d7f2e76SPhilippe Mathieu-Daudé                 qemu_opts_parse_noisily(olist, "reboot=shutdown", false);
33668d7f2e76SPhilippe Mathieu-Daudé                 break;
33678d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_no_shutdown:
33688d7f2e76SPhilippe Mathieu-Daudé                 olist = qemu_find_opts("action");
33698d7f2e76SPhilippe Mathieu-Daudé                 qemu_opts_parse_noisily(olist, "shutdown=pause", false);
33708d7f2e76SPhilippe Mathieu-Daudé                 break;
33718d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_uuid:
33728d7f2e76SPhilippe Mathieu-Daudé                 if (qemu_uuid_parse(optarg, &qemu_uuid) < 0) {
33738d7f2e76SPhilippe Mathieu-Daudé                     error_report("failed to parse UUID string: wrong format");
33748d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
33758d7f2e76SPhilippe Mathieu-Daudé                 }
33768d7f2e76SPhilippe Mathieu-Daudé                 qemu_uuid_set = true;
33778d7f2e76SPhilippe Mathieu-Daudé                 break;
33788d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_option_rom:
33798d7f2e76SPhilippe Mathieu-Daudé                 if (nb_option_roms >= MAX_OPTION_ROMS) {
33808d7f2e76SPhilippe Mathieu-Daudé                     error_report("too many option ROMs");
33818d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
33828d7f2e76SPhilippe Mathieu-Daudé                 }
33838d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("option-rom"),
33848d7f2e76SPhilippe Mathieu-Daudé                                                optarg, true);
33858d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
33868d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
33878d7f2e76SPhilippe Mathieu-Daudé                 }
33888d7f2e76SPhilippe Mathieu-Daudé                 option_rom[nb_option_roms].name = qemu_opt_get(opts, "romfile");
33898d7f2e76SPhilippe Mathieu-Daudé                 option_rom[nb_option_roms].bootindex =
33908d7f2e76SPhilippe Mathieu-Daudé                     qemu_opt_get_number(opts, "bootindex", -1);
33918d7f2e76SPhilippe Mathieu-Daudé                 if (!option_rom[nb_option_roms].name) {
33928d7f2e76SPhilippe Mathieu-Daudé                     error_report("Option ROM file is not specified");
33938d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
33948d7f2e76SPhilippe Mathieu-Daudé                 }
33958d7f2e76SPhilippe Mathieu-Daudé                 nb_option_roms++;
33968d7f2e76SPhilippe Mathieu-Daudé                 break;
33978d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_semihosting:
33988d7f2e76SPhilippe Mathieu-Daudé                 qemu_semihosting_enable();
33998d7f2e76SPhilippe Mathieu-Daudé                 break;
34008d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_semihosting_config:
34018d7f2e76SPhilippe Mathieu-Daudé                 if (qemu_semihosting_config_options(optarg) != 0) {
34028d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
34038d7f2e76SPhilippe Mathieu-Daudé                 }
34048d7f2e76SPhilippe Mathieu-Daudé                 break;
34058d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_name:
34068d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("name"),
34078d7f2e76SPhilippe Mathieu-Daudé                                                optarg, true);
34088d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
34098d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
34108d7f2e76SPhilippe Mathieu-Daudé                 }
34118d7f2e76SPhilippe Mathieu-Daudé                 /* Capture guest name if -msg guest-name is used later */
34128d7f2e76SPhilippe Mathieu-Daudé                 error_guest_name = qemu_opt_get(opts, "guest");
34138d7f2e76SPhilippe Mathieu-Daudé                 break;
34148d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_prom_env:
34158d7f2e76SPhilippe Mathieu-Daudé                 if (nb_prom_envs >= MAX_PROM_ENVS) {
34168d7f2e76SPhilippe Mathieu-Daudé                     error_report("too many prom variables");
34178d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
34188d7f2e76SPhilippe Mathieu-Daudé                 }
34198d7f2e76SPhilippe Mathieu-Daudé                 prom_envs[nb_prom_envs] = optarg;
34208d7f2e76SPhilippe Mathieu-Daudé                 nb_prom_envs++;
34218d7f2e76SPhilippe Mathieu-Daudé                 break;
34228d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_old_param:
34238d7f2e76SPhilippe Mathieu-Daudé                 old_param = 1;
34248d7f2e76SPhilippe Mathieu-Daudé                 break;
34258d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_rtc:
34268d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("rtc"), optarg,
34278d7f2e76SPhilippe Mathieu-Daudé                                                false);
34288d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
34298d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
34308d7f2e76SPhilippe Mathieu-Daudé                 }
34318d7f2e76SPhilippe Mathieu-Daudé                 break;
34328d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_icount:
34338d7f2e76SPhilippe Mathieu-Daudé                 icount_opts = qemu_opts_parse_noisily(qemu_find_opts("icount"),
34348d7f2e76SPhilippe Mathieu-Daudé                                                       optarg, true);
34358d7f2e76SPhilippe Mathieu-Daudé                 if (!icount_opts) {
34368d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
34378d7f2e76SPhilippe Mathieu-Daudé                 }
34388d7f2e76SPhilippe Mathieu-Daudé                 break;
34398d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_incoming:
34408d7f2e76SPhilippe Mathieu-Daudé                 if (!incoming) {
34418d7f2e76SPhilippe Mathieu-Daudé                     runstate_set(RUN_STATE_INMIGRATE);
34428d7f2e76SPhilippe Mathieu-Daudé                 }
34438d7f2e76SPhilippe Mathieu-Daudé                 incoming = optarg;
34448d7f2e76SPhilippe Mathieu-Daudé                 break;
34458d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_only_migratable:
34468d7f2e76SPhilippe Mathieu-Daudé                 only_migratable = 1;
34478d7f2e76SPhilippe Mathieu-Daudé                 break;
34488d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_nodefaults:
34498d7f2e76SPhilippe Mathieu-Daudé                 has_defaults = 0;
34508d7f2e76SPhilippe Mathieu-Daudé                 break;
34518d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_xen_domid:
34528d7f2e76SPhilippe Mathieu-Daudé                 if (!(accel_find("xen")) && !(accel_find("kvm"))) {
34538d7f2e76SPhilippe Mathieu-Daudé                     error_report("Option not supported for this target");
34548d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
34558d7f2e76SPhilippe Mathieu-Daudé                 }
34568d7f2e76SPhilippe Mathieu-Daudé                 xen_domid = atoi(optarg);
34578d7f2e76SPhilippe Mathieu-Daudé                 break;
34588d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_xen_attach:
34598d7f2e76SPhilippe Mathieu-Daudé                 if (!(accel_find("xen"))) {
34608d7f2e76SPhilippe Mathieu-Daudé                     error_report("Option not supported for this target");
34618d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
34628d7f2e76SPhilippe Mathieu-Daudé                 }
34638d7f2e76SPhilippe Mathieu-Daudé                 xen_mode = XEN_ATTACH;
34648d7f2e76SPhilippe Mathieu-Daudé                 break;
34658d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_xen_domid_restrict:
34668d7f2e76SPhilippe Mathieu-Daudé                 if (!(accel_find("xen"))) {
34678d7f2e76SPhilippe Mathieu-Daudé                     error_report("Option not supported for this target");
34688d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
34698d7f2e76SPhilippe Mathieu-Daudé                 }
34708d7f2e76SPhilippe Mathieu-Daudé                 xen_domid_restrict = true;
34718d7f2e76SPhilippe Mathieu-Daudé                 break;
34728d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_trace:
34738d7f2e76SPhilippe Mathieu-Daudé                 trace_opt_parse(optarg);
34748d7f2e76SPhilippe Mathieu-Daudé                 break;
34758d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_plugin:
34768d7f2e76SPhilippe Mathieu-Daudé                 qemu_plugin_opt_parse(optarg, &plugin_list);
34778d7f2e76SPhilippe Mathieu-Daudé                 break;
34788d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_readconfig:
34798d7f2e76SPhilippe Mathieu-Daudé                 qemu_read_config_file(optarg, qemu_parse_config_group, &error_fatal);
34808d7f2e76SPhilippe Mathieu-Daudé                 break;
34818d7f2e76SPhilippe Mathieu-Daudé #ifdef CONFIG_SPICE
34828d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_spice:
34836d9ed4ebSMarc-André Lureau                 opts = qemu_opts_parse_noisily(qemu_find_opts("spice"), optarg, false);
34848d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
34858d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
34868d7f2e76SPhilippe Mathieu-Daudé                 }
34878d7f2e76SPhilippe Mathieu-Daudé                 display_remote++;
34888d7f2e76SPhilippe Mathieu-Daudé                 break;
34898d7f2e76SPhilippe Mathieu-Daudé #endif
34908d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_qtest:
34918d7f2e76SPhilippe Mathieu-Daudé                 qtest_chrdev = optarg;
34928d7f2e76SPhilippe Mathieu-Daudé                 break;
34938d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_qtest_log:
34948d7f2e76SPhilippe Mathieu-Daudé                 qtest_log = optarg;
34958d7f2e76SPhilippe Mathieu-Daudé                 break;
34968d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_sandbox:
34978d7f2e76SPhilippe Mathieu-Daudé                 olist = qemu_find_opts("sandbox");
34988d7f2e76SPhilippe Mathieu-Daudé                 if (!olist) {
34998d7f2e76SPhilippe Mathieu-Daudé #ifndef CONFIG_SECCOMP
35008d7f2e76SPhilippe Mathieu-Daudé                     error_report("-sandbox support is not enabled "
35018d7f2e76SPhilippe Mathieu-Daudé                                  "in this QEMU binary");
35028d7f2e76SPhilippe Mathieu-Daudé #endif
35038d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
35048d7f2e76SPhilippe Mathieu-Daudé                 }
35058d7f2e76SPhilippe Mathieu-Daudé 
35068d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(olist, optarg, true);
35078d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
35088d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
35098d7f2e76SPhilippe Mathieu-Daudé                 }
35108d7f2e76SPhilippe Mathieu-Daudé                 break;
35118d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_add_fd:
35128d7f2e76SPhilippe Mathieu-Daudé #ifndef _WIN32
35138d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("add-fd"),
35148d7f2e76SPhilippe Mathieu-Daudé                                                optarg, false);
35158d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
35168d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
35178d7f2e76SPhilippe Mathieu-Daudé                 }
35188d7f2e76SPhilippe Mathieu-Daudé #else
35198d7f2e76SPhilippe Mathieu-Daudé                 error_report("File descriptor passing is disabled on this "
35208d7f2e76SPhilippe Mathieu-Daudé                              "platform");
35218d7f2e76SPhilippe Mathieu-Daudé                 exit(1);
35228d7f2e76SPhilippe Mathieu-Daudé #endif
35238d7f2e76SPhilippe Mathieu-Daudé                 break;
35248d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_object:
35258d7f2e76SPhilippe Mathieu-Daudé                 object_option_parse(optarg);
35268d7f2e76SPhilippe Mathieu-Daudé                 break;
35278d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_overcommit:
35288d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("overcommit"),
35298d7f2e76SPhilippe Mathieu-Daudé                                                optarg, false);
35308d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
35318d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
35328d7f2e76SPhilippe Mathieu-Daudé                 }
35338d7f2e76SPhilippe Mathieu-Daudé                 enable_mlock = qemu_opt_get_bool(opts, "mem-lock", false);
35348d7f2e76SPhilippe Mathieu-Daudé                 enable_cpu_pm = qemu_opt_get_bool(opts, "cpu-pm", false);
35358d7f2e76SPhilippe Mathieu-Daudé                 break;
35368d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_compat:
35378d7f2e76SPhilippe Mathieu-Daudé                 {
35388d7f2e76SPhilippe Mathieu-Daudé                     CompatPolicy *opts_policy;
35398d7f2e76SPhilippe Mathieu-Daudé                     Visitor *v;
35408d7f2e76SPhilippe Mathieu-Daudé 
35418d7f2e76SPhilippe Mathieu-Daudé                     v = qobject_input_visitor_new_str(optarg, NULL,
35428d7f2e76SPhilippe Mathieu-Daudé                                                       &error_fatal);
35438d7f2e76SPhilippe Mathieu-Daudé 
35448d7f2e76SPhilippe Mathieu-Daudé                     visit_type_CompatPolicy(v, NULL, &opts_policy, &error_fatal);
35458d7f2e76SPhilippe Mathieu-Daudé                     QAPI_CLONE_MEMBERS(CompatPolicy, &compat_policy, opts_policy);
35468d7f2e76SPhilippe Mathieu-Daudé 
35478d7f2e76SPhilippe Mathieu-Daudé                     qapi_free_CompatPolicy(opts_policy);
35488d7f2e76SPhilippe Mathieu-Daudé                     visit_free(v);
35498d7f2e76SPhilippe Mathieu-Daudé                     break;
35508d7f2e76SPhilippe Mathieu-Daudé                 }
35518d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_msg:
35528d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("msg"), optarg,
35538d7f2e76SPhilippe Mathieu-Daudé                                                false);
35548d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
35558d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
35568d7f2e76SPhilippe Mathieu-Daudé                 }
35578d7f2e76SPhilippe Mathieu-Daudé                 configure_msg(opts);
35588d7f2e76SPhilippe Mathieu-Daudé                 break;
35598d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_dump_vmstate:
35608d7f2e76SPhilippe Mathieu-Daudé                 if (vmstate_dump_file) {
35618d7f2e76SPhilippe Mathieu-Daudé                     error_report("only one '-dump-vmstate' "
35628d7f2e76SPhilippe Mathieu-Daudé                                  "option may be given");
35638d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
35648d7f2e76SPhilippe Mathieu-Daudé                 }
35658d7f2e76SPhilippe Mathieu-Daudé                 vmstate_dump_file = fopen(optarg, "w");
35668d7f2e76SPhilippe Mathieu-Daudé                 if (vmstate_dump_file == NULL) {
35678d7f2e76SPhilippe Mathieu-Daudé                     error_report("open %s: %s", optarg, strerror(errno));
35688d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
35698d7f2e76SPhilippe Mathieu-Daudé                 }
35708d7f2e76SPhilippe Mathieu-Daudé                 break;
35718d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_enable_sync_profile:
35728d7f2e76SPhilippe Mathieu-Daudé                 qsp_enable();
35738d7f2e76SPhilippe Mathieu-Daudé                 break;
35748d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_nouserconfig:
35758d7f2e76SPhilippe Mathieu-Daudé                 /* Nothing to be parsed here. Especially, do not error out below. */
35768d7f2e76SPhilippe Mathieu-Daudé                 break;
35778d7f2e76SPhilippe Mathieu-Daudé #if defined(CONFIG_POSIX)
35788d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_runas:
35798d7f2e76SPhilippe Mathieu-Daudé                 if (!os_set_runas(optarg)) {
35808d7f2e76SPhilippe Mathieu-Daudé                     error_report("User \"%s\" doesn't exist"
35818d7f2e76SPhilippe Mathieu-Daudé                                  " (and is not <uid>:<gid>)",
35828d7f2e76SPhilippe Mathieu-Daudé                                  optarg);
35838d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
35848d7f2e76SPhilippe Mathieu-Daudé                 }
35858d7f2e76SPhilippe Mathieu-Daudé                 break;
35868d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_chroot:
35878d7f2e76SPhilippe Mathieu-Daudé                 warn_report("option is deprecated,"
35888d7f2e76SPhilippe Mathieu-Daudé                             " use '-run-with chroot=...' instead");
35898d7f2e76SPhilippe Mathieu-Daudé                 os_set_chroot(optarg);
35908d7f2e76SPhilippe Mathieu-Daudé                 break;
35918d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_daemonize:
35928d7f2e76SPhilippe Mathieu-Daudé                 os_set_daemonize(true);
35938d7f2e76SPhilippe Mathieu-Daudé                 break;
35948d7f2e76SPhilippe Mathieu-Daudé #if defined(CONFIG_LINUX)
35958d7f2e76SPhilippe Mathieu-Daudé             /* deprecated */
35968d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_asyncteardown:
35978d7f2e76SPhilippe Mathieu-Daudé                 init_async_teardown();
35988d7f2e76SPhilippe Mathieu-Daudé                 break;
35998d7f2e76SPhilippe Mathieu-Daudé #endif
36008d7f2e76SPhilippe Mathieu-Daudé             case QEMU_OPTION_run_with: {
36018d7f2e76SPhilippe Mathieu-Daudé                 const char *str;
36028d7f2e76SPhilippe Mathieu-Daudé                 opts = qemu_opts_parse_noisily(qemu_find_opts("run-with"),
36038d7f2e76SPhilippe Mathieu-Daudé                                                          optarg, false);
36048d7f2e76SPhilippe Mathieu-Daudé                 if (!opts) {
36058d7f2e76SPhilippe Mathieu-Daudé                     exit(1);
36068d7f2e76SPhilippe Mathieu-Daudé                 }
36078d7f2e76SPhilippe Mathieu-Daudé #if defined(CONFIG_LINUX)
36088d7f2e76SPhilippe Mathieu-Daudé                 if (qemu_opt_get_bool(opts, "async-teardown", false)) {
36098d7f2e76SPhilippe Mathieu-Daudé                     init_async_teardown();
36108d7f2e76SPhilippe Mathieu-Daudé                 }
36118d7f2e76SPhilippe Mathieu-Daudé #endif
36128d7f2e76SPhilippe Mathieu-Daudé                 str = qemu_opt_get(opts, "chroot");
36138d7f2e76SPhilippe Mathieu-Daudé                 if (str) {
36148d7f2e76SPhilippe Mathieu-Daudé                     os_set_chroot(str);
36158d7f2e76SPhilippe Mathieu-Daudé                 }
36168d7f2e76SPhilippe Mathieu-Daudé                 break;
36178d7f2e76SPhilippe Mathieu-Daudé             }
36188d7f2e76SPhilippe Mathieu-Daudé #endif /* CONFIG_POSIX */
36198d7f2e76SPhilippe Mathieu-Daudé 
36208d7f2e76SPhilippe Mathieu-Daudé             default:
36218d7f2e76SPhilippe Mathieu-Daudé                 error_report("Option not supported in this build");
36228d7f2e76SPhilippe Mathieu-Daudé                 exit(1);
36238d7f2e76SPhilippe Mathieu-Daudé             }
36248d7f2e76SPhilippe Mathieu-Daudé         }
36258d7f2e76SPhilippe Mathieu-Daudé     }
36268d7f2e76SPhilippe Mathieu-Daudé     /*
36278d7f2e76SPhilippe Mathieu-Daudé      * Clear error location left behind by the loop.
36288d7f2e76SPhilippe Mathieu-Daudé      * Best done right after the loop.  Do not insert code here!
36298d7f2e76SPhilippe Mathieu-Daudé      */
36308d7f2e76SPhilippe Mathieu-Daudé     loc_set_none();
36318d7f2e76SPhilippe Mathieu-Daudé 
36328d7f2e76SPhilippe Mathieu-Daudé     qemu_validate_options(machine_opts_dict);
36338d7f2e76SPhilippe Mathieu-Daudé     qemu_process_sugar_options();
36348d7f2e76SPhilippe Mathieu-Daudé 
36358d7f2e76SPhilippe Mathieu-Daudé     /*
36368d7f2e76SPhilippe Mathieu-Daudé      * These options affect everything else and should be processed
36378d7f2e76SPhilippe Mathieu-Daudé      * before daemonizing.
36388d7f2e76SPhilippe Mathieu-Daudé      */
36398d7f2e76SPhilippe Mathieu-Daudé     qemu_process_early_options();
36408d7f2e76SPhilippe Mathieu-Daudé 
36418d7f2e76SPhilippe Mathieu-Daudé     qemu_process_help_options();
36428d7f2e76SPhilippe Mathieu-Daudé     qemu_maybe_daemonize(pid_file);
36438d7f2e76SPhilippe Mathieu-Daudé 
36448d7f2e76SPhilippe Mathieu-Daudé     /*
36458d7f2e76SPhilippe Mathieu-Daudé      * The trace backend must be initialized after daemonizing.
36468d7f2e76SPhilippe Mathieu-Daudé      * trace_init_backends() will call st_init(), which will create the
36478d7f2e76SPhilippe Mathieu-Daudé      * trace thread in the parent, and also register st_flush_trace_buffer()
36488d7f2e76SPhilippe Mathieu-Daudé      * in atexit(). This function will force the parent to wait for the
36498d7f2e76SPhilippe Mathieu-Daudé      * writeout thread to finish, which will not occur, and the parent
36508d7f2e76SPhilippe Mathieu-Daudé      * process will be left in the host.
36518d7f2e76SPhilippe Mathieu-Daudé      */
36528d7f2e76SPhilippe Mathieu-Daudé     if (!trace_init_backends()) {
36538d7f2e76SPhilippe Mathieu-Daudé         exit(1);
36548d7f2e76SPhilippe Mathieu-Daudé     }
36558d7f2e76SPhilippe Mathieu-Daudé     trace_init_file();
36568d7f2e76SPhilippe Mathieu-Daudé 
36578d7f2e76SPhilippe Mathieu-Daudé     qemu_init_main_loop(&error_fatal);
36588d7f2e76SPhilippe Mathieu-Daudé     cpu_timers_init();
36598d7f2e76SPhilippe Mathieu-Daudé 
36608d7f2e76SPhilippe Mathieu-Daudé     user_register_global_props();
36618d7f2e76SPhilippe Mathieu-Daudé     replay_configure(icount_opts);
36628d7f2e76SPhilippe Mathieu-Daudé 
36638d7f2e76SPhilippe Mathieu-Daudé     configure_rtc(qemu_find_opts_singleton("rtc"));
36648d7f2e76SPhilippe Mathieu-Daudé 
36658d7f2e76SPhilippe Mathieu-Daudé     /* Transfer QemuOpts options into machine options */
36668d7f2e76SPhilippe Mathieu-Daudé     parse_memory_options();
36678d7f2e76SPhilippe Mathieu-Daudé 
36688d7f2e76SPhilippe Mathieu-Daudé     qemu_create_machine(machine_opts_dict);
36698d7f2e76SPhilippe Mathieu-Daudé 
36708d7f2e76SPhilippe Mathieu-Daudé     suspend_mux_open();
36718d7f2e76SPhilippe Mathieu-Daudé 
36728d7f2e76SPhilippe Mathieu-Daudé     qemu_disable_default_devices();
36738d7f2e76SPhilippe Mathieu-Daudé     qemu_create_default_devices();
36748d7f2e76SPhilippe Mathieu-Daudé     qemu_create_early_backends();
36758d7f2e76SPhilippe Mathieu-Daudé 
36768d7f2e76SPhilippe Mathieu-Daudé     qemu_apply_legacy_machine_options(machine_opts_dict);
36778d7f2e76SPhilippe Mathieu-Daudé     qemu_apply_machine_options(machine_opts_dict);
36788d7f2e76SPhilippe Mathieu-Daudé     qobject_unref(machine_opts_dict);
36798d7f2e76SPhilippe Mathieu-Daudé     phase_advance(PHASE_MACHINE_CREATED);
36808d7f2e76SPhilippe Mathieu-Daudé 
36818d7f2e76SPhilippe Mathieu-Daudé     /*
36828d7f2e76SPhilippe Mathieu-Daudé      * Note: uses machine properties such as kernel-irqchip, must run
36838d7f2e76SPhilippe Mathieu-Daudé      * after qemu_apply_machine_options.
36848d7f2e76SPhilippe Mathieu-Daudé      */
36858d7f2e76SPhilippe Mathieu-Daudé     configure_accelerators(argv[0]);
36868d7f2e76SPhilippe Mathieu-Daudé     phase_advance(PHASE_ACCEL_CREATED);
36878d7f2e76SPhilippe Mathieu-Daudé 
36888d7f2e76SPhilippe Mathieu-Daudé     /*
36898d7f2e76SPhilippe Mathieu-Daudé      * Beware, QOM objects created before this point miss global and
36908d7f2e76SPhilippe Mathieu-Daudé      * compat properties.
36918d7f2e76SPhilippe Mathieu-Daudé      *
36928d7f2e76SPhilippe Mathieu-Daudé      * Global properties get set up by qdev_prop_register_global(),
36938d7f2e76SPhilippe Mathieu-Daudé      * called from user_register_global_props(), and certain option
36948d7f2e76SPhilippe Mathieu-Daudé      * desugaring.  Also in CPU feature desugaring (buried in
36958d7f2e76SPhilippe Mathieu-Daudé      * parse_cpu_option()), which happens below this point, but may
36968d7f2e76SPhilippe Mathieu-Daudé      * only target the CPU type, which can only be created after
36978d7f2e76SPhilippe Mathieu-Daudé      * parse_cpu_option() returned the type.
36988d7f2e76SPhilippe Mathieu-Daudé      *
36998d7f2e76SPhilippe Mathieu-Daudé      * Machine compat properties: object_set_machine_compat_props().
37008d7f2e76SPhilippe Mathieu-Daudé      * Accelerator compat props: object_set_accelerator_compat_props(),
37018d7f2e76SPhilippe Mathieu-Daudé      * called from do_configure_accelerator().
37028d7f2e76SPhilippe Mathieu-Daudé      */
37038d7f2e76SPhilippe Mathieu-Daudé 
37048d7f2e76SPhilippe Mathieu-Daudé     machine_class = MACHINE_GET_CLASS(current_machine);
37058d7f2e76SPhilippe Mathieu-Daudé     if (!qtest_enabled() && machine_class->deprecation_reason) {
37068d7f2e76SPhilippe Mathieu-Daudé         warn_report("Machine type '%s' is deprecated: %s",
37078d7f2e76SPhilippe Mathieu-Daudé                      machine_class->name, machine_class->deprecation_reason);
37088d7f2e76SPhilippe Mathieu-Daudé     }
37098d7f2e76SPhilippe Mathieu-Daudé 
37108d7f2e76SPhilippe Mathieu-Daudé     /*
37118d7f2e76SPhilippe Mathieu-Daudé      * Create backends before creating migration objects, so that it can
37128d7f2e76SPhilippe Mathieu-Daudé      * check against compatibilities on the backend memories (e.g. postcopy
37138d7f2e76SPhilippe Mathieu-Daudé      * over memory-backend-file objects).
37148d7f2e76SPhilippe Mathieu-Daudé      */
37158d7f2e76SPhilippe Mathieu-Daudé     qemu_create_late_backends();
37168d7f2e76SPhilippe Mathieu-Daudé 
37178d7f2e76SPhilippe Mathieu-Daudé     /*
37188d7f2e76SPhilippe Mathieu-Daudé      * Note: creates a QOM object, must run only after global and
37198d7f2e76SPhilippe Mathieu-Daudé      * compat properties have been set up.
37208d7f2e76SPhilippe Mathieu-Daudé      */
37218d7f2e76SPhilippe Mathieu-Daudé     migration_object_init();
37228d7f2e76SPhilippe Mathieu-Daudé 
37238d7f2e76SPhilippe Mathieu-Daudé     /* parse features once if machine provides default cpu_type */
37248d7f2e76SPhilippe Mathieu-Daudé     current_machine->cpu_type = machine_class->default_cpu_type;
37258d7f2e76SPhilippe Mathieu-Daudé     if (cpu_option) {
37268d7f2e76SPhilippe Mathieu-Daudé         current_machine->cpu_type = parse_cpu_option(cpu_option);
37278d7f2e76SPhilippe Mathieu-Daudé     }
37288d7f2e76SPhilippe Mathieu-Daudé     /* NB: for machine none cpu_type could STILL be NULL here! */
37298d7f2e76SPhilippe Mathieu-Daudé 
37308d7f2e76SPhilippe Mathieu-Daudé     qemu_resolve_machine_memdev();
37318d7f2e76SPhilippe Mathieu-Daudé     parse_numa_opts(current_machine);
37328d7f2e76SPhilippe Mathieu-Daudé 
37338d7f2e76SPhilippe Mathieu-Daudé     if (vmstate_dump_file) {
37348d7f2e76SPhilippe Mathieu-Daudé         /* dump and exit */
37358d7f2e76SPhilippe Mathieu-Daudé         module_load_qom_all();
37368d7f2e76SPhilippe Mathieu-Daudé         dump_vmstate_json_to_file(vmstate_dump_file);
37378d7f2e76SPhilippe Mathieu-Daudé         exit(0);
37388d7f2e76SPhilippe Mathieu-Daudé     }
37398d7f2e76SPhilippe Mathieu-Daudé 
37408d7f2e76SPhilippe Mathieu-Daudé     if (!preconfig_requested) {
37418d7f2e76SPhilippe Mathieu-Daudé         qmp_x_exit_preconfig(&error_fatal);
37428d7f2e76SPhilippe Mathieu-Daudé     }
37438d7f2e76SPhilippe Mathieu-Daudé     qemu_init_displays();
37448d7f2e76SPhilippe Mathieu-Daudé     accel_setup_post(current_machine);
37458d7f2e76SPhilippe Mathieu-Daudé     os_setup_post();
37468d7f2e76SPhilippe Mathieu-Daudé     resume_mux_open();
37478d7f2e76SPhilippe Mathieu-Daudé }
3748