int max_cpus = 0;
int smp_cores = 1;
int smp_threads = 1;
+#ifdef CONFIG_VNC
const char *vnc_display;
+#endif
int acpi_enabled = 1;
int no_hpet = 0;
int fd_bootchk = 1;
unsigned int nb_prom_envs = 0;
const char *prom_envs[MAX_PROM_ENVS];
int boot_menu;
+uint8_t *boot_splash_filedata;
+int boot_splash_filedata_size;
+uint8_t qemu_extra_params_fw[2];
typedef struct FWBootEntry FWBootEntry;
static NotifierList machine_init_done_notifiers =
NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
+static int tcg_allowed = 1;
int kvm_allowed = 0;
+int xen_allowed = 0;
uint32_t xen_domid;
enum xen_mode xen_mode = XEN_EMULATE;
+static int tcg_tb_size;
static int default_serial = 1;
static int default_parallel = 1;
{ .driver = "isa-serial", .flag = &default_serial },
{ .driver = "isa-parallel", .flag = &default_parallel },
{ .driver = "isa-fdc", .flag = &default_floppy },
+ { .driver = "ide-cd", .flag = &default_cdrom },
+ { .driver = "ide-hd", .flag = &default_cdrom },
{ .driver = "ide-drive", .flag = &default_cdrom },
+ { .driver = "scsi-cd", .flag = &default_cdrom },
{ .driver = "virtio-serial-pci", .flag = &default_virtcon },
{ .driver = "virtio-serial-s390", .flag = &default_virtcon },
{ .driver = "virtio-serial", .flag = &default_virtcon },
{ .driver = "VGA", .flag = &default_vga },
{ .driver = "cirrus-vga", .flag = &default_vga },
{ .driver = "vmware-svga", .flag = &default_vga },
+ { .driver = "isa-vga", .flag = &default_vga },
+ { .driver = "qxl-vga", .flag = &default_vga },
};
+static void res_free(void)
+{
+ if (boot_splash_filedata != NULL) {
+ g_free(boot_splash_filedata);
+ boot_splash_filedata = NULL;
+ }
+}
+
static int default_driver_check(QemuOpts *opts, void *opaque)
{
const char *driver = qemu_opt_get(opts, "driver");
if (vlan->id == id)
return &vlan->net;
}
- vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
+ vlan = g_malloc0(sizeof(struct bt_vlan_s));
vlan->id = id;
pvlan = &first_bt_vlan;
while (*pvlan != NULL)
qemu_boot_set(standard_boot_devices);
qemu_unregister_reset(restore_boot_devices, standard_boot_devices);
- qemu_free(standard_boot_devices);
+ g_free(standard_boot_devices);
}
void add_boot_device_path(int32_t bootindex, DeviceState *dev,
assert(dev != NULL || suffix != NULL);
- node = qemu_mallocz(sizeof(FWBootEntry));
+ node = g_malloc0(sizeof(FWBootEntry));
node->bootindex = bootindex;
- node->suffix = suffix ? qemu_strdup(suffix) : NULL;
+ node->suffix = suffix ? g_strdup(suffix) : NULL;
node->dev = dev;
QTAILQ_FOREACH(i, &fw_boot_order, link) {
/*
* This function returns null terminated string that consist of new line
- * separated device pathes.
+ * separated device paths.
*
* memory pointed by "size" is assigned total length of the array in bytes
*
if (i->suffix && devpath) {
size_t bootpathlen = strlen(devpath) + strlen(i->suffix) + 1;
- bootpath = qemu_malloc(bootpathlen);
+ bootpath = g_malloc(bootpathlen);
snprintf(bootpath, bootpathlen, "%s%s", devpath, i->suffix);
- qemu_free(devpath);
+ g_free(devpath);
} else if (devpath) {
bootpath = devpath;
} else {
- bootpath = qemu_strdup(i->suffix);
+ bootpath = g_strdup(i->suffix);
assert(bootpath);
}
list[total-1] = '\n';
}
len = strlen(bootpath) + 1;
- list = qemu_realloc(list, total + len);
+ list = g_realloc(list, total + len);
memcpy(&list[total], bootpath, len);
total += len;
- qemu_free(bootpath);
+ g_free(bootpath);
}
*size = total;
goto done;
/* the other ones */
+#ifndef CONFIG_LINUX
+ /* only the linux version is qdev-ified, usb-bsd still needs this */
if (strstart(devname, "host:", &p)) {
dev = usb_host_device_open(p);
- } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
+ } else
+#endif
+ if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
dev = usb_bt_init(devname[2] ? hci_init(p) :
bt_new_hci(qemu_find_bt_vlan(0)));
} else {
{
struct pcmcia_socket_entry_s *entry;
- entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
+ entry = g_malloc(sizeof(struct pcmcia_socket_entry_s));
entry->socket = socket;
entry->next = pcmcia_sockets;
pcmcia_sockets = entry;
for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
if (entry->socket == socket) {
*ptr = entry->next;
- qemu_free(entry);
+ g_free(entry);
}
}
"Empty");
}
-/***********************************************************/
-/* I/O handling */
-
-typedef struct IOHandlerRecord {
- int fd;
- IOCanReadHandler *fd_read_poll;
- IOHandler *fd_read;
- IOHandler *fd_write;
- int deleted;
- void *opaque;
- /* temporary data */
- struct pollfd *ufd;
- QLIST_ENTRY(IOHandlerRecord) next;
-} IOHandlerRecord;
-
-static QLIST_HEAD(, IOHandlerRecord) io_handlers =
- QLIST_HEAD_INITIALIZER(io_handlers);
-
-
-/* XXX: fd_read_poll should be suppressed, but an API change is
- necessary in the character devices to suppress fd_can_read(). */
-int qemu_set_fd_handler2(int fd,
- IOCanReadHandler *fd_read_poll,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque)
-{
- IOHandlerRecord *ioh;
-
- if (!fd_read && !fd_write) {
- QLIST_FOREACH(ioh, &io_handlers, next) {
- if (ioh->fd == fd) {
- ioh->deleted = 1;
- break;
- }
- }
- } else {
- QLIST_FOREACH(ioh, &io_handlers, next) {
- if (ioh->fd == fd)
- goto found;
- }
- ioh = qemu_mallocz(sizeof(IOHandlerRecord));
- QLIST_INSERT_HEAD(&io_handlers, ioh, next);
- found:
- ioh->fd = fd;
- ioh->fd_read_poll = fd_read_poll;
- ioh->fd_read = fd_read;
- ioh->fd_write = fd_write;
- ioh->opaque = opaque;
- ioh->deleted = 0;
- }
- return 0;
-}
-
-int qemu_set_fd_handler(int fd,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque)
-{
- return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
-}
-
/***********************************************************/
/* machine registration */
interval = dcl->gui_timer_interval;
dcl = dcl->next;
}
- qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock));
+ qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock_ms(rt_clock));
}
static void nographic_update(void *opaque)
uint64_t interval = GUI_REFRESH_INTERVAL;
qemu_flush_coalesced_mmio_buffer();
- qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
+ qemu_mod_timer(nographic_timer, interval + qemu_get_clock_ms(rt_clock));
}
struct vm_change_state_entry {
{
VMChangeStateEntry *e;
- e = qemu_mallocz(sizeof (*e));
+ e = g_malloc0(sizeof (*e));
e->cb = cb;
e->opaque = opaque;
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
{
QLIST_REMOVE (e, entries);
- qemu_free (e);
+ g_free (e);
}
void vm_state_notify(int running, int reason)
static QTAILQ_HEAD(reset_handlers, QEMUResetEntry) reset_handlers =
QTAILQ_HEAD_INITIALIZER(reset_handlers);
static int reset_requested;
-static int shutdown_requested;
+static int shutdown_requested, shutdown_signal = -1;
+static pid_t shutdown_pid;
static int powerdown_requested;
static int debug_requested;
static int vmstop_requested;
+int qemu_shutdown_requested_get(void)
+{
+ return shutdown_requested;
+}
+
+int qemu_reset_requested_get(void)
+{
+ return reset_requested;
+}
+
int qemu_shutdown_requested(void)
{
int r = shutdown_requested;
return r;
}
+void qemu_kill_report(void)
+{
+ if (shutdown_signal != -1) {
+ fprintf(stderr, "qemu: terminating on signal %d", shutdown_signal);
+ if (shutdown_pid == 0) {
+ /* This happens for eg ^C at the terminal, so it's worth
+ * avoiding printing an odd message in that case.
+ */
+ fputc('\n', stderr);
+ } else {
+ fprintf(stderr, " from pid " FMT_pid "\n", shutdown_pid);
+ }
+ shutdown_signal = -1;
+ }
+}
+
int qemu_reset_requested(void)
{
int r = reset_requested;
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
{
- QEMUResetEntry *re = qemu_mallocz(sizeof(QEMUResetEntry));
+ QEMUResetEntry *re = g_malloc0(sizeof(QEMUResetEntry));
re->func = func;
re->opaque = opaque;
QTAILQ_FOREACH(re, &reset_handlers, entry) {
if (re->func == func && re->opaque == opaque) {
QTAILQ_REMOVE(&reset_handlers, re, entry);
- qemu_free(re);
+ g_free(re);
return;
}
}
}
-void qemu_system_reset(void)
+void qemu_system_reset(bool report)
{
QEMUResetEntry *re, *nre;
QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
re->func(re->opaque);
}
- monitor_protocol_event(QEVENT_RESET, NULL);
+ if (report) {
+ monitor_protocol_event(QEVENT_RESET, NULL);
+ }
cpu_synchronize_all_post_reset();
}
qemu_notify_event();
}
+void qemu_system_killed(int signal, pid_t pid)
+{
+ shutdown_signal = signal;
+ shutdown_pid = pid;
+ qemu_system_shutdown_request();
+}
+
void qemu_system_shutdown_request(void)
{
shutdown_requested = 1;
void main_loop_wait(int nonblocking)
{
- IOHandlerRecord *ioh;
fd_set rfds, wfds, xfds;
int ret, nfds;
struct timeval tv;
os_host_main_loop_wait(&timeout);
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+
/* poll any events */
/* XXX: separate device handlers from system ones */
nfds = -1;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&xfds);
- QLIST_FOREACH(ioh, &io_handlers, next) {
- if (ioh->deleted)
- continue;
- if (ioh->fd_read &&
- (!ioh->fd_read_poll ||
- ioh->fd_read_poll(ioh->opaque) != 0)) {
- FD_SET(ioh->fd, &rfds);
- if (ioh->fd > nfds)
- nfds = ioh->fd;
- }
- if (ioh->fd_write) {
- FD_SET(ioh->fd, &wfds);
- if (ioh->fd > nfds)
- nfds = ioh->fd;
- }
- }
-
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
-
+ qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
qemu_mutex_unlock_iothread();
ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
qemu_mutex_lock_iothread();
- if (ret > 0) {
- IOHandlerRecord *pioh;
-
- QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) {
- if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
- ioh->fd_read(ioh->opaque);
- }
- if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
- ioh->fd_write(ioh->opaque);
- }
-
- /* Do this last in case read/write handlers marked it for deletion */
- if (ioh->deleted) {
- QLIST_REMOVE(ioh, next);
- qemu_free(ioh);
- }
- }
- }
+ qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
qemu_run_all_timers();
vm_stop(VMSTOP_DEBUG);
}
if (qemu_shutdown_requested()) {
+ qemu_kill_report();
monitor_protocol_event(QEVENT_SHUTDOWN, NULL);
if (no_shutdown) {
vm_stop(VMSTOP_SHUTDOWN);
- no_shutdown = 0;
} else
break;
}
if (qemu_reset_requested()) {
pause_all_vcpus();
- qemu_system_reset();
+ cpu_synchronize_all_states();
+ qemu_system_reset(VMRESET_REPORT);
resume_all_vcpus();
}
if (qemu_powerdown_requested()) {
}
}
+static DisplayType select_display(const char *p)
+{
+ const char *opts;
+ DisplayType display = DT_DEFAULT;
+
+ if (strstart(p, "sdl", &opts)) {
+#ifdef CONFIG_SDL
+ display = DT_SDL;
+ while (*opts) {
+ const char *nextopt;
+
+ if (strstart(opts, ",frame=", &nextopt)) {
+ opts = nextopt;
+ if (strstart(opts, "on", &nextopt)) {
+ no_frame = 0;
+ } else if (strstart(opts, "off", &nextopt)) {
+ no_frame = 1;
+ } else {
+ goto invalid_sdl_args;
+ }
+ } else if (strstart(opts, ",alt_grab=", &nextopt)) {
+ opts = nextopt;
+ if (strstart(opts, "on", &nextopt)) {
+ alt_grab = 1;
+ } else if (strstart(opts, "off", &nextopt)) {
+ alt_grab = 0;
+ } else {
+ goto invalid_sdl_args;
+ }
+ } else if (strstart(opts, ",ctrl_grab=", &nextopt)) {
+ opts = nextopt;
+ if (strstart(opts, "on", &nextopt)) {
+ ctrl_grab = 1;
+ } else if (strstart(opts, "off", &nextopt)) {
+ ctrl_grab = 0;
+ } else {
+ goto invalid_sdl_args;
+ }
+ } else if (strstart(opts, ",window_close=", &nextopt)) {
+ opts = nextopt;
+ if (strstart(opts, "on", &nextopt)) {
+ no_quit = 0;
+ } else if (strstart(opts, "off", &nextopt)) {
+ no_quit = 1;
+ } else {
+ goto invalid_sdl_args;
+ }
+ } else {
+ invalid_sdl_args:
+ fprintf(stderr, "Invalid SDL option string: %s\n", p);
+ exit(1);
+ }
+ opts = nextopt;
+ }
+#else
+ fprintf(stderr, "SDL support is disabled\n");
+ exit(1);
+#endif
+ } else if (strstart(p, "vnc", &opts)) {
+#ifdef CONFIG_VNC
+ display_remote++;
+
+ if (*opts) {
+ const char *nextopt;
+
+ if (strstart(opts, "=", &nextopt)) {
+ vnc_display = nextopt;
+ }
+ }
+ if (!vnc_display) {
+ fprintf(stderr, "VNC requires a display argument vnc=<display>\n");
+ exit(1);
+ }
+#else
+ fprintf(stderr, "VNC support is disabled\n");
+ exit(1);
+#endif
+ } else if (strstart(p, "curses", &opts)) {
+#ifdef CONFIG_CURSES
+ display = DT_CURSES;
+#else
+ fprintf(stderr, "Curses support is disabled\n");
+ exit(1);
+#endif
+ } else if (strstart(p, "none", &opts)) {
+ display = DT_NONE;
+ } else {
+ fprintf(stderr, "Unknown display type: %s\n", p);
+ exit(1);
+ }
+
+ return display;
+}
+
static int balloon_parse(const char *arg)
{
QemuOpts *opts;
/* create empty opts */
opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0);
}
- qemu_opt_set(opts, "driver", "virtio-balloon-pci");
+ qemu_opt_set(opts, "driver", "virtio-balloon");
return 0;
}
/* If name contains path separators then try it as a straight path. */
if ((strchr(name, '/') || strchr(name, '\\'))
&& access(name, R_OK) == 0) {
- return qemu_strdup(name);
+ return g_strdup(name);
}
switch (type) {
case QEMU_FILE_TYPE_BIOS:
abort();
}
len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
- buf = qemu_mallocz(len);
+ buf = g_malloc0(len);
snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
if (access(buf, R_OK)) {
- qemu_free(buf);
+ g_free(buf);
return NULL;
}
return buf;
{
CharDriverState *chr;
- chr = qemu_chr_open_opts(opts, NULL);
+ chr = qemu_chr_new_from_opts(opts, NULL);
if (!chr)
return -1;
return 0;
{
struct device_config *conf;
- conf = qemu_mallocz(sizeof(*conf));
+ conf = g_malloc0(sizeof(*conf));
conf->type = type;
conf->cmdline = cmdline;
QTAILQ_INSERT_TAIL(&device_configs, conf, next);
exit(1);
}
snprintf(label, sizeof(label), "serial%d", index);
- serial_hds[index] = qemu_chr_open(label, devname, NULL);
+ serial_hds[index] = qemu_chr_new(label, devname, NULL);
if (!serial_hds[index]) {
fprintf(stderr, "qemu: could not open serial device '%s': %s\n",
devname, strerror(errno));
exit(1);
}
snprintf(label, sizeof(label), "parallel%d", index);
- parallel_hds[index] = qemu_chr_open(label, devname, NULL);
+ parallel_hds[index] = qemu_chr_new(label, devname, NULL);
if (!parallel_hds[index]) {
fprintf(stderr, "qemu: could not open parallel device '%s': %s\n",
devname, strerror(errno));
qemu_opt_set(dev_opts, "driver", "virtconsole");
snprintf(label, sizeof(label), "virtcon%d", index);
- virtcon_hds[index] = qemu_chr_open(label, devname, NULL);
+ virtcon_hds[index] = qemu_chr_new(label, devname, NULL);
if (!virtcon_hds[index]) {
fprintf(stderr, "qemu: could not open virtio console '%s': %s\n",
devname, strerror(errno));
{
QemuOpts *opts;
- if (!qemu_chr_open("debugcon", devname, NULL)) {
+ if (!qemu_chr_new("debugcon", devname, NULL)) {
exit(1);
}
opts = qemu_opts_create(qemu_find_opts("device"), "debugcon", 1);
return 0;
}
+static QEMUMachine *machine_parse(const char *name)
+{
+ QEMUMachine *m, *machine = NULL;
+
+ if (name) {
+ machine = find_machine(name);
+ }
+ if (machine) {
+ return machine;
+ }
+ printf("Supported machines are:\n");
+ for (m = first_machine; m != NULL; m = m->next) {
+ if (m->alias) {
+ printf("%-10s %s (alias of %s)\n", m->alias, m->desc, m->name);
+ }
+ printf("%-10s %s%s\n", m->name, m->desc,
+ m->is_default ? " (default)" : "");
+ }
+ exit(!name || *name != '?');
+}
+
+static int tcg_init(void)
+{
+ tcg_exec_init(tcg_tb_size * 1024 * 1024);
+ return 0;
+}
+
+static struct {
+ const char *opt_name;
+ const char *name;
+ int (*available)(void);
+ int (*init)(void);
+ int *allowed;
+} accel_list[] = {
+ { "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
+ { "xen", "Xen", xen_available, xen_init, &xen_allowed },
+ { "kvm", "KVM", kvm_available, kvm_init, &kvm_allowed },
+};
+
+static int configure_accelerator(void)
+{
+ const char *p = NULL;
+ char buf[10];
+ int i, ret;
+ bool accel_initalised = 0;
+ bool init_failed = 0;
+
+ QemuOptsList *list = qemu_find_opts("machine");
+ if (!QTAILQ_EMPTY(&list->head)) {
+ p = qemu_opt_get(QTAILQ_FIRST(&list->head), "accel");
+ }
+
+ if (p == NULL) {
+ /* Use the default "accelerator", tcg */
+ p = "tcg";
+ }
+
+ while (!accel_initalised && *p != '\0') {
+ if (*p == ':') {
+ p++;
+ }
+ p = get_opt_name(buf, sizeof (buf), p, ':');
+ for (i = 0; i < ARRAY_SIZE(accel_list); i++) {
+ if (strcmp(accel_list[i].opt_name, buf) == 0) {
+ *(accel_list[i].allowed) = 1;
+ ret = accel_list[i].init();
+ if (ret < 0) {
+ init_failed = 1;
+ if (!accel_list[i].available()) {
+ printf("%s not supported for this target\n",
+ accel_list[i].name);
+ } else {
+ fprintf(stderr, "failed to initialize %s: %s\n",
+ accel_list[i].name,
+ strerror(-ret));
+ }
+ *(accel_list[i].allowed) = 0;
+ } else {
+ accel_initalised = 1;
+ }
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(accel_list)) {
+ fprintf(stderr, "\"%s\" accelerator does not exist.\n", buf);
+ }
+ }
+
+ if (!accel_initalised) {
+ fprintf(stderr, "No accelerator found!\n");
+ exit(1);
+ }
+
+ if (init_failed) {
+ fprintf(stderr, "Back to %s accelerator.\n", accel_list[i].name);
+ }
+
+ return !accel_initalised;
+}
+
void qemu_add_exit_notifier(Notifier *notify)
{
notifier_list_add(&exit_notifiers, notify);
static void qemu_run_exit_notifiers(void)
{
- notifier_list_notify(&exit_notifiers);
+ notifier_list_notify(&exit_notifiers, NULL);
}
void qemu_add_machine_init_done_notifier(Notifier *notify)
static void qemu_run_machine_init_done_notifiers(void)
{
- notifier_list_notify(&machine_init_done_notifiers);
+ notifier_list_notify(&machine_init_done_notifiers, NULL);
}
static const QEMUOption *lookup_opt(int argc, char **argv,
return popt;
}
+static gpointer malloc_and_trace(gsize n_bytes)
+{
+ void *ptr = malloc(n_bytes);
+ trace_qemu_malloc(n_bytes, ptr);
+ return ptr;
+}
+
+static gpointer realloc_and_trace(gpointer mem, gsize n_bytes)
+{
+ void *ptr = realloc(mem, n_bytes);
+ trace_qemu_realloc(mem, n_bytes, ptr);
+ return ptr;
+}
+
+static void free_and_trace(gpointer mem)
+{
+ trace_qemu_free(mem);
+ free(mem);
+}
+
int main(int argc, char **argv, char **envp)
{
const char *gdbstub_dev = NULL;
const char *loadvm = NULL;
QEMUMachine *machine;
const char *cpu_model;
- int tb_size;
const char *pid_file = NULL;
const char *incoming = NULL;
+#ifdef CONFIG_VNC
int show_vnc_port = 0;
+#endif
int defconfig = 1;
const char *trace_file = NULL;
+ const char *log_mask = NULL;
+ const char *log_file = NULL;
+ GMemVTable mem_trace = {
+ .malloc = malloc_and_trace,
+ .realloc = realloc_and_trace,
+ .free = free_and_trace,
+ };
atexit(qemu_run_exit_notifiers);
error_set_progname(argv[0]);
+ g_mem_set_vtable(&mem_trace);
+
init_clocks();
qemu_cache_utils_init(envp);
nb_numa_nodes = 0;
nb_nics = 0;
- tb_size = 0;
autostart= 1;
/* first pass of option parsing */
}
switch(popt->index) {
case QEMU_OPTION_M:
- machine = find_machine(optarg);
- if (!machine) {
- QEMUMachine *m;
- printf("Supported machines are:\n");
- for(m = first_machine; m != NULL; m = m->next) {
- if (m->alias)
- printf("%-10s %s (alias of %s)\n",
- m->alias, m->desc, m->name);
- printf("%-10s %s%s\n",
- m->name, m->desc,
- m->is_default ? " (default)" : "");
- }
- exit(*optarg != '?');
- }
+ machine = machine_parse(optarg);
break;
case QEMU_OPTION_cpu:
/* hw initialization will check this */
HD_OPTS);
break;
case QEMU_OPTION_drive:
- drive_def(optarg);
+ if (drive_def(optarg) == NULL) {
+ exit(1);
+ }
break;
case QEMU_OPTION_set:
if (qemu_set_option(optarg) != 0)
}
numa_add(optarg);
break;
+ case QEMU_OPTION_display:
+ display_type = select_display(optarg);
+ break;
case QEMU_OPTION_nographic:
display_type = DT_NOGRAPHIC;
break;
-#ifdef CONFIG_CURSES
case QEMU_OPTION_curses:
+#ifdef CONFIG_CURSES
display_type = DT_CURSES;
- break;
+#else
+ fprintf(stderr, "Curses support is disabled\n");
+ exit(1);
#endif
+ break;
case QEMU_OPTION_portrait:
- graphic_rotate = 1;
+ graphic_rotate = 90;
+ break;
+ case QEMU_OPTION_rotate:
+ graphic_rotate = strtol(optarg, (char **) &optarg, 10);
+ if (graphic_rotate != 0 && graphic_rotate != 90 &&
+ graphic_rotate != 180 && graphic_rotate != 270) {
+ fprintf(stderr,
+ "qemu: only 90, 180, 270 deg rotation is available\n");
+ exit(1);
+ }
break;
case QEMU_OPTION_kernel:
kernel_filename = optarg;
case QEMU_OPTION_boot:
{
static const char * const params[] = {
- "order", "once", "menu", NULL
+ "order", "once", "menu",
+ "splash", "splash-time", NULL
};
char buf[sizeof(boot_devices)];
char *standard_boot_devices;
if (get_param_value(buf, sizeof(buf),
"once", optarg)) {
validate_bootdevices(buf);
- standard_boot_devices = qemu_strdup(boot_devices);
+ standard_boot_devices = g_strdup(boot_devices);
pstrcpy(boot_devices, sizeof(boot_devices), buf);
qemu_register_reset(restore_boot_devices,
standard_boot_devices);
exit(1);
}
}
+ qemu_opts_parse(qemu_find_opts("boot-opts"),
+ optarg, 0);
}
}
break;
exit(1);
}
- /* On 32-bit hosts, QEMU is limited by virtual address space */
- if (value > (2047 << 20) && HOST_LONG_BITS == 32) {
- fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
- exit(1);
- }
if (value != (uint64_t)(ram_addr_t)value) {
fprintf(stderr, "qemu: ram size too large\n");
exit(1);
break;
#endif
case QEMU_OPTION_d:
- set_cpu_log(optarg);
+ log_mask = optarg;
+ break;
+ case QEMU_OPTION_D:
+ log_file = optarg;
break;
case QEMU_OPTION_s:
gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
}
break;
case QEMU_OPTION_virtfs: {
- char *arg_fsdev = NULL;
- char *arg_9p = NULL;
- int len = 0;
+ QemuOpts *fsdev;
+ QemuOpts *device;
olist = qemu_find_opts("virtfs");
if (!olist) {
qemu_opt_get(opts, "security_model") == NULL) {
fprintf(stderr, "Usage: -virtfs fstype,path=/share_path/,"
"security_model=[mapped|passthrough|none],"
- "mnt_tag=tag.\n");
+ "mount_tag=tag.\n");
exit(1);
}
- len = strlen(",id=,path=,security_model=");
- len += strlen(qemu_opt_get(opts, "fstype"));
- len += strlen(qemu_opt_get(opts, "mount_tag"));
- len += strlen(qemu_opt_get(opts, "path"));
- len += strlen(qemu_opt_get(opts, "security_model"));
- arg_fsdev = qemu_malloc((len + 1) * sizeof(*arg_fsdev));
-
- snprintf(arg_fsdev, (len + 1) * sizeof(*arg_fsdev),
- "%s,id=%s,path=%s,security_model=%s",
- qemu_opt_get(opts, "fstype"),
- qemu_opt_get(opts, "mount_tag"),
- qemu_opt_get(opts, "path"),
- qemu_opt_get(opts, "security_model"));
-
- len = strlen("virtio-9p-pci,fsdev=,mount_tag=");
- len += 2*strlen(qemu_opt_get(opts, "mount_tag"));
- arg_9p = qemu_malloc((len + 1) * sizeof(*arg_9p));
-
- snprintf(arg_9p, (len + 1) * sizeof(*arg_9p),
- "virtio-9p-pci,fsdev=%s,mount_tag=%s",
- qemu_opt_get(opts, "mount_tag"),
- qemu_opt_get(opts, "mount_tag"));
-
- if (!qemu_opts_parse(qemu_find_opts("fsdev"), arg_fsdev, 1)) {
- fprintf(stderr, "parse error [fsdev]: %s\n", optarg);
+ fsdev = qemu_opts_create(qemu_find_opts("fsdev"),
+ qemu_opt_get(opts, "mount_tag"), 1);
+ if (!fsdev) {
+ fprintf(stderr, "duplicate fsdev id: %s\n",
+ qemu_opt_get(opts, "mount_tag"));
exit(1);
}
-
- if (!qemu_opts_parse(qemu_find_opts("device"), arg_9p, 1)) {
- fprintf(stderr, "parse error [device]: %s\n", optarg);
- exit(1);
- }
-
- qemu_free(arg_fsdev);
- qemu_free(arg_9p);
+ qemu_opt_set(fsdev, "fstype", qemu_opt_get(opts, "fstype"));
+ qemu_opt_set(fsdev, "path", qemu_opt_get(opts, "path"));
+ qemu_opt_set(fsdev, "security_model",
+ qemu_opt_get(opts, "security_model"));
+
+ device = qemu_opts_create(qemu_find_opts("device"), NULL, 0);
+ qemu_opt_set(device, "driver", "virtio-9p-pci");
+ qemu_opt_set(device, "fsdev",
+ qemu_opt_get(opts, "mount_tag"));
+ qemu_opt_set(device, "mount_tag",
+ qemu_opt_get(opts, "mount_tag"));
break;
}
case QEMU_OPTION_serial:
case QEMU_OPTION_sdl:
display_type = DT_SDL;
break;
+#else
+ case QEMU_OPTION_no_frame:
+ case QEMU_OPTION_alt_grab:
+ case QEMU_OPTION_ctrl_grab:
+ case QEMU_OPTION_no_quit:
+ case QEMU_OPTION_sdl:
+ fprintf(stderr, "SDL support is disabled\n");
+ exit(1);
#endif
case QEMU_OPTION_pidfile:
pid_file = optarg;
do_smbios_option(optarg);
break;
case QEMU_OPTION_enable_kvm:
- kvm_allowed = 1;
+ olist = qemu_find_opts("machine");
+ qemu_opts_reset(olist);
+ qemu_opts_parse(olist, "accel=kvm", 0);
+ break;
+ case QEMU_OPTION_machine:
+ olist = qemu_find_opts("machine");
+ qemu_opts_reset(olist);
+ opts = qemu_opts_parse(olist, optarg, 1);
+ if (!opts) {
+ fprintf(stderr, "parse error: %s\n", optarg);
+ exit(1);
+ }
+ optarg = qemu_opt_get(opts, "type");
+ if (optarg) {
+ machine = machine_parse(optarg);
+ }
break;
case QEMU_OPTION_usb:
usb_enabled = 1;
}
break;
case QEMU_OPTION_vnc:
+#ifdef CONFIG_VNC
display_remote++;
- vnc_display = optarg;
- break;
+ vnc_display = optarg;
+#else
+ fprintf(stderr, "VNC support is disabled\n");
+ exit(1);
+#endif
+ break;
case QEMU_OPTION_no_acpi:
acpi_enabled = 0;
break;
semihosting_enabled = 1;
break;
case QEMU_OPTION_name:
- qemu_name = qemu_strdup(optarg);
+ qemu_name = g_strdup(optarg);
{
char *p = strchr(qemu_name, ',');
if (p != NULL) {
configure_rtc(opts);
break;
case QEMU_OPTION_tb_size:
- tb_size = strtol(optarg, NULL, 0);
- if (tb_size < 0)
- tb_size = 0;
+ tcg_tb_size = strtol(optarg, NULL, 0);
+ if (tcg_tb_size < 0) {
+ tcg_tb_size = 0;
+ }
break;
case QEMU_OPTION_icount:
icount_option = optarg;
}
loc_set_none();
- st_init(trace_file);
+ /* Open the logfile at this point, if necessary. We can't open the logfile
+ * when encountering either of the logging options (-d or -D) because the
+ * other one may be encountered later on the command line, changing the
+ * location or level of logging.
+ */
+ if (log_mask) {
+ if (log_file) {
+ set_cpu_log_filename(log_file);
+ }
+ set_cpu_log(log_mask);
+ }
+
+ if (!st_init(trace_file)) {
+ fprintf(stderr, "warning: unable to initialize simple trace backend\n");
+ }
/* If no data_dir is specified then try to find it relative to the
executable path. */
exit(1);
}
+ /*
+ * Get the default machine options from the machine if it is not already
+ * specified either by the configuration file or by the command line.
+ */
+ if (machine->default_machine_opts) {
+ QemuOptsList *list = qemu_find_opts("machine");
+ const char *p = NULL;
+
+ if (!QTAILQ_EMPTY(&list->head)) {
+ p = qemu_opt_get(QTAILQ_FIRST(&list->head), "accel");
+ }
+ if (p == NULL) {
+ qemu_opts_reset(list);
+ opts = qemu_opts_parse(list, machine->default_machine_opts, 0);
+ if (!opts) {
+ fprintf(stderr, "parse error for machine %s: %s\n",
+ machine->name, machine->default_machine_opts);
+ exit(1);
+ }
+ }
+ }
+
qemu_opts_foreach(qemu_find_opts("device"), default_driver_check, NULL, 0);
qemu_opts_foreach(qemu_find_opts("global"), default_driver_check, NULL, 0);
exit(1);
}
- if (kvm_allowed) {
- int ret = kvm_init();
- if (ret < 0) {
- if (!kvm_available()) {
- printf("KVM not supported for this target\n");
- } else {
- fprintf(stderr, "failed to initialize KVM: %s\n", strerror(-ret));
- }
- exit(1);
- }
+ /* init the memory */
+ if (ram_size == 0) {
+ ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
}
+ configure_accelerator();
+
if (qemu_init_main_loop()) {
fprintf(stderr, "qemu_init_main_loop failed\n");
exit(1);
if (foreach_device_config(DEV_BT, bt_parse))
exit(1);
- /* init the memory */
- if (ram_size == 0)
- ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
+ if (!xen_enabled()) {
+ /* On 32-bit hosts, QEMU is limited by virtual address space */
+ if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) {
+ fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
+ exit(1);
+ }
+ }
- /* init the dynamic translator */
- cpu_exec_init_all(tb_size * 1024 * 1024);
+ cpu_exec_init_all();
bdrv_init_with_whitelist();
if (nb_numa_nodes > 0) {
int i;
- if (nb_numa_nodes > smp_cpus) {
- nb_numa_nodes = smp_cpus;
+ if (nb_numa_nodes > MAX_NODES) {
+ nb_numa_nodes = MAX_NODES;
}
/* If no memory size if given for any node, assume the default case
cpu_synchronize_all_post_init();
- /* must be after terminal init, SDL library changes signal handlers */
- os_setup_signal_handling();
-
set_numa_modes();
current_machine = machine;
if (display_type == DT_DEFAULT && !display_remote) {
#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
display_type = DT_SDL;
-#else
+#elif defined(CONFIG_VNC)
vnc_display = "localhost:0,to=99";
show_vnc_port = 1;
+#else
+ display_type = DT_NONE;
#endif
}
-
+
/* init local displays */
switch (display_type) {
break;
}
+ /* must be after terminal init, SDL library changes signal handlers */
+ os_setup_signal_handling();
+
+#ifdef CONFIG_VNC
/* init remote displays */
if (vnc_display) {
vnc_display_init(ds);
printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
}
}
+#endif
#ifdef CONFIG_SPICE
if (using_spice && !qxl_enabled) {
qemu_spice_display_init(ds);
dcl = ds->listeners;
while (dcl != NULL) {
if (dcl->dpy_refresh != NULL) {
- ds->gui_timer = qemu_new_timer(rt_clock, gui_update, ds);
- qemu_mod_timer(ds->gui_timer, qemu_get_clock(rt_clock));
+ ds->gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
+ qemu_mod_timer(ds->gui_timer, qemu_get_clock_ms(rt_clock));
break;
}
dcl = dcl->next;
}
if (ds->gui_timer == NULL) {
- nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
- qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
+ nographic_timer = qemu_new_timer_ms(rt_clock, nographic_update, NULL);
+ qemu_mod_timer(nographic_timer, qemu_get_clock_ms(rt_clock));
}
text_consoles_set_display(ds);
qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
qemu_run_machine_init_done_notifiers();
- qemu_system_reset();
+ qemu_system_reset(VMRESET_SILENT);
if (loadvm) {
if (load_vmstate(loadvm) < 0) {
autostart = 0;
main_loop();
quit_timers();
net_cleanup();
+ res_free();
return 0;
}