#include <glib.h>
+#include "qemu/sockets.h"
#include "hw/hw.h"
#include "hw/boards.h"
#include "hw/usb.h"
#include "disas/disas.h"
-#include "qemu/sockets.h"
#include "slirp/libslirp.h"
},
};
+static QemuOptsList qemu_mem_opts = {
+ .name = "memory",
+ .implied_opt_name = "size",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
+ .merge_lists = true,
+ .desc = {
+ {
+ .name = "size",
+ .type = QEMU_OPT_SIZE,
+ },
+ { /* end of list */ }
+ },
+};
+
/**
* Get machine options
*
*/
QemuOpts *qemu_get_machine_opts(void)
{
- QemuOptsList *list;
- QemuOpts *opts;
-
- list = qemu_find_opts("machine");
- assert(list);
- opts = qemu_opts_find(list, NULL);
- if (!opts) {
- opts = qemu_opts_create(list, NULL, 0, &error_abort);
- }
- return opts;
+ return qemu_find_opts_singleton("machine");
}
const char *qemu_get_vm_name(void)
* memory pointed by "size" is assigned total length of the array in bytes
*
*/
-char *get_boot_devices_list(size_t *size)
+char *get_boot_devices_list(size_t *size, bool ignore_suffixes)
{
FWBootEntry *i;
size_t total = 0;
assert(devpath);
}
- if (i->suffix && devpath) {
+ if (i->suffix && !ignore_suffixes && devpath) {
size_t bootpathlen = strlen(devpath) + strlen(i->suffix) + 1;
bootpath = g_malloc(bootpathlen);
g_free(devpath);
} else if (devpath) {
bootpath = devpath;
- } else {
+ } else if (!ignore_suffixes) {
assert(i->suffix);
bootpath = g_strdup(i->suffix);
+ } else {
+ bootpath = g_strdup("");
}
if (total) {
max_cpus = smp_cpus;
}
- if (max_cpus > 255) {
+ if (max_cpus > MAX_CPUMASK_BITS) {
fprintf(stderr, "Unsupported number of maxcpus\n");
exit(1);
}
static void machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
+ QEMUMachine *qm = data;
mc->qemu_machine = data;
+
+ mc->name = qm->name;
+ mc->alias = qm->alias;
+ mc->desc = qm->desc;
+ mc->init = qm->init;
+ mc->reset = qm->reset;
+ mc->hot_add_cpu = qm->hot_add_cpu;
+ mc->kvm_type = qm->kvm_type;
+ mc->block_default_type = qm->block_default_type;
+ mc->max_cpus = qm->max_cpus;
+ mc->no_serial = qm->no_serial;
+ mc->no_parallel = qm->no_parallel;
+ mc->use_virtcon = qm->use_virtcon;
+ mc->use_sclp = qm->use_sclp;
+ mc->no_floppy = qm->no_floppy;
+ mc->no_cdrom = qm->no_cdrom;
+ mc->no_sdcard = qm->no_sdcard;
+ mc->is_default = qm->is_default;
+ mc->default_machine_opts = qm->default_machine_opts;
+ mc->default_boot_order = qm->default_boot_order;
+ mc->compat_props = qm->compat_props;
+ mc->hw_version = qm->hw_version;
}
int qemu_register_machine(QEMUMachine *m)
{
+ char *name = g_strconcat(m->name, TYPE_MACHINE_SUFFIX, NULL);
TypeInfo ti = {
- .name = g_strconcat(m->name, TYPE_MACHINE_SUFFIX, NULL),
+ .name = name,
.parent = TYPE_MACHINE,
.class_init = machine_class_init,
.class_data = (void *)m,
};
type_register(&ti);
+ g_free(name);
return 0;
}
exit(!name || !is_help_option(name));
}
-static int tcg_init(QEMUMachine *machine)
+static int tcg_init(MachineClass *mc)
{
tcg_exec_init(tcg_tb_size * 1024 * 1024);
return 0;
const char *opt_name;
const char *name;
int (*available)(void);
- int (*init)(QEMUMachine *);
+ int (*init)(MachineClass *mc);
bool *allowed;
} accel_list[] = {
{ "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
{ "qtest", "QTest", qtest_available, qtest_init_accel, &qtest_allowed },
};
-static int configure_accelerator(QEMUMachine *machine)
+static int configure_accelerator(MachineClass *mc)
{
const char *p;
char buf[10];
if (!accel_list[i].available()) {
printf("%s not supported for this target\n",
accel_list[i].name);
- continue;
+ break;
}
*(accel_list[i].allowed) = true;
- ret = accel_list[i].init(machine);
+ ret = accel_list[i].init(mc);
if (ret < 0) {
init_failed = true;
fprintf(stderr, "failed to initialize %s: %s\n",
};
const char *trace_events = NULL;
const char *trace_file = NULL;
+ const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
+ 1024 * 1024;
atexit(qemu_run_exit_notifiers);
error_set_progname(argv[0]);
qemu_init_exec_dir(argv[0]);
g_mem_set_vtable(&mem_trace);
- if (!g_thread_supported()) {
-#if !GLIB_CHECK_VERSION(2, 31, 0)
- g_thread_init(NULL);
-#else
- fprintf(stderr, "glib threading failed to initialize.\n");
- exit(1);
-#endif
- }
module_call_init(MODULE_INIT_QOM);
qemu_add_opts(&qemu_trace_opts);
qemu_add_opts(&qemu_option_rom_opts);
qemu_add_opts(&qemu_machine_opts);
+ qemu_add_opts(&qemu_mem_opts);
qemu_add_opts(&qemu_smp_opts);
qemu_add_opts(&qemu_boot_opts);
qemu_add_opts(&qemu_sandbox_opts);
module_call_init(MODULE_INIT_MACHINE);
machine_class = find_default_machine();
cpu_model = NULL;
- ram_size = 0;
+ ram_size = default_ram_size;
snapshot = 0;
cyls = heads = secs = 0;
translation = BIOS_ATA_TRANSLATION_AUTO;
if (argv[optind][0] != '-') {
/* disk image */
optind++;
- continue;
} else {
const QEMUOption *popt;
exit(0);
break;
case QEMU_OPTION_m: {
- int64_t value;
uint64_t sz;
- char *end;
+ const char *mem_str;
- value = strtosz(optarg, &end);
- if (value < 0 || *end) {
- fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
- exit(1);
+ opts = qemu_opts_parse(qemu_find_opts("memory"),
+ optarg, 1);
+ if (!opts) {
+ exit(EXIT_FAILURE);
+ }
+
+ mem_str = qemu_opt_get(opts, "size");
+ if (!mem_str) {
+ error_report("invalid -m option, missing 'size' option");
+ exit(EXIT_FAILURE);
+ }
+ if (!*mem_str) {
+ error_report("missing 'size' option value");
+ exit(EXIT_FAILURE);
+ }
+
+ sz = qemu_opt_get_size(opts, "size", ram_size);
+
+ /* Fix up legacy suffix-less format */
+ if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
+ uint64_t overflow_check = sz;
+
+ sz <<= 20;
+ if ((sz >> 20) != overflow_check) {
+ error_report("too large 'size' option value");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* backward compatibility behaviour for case "-m 0" */
+ if (sz == 0) {
+ sz = default_ram_size;
}
- sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
+
+ sz = QEMU_ALIGN_UP(sz, 8192);
ram_size = sz;
if (ram_size != sz) {
- fprintf(stderr, "qemu: ram size too large\n");
- exit(1);
+ error_report("ram size too large");
+ exit(EXIT_FAILURE);
}
break;
}
}
}
qemu_config_write(fp);
- fclose(fp);
+ if (fp != stdout) {
+ fclose(fp);
+ }
break;
}
case QEMU_OPTION_qtest:
#endif
if (machine_class == NULL) {
- fprintf(stderr, "No machine found.\n");
+ fprintf(stderr, "No machine specified, and there is no default.\n"
+ "Use -machine help to list supported machines!\n");
exit(1);
}
exit(1);
}
- /* init the memory */
- if (ram_size == 0) {
- ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
- }
+ /* store value for the future use */
+ qemu_opt_set_number(qemu_find_opts_singleton("memory"), "size", ram_size);
if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0)
!= 0) {
exit(0);
}
- configure_accelerator(machine);
+ configure_accelerator(machine_class);
if (qtest_chrdev) {
Error *local_err = NULL;
qdev_machine_init();
- QEMUMachineInitArgs args = { .machine = machine,
- .ram_size = ram_size,
- .boot_order = boot_order,
- .kernel_filename = kernel_filename,
- .kernel_cmdline = kernel_cmdline,
- .initrd_filename = initrd_filename,
- .cpu_model = cpu_model };
+ current_machine->init_args = (QEMUMachineInitArgs) {
+ .machine = machine_class,
+ .ram_size = ram_size,
+ .boot_order = boot_order,
+ .kernel_filename = kernel_filename,
+ .kernel_cmdline = kernel_cmdline,
+ .initrd_filename = initrd_filename,
+ .cpu_model = cpu_model };
- current_machine->init_args = args;
machine->init(¤t_machine->init_args);
audio_init();