From: SeokYeon Hwang Date: Mon, 21 Dec 2015 09:00:30 +0000 (+0900) Subject: Merge tag 'v2.5.0' into tizen_3.0_qemu_2.5 X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.2~121^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7864519e39b0f45ebcb4be913439a03d5a962b70;p=sdk%2Femulator%2Fqemu.git Merge tag 'v2.5.0' into tizen_3.0_qemu_2.5 v2.5.0 release Signed-off-by: SeokYeon Hwang --- 7864519e39b0f45ebcb4be913439a03d5a962b70 diff --cc .gitignore index bd893c6ea0,88a80ff4a5..65fa775533 --- a/.gitignore +++ b/.gitignore @@@ -58,10 -61,9 +61,11 @@@ *.cp *.dvi *.exe + *.msi *.dll *.so +*.dylib +/.DS_Store *.mo *.fn *.ky diff --cc Makefile.target index edb2156634,962d0045ff..4cb691ee74 --- a/Makefile.target +++ b/Makefile.target @@@ -160,14 -154,8 +163,14 @@@ els obj-y += hw/$(TARGET_BASE_ARCH)/ endif - GENERATED_HEADERS += hmp-commands.h qmp-commands-old.h + GENERATED_HEADERS += hmp-commands.h hmp-commands-info.h qmp-commands-old.h +# Makefile for TIZEN-maru +ifdef CONFIG_MARU +obj-y += tizen/src/ +endif +## + endif # CONFIG_SOFTMMU # Workaround for http://gcc.gnu.org/PR55489, see configure. diff --cc configure index c2902b115e,b9552fda6f..f6f3b1d0e5 --- a/configure +++ b/configure @@@ -339,27 -344,8 +345,28 @@@ libssh2=" vhdx="" numa="" tcmalloc="no" + jemalloc="no" +yagl="no" +yagl_stats="no" +glx="" +vigs="no" +libtizenusb="no" + +# for TIZEN-maru +maru="no" +winver="0x501" +java_ui="no" +shm="no" +libav="" +libpng="no" +dxva2="" +vaapi="" +qt="no" +qtabi="5.0" +extension_path="" +# + # parse CC options first for opt do optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'` @@@ -740,9 -724,11 +747,11 @@@ f if test "$mingw32" = "yes" ; then EXESUF=".exe" DSOSUF=".dll" - QEMU_CFLAGS="-DWIN32_LEAN_AND_MEAN -DWINVER=0x501 $QEMU_CFLAGS" + QEMU_CFLAGS="-DWIN32_LEAN_AND_MEAN $QEMU_CFLAGS" # enable C99/POSIX format strings (needs mingw32-runtime 3.15 or later) QEMU_CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $QEMU_CFLAGS" + # MinGW needs -mthreads for TLS and macro _MT. + QEMU_CFLAGS="-mthreads $QEMU_CFLAGS" LIBS="-lwinmm -lws2_32 -liphlpapi $LIBS" write_c_skeleton; if compile_prog "" "-liberty" ; then @@@ -1198,36 -1165,10 +1214,40 @@@ for opt d ;; --enable-tcmalloc) tcmalloc="yes" ;; + --disable-jemalloc) jemalloc="no" + ;; + --enable-jemalloc) jemalloc="yes" + ;; +# for TIZEN-maru + --enable-maru) maru="yes" + ;; + --winver=*) winver="$optarg" + ;; + --enable-java-ui) java_ui="yes" + ;; + --enable-shm) shm="yes" + ;; + --enable-libav) libav="yes" + ;; + --disable-libav) libav="no" + ;; + --enable-libpng) libpng="yes" + ;; + --enable-dxva2) dxva2="yes" + ;; + --disable-dxva2) dxva2="no" + ;; + --enable-vaapi) vaapi="yes" + ;; + --disable-vaapi) vaapi="no" + ;; + --disable-qt) qt="no" + ;; + --enable-qt) qt="yes" + ;; + --extension-path=*) extension_path="$optarg" + ;; +# *) echo "ERROR: unknown option $opt" echo "Try '$0 --help' for more information" @@@ -1453,25 -1390,7 +1469,26 @@@ disabled with --disable-FEATURE, defaul vhdx support for the Microsoft VHDX image format numa libnuma support tcmalloc tcmalloc support + jemalloc jemalloc support + qt Qt5 UI + hax HAX acceleration support + yagl YaGL device + yagl-stats YaGL stats + vigs VIGS device + +TIZEN-maru options: + --enable-maru enable maru board + --winver=WINVER set WINVER + --enable-java-ui enable java UI + --enable-shm enable shared memory for framebuffer + --enable-libav enable libav library + --disable-libav disable libav library + --enable-libpng enable png library + --enable-dxva2 enable dxva2 support + --disable-dxva2 disable dxva2 support + --ensable-vaapi enable vaapi support + --disable-vaapi disable vaapi support + --extension-path=PATH set extension path NOTE: The object files are built at the place where configure is launched EOF @@@ -4931,31 -4842,8 +5184,32 @@@ echo "snappy support $snappy echo "bzip2 support $bzip2" echo "NUMA host support $numa" echo "tcmalloc support $tcmalloc" + echo "jemalloc support $jemalloc" +echo "Qt support $qt" +echo "HAX support $hax" +echo "YaGL support $yagl" +echo "YaGL stats $yagl_stats" +echo "VIGS support $vigs" + +# for TIZEN-maru +if test "$maru" = "yes"; then +echo "TIZEN-maru options:" +echo "maru enabled $maru" + if test "$mingw32" = "yes"; then +echo "WINVER $winver" + fi +echo "Java UI enabled $java_ui" +echo "shared framebuffer enabled $shm" +echo "libav support $libav" +echo "libpng support $libpng" +echo "DXVA2 support $dxva2" +echo "vaapi support $vaapi" +echo "libtizenusb support $libtizenusb" +echo "extension path $extension_path" +fi +# + if test "$sdl_too_old" = "yes"; then echo "-> Your SDL version is too old - please upgrade to have SDL support" fi @@@ -5246,10 -5141,11 +5507,15 @@@ if test "$vte" = "yes" ; the echo "CONFIG_VTE=y" >> $config_host_mak echo "VTE_CFLAGS=$vte_cflags" >> $config_host_mak fi + if test "$virglrenderer" = "yes" ; then + echo "CONFIG_VIRGL=y" >> $config_host_mak + echo "VIRGL_CFLAGS=$virgl_cflags" >> $config_host_mak + echo "VIRGL_LIBS=$virgl_libs" >> $config_host_mak + fi +if test "$qt" = "yes" ; then + echo "CONFIG_QT=y" >> $config_host_mak + echo "QT_CFLAGS=$qt_cflags" >> $config_host_mak +fi if test "$xen" = "yes" ; then echo "CONFIG_XEN_BACKEND=y" >> $config_host_mak echo "CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version" >> $config_host_mak @@@ -5307,32 -5203,6 +5573,28 @@@ if test "$spice" = "yes" ; the echo "CONFIG_SPICE=y" >> $config_host_mak fi - if test "$efence" = "yes" ; then - echo "CONFIG_EFENCE=y" >> $config_host_mak - fi - +if test "$yagl" = "yes" ; then + echo "CONFIG_YAGL=y" >> $config_host_mak + if test "$linux" = "yes" ; then + LIBS="-lGLU -ldl $LIBS" + elif test "$mingw32" = "yes" ; then + LIBS="-lopengl32 -lglu32 $LIBS" + elif test "$darwin" = "yes" ; then + LIBS="-framework OpenGL -framework AGL -framework GLUT $LIBS" + else + echo "ERROR: YaGL is not available on $targetos" + exit 1 + fi +fi + +if test "$yagl_stats" = "yes" ; then + echo "CONFIG_YAGL_STATS=y" >> $config_host_mak +fi + +if test "$vigs" = "yes" ; then + echo "CONFIG_VIGS=y" >> $config_host_mak +fi + if test "$smartcard" = "yes" ; then echo "CONFIG_SMARTCARD=y" >> $config_host_mak fi @@@ -5896,47 -5745,16 +6157,24 @@@ if test "$target_bsd_user" = "yes" ; th echo "CONFIG_BSD_USER=y" >> $config_target_mak fi - # generate QEMU_CFLAGS/LDFLAGS for targets - - cflags="" - ldflags="" - - if test "$tcg_interpreter" = "yes"; then - includes="-I\$(SRC_PATH)/tcg/tci $includes" - elif test "$ARCH" = "sparc64" ; then - includes="-I\$(SRC_PATH)/tcg/sparc $includes" - elif test "$ARCH" = "s390x" ; then - includes="-I\$(SRC_PATH)/tcg/s390 $includes" - elif test "$ARCH" = "x86_64" ; then - includes="-I\$(SRC_PATH)/tcg/i386 $includes" - else - includes="-I\$(SRC_PATH)/tcg/\$(ARCH) $includes" - fi - includes="-I\$(SRC_PATH)/tcg $includes" - - if test "$linux" = "yes" ; then - includes="-I\$(SRC_PATH)/linux-headers $includes" - fi - - if test "$target_user_only" = "yes" ; then - libdis_config_mak=libdis-user/config.mak - else - libdis_config_mak=libdis/config.mak - fi - - if test "$efence" = "yes" ; then - echo "CONFIG_BUILD_WITH_EFENCE=y" >> $config_target_mak - echo "LIBS+=-lefence" >> $config_target_mak - fi - +if test "$yagl" = "yes" ; then + echo "CONFIG_BUILD_YAGL=y" >> $config_target_mak +fi + +if test "$vigs" = "yes" ; then + echo "CONFIG_BUILD_VIGS=y" >> $config_target_mak +fi + + # generate QEMU_CFLAGS/LDFLAGS for targets + + cflags="" + ldflags="" + + disas_config() { + echo "CONFIG_${1}_DIS=y" >> $config_target_mak + echo "CONFIG_${1}_DIS=y" >> config-all-disas.mak + } + for i in $ARCH $TARGET_BASE_ARCH ; do case "$i" in alpha) diff --cc cpu-exec.c index 81d47a1822,c88d0ffdcd..62eb0eddb2 --- a/cpu-exec.c +++ b/cpu-exec.c @@@ -25,10 -25,12 +25,13 @@@ #include "sysemu/qtest.h" #include "qemu/timer.h" #include "exec/address-spaces.h" - #include "exec/memory-internal.h" #include "qemu/rcu.h" #include "exec/tb-hash.h" +#include "sysemu/hax.h" + #if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY) + #include "hw/i386/apic.h" + #endif + #include "sysemu/replay.h" /* -icount align implementation. */ @@@ -422,17 -407,24 +408,29 @@@ int cpu_exec(CPUState *cpu cpu->exception_index = -1; break; #else - cc->do_interrupt(cpu); - cpu->exception_index = -1; + if (replay_exception()) { + cc->do_interrupt(cpu); + cpu->exception_index = -1; + } else if (!replay_has_interrupt()) { + /* give a chance to iothread in replay mode */ + ret = EXCP_INTERRUPT; + break; + } #endif } + } else if (replay_has_exception() + && cpu->icount_decr.u16.low + cpu->icount_extra == 0) { + /* try to cause an exception pending in the log */ + cpu_exec_nocache(cpu, 1, tb_find_fast(cpu), true); + ret = -1; + break; } +#ifdef CONFIG_HAX + if (hax_enabled() && !hax_vcpu_exec(cpu)) + longjmp(cpu->jmp_env, 1); +#endif + next_tb = 0; /* force lookup of first TB */ for(;;) { interrupt_request = cpu->interrupt_request; @@@ -560,11 -561,6 +567,10 @@@ break; } } - cpu->current_tb = NULL; +#ifdef CONFIG_HAX + if (hax_enabled() && hax_stop_emulation(cpu)) + cpu_loop_exit(cpu); +#endif /* Try to align the host and virtual clocks if the guest is in advance */ align_clocks(&sc, cpu); diff --cc cpus.c index 5389f24356,43676fa1f3..53a76f9fbc --- a/cpus.c +++ b/cpus.c @@@ -1139,46 -1164,22 +1213,77 @@@ static void qemu_cpu_kick_thread(CPUSta fprintf(stderr, "qemu:%s: %s", __func__, strerror(err)); exit(1); } - /* The cpu thread cannot catch it reliably when shutdown the guest on Mac. - * We can double check it and resend it - */ + - #ifdef CONFIG_DARWIN - if (!exit_request) - cpu_signal(0); ++# ifdef CONFIG_DARWIN ++ /* The cpu thread cannot catch it reliably when shutdown the guest on Mac. ++ * We can double check it and resend it ++ */ ++ if (!exit_request) { ++ // FIXME: check it soon ++// cpu_signal(0); ++ } + - if (hax_enabled() && hax_ug_platform()) - cpu->exit_request = 1; - #endif ++ if (hax_enabled() && hax_ug_platform()) { ++ cpu->exit_request = 1; ++ } ++# endif #else /* _WIN32 */ ++# ifndef CONFIG_HAX + abort(); ++# else ++ // FIXME: check it soon ++#if 0 + if (!qemu_cpu_is_self(cpu)) { + CONTEXT tcgContext; + + if (SuspendThread(cpu->hThread) == (DWORD)-1) { + fprintf(stderr, "qemu:%s: GetLastError:%lu\n", __func__, + GetLastError()); + exit(1); + } + + /* On multi-core systems, we are not sure that the thread is actually + * suspended until we can get the context. + */ + tcgContext.ContextFlags = CONTEXT_CONTROL; + while (GetThreadContext(cpu->hThread, &tcgContext) != 0) { + continue; + } + - cpu_signal(0); - if(hax_enabled() && hax_ug_platform()) - cpu->exit_request = 1; ++// cpu_signal(0); + ++ if(hax_enabled() && hax_ug_platform()) { ++ cpu->exit_request = 1; ++ } else { ++ abort(); ++ } + if (ResumeThread(cpu->hThread) == (DWORD)-1) { + fprintf(stderr, "qemu:%s: GetLastError:%lu\n", __func__, + GetLastError()); + exit(1); + } + } +#endif ++ if (!qemu_cpu_is_self(cpu)) { ++ if(hax_enabled() && hax_ug_platform()) { ++ cpu->exit_request = 1; ++ } ++ } ++# endif + #endif + } + + static void qemu_cpu_kick_no_halt(void) + { + CPUState *cpu; + /* Ensure whatever caused the exit has reached the CPU threads before + * writing exit_request. + */ + atomic_mb_set(&exit_request, 1); + cpu = atomic_mb_read(&tcg_current_cpu); + if (cpu) { + cpu_exit(cpu); + } } void qemu_cpu_kick(CPUState *cpu) @@@ -1312,11 -1306,9 +1410,14 @@@ void resume_all_vcpus(void static void qemu_tcg_init_vcpu(CPUState *cpu) { - #ifdef CONFIG_HAX - if (hax_enabled()) ++#ifdef CONFIG_HAX ++ if (hax_enabled()) { + hax_init_vcpu(cpu); ++ } +#endif char thread_name[VCPU_THREAD_NAME_SIZE]; + static QemuCond *tcg_halt_cond; + static QemuThread *tcg_cpu_thread; tcg_cpu_address_space_init(cpu, cpu->as); @@@ -1343,29 -1335,6 +1444,29 @@@ } } +#ifdef CONFIG_HAX +static void qemu_hax_start_vcpu(CPUState *cpu) +{ + char thread_name[VCPU_THREAD_NAME_SIZE]; + + cpu->thread = g_malloc0(sizeof(QemuThread)); + cpu->halt_cond = g_malloc0(sizeof(QemuCond)); + qemu_cond_init(cpu->halt_cond); + + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HAX", + cpu->cpu_index); + + qemu_thread_create(cpu->thread, thread_name, qemu_hax_cpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); +#ifdef _WIN32 - cpu->hThread = qemu_thread_get_handle(cpu->thread); ++ cpu->hThread = qemu_thread_get_handle(cpu->thread); +#endif + while (!cpu->created) { + qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); + } +} +#endif + static void qemu_kvm_start_vcpu(CPUState *cpu) { char thread_name[VCPU_THREAD_NAME_SIZE]; diff --cc hw/9pfs/cofile.c index 4a95637840,7cb55ee93a..3d3688b053 --- a/hw/9pfs/cofile.c +++ b/hw/9pfs/cofile.c @@@ -14,17 -14,9 +14,17 @@@ #include "fsdev/qemu-fsdev.h" #include "qemu/thread.h" - #include "block/coroutine.h" + #include "qemu/coroutine.h" #include "virtio-9p-coth.h" +#ifdef CONFIG_MARU +#ifdef CONFIG_WIN32 +#ifdef fsync +#undef fsync +#endif +#endif +#endif + int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode, V9fsStatDotl *v9stat) { diff --cc hw/9pfs/virtio-9p-device.c index 70da7dfdda,b42d3b30a0..6baa5f9d5c --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@@ -136,9 -134,9 +142,10 @@@ static void virtio_9p_device_realize(De error_setg(errp, "share path %s is not a directory", fse->path); goto out; } + v9fs_path_free(&path); + register_savevm(dev, "virtio-9p", -1, 1, virtio_9p_save, virtio_9p_load, s); return; out: g_free(s->ctx.fs_root); diff --cc hw/Makefile.objs index f00c66e0a7,7e7c241104..ecb2b9696d --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@@ -31,8 -31,7 +31,9 @@@ devices-dirs-$(CONFIG_VIRTIO) += virtio devices-dirs-$(CONFIG_SOFTMMU) += watchdog/ devices-dirs-$(CONFIG_SOFTMMU) += xen/ devices-dirs-$(CONFIG_MEM_HOTPLUG) += mem/ + devices-dirs-$(CONFIG_SMBIOS) += smbios/ +devices-dirs-$(CONFIG_BUILD_VIGS) += yagl/ +devices-dirs-$(CONFIG_BUILD_VIGS) += vigs/ devices-dirs-y += core/ common-obj-y += $(devices-dirs-y) obj-y += $(devices-dirs-y) diff --cc hw/arm/Makefile.objs index 4f0aa46805,2195b60fac..7b7558f91e --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@@ -1,34 -1,6 +1,34 @@@ +obj-y = arm_pic.o +obj-y += arm_boot.o +obj-y += zynq_slcr.o +obj-y += arm_gic.o arm_gic_common.o +obj-y += realview_gic.o arm_sysctl.o arm11mpcore.o a9mpcore.o +obj-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o +obj-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o +obj-y += exynos4210_pmu.o exynos4210_mct.o exynos4210_fimd.o +obj-y += exynos4210_rtc.o exynos4210_i2c.o +obj-y += exynos4210_cmu.o exynos4210_g3d.o +obj-y += exynos4210_i2s.o exynos4210_audio.o +obj-y += arm_mptimer.o a15mpcore.o +obj-y += armv7m.o armv7m_nvic.o stellaris_enet.o +obj-y += pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o +obj-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o +obj-y += zaurus.o ide/microdrive.o tc6393xb.o +obj-y += omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o \ + omap_gpio.o omap_intc.o omap_uart.o +obj-y += omap2.o omap_dss.o soc_dma.o omap_gptimer.o omap_synctimer.o \ + omap_gpmc.o omap_sdrc.o omap_spi.o omap_tap.o omap_l4.o +obj-y += tsc210x.o +obj-y += blizzard.o onenand.o cbus.o tusb6010.o usb/hcd-musb.o +obj-y += mst_fpga.o +obj-y += bitbang_i2c.o marvell_88w8618_audio.o +obj-y += framebuffer.o +obj-y += strongarm.o +obj-y += imx_serial.o imx_ccm.o imx_timer.o imx_avic.o +obj-$(CONFIG_FDT) += ../device_tree.o obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o obj-$(CONFIG_DIGIC) += digic_boards.o - obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o + obj-y += integratorcp.o mainstone.o musicpal.o nseries.o obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o obj-$(CONFIG_ACPI) += virt-acpi-build.o diff --cc hw/i386/pc_piix.c index 61c4a2466f,2e41efe1b4..de01fda284 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@@ -304,15 -294,13 +294,22 @@@ static void pc_init1(MachineState *mach } } +#ifdef CONFIG_MARU +void maru_pc_init(MachineState *machine); + +void maru_pc_init(MachineState *machine) +{ - pc_init1(machine); ++ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, TYPE_I440FX_PCI_DEVICE); +} +#endif + + /* Looking for a pc_compat_2_4() function? It doesn't exist. + * pc_compat_*() functions that run on machine-init time and + * change global QEMU state are deprecated. Please don't create + * one, and implement any pc-*-2.4 (and newer) compat code in + * HW_COMPAT_*, PC_COMPAT_*, or * pc_*_machine_options(). + */ + static void pc_compat_2_3(MachineState *machine) { PCMachineState *pcms = PC_MACHINE(machine); diff --cc hw/intc/apic_common.c index 7aa1688682,ad959c4e77..afdfde48b6 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@@ -307,13 -306,7 +306,8 @@@ static void apic_common_realize(DeviceS info = APIC_COMMON_GET_CLASS(s); info->realize(dev, errp); - if (!mmio_registered) { - ICCBus *b = ICC_BUS(qdev_get_parent_bus(dev)); - memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory); - mmio_registered = true; - } +#ifndef CONFIG_MARU /* Note: We need at least 1M to map the VAPIC option ROM */ if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK && ram_size >= 1024 * 1024) { diff --cc include/qom/cpu.h index 595e91665b,51a1323ead..dff6b1e538 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@@ -322,12 -333,7 +337,12 @@@ struct CPUState offset from AREG0. Leave this field at the end so as to make the (absolute value) offset as small as possible. This reduces code size, especially for hosts without large memory offsets. */ - volatile sig_atomic_t tcg_exit_req; + uint32_t tcg_exit_req; + +#ifdef CONFIG_HAX + int hax_vcpu_dirty; + struct hax_vcpu_state *hax_vcpu; +#endif }; QTAILQ_HEAD(CPUTailQ, CPUState); diff --cc net/tap.c index 079d732d78,85c4142d15..6642bc42ba --- a/net/tap.c +++ b/net/tap.c @@@ -787,10 -728,11 +787,10 @@@ int net_init_tap(const NetClientOption const char *vhostfdname; char ifname[128]; - assert(opts->kind == NET_CLIENT_OPTIONS_KIND_TAP); - tap = opts->tap; + assert(opts->type == NET_CLIENT_OPTIONS_KIND_TAP); + tap = opts->u.tap; queues = tap->has_queues ? tap->queues : 1; vhostfdname = tap->has_vhostfd ? tap->vhostfd : NULL; - /* QEMU vlans does not support multiqueue tap, in this case peer is set. * For -netdev, peer is always NULL. */ if (peer && (tap->has_queues || tap->has_fds || tap->has_vhostfds)) { diff --cc qemu-char.c index 2d3e659235,2969c44e84..d2a32fdbb8 --- a/qemu-char.c +++ b/qemu-char.c @@@ -1900,14 -1902,14 +1902,14 @@@ static int win_chr_init(CharDriverStat } s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL); if (!s->hrecv) { - fprintf(stderr, "Failed CreateEvent\n"); + error_setg(errp, "Failed CreateEvent"); goto fail; } - - s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, + s->hcom = CreateFile(filename, + GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (s->hcom == INVALID_HANDLE_VALUE) { - fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError()); + error_setg(errp, "Failed CreateFile (%lu)", GetLastError()); s->hcom = NULL; goto fail; } diff --cc target-i386/translate.c index 89e08d4e02,a3dd167a9b..f0abc1a672 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@@ -8002,40 -7979,26 +7980,34 @@@ void gen_intermediate_code(CPUX86State gen_tb_start(tb); for(;;) { - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) { - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { - if (bp->pc == pc_ptr && - !((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) { - gen_debug(dc, pc_ptr - dc->cs_base); - goto done_generating; - } - } - } - if (search_pc) { - j = tcg_op_buf_count(); - if (lj < j) { - lj++; - while (lj < j) - tcg_ctx.gen_opc_instr_start[lj++] = 0; - } - tcg_ctx.gen_opc_pc[lj] = pc_ptr; - gen_opc_cc_op[lj] = dc->cc_op; - tcg_ctx.gen_opc_instr_start[lj] = 1; - tcg_ctx.gen_opc_icount[lj] = num_insns; - } - if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) + tcg_gen_insn_start(pc_ptr, dc->cc_op); + num_insns++; + + /* If RF is set, suppress an internally generated breakpoint. */ + if (unlikely(cpu_breakpoint_test(cs, pc_ptr, + tb->flags & HF_RF_MASK + ? BP_GDB : BP_ANY))) { + gen_debug(dc, pc_ptr - dc->cs_base); + /* The address covered by the breakpoint must be included in + [tb->pc, tb->pc + tb->size) in order to for it to be + properly cleared -- thus we increment the PC here so that + the logic setting tb->size below does the right thing. */ + pc_ptr += 1; + goto done_generating; + } + if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) { gen_io_start(); + } pc_ptr = disas_insn(env, dc, pc_ptr); - num_insns++; +#ifdef CONFIG_HAX + if (hax_enabled() && hax_stop_translate(cs)) + { + gen_jmp_im(pc_ptr - dc->cs_base); + gen_eob(dc); + break; + } +#endif /* stop translation if indicated */ if (dc->is_jmp) break; diff --cc target-s390x/kvm.c index 6d1f284da0,75a0e5d1c3..0d8b0591f3 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@@ -2077,11 -2084,8 +2084,11 @@@ void kvm_s390_crw_mchk(void struct kvm_s390_irq irq = { .type = KVM_S390_MCHK, .u.mchk.cr14 = 1 << 28, - .u.mchk.mcic = 0x00400f1d40330000ULL, + .u.mchk.mcic = build_channel_report_mcic(), }; + if (kvm_check_extension(kvm_state, KVM_CAP_S390_VECTOR_REGISTERS)) { + irq.u.mchk.mcic |= 0x0000004000000000ULL; + } kvm_s390_floating_interrupt(&irq); } diff --cc tizen/src/emulator.c index 6b037c0ef6,0000000000..e5d7ab9263 mode 100644,000000..100644 --- a/tizen/src/emulator.c +++ b/tizen/src/emulator.c @@@ -1,428 -1,0 +1,438 @@@ +/* + * Emulator + * + * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * SeokYeon Hwang + * MunKyu Im + * GiWoong Kim + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * Contributors: + * - S-Core Co., Ltd + * + */ + +#include +#include +#include + +#include "qemu/config-file.h" +#include "qemu/sockets.h" +#include "qemu/error-report.h" + +#include "build_info.h" +#include "emulator.h" +#include "emul_state.h" +#include "emulator_options.h" +#include "util/error_handler.h" +#include "util/osutil.h" +#include "util/sdb.h" +#include "util/new_debug_ch.h" +#include "ecs/ecs.h" +#include "util/device_hotplug.h" +#include "util/exported_strings.h" + +#ifdef CONFIG_JAVA_UI +#include "skin/maruskin_server.h" +#include "skin/maruskin_client.h" +#endif + +#ifdef CONFIG_QT +#include +#endif + +#ifdef CONFIG_SDL +#include +#endif + +#ifdef CONFIG_DARWIN +#include "ns_event.h" +int thread_running = 1; /* Check if we need exit main */ +#endif + +DECLARE_DEBUG_CHANNEL(main); + +#define ARGS_LIMIT 128 +char *maru_kernel_cmdline; + +char tizen_target_path[PATH_MAX]; + +#if defined(CONFIG_JAVA_UI) +int _skin_argc; +char **_skin_argv; +#endif +int _qemu_argc; +char **_qemu_argv; + +void emulator_add_exit_notifier(Notifier *notify) +{ + qemu_add_exit_notifier(notify); +} + +#if defined(CONFIG_JAVA_UI) +static void construct_main_window(bool skin_enabled, + int skin_argc, char *skin_argv[], + int qemu_argc, char *qemu_argv[]) +{ + LOG_INFO("construct main window\n"); + + start_skin_server(skin_argc, skin_argv, qemu_argc, qemu_argv); + + set_emul_caps_lock_state(0); + set_emul_num_lock_state(0); + + set_skin_enabled(skin_enabled); + + /* do not start skin client process if skin is disabled*/ + /* the next line checks for debugging and etc.. */ + if (skin_enabled) { + if (0 > start_skin_client(skin_argc, skin_argv)) { + error_report(FAILED_TO_INITIALIZE_SKIN); + exit(1); + } + } +} +#endif + +static void emulator_notify_exit(Notifier *notifier, void *data) +{ + int i; + for (i = 0; i < _qemu_argc; ++i) { + g_free(_qemu_argv[i]); + } +#if defined(CONFIG_JAVA_UI) + for (i = 0; i < _skin_argc; ++i) { + g_free(_skin_argv[i]); + } +#endif + reset_variables(); + + LOG_INFO("Exit emulator...\n"); +} + +static Notifier emulator_exit = { .notify = emulator_notify_exit }; + +static void* run_timed_shutdown_thread(void* args) +{ + send_shutdown_request(ECS_SYSTEM_ACTION_FORCE_CLOSE); + + const int sleep_interval_time = 1000; /* milli-seconds */ + const int timeout_for_shutdown = (uintptr_t)args; + + int i; + for (i = 0; i < timeout_for_shutdown; i++) { +#ifdef CONFIG_WIN32 + Sleep(sleep_interval_time); +#else + usleep(sleep_interval_time * 1000); +#endif + /* do not use logger to help user see log in console */ + fprintf(stdout, "Wait for shutdown qemu...%d\n", (i + 1)); + } + + LOG_INFO("Shutdown qemu !!!\n"); + + qemu_system_shutdown_request(); + + return NULL; +} + +void qemu_system_graceful_shutdown_request(unsigned int sec) +{ + static bool requested_shutdown_qemu_gracefully = false; + + if (!requested_shutdown_qemu_gracefully) { + requested_shutdown_qemu_gracefully = true; + + LOG_INFO("shutdown_qemu_gracefully was called\n"); + QemuThread thread_id; + qemu_thread_create(&thread_id, "shutdown_thread", + run_timed_shutdown_thread, (void *)(uintptr_t)sec, + QEMU_THREAD_DETACHED); + } else { + LOG_INFO("shutdown_qemu_gracefully was called twice\n"); ++ + qemu_system_shutdown_request(); ++ ++ // FIXME ++#if 0 ++ /* Cannot call qemu_system_shutdown_request directly because ++ * we are in a signal handler. ++ */ ++ shutdown_requested = 1; ++ qemu_notify_event(); ++#endif + } +} + +void print_system_info(void) +{ + static bool is_printed = false; + + if (is_printed) { + return; + } + + LOG_INFO("* Board name : %s\n", build_version); + LOG_INFO("* Package %s\n", pkginfo_version); + LOG_INFO("* Package %s\n", pkginfo_maintainer); + LOG_INFO("* Git Head : %s\n", pkginfo_githead); + LOG_INFO("* %s\n", latest_gittag); + LOG_INFO("* User name : %s\n", g_get_real_name()); + LOG_INFO("* Host name : %s\n", g_get_host_name()); + + /* time stamp */ + LOG_INFO("* Build date : %s\n", build_date); + + qemu_timeval tval = { 0, }; + if (qemu_gettimeofday(&tval) == 0) { + char timeinfo[64] = {0, }; + + time_t ti = tval.tv_sec; + struct tm *tm_time = localtime(&ti); + strftime(timeinfo, sizeof(timeinfo), "%Y-%m-%d %H:%M:%S", tm_time); + LOG_INFO("* Current time : %s\n", timeinfo); + } + +#ifdef CONFIG_QT + LOG_INFO("* Host Qt version : %s\n", qt5_get_version()); +#endif + +#ifdef CONFIG_SDL + /* Gets the version of the dynamically linked SDL library */ + const SDL_version *sdl_linked; +# if (SDL_MAJOR_VERSION == 2) + SDL_version linked; + SDL_GetVersion(&linked); + sdl_linked = &linked; +# else + sdl_linked = SDL_Linked_Version(); +# endif + LOG_INFO("* Host SDL version : %d.%d.%d\n", + sdl_linked->major, + sdl_linked->minor, + sdl_linked->patch); +#endif + + print_system_info_os(); + + is_printed = true; +} + +static void print_options_info(void) +{ + int i; + + fprintf(stdout, "qemu args: =========================================\n"); + for (i = 0; i < _qemu_argc; ++i) { + fprintf(stdout, "\"%s\" ", _qemu_argv[i]); + } + fprintf(stdout, "\n====================================================\n"); + +#if defined(CONFIG_JAVA_UI) + if (_skin_argc > 0) { + fprintf(stdout, "skin args: =========================================\n"); + for (i = 0; i < _skin_argc; ++i) { + fprintf(stdout, "%s ", _skin_argv[i]); + } + fprintf(stdout, "\n====================================================\n"); + } +#endif + + fflush(stdout); +} + +const char *prepare_maru(const char * const kernel_cmdline) +{ + // FIXME: we needs modified kernel commandline now. + // So we need independent kernel to use QEMU linux bootloader. + // TODO: we should remove kernel commandline dependencies. + const char *kernel_filename = + qemu_opt_get(qemu_get_machine_opts(), "kernel"); + if (!kernel_filename) { + error_report("Independent kernel must be specified!"); + exit(1); + } + + print_system_info(); + + init_emul_state(); + + // We should call socket_init() here since this function called + // before calling socket_init() in "vl.c". + // It is safe to call socket_init() multiple times. + socket_init(); + init_vm_base_port(); + + // Assemble new kernel cmdline + maru_kernel_cmdline = g_strdup_printf("%s sdb_port=%d, " + "vm_resolution=%dx%d", kernel_cmdline, get_emul_vm_base_port(), + get_display_resolution_width(), get_display_resolution_height()); + set_emul_host_ip(maru_kernel_cmdline); + LOG_INFO("kernel commandline : %s\n", maru_kernel_cmdline); + + return maru_kernel_cmdline; +} + +void prepare_maru_after_device_init(void) +{ + make_vm_lock_os(); + init_device_hotplug(); + start_ecs(); + init_sdb(get_emul_vm_base_port()); + + // Only for intent logging of essential information + get_vm_name(); + get_vm_data_path(); +} + +#if defined(CONFIG_JAVA_UI) +void start_skin(bool skin_enabled) +{ + LOG_INFO("Start skin\n"); + + construct_main_window(skin_enabled, + _skin_argc, _skin_argv, _qemu_argc, _qemu_argv); +} +#endif + +#ifdef CONFIG_COCOA +int cocoa_main(int argc, const char * argv[]); +#else +int qemu_main(int argc, char **argv, char **envp); +#endif + +static int emulator_main(int argc, char *argv[], char **envp) +{ + int c = 0; + int qemu_arg_index = 0; + + _qemu_argv = g_malloc(sizeof(char*) * ARGS_LIMIT); +#if defined(CONFIG_JAVA_UI) + _skin_argv = g_malloc(sizeof(char*) * ARGS_LIMIT); +#endif + + // parse arguments + // prevent the error message for undefined options + opterr = 0; + + while (c != -1) { + static struct option long_options[] = { + {"conf", required_argument, 0, 'c' }, + {"qemu", required_argument, 0, 'q' }, + {0, 0, 0, 0 } + }; + + c = getopt_long(argc, argv, "c:q:", long_options, NULL); + + if (c == -1) + break; + + switch (c) { + case '?': + set_variable(argv[optind - 1], argv[optind], true); + break; + case 'c': + launch_conf_file = g_strdup(optarg); + break; + case 'q': + c = -1; + qemu_arg_index = optind - 1; + break; + default: + break; + } + } + + if (!launch_conf_file && qemu_arg_index == 0) { + fprintf(stderr, "Usage: %s {-c|--conf} conf_file ...\n", + basename(argv[0])); + + return -1; + } + + // load configurations + _qemu_argc = 0; + _qemu_argv[_qemu_argc++] = g_strdup(argv[0]); + + set_bin_path_os(_qemu_argv[0]); + + if (launch_conf_file) { + if (!load_conf(launch_conf_file)) { + return -1; + } + + // assemble arguments for qemu and skin +#ifdef SUPPORT_SKIN_OPTIONS + if (!assemble_emulator_args(&_qemu_argc, _qemu_argv, + &_skin_argc, _skin_argv)) { + return -1; + } +#else + if (!assemble_emulator_args(&_qemu_argc, _qemu_argv)) { + return -1; + } + #if defined(CONFIG_JAVA_UI) + // java skin is deprecated, it is used for only debugging... + _skin_argv[_skin_argc++] = + g_strdup_printf("skin.path=%s", get_emul_skin_path()); + _skin_argv[_skin_argc++] = + g_strdup_printf("resolution=%s", get_variable("resolution")); + _skin_argv[_skin_argc++] = + g_strdup_printf("vm.path=%s/%s", + get_variable("vms_path"), get_variable("vm_name")); + #endif +#endif + } + + // if "--qemu" is specified, we should respect specified args + if (qemu_arg_index > 0) { + while (qemu_arg_index < argc) { + _qemu_argv[_qemu_argc++] = g_strdup(argv[qemu_arg_index++]); + } + } + + emulator_add_exit_notifier(&emulator_exit); + + LOG_INFO("Start emulator...\n"); + print_options_info(); + + LOG_INFO("qemu main start...\n"); +#ifdef CONFIG_COCOA + cocoa_main(_qemu_argc, (const char **)_qemu_argv); +#else + qemu_main(_qemu_argc, _qemu_argv, envp); +#endif + + return 0; +} + +#if defined (CONFIG_LINUX) +int main(int argc, char *argv[], char **envp) +{ + init_error_handler(); + return emulator_main(argc, argv, envp); +} +#else +int main(int argc, char *argv[]) +{ + init_error_handler(); + return emulator_main(argc, argv, NULL); +} +#endif diff --cc tizen/src/hw/maru_board.c index c00398baf8,0000000000..1066912f85 mode 100644,000000..100644 --- a/tizen/src/hw/maru_board.c +++ b/tizen/src/hw/maru_board.c @@@ -1,77 -1,0 +1,75 @@@ +/* + * TIZEN base board + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: + * SeokYeon Hwang + * SangJin Kim + * KiTae Kim + * JinHyung Jo + * SungMin Ha + * MunKyu Im + * JiHye Kim + * GiWoong Kim + * DongKyun Yun + * DoHyung Hong + * Hyunjun Son + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributors: + * - S-Core Co., Ltd + * + * x86 board from pc_piix.c... + * add some TIZEN-speciaized device... + */ + +#include "hw/boards.h" +#include "hw/i386/pc.h" + +#include "emulator_common.h" +#include "maru_pm.h" + +/* maru specialized device init */ +static void maru_device_init(void) +{ + // do nothing for now... +} + +extern void maru_pc_init(MachineState *args); +static void maru_x86_board_init(MachineState *machine) +{ + maru_pc_init(machine); + + maru_device_init(); +} + +static void maru_x86_machine_options(MachineClass *m) +{ - pc_default_machine_options(m); + m->family = "pc_piix"; + m->desc = "Maru Board (x86)"; - m->hot_add_cpu = pc_hot_add_cpu; + m->default_machine_opts = "firmware=bios-256k.bin"; - m->default_display = "std"; + m->alias = "maru-x86-machine"; ++ m->default_display = "std"; + m->no_parallel = 1; + m->no_floppy = 1; + m->no_cdrom = 1; + m->no_sdcard = 1; + m->default_boot_order = "c"; +} + +DEFINE_PC_MACHINE(maru, "maru-x86-machine", maru_x86_board_init, + maru_x86_machine_options); diff --cc tizen/src/util/device_hotplug.c index dedce1c88b,0000000000..05acabca0d mode 100644,000000..100644 --- a/tizen/src/util/device_hotplug.c +++ b/tizen/src/util/device_hotplug.c @@@ -1,298 -1,0 +1,299 @@@ +/* + * Maru device hotplug + * + * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * SeokYeon Hwang + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * Contributors: + * - S-Core Co., Ltd + * + */ + +#include "qemu/main-loop.h" +#include "qemu/config-file.h" +#include "hw/qdev.h" +#include "qemu/event_notifier.h" ++#include "qapi/qmp/qstring.h" +#include "sysemu/block-backend.h" + +#include "emulator.h" +#include "emul_state.h" +#include "device_hotplug.h" +#include "ecs/ecs_hds.h" +#include "hds.h" +#include "ecs/ecs_sdcard.h" + +#define HOST_KEYBOARD_DRIVER "virtio-maru-keyboard-pci" +#define HOST_KEYBOARD_DEFAULT_ID "HOSTKBD0" + +#define FS_MOUNT_TAG "fileshare" + +#include "debug_ch.h" + +MULTI_DEBUG_CHANNEL(qemu, hotplug); + +struct maru_device_hotplug { + EventNotifier notifier; + + char *opaque; + int command; + + // FIXME: Should we query device every time ?? + bool host_keyboard_attached; + bool sdcard_attached; +}; + +static struct maru_device_hotplug *state; + +static bool do_host_keyboard_attach(void) +{ + QDict *qdict = qdict_new(); + qdict_put(qdict, "driver", qstring_from_str(HOST_KEYBOARD_DRIVER)); + qdict_put(qdict, "id", qstring_from_str(HOST_KEYBOARD_DEFAULT_ID)); + + qmp_device_add(qdict, NULL, &error_abort); + + QDECREF(qdict); + + state->host_keyboard_attached = true; + + return true; +} + +static bool do_host_keyboard_detach(void) +{ + QDict *qdict = qdict_new(); + qdict_put(qdict, "id", qstring_from_str(HOST_KEYBOARD_DEFAULT_ID)); + - qmp_marshal_input_device_del(qdict, NULL, &error_abort); ++ qmp_marshal_device_del(qdict, NULL, &error_abort); + + QDECREF(qdict); + + state->host_keyboard_attached = false; + + return true; +} + +static bool do_sdcard_attach(const char * const file) +{ + QDict *qdict = qdict_new(); + QDict *qdict_file = qdict_new(); + QDict *qdict_options = qdict_new(); + gchar *sdcard_img = g_path_get_basename(file); + gchar *sdcard_device_id = g_strdup_printf("device_id_%s", sdcard_img); + gchar *sdcard_drive_id = g_strdup_printf("drive_id_%s", sdcard_img); + DriveInfo* dinfo = NULL; + + g_free(sdcard_img); + + qdict_put(qdict_file, "driver", qstring_from_str("file")); + qdict_put(qdict_file, "filename", qstring_from_str(file)); + qdict_put(qdict_options, "file", qdict_file); + qdict_put(qdict_options, "driver", qstring_from_str("qcow2")); + qdict_put(qdict_options, "id", qstring_from_str(sdcard_device_id)); + qdict_put(qdict, "options", qdict_options); + - qmp_marshal_input_blockdev_add(qdict, NULL, &error_abort); ++ qmp_marshal_blockdev_add(qdict, NULL, &error_abort); + + dinfo = g_malloc0(sizeof(*dinfo)); + dinfo->type = IF_VIRTIO; + blk_set_legacy_dinfo(blk_by_name(sdcard_device_id), dinfo); + + QDECREF(qdict); + + qdict = qdict_new(); + qdict_put(qdict, "driver", qstring_from_str(SDCARD_DRIVER)); + qdict_put(qdict, "drive", qstring_from_str(sdcard_device_id)); + /* set sdcard id as sdcard image file name */ + qdict_put(qdict, "id", qstring_from_str(sdcard_drive_id)); + + qmp_device_add(qdict, NULL, &error_abort); + + QDECREF(qdict); + g_free(sdcard_device_id); + g_free(sdcard_drive_id); + state->sdcard_attached = true; + return true; +} + +static bool do_sdcard_detach(const char * const file) +{ + QDict *qdict = qdict_new(); + gchar *sdcard_drive_id = g_strdup_printf("drive_id_%s", g_path_get_basename(file)); + qdict_put(qdict, "id", qstring_from_str(sdcard_drive_id)); + - qmp_marshal_input_device_del(qdict, NULL, &error_abort); ++ qmp_marshal_device_del(qdict, NULL, &error_abort); + + QDECREF(qdict); + state->sdcard_attached = false; + g_free(sdcard_drive_id); + return true; +} + +static bool do_hds_attach(const char * const id) +{ + QemuOpts *fsdev; + int ret; + QDict *qdict; + char* host; + int len = 0; + char* guest = NULL; + char emuld_data [OUT_BUF_SIZE]; + + fsdev = qemu_opts_create(qemu_find_opts("fsdev"), + id, 0, NULL); + if (!fsdev) { + return false; + } + + LOG_INFO("do_hds_attach - id: %s\n", id); + + host = get_host_path_by_id((char*)id); + if (host == NULL) { + LOG_SEVERE("host path is null\n"); + return false; + } + + qemu_opt_set(fsdev, "fsdriver", "local", &error_abort); + qemu_opt_set(fsdev, "path", host, &error_abort); + qemu_opt_set(fsdev, "security_model", "none", &error_abort); + + ret = qemu_fsdev_add(fsdev); + if (ret != 0) { + return false; + } + + qdict = qdict_new(); + qdict_put(qdict, "driver", qstring_from_str("virtio-9p-pci")); + qdict_put(qdict, "fsdev", qstring_from_str(id)); + qdict_put(qdict, "mount_tag", qstring_from_str(id)); + qdict_put(qdict, "id", qstring_from_str(id)); + + qmp_device_add(qdict, NULL, &error_abort); + + set_hds_attached(id, true); + + QDECREF(qdict); + + // send mount message to emuld + + guest = get_guest_path_by_id((char*)id); + if (guest == NULL) { + LOG_SEVERE("guest path is null\n"); + return false; + } + + len = snprintf(emuld_data, sizeof(emuld_data), "%s\n%s\n", id, guest); + LOG_INFO("send emuld to mount: %s", emuld_data); + send_msg_to_guest(MSG_TYPE_HDS, ECS_HDS_MSG_GROUP, + ECS_HDS_ACTION_MOUNT, emuld_data, len + 1); + + return true; +} + +static bool do_hds_detach(const char * const id) +{ + QDict *qdict = qdict_new(); + qemu_fsdev_remove(id); + + qdict_put(qdict, "id", qstring_from_str(id)); + - qmp_marshal_input_device_del(qdict, NULL, &error_abort); ++ qmp_marshal_device_del(qdict, NULL, &error_abort); + + QDECREF(qdict); + + remove_hds_list(id); + + return true; +} + +void do_hotplug(int command, void *opaque, size_t size) +{ + if (opaque != NULL && size > 0) { + state->opaque = g_malloc(size); + memcpy(state->opaque, opaque, size); + } + state->command = command; + + event_notifier_set(&state->notifier); +} + +static void device_hotplug_handler(EventNotifier *e) +{ + event_notifier_test_and_clear(e); + + switch(state->command) { + case ATTACH_HOST_KEYBOARD: + do_host_keyboard_attach(); + break; + case DETACH_HOST_KEYBOARD: + do_host_keyboard_detach(); + break; + case ATTACH_SDCARD: + do_sdcard_attach(state->opaque); + break; + case DETACH_SDCARD: + do_sdcard_detach(state->opaque); + break; + case ATTACH_HDS: + do_hds_attach(state->opaque); + break; + case DETACH_HDS: + do_hds_detach(state->opaque); + break; + default: + break; + } + + if (state->opaque != NULL) { + g_free(state->opaque); + state->opaque = NULL; + } +} + +static void deinit_maru_device_hotplug(Notifier *notifier, void *data) +{ + event_notifier_cleanup(&state->notifier); + + g_free(state); +} + +static Notifier maru_device_hotplug_exit = { .notify = deinit_maru_device_hotplug }; + +void init_device_hotplug(void) +{ + state = g_malloc0(sizeof(struct maru_device_hotplug)); + + event_notifier_init(&state->notifier, 0); + event_notifier_set_handler(&state->notifier, device_hotplug_handler); + + emulator_add_exit_notifier(&maru_device_hotplug_exit); +} + +bool is_host_keyboard_attached(void) +{ + return state->host_keyboard_attached; +} + +bool is_sdcard_attached(void) +{ + //TODO: support checking multi sdcard attached + return state->sdcard_attached; +} diff --cc ui/cocoa.m index 75832ebc87,d76b942732..abb0906e4c --- a/ui/cocoa.m +++ b/ui/cocoa.m @@@ -1125,12 -1132,23 +1132,27 @@@ QemuCocoaView *cocoaView } } + /* Verifies if the user really wants to quit */ + - (BOOL)verifyQuit + { + NSAlert *alert = [NSAlert new]; + [alert autorelease]; + [alert setMessageText: @"Are you sure you want to quit QEMU?"]; + [alert addButtonWithTitle: @"Cancel"]; + [alert addButtonWithTitle: @"Quit"]; + if([alert runModal] == NSAlertSecondButtonReturn) { + return YES; + } else { + return NO; + } + } + @end +#ifdef CONFIG_MARU +int cocoa_main (int argc, const char * argv[]); +#define main cocoa_main +#endif int main (int argc, const char * argv[]) { diff --cc ui/input.c index 84031dba52,a0f9873f59..9557158b7d --- a/ui/input.c +++ b/ui/input.c @@@ -6,24 -6,8 +6,25 @@@ #include "trace.h" #include "ui/input.h" #include "ui/console.h" + #include "sysemu/replay.h" +#if defined CONFIG_MARU && defined CONFIG_SPICE && defined CONFIG_LINUX +# ifdef CONFIG_JAVA_UI +#include + +extern void maru_hwkey_event(int event_type, int keycode); +extern void do_rotation_event(int rotation_type); +extern void do_host_kbd_enable(bool on); +extern void qemu_system_graceful_shutdown_request(unsigned int sec); +extern void request_close(void); +void* tizen_close_thread(void* data); +# endif +#endif + +//#include "tizen/src/debug_ch.h" + +//MULTI_DEBUG_CHANNEL(tizen, input); + struct QemuInputHandlerState { DeviceState *dev; QemuInputHandler *handler; diff --cc util/coroutine-win32.c index 0000000000,4f922c53af..990a3b3b0c mode 000000,100644..100644 --- a/util/coroutine-win32.c +++ b/util/coroutine-win32.c @@@ -1,0 -1,101 +1,104 @@@ + /* + * Win32 coroutine initialization code + * + * Copyright (c) 2011 Kevin Wolf + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + #include "qemu-common.h" + #include "qemu/coroutine_int.h" + + typedef struct + { + Coroutine base; + + LPVOID fiber; + CoroutineAction action; + } CoroutineWin32; + + static __thread CoroutineWin32 leader; + static __thread Coroutine *current; + + /* This function is marked noinline to prevent GCC from inlining it + * into coroutine_trampoline(). If we allow it to do that then it + * hoists the code to get the address of the TLS variable "current" + * out of the while() loop. This is an invalid transformation because + * the SwitchToFiber() call may be called when running thread A but + * return in thread B, and so we might be in a different thread + * context each time round the loop. + */ + CoroutineAction __attribute__((noinline)) + qemu_coroutine_switch(Coroutine *from_, Coroutine *to_, + CoroutineAction action) + { + CoroutineWin32 *from = DO_UPCAST(CoroutineWin32, base, from_); + CoroutineWin32 *to = DO_UPCAST(CoroutineWin32, base, to_); + + current = to_; + + to->action = action; + SwitchToFiber(to->fiber); + return from->action; + } + + static void CALLBACK coroutine_trampoline(void *co_) + { + Coroutine *co = co_; + + while (true) { + co->entry(co->entry_arg); + qemu_coroutine_switch(co, co->caller, COROUTINE_TERMINATE); + } + } + + Coroutine *qemu_coroutine_new(void) + { + const size_t stack_size = 1 << 20; + CoroutineWin32 *co; + + co = g_malloc0(sizeof(*co)); + co->fiber = CreateFiber(stack_size, coroutine_trampoline, &co->base); ++ ++ g_assert(co->fiber); ++ + return &co->base; + } + + void qemu_coroutine_delete(Coroutine *co_) + { + CoroutineWin32 *co = DO_UPCAST(CoroutineWin32, base, co_); + + DeleteFiber(co->fiber); + g_free(co); + } + + Coroutine *qemu_coroutine_self(void) + { + if (!current) { + current = &leader.base; + leader.fiber = ConvertThreadToFiber(NULL); + } + return current; + } + + bool qemu_in_coroutine(void) + { + return current && current->caller; + } diff --cc util/oslib-posix.c index 997f24d21b,d25f6715c7..6f18866cad --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@@ -73,10 -70,8 +71,12 @@@ extern int daemon(int, int) #include #endif + #include + +#ifdef CONFIG_MARU +#include "../../tizen/src/emulator_common.h" +#endif + int qemu_get_thread_id(void) { #if defined(__linux__) @@@ -139,19 -127,8 +139,16 @@@ int preallocated_ram_size = -1 /* alloc shared memory pages */ void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment) { +#ifdef CONFIG_MARU + if (size == preallocated_ram_size && preallocated_ram_ptr) { + void *ptr = preallocated_ram_ptr; + preallocated_ram_ptr = NULL; + preallocated_ram_size = -1; + return ptr; + } +#endif size_t align = QEMU_VMALLOC_ALIGN; - size_t total = size + align - getpagesize(); - void *ptr = mmap(0, total, PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - size_t offset = QEMU_ALIGN_UP((uintptr_t)ptr, align) - (uintptr_t)ptr; + void *ptr = qemu_ram_mmap(-1, size, align, false); if (ptr == MAP_FAILED) { return NULL; diff --cc util/qemu-coroutine.c index 0000000000,8953560223..9a04f28865 mode 000000,100644..100644 --- a/util/qemu-coroutine.c +++ b/util/qemu-coroutine.c @@@ -1,0 -1,146 +1,150 @@@ + /* + * QEMU coroutines + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Stefan Hajnoczi + * Kevin Wolf + * + * This work is licensed under the terms of the GNU LGPL, version 2 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + + #include "trace.h" + #include "qemu-common.h" + #include "qemu/thread.h" + #include "qemu/atomic.h" + #include "qemu/coroutine.h" + #include "qemu/coroutine_int.h" + + enum { ++#if defined(_WIN32) && !defined(_WIN64) ++ POOL_BATCH_SIZE = 32, ++#else + POOL_BATCH_SIZE = 64, ++#endif + }; + + /** Free list to speed up creation */ + static QSLIST_HEAD(, Coroutine) release_pool = QSLIST_HEAD_INITIALIZER(pool); + static unsigned int release_pool_size; + static __thread QSLIST_HEAD(, Coroutine) alloc_pool = QSLIST_HEAD_INITIALIZER(pool); + static __thread unsigned int alloc_pool_size; + static __thread Notifier coroutine_pool_cleanup_notifier; + + static void coroutine_pool_cleanup(Notifier *n, void *value) + { + Coroutine *co; + Coroutine *tmp; + + QSLIST_FOREACH_SAFE(co, &alloc_pool, pool_next, tmp) { + QSLIST_REMOVE_HEAD(&alloc_pool, pool_next); + qemu_coroutine_delete(co); + } + } + + Coroutine *qemu_coroutine_create(CoroutineEntry *entry) + { + Coroutine *co = NULL; + + if (CONFIG_COROUTINE_POOL) { + co = QSLIST_FIRST(&alloc_pool); + if (!co) { + if (release_pool_size > POOL_BATCH_SIZE) { + /* Slow path; a good place to register the destructor, too. */ + if (!coroutine_pool_cleanup_notifier.notify) { + coroutine_pool_cleanup_notifier.notify = coroutine_pool_cleanup; + qemu_thread_atexit_add(&coroutine_pool_cleanup_notifier); + } + + /* This is not exact; there could be a little skew between + * release_pool_size and the actual size of release_pool. But + * it is just a heuristic, it does not need to be perfect. + */ + alloc_pool_size = atomic_xchg(&release_pool_size, 0); + QSLIST_MOVE_ATOMIC(&alloc_pool, &release_pool); + co = QSLIST_FIRST(&alloc_pool); + } + } + if (co) { + QSLIST_REMOVE_HEAD(&alloc_pool, pool_next); + alloc_pool_size--; + } + } + + if (!co) { + co = qemu_coroutine_new(); + } + + co->entry = entry; + QTAILQ_INIT(&co->co_queue_wakeup); + return co; + } + + static void coroutine_delete(Coroutine *co) + { + co->caller = NULL; + + if (CONFIG_COROUTINE_POOL) { + if (release_pool_size < POOL_BATCH_SIZE * 2) { + QSLIST_INSERT_HEAD_ATOMIC(&release_pool, co, pool_next); + atomic_inc(&release_pool_size); + return; + } + if (alloc_pool_size < POOL_BATCH_SIZE) { + QSLIST_INSERT_HEAD(&alloc_pool, co, pool_next); + alloc_pool_size++; + return; + } + } + + qemu_coroutine_delete(co); + } + + void qemu_coroutine_enter(Coroutine *co, void *opaque) + { + Coroutine *self = qemu_coroutine_self(); + CoroutineAction ret; + + trace_qemu_coroutine_enter(self, co, opaque); + + if (co->caller) { + fprintf(stderr, "Co-routine re-entered recursively\n"); + abort(); + } + + co->caller = self; + co->entry_arg = opaque; + ret = qemu_coroutine_switch(self, co, COROUTINE_ENTER); + + qemu_co_queue_run_restart(co); + + switch (ret) { + case COROUTINE_YIELD: + return; + case COROUTINE_TERMINATE: + trace_qemu_coroutine_terminate(co); + coroutine_delete(co); + return; + default: + abort(); + } + } + + void coroutine_fn qemu_coroutine_yield(void) + { + Coroutine *self = qemu_coroutine_self(); + Coroutine *to = self->caller; + + trace_qemu_coroutine_yield(self, to); + + if (!to) { + fprintf(stderr, "Co-routine is yielding to no one\n"); + abort(); + } + + self->caller = NULL; + qemu_coroutine_switch(self, to, COROUTINE_YIELD); + } diff --cc vl.c index 3405c042ef,4211ff1ffd..e1cfa7a165 --- a/vl.c +++ b/vl.c @@@ -133,22 -122,9 +133,24 @@@ int qemu_main(int argc, char **argv, ch #include "qapi-event.h" #include "exec/semihost.h" #include "crypto/init.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" +# ifdef CONFIG_JAVA_UI +#include "tizen/src/display/maru_display.h" +# endif +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 @@@ -1835,14 -1824,11 +1850,18 @@@ void qemu_system_killed(int signal, pid 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 - qemu_system_shutdown_request(); + /* 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) @@@ -4417,16 -4288,7 +4459,17 @@@ int main(int argc, char **argv, char ** 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(); if (qemu_opts_foreach(qemu_find_opts("object"), @@@ -4551,8 -4409,8 +4588,8 @@@ cpu_ticks_init(); if (icount_opts) { - if (kvm_enabled() || xen_enabled()) { + if (kvm_enabled() || xen_enabled() || hax_enabled()) { - fprintf(stderr, "-icount is not allowed with kvm or xen\n"); + error_report("-icount is not allowed with kvm or xen"); exit(1); } configure_icount(icount_opts, &error_abort); @@@ -4866,10 -4681,9 +4923,12 @@@ } } +#ifdef CONFIG_MARU + enable_print_backtrace_at_normal_exit(); +#endif main_loop(); + replay_disable_events(); + bdrv_close_all(); pause_all_vcpus(); res_free();