* THE SOFTWARE.
*/
#include "qemu/osdep.h"
+#include "qemu-version.h"
#include "qemu/cutils.h"
#include "qemu/help_option.h"
#ifdef CONFIG_SDL
#if defined(__APPLE__) || defined(main)
#include <SDL.h>
+#ifndef CONFIG_MARU
int qemu_main(int argc, char **argv, char **envp);
int main(int argc, char **argv)
{
#undef main
#define main qemu_main
#endif
+#endif
#endif /* CONFIG_SDL */
#ifdef CONFIG_COCOA
#define main qemu_main
#endif /* CONFIG_COCOA */
-#include <glib.h>
+#ifdef CONFIG_MARU
+#ifdef main
+#undef main
+#endif
+int qemu_main(int argc, char **argv, char **envp);
+#define main qemu_main
+#endif
#include "qemu/error-report.h"
#include "qemu/sockets.h"
#include "migration/migration.h"
#include "sysemu/cpus.h"
#include "sysemu/kvm.h"
+#include "sysemu/hax.h"
#include "qapi/qmp/qjson.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "sysemu/replay.h"
#include "qapi/qmp/qerror.h"
+#ifdef CONFIG_MARU
+#include "tizen/src/emulator.h"
+#include "tizen/src/emul_state.h"
+#include "tizen/src/ui/qt5.h"
+#include "tizen/src/util/ui_operations.h"
+#include "tizen/src/ecs/ecs.h"
+#include "tizen/src/util/error_handler.h"
+#include "tizen/src/util/exported_strings.h"
+
+inline static bool is_maru_machine(MachineClass *mc) {
+ return g_str_has_prefix(mc->name, "maru");
+}
+#endif
+
#define MAX_VIRTIO_CONSOLES 1
#define MAX_SCLP_CONSOLES 1
int win2k_install_hack = 0;
int singlestep = 0;
int smp_cpus = 1;
-int max_cpus = 0;
+int max_cpus = 1;
int smp_cores = 1;
int smp_threads = 1;
int acpi_enabled = 1;
static int default_cdrom = 1;
static int default_sdcard = 1;
static int default_vga = 1;
+static int default_net = 1;
static struct {
const char *driver;
},
};
-static QemuOptsList qemu_trace_opts = {
- .name = "trace",
- .implied_opt_name = "enable",
- .head = QTAILQ_HEAD_INITIALIZER(qemu_trace_opts.head),
- .desc = {
- {
- .name = "enable",
- .type = QEMU_OPT_STRING,
- },
- {
- .name = "events",
- .type = QEMU_OPT_STRING,
- },{
- .name = "file",
- .type = QEMU_OPT_STRING,
- },
- { /* end of list */ }
- },
-};
-
static QemuOptsList qemu_option_rom_opts = {
.name = "option-rom",
.implied_opt_name = "romfile",
{
assert(new_state < RUN_STATE__MAX);
+ if (current_run_state == new_state) {
+ return;
+ }
+
if (!runstate_valid_transitions[current_run_state][new_state]) {
error_report("invalid runstate transition: '%s' -> '%s'",
RunState_lookup[current_run_state],
return has_defaults;
}
-bool usb_enabled(void)
-{
- return machine_usb(current_machine);
-}
-
#ifndef _WIN32
static int parse_add_fd(void *opaque, QemuOpts *opts, Error **errp)
{
static void smp_parse(QemuOpts *opts)
{
if (opts) {
-
unsigned cpus = qemu_opt_get_number(opts, "cpus", 0);
unsigned sockets = qemu_opt_get_number(opts, "sockets", 0);
unsigned cores = qemu_opt_get_number(opts, "cores", 0);
} else if (cores == 0) {
threads = threads > 0 ? threads : 1;
cores = cpus / (sockets * threads);
+ cores = cores > 0 ? cores : 1;
} else if (threads == 0) {
threads = cpus / (cores * sockets);
+ threads = threads > 0 ? threads : 1;
} else if (sockets * cores * threads < cpus) {
error_report("cpu topology: "
"sockets (%u) * cores (%u) * threads (%u) < "
}
max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus);
+
+ if (max_cpus > MAX_CPUMASK_BITS) {
+ error_report("unsupported number of maxcpus");
+ exit(1);
+ }
+
+ if (max_cpus < cpus) {
+ error_report("maxcpus must be equal to or greater than smp");
+ exit(1);
+ }
+
if (sockets * cores * threads > max_cpus) {
error_report("cpu topology: "
"sockets (%u) * cores (%u) * threads (%u) > "
}
smp_cpus = cpus;
- smp_cores = cores > 0 ? cores : 1;
- smp_threads = threads > 0 ? threads : 1;
-
- }
-
- if (max_cpus == 0) {
- max_cpus = smp_cpus;
+ smp_cores = cores;
+ smp_threads = threads;
}
- if (max_cpus > MAX_CPUMASK_BITS) {
- error_report("unsupported number of maxcpus");
- exit(1);
- }
- if (max_cpus < smp_cpus) {
- error_report("maxcpus must be equal to or greater than smp");
- exit(1);
- }
-
- if (smp_cpus > 1 || smp_cores > 1 || smp_threads > 1) {
+ if (smp_cpus > 1) {
Error *blocker = NULL;
error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp");
replay_add_blocker(blocker);
const char *p;
#endif
- if (!usb_enabled()) {
+ if (!machine_usb(current_machine)) {
return -1;
}
return -1;
}
- if (!usb_enabled()) {
+ if (!machine_usb(current_machine)) {
return -1;
}
info->name = g_strdup(mc->name);
info->cpu_max = !mc->max_cpus ? 1 : mc->max_cpus;
+ info->hotpluggable_cpus = !!mc->query_hotpluggable_cpus;
entry = g_malloc0(sizeof(*entry));
entry->value = info;
shutdown_pid = pid;
no_shutdown = 0;
+#ifdef CONFIG_MARU
+ if (current_machine &&
+ is_maru_machine(MACHINE_GET_CLASS(current_machine))) {
+ qemu_system_graceful_shutdown_request(TIMEOUT_FOR_SHUTDOWN);
+ }
+#else
/* Cannot call qemu_system_shutdown_request directly because
* we are in a signal handler.
*/
shutdown_requested = 1;
qemu_notify_event();
+#endif
}
void qemu_system_shutdown_request(void)
#ifdef CONFIG_PROFILER
int64_t ti;
#endif
+
+ hax_sync_vcpus();
+
do {
- nonblocking = !kvm_enabled() && !xen_enabled() && last_io > 0;
+ nonblocking = !kvm_enabled() && !xen_enabled() && !hax_enabled() && last_io > 0;
#ifdef CONFIG_PROFILER
ti = profile_getclock();
#endif
static void version(void)
{
- printf("QEMU emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
+ printf("QEMU emulator version " QEMU_VERSION QEMU_PKGVERSION ", "
+ QEMU_COPYRIGHT "\n");
}
static void help(int exitcode)
DT_SDL,
DT_COCOA,
DT_GTK,
+#ifdef CONFIG_MARU
+ DT_MARU_REMOTE_SPICE,
+# ifdef CONFIG_QT
+ DT_MARU_QT_ONSCREEN,
+ DT_MARU_QT_OFFSCREEN,
+# endif
+#endif
DT_NONE,
} DisplayType;
error_report("GTK support is disabled");
exit(1);
#endif
+#ifdef CONFIG_MARU
+ } else if (strstart(p, "maru_remote_spice", &opts)) {
+# ifdef CONFIG_SPICE
+ display = DT_MARU_REMOTE_SPICE;
+# else
+ fprintf(stderr, "maru_remote_spice is disabled\n");
+ exit(1);
+# endif
+ } else if (strstart(p, "maru_qt", &opts)) {
+# ifdef CONFIG_QT
+ display = DT_MARU_QT_ONSCREEN;
+ while (*opts) {
+ const char *nextopt;
+ if (strstart(opts, ",rendering=", &nextopt)) {
+ opts = nextopt;
+ if (strstart(opts, "onscreen", &nextopt)) {
+ display = DT_MARU_QT_ONSCREEN;
+ } else if (strstart(opts, "offscreen", &nextopt)) {
+ display = DT_MARU_QT_OFFSCREEN;
+ } else {
+ goto invalid_maru_qt_args;
+ }
+ } else if (strstart(opts, ",resolution=", &nextopt)) {
+ opts = nextopt;
+ char *endptr = NULL;
+ // Resolution should be formed "640x480" or "640*480".
+ int width = (int)g_ascii_strtoll(opts, &endptr, 10);
+ int height = (int)g_ascii_strtoll(++endptr, &endptr, 10);
+ if (width <= 0 || height <= 0) {
+ goto invalid_maru_qt_args;
+ }
+ set_initial_display_resolution(width, height);
+ nextopt = endptr;
+ } else if (strstart(opts, ",dpi=", &nextopt)) {
+ opts = nextopt;
+ char *endptr = NULL;
+ int dpi = (int)g_ascii_strtoll(opts, &endptr, 10);
+ if (dpi <= 0) {
+ goto invalid_maru_qt_args;
+ }
+ set_display_pixel_density(dpi);
+ nextopt = endptr;
+ } else if (strstart(opts, ",forcelegacy", &nextopt)) {
+ opts = nextopt;
+ maru_qt5_set_force_legacy(true);
+ } else {
+ invalid_maru_qt_args:
+ error_report(FAILED_TO_DISPLAY_PARSING);
+ exit(1);
+ }
+ opts = nextopt;
+ }
+# else
+ error_report("maru_qt is disabled.\n");
+
+ exit(1);
+# endif
+#endif /* CONFIG_MARU */
} else if (strstart(p, "none", &opts)) {
display = DT_NONE;
} else {
#ifdef CONFIG_VIRTFS
static int fsdev_init_func(void *opaque, QemuOpts *opts, Error **errp)
{
- int ret;
- ret = qemu_fsdev_add(opts);
-
- return ret;
+ return qemu_fsdev_add(opts);
}
#endif
}
}
+void qemu_remove_machine_init_done_notifier(Notifier *notify)
+{
+ notifier_remove(notify);
+}
+
static void qemu_run_machine_init_done_notifiers(void)
{
notifier_list_notify(&machine_init_done_notifiers, NULL);
loc_pop(&loc);
}
+static int global_init_func(void *opaque, QemuOpts *opts, Error **errp)
+{
+ GlobalProperty *g;
+
+ g = g_malloc0(sizeof(*g));
+ g->driver = qemu_opt_get(opts, "driver");
+ g->property = qemu_opt_get(opts, "property");
+ g->value = qemu_opt_get(opts, "value");
+ g->user_provided = true;
+ g->errp = &error_fatal;
+ qdev_prop_register_global(g);
+ return 0;
+}
+
+#ifdef CONFIG_MARU
+// W/A for preserve larger continuous heap for RAM.
+extern void *preallocated_ram_ptr;
+extern int preallocated_ram_size;
+// FIXME
+extern bool nodisplay;
+#endif
+
int main(int argc, char **argv, char **envp)
{
int i;
const char *qtest_log = NULL;
const char *pid_file = NULL;
const char *incoming = NULL;
- int show_vnc_port = 0;
bool defconfig = true;
bool userconfig = true;
bool nographic = false;
FILE *vmstate_dump_file = NULL;
Error *main_loop_err = NULL;
Error *err = NULL;
+ bool list_data_dirs = false;
+#ifdef CONFIG_YAGL
+ static bool yagl_enabled = false;
+#endif /* CONFIG_YAGL */
+#ifdef CONFIG_VIGS
+ static bool vigs_enabled = false;
+ static char *vigs_backend = NULL;
+#endif /* CONFIG_VIGS */
qemu_init_cpu_loop();
qemu_mutex_lock_iothread();
popt = lookup_opt(argc, argv, &optarg, &optind);
if (!(popt->arch_mask & arch_type)) {
- printf("Option %s not supported for this target\n", popt->name);
+ error_report("Option not supported for this target");
exit(1);
}
switch(popt->index) {
fd_bootchk = 0;
break;
case QEMU_OPTION_netdev:
+ default_net = 0;
if (net_client_parse(qemu_find_opts("netdev"), optarg) == -1) {
exit(1);
}
break;
case QEMU_OPTION_net:
+ default_net = 0;
if (net_client_parse(qemu_find_opts("net"), optarg) == -1) {
exit(1);
}
log_file = optarg;
break;
case QEMU_OPTION_DFILTER:
- qemu_set_dfilter_ranges(optarg);
+ qemu_set_dfilter_ranges(optarg, &error_fatal);
break;
case QEMU_OPTION_s:
add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT);
add_device_config(DEV_GDB, optarg);
break;
case QEMU_OPTION_L:
- if (data_dir_idx < ARRAY_SIZE(data_dir)) {
+ if (is_help_option(optarg)) {
+ list_data_dirs = true;
+ } else if (data_dir_idx < ARRAY_SIZE(data_dir)) {
data_dir[data_dir_idx++] = optarg;
}
break;
olist = qemu_find_opts("machine");
qemu_opts_parse_noisily(olist, "accel=kvm", false);
break;
+ case QEMU_OPTION_enable_yagl:
+#if defined(CONFIG_YAGL)
+ yagl_enabled = true;
+#else
+ fprintf(stderr, "YaGL openGLES passthrough support is disabled,"
+ " ignoring -enable-yagl\n");
+#endif
+ break;
+ case QEMU_OPTION_enable_vigs:
+#if defined(CONFIG_VIGS)
+ vigs_enabled = true;
+#else
+ fprintf(stderr, "VIGS support is disabled,"
+ " ignoring -enable-vigs\n");
+#endif
+ break;
+ case QEMU_OPTION_vigs_backend:
+#if defined(CONFIG_VIGS)
+ vigs_backend = g_strdup(optarg);
+#else
+ fprintf(stderr, "VIGS support is disabled,"
+ " ignoring -vigs-backend\n");
+#endif
+ break;
case QEMU_OPTION_M:
case QEMU_OPTION_machine:
olist = qemu_find_opts("machine");
break;
case QEMU_OPTION_xen_domid:
if (!(xen_available())) {
- printf("Option %s not supported for this target\n", popt->name);
+ error_report("Option not supported for this target");
exit(1);
}
xen_domid = atoi(optarg);
break;
case QEMU_OPTION_xen_create:
if (!(xen_available())) {
- printf("Option %s not supported for this target\n", popt->name);
+ error_report("Option not supported for this target");
exit(1);
}
xen_mode = XEN_CREATE;
break;
case QEMU_OPTION_xen_attach:
if (!(xen_available())) {
- printf("Option %s not supported for this target\n", popt->name);
+ error_report("Option not supported for this target");
exit(1);
}
xen_mode = XEN_ATTACH;
break;
case QEMU_OPTION_trace:
- {
- opts = qemu_opts_parse_noisily(qemu_find_opts("trace"),
- optarg, true);
- if (!opts) {
- exit(1);
- }
- if (qemu_opt_get(opts, "enable")) {
- trace_enable_events(qemu_opt_get(opts, "enable"));
- }
- trace_init_events(qemu_opt_get(opts, "events"));
- if (trace_file) {
- g_free(trace_file);
- }
- trace_file = g_strdup(qemu_opt_get(opts, "file"));
- qemu_opts_del(opts);
+ g_free(trace_file);
+ trace_file = trace_opt_parse(optarg);
break;
- }
case QEMU_OPTION_readconfig:
{
int ret = qemu_read_config_file(optarg);
exit(1);
}
break;
+ case QEMU_OPTION_enable_hax:
+ olist = qemu_find_opts("machine");
+ qemu_opts_parse_noisily(olist, "accel=hax", false);
+ break;
case QEMU_OPTION_add_fd:
#ifndef _WIN32
opts = qemu_opts_parse_noisily(qemu_find_opts("add-fd"),
exit(1);
#endif
break;
+#if defined(CONFIG_MARU)
+ case QEMU_OPTION_enable_suspend:
+ ecs_set_suspend_state(SUSPEND_UNLOCK);
+ break;
+#endif
case QEMU_OPTION_object:
opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
optarg, true);
machine_class = select_machine();
+#if defined(CONFIG_MARU)
+ if (is_maru_machine(machine_class)) {
+ preallocated_ram_ptr = qemu_anon_ram_alloc(ram_size, NULL);
+ if (preallocated_ram_ptr) {
+ preallocated_ram_size = ram_size;
+ }
+ }
+#endif
+
set_memory_options(&ram_slots, &maxram_size, machine_class);
os_daemonize();
qemu_set_hw_version(machine_class->hw_version);
}
- /* Init CPU def lists, based on config
- * - Must be called after all the qemu_read_config_file() calls
- * - Must be called before list_cpus()
- * - Must be called before machine_class->init()
- */
- cpudef_init();
-
if (cpu_model && is_help_option(cpu_model)) {
list_cpus(stdout, &fprintf, cpu_model);
exit(0);
/* Open the logfile at this point and set the log mask if necessary.
*/
if (log_file) {
- qemu_set_log_filename(log_file);
+ qemu_set_log_filename(log_file, &error_fatal);
}
if (log_mask) {
data_dir[data_dir_idx++] = CONFIG_QEMU_DATADIR;
}
+ /* -L help lists the data directories and exits. */
+ if (list_data_dirs) {
+ for (i = 0; i < data_dir_idx; i++) {
+ printf("%s\n", data_dir[i]);
+ }
+ exit(0);
+ }
+
smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */
display_type = DT_COCOA;
#elif defined(CONFIG_VNC)
vnc_parse("localhost:0,to=99,id=default", &error_abort);
- show_vnc_port = 1;
#else
display_type = DT_NONE;
#endif
exit(1);
}
+#ifdef CONFIG_MARU
+# if defined(CONFIG_QT)
+ if (display_type == DT_MARU_QT_ONSCREEN) {
+ maru_early_qt5_display_init(true);
+ } else if (display_type == DT_MARU_QT_OFFSCREEN) {
+ maru_early_qt5_display_init(false);
+ }
+# endif
+#endif
+
page_size_init();
socket_init();
exit(1);
}
- configure_accelerator(current_machine);
-
if (qtest_chrdev) {
qtest_init(qtest_chrdev, qtest_log, &error_fatal);
}
cpu_ticks_init();
if (icount_opts) {
- if (kvm_enabled() || xen_enabled()) {
+ if (kvm_enabled() || xen_enabled() || hax_enabled()) {
error_report("-icount is not allowed with kvm or xen");
exit(1);
}
qemu_opts_del(icount_opts);
}
- /* clean up network at qemu process termination */
- atexit(&net_cleanup);
+ if (default_net) {
+ QemuOptsList *net = qemu_find_opts("net");
+ qemu_opts_set(net, NULL, "type", "nic", &error_abort);
+#ifdef CONFIG_SLIRP
+ qemu_opts_set(net, NULL, "type", "user", &error_abort);
+#endif
+ }
if (net_init_clients() < 0) {
exit(1);
exit (i == 1 ? 1 : 0);
}
- if (machine_class->compat_props) {
- GlobalProperty *p;
- for (i = 0; i < machine_class->compat_props->len; i++) {
- p = g_array_index(machine_class->compat_props, GlobalProperty *, i);
- qdev_prop_register_global(p);
- }
- }
- qemu_add_globals();
+ machine_register_compat_props(current_machine);
+
+ qemu_opts_foreach(qemu_find_opts("global"),
+ global_init_func, NULL, NULL);
/* This checkpoint is required by replay to separate prior clock
reading from the other reads, because timer polling functions query
current_machine->boot_order = boot_order;
current_machine->cpu_model = cpu_model;
+ configure_accelerator(current_machine);
+
+#if defined(CONFIG_MARU)
+ if (is_maru_machine(machine_class)) {
+ kernel_cmdline = qemu_opt_get(machine_opts, "append");
+ // Returned variable points different address from input variable.
+ kernel_cmdline = prepare_maru(kernel_cmdline);
+ qemu_opt_set(qemu_get_machine_opts(), "append",
+ kernel_cmdline, &error_abort);
+
+ current_machine->kernel_cmdline = (char *)kernel_cmdline;
+ if (display_type == DT_NONE) {
+ nodisplay = true;
+ }
+ }
+#endif
+
machine_class->init(current_machine);
realtime_init();
+ // TODO: Check about it...
audio_init();
cpu_synchronize_all_post_init();
exit(1);
}
+ if (hax_enabled()) {
+ hax_sync_vcpus();
+ }
+
/* init USB devices */
- if (usb_enabled()) {
+ if (machine_usb(current_machine)) {
if (foreach_device_config(DEV_USB, usb_parse) < 0)
exit(1);
}
}
rom_reset_order_override();
+#if defined(CONFIG_MARU)
+ if (is_maru_machine(machine_class)) {
+ prepare_maru_after_device_init();
+ }
+#endif
+#ifdef CONFIG_VIGS
+ // To support legacy VIGS options
+ if (vigs_enabled) {
+ PCIBus *pci_bus = (PCIBus *) object_resolve_path_type("", TYPE_PCI_BUS, NULL);
+ PCIDevice *pci_dev = pci_create(pci_bus, -1, "vigs");
+ if (vigs_backend) {
+ qdev_prop_set_string(&pci_dev->qdev, "backend", vigs_backend);
+ } else {
+ qdev_prop_set_string(&pci_dev->qdev, "backend", "gl");
+ }
+ qdev_prop_set_string(&pci_dev->qdev, "wsi", "wsi0");
+ qdev_init_nofail(&pci_dev->qdev);
+ }
+#endif
+#ifdef CONFIG_YAGL
+ // To support legacy YaGL options
+ if (yagl_enabled) {
+ PCIBus *pci_bus = (PCIBus *) object_resolve_path_type("", TYPE_PCI_BUS, NULL);
+ PCIDevice *pci_dev = pci_create(pci_bus, -1, "yagl");
+ if (vigs_enabled) {
+ qdev_prop_set_string(&pci_dev->qdev, "wsi", "wsi0");
+ }
+ qdev_init_nofail(&pci_dev->qdev);
+ }
+#endif
+
/* Did we create any drives that we failed to create a device for? */
drive_check_orphaned();
- net_check_clients();
+ /* Don't warn about the default network setup that you get if
+ * no command line -net or -netdev options are specified. There
+ * are two cases that we would otherwise complain about:
+ * (1) board doesn't support a NIC but the implicit "-net nic"
+ * requested one
+ * (2) CONFIG_SLIRP not set, in which case the implicit "-net nic"
+ * sets up a nic that isn't connected to anything.
+ */
+ if (!default_net) {
+ net_check_clients();
+ }
+
if (boot_once) {
qemu_boot_set(boot_once, &error_fatal);
case DT_GTK:
gtk_display_init(ds, full_screen, grab_on_hover);
break;
+#if defined(CONFIG_MARU)
+ #if defined(CONFIG_QT)
+ case DT_MARU_QT_ONSCREEN:
+ case DT_MARU_QT_OFFSCREEN:
+ if (!is_maru_machine(machine_class)) {
+ error_report("maru_qt can not work"
+ " without maru machine");
+ exit(1);
+ }
+ maru_qt5_display_init(ds, full_screen);
+ break;
+ #endif
+#endif
default:
break;
}
os_setup_signal_handling();
/* init remote displays */
+#ifdef CONFIG_VNC
qemu_opts_foreach(qemu_find_opts("vnc"),
vnc_init_func, NULL, NULL);
- if (show_vnc_port) {
- char *ret = vnc_display_local_addr("default");
- printf("VNC server running on '%s'\n", ret);
- g_free(ret);
- }
+#endif
if (using_spice) {
qemu_spice_display_init();
os_setup_post();
+#ifdef CONFIG_MARU
+ enable_print_backtrace_at_normal_exit();
+#endif
+ trace_init_vcpu_events();
main_loop();
replay_disable_events();
tpm_cleanup();
#endif
+ /* vhost-user must be cleaned up before chardevs. */
+ net_cleanup();
+ audio_cleanup();
+ monitor_cleanup();
+ qemu_chr_cleanup();
+
+#if defined(CONFIG_MARU) && defined(CONFIG_QT)
+ switch (display_type) {
+ case DT_MARU_QT_ONSCREEN:
+ case DT_MARU_QT_OFFSCREEN:
+ maru_qt5_display_fini();
+ break;
+ default:
+ break;
+ }
+#endif
+
return 0;
}