--- qemu-snapshot-2005-03-26_23/vl.c Sun Mar 13 17:59:37 2005 +++ qemu-snapshot-2005-03-26_23-on-quit/vl.c Mon Mar 28 02:06:52 2005 @@ -139,6 +139,9 @@ int graphic_height = 600; int graphic_depth = 15; int full_screen = 0; +#ifdef TARGET_I386 +int on_quit = 0; +#endif TextConsole *vga_console; CharDriverState *serial_hds[MAX_SERIAL_PORTS]; CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; @@ -2675,6 +2678,17 @@ qemu_get_clock(rt_clock)); } +#ifdef TARGET_I386 +int ishalted() { + uint8_t buf[16]; + uint64_t v; + + cpu_memory_rw_debug(cpu_single_env, cpu_single_env->eip-1, buf, 16, 0); + v = ldub_raw(buf); + return (v == 0xf4) && ( !(cpu_single_env->eflags & 0x200) ); +} +#endif + int main_loop(void) { int ret, timeout; @@ -2684,9 +2698,16 @@ if (vm_running) { ret = cpu_exec(env); if (shutdown_requested) { +#ifdef TARGET_I386 + if( on_quit == 0 || on_quit == 2 || ( on_quit == 1 && ishalted() ) ) { +#endif ret = EXCP_INTERRUPT; break; } +#ifdef TARGET_I386 + shutdown_requested = 0; + } +#endif if (reset_requested) { reset_requested = 0; qemu_system_reset(); @@ -2783,6 +2804,11 @@ "-std-vga simulate a standard VGA card with VESA Bochs Extensions\n" " (default is CL-GD5446 PCI VGA)\n" #endif +#ifdef TARGET_I386 + "-on-quit [ignore-unless-halted|suspend-unless-halted]\n" + " select the behaviour when the emulator window is asked to quit\n" + " (default is none)\n" +#endif "-loadvm file start right away with a saved state (loadvm in monitor)\n" "\n" "During emulation, the following keys are useful:\n" @@ -2864,6 +2890,10 @@ QEMU_OPTION_full_screen, QEMU_OPTION_pidfile, QEMU_OPTION_no_kqemu, + +#ifdef TARGET_I386 + QEMU_OPTION_on_quit +#endif }; typedef struct QEMUOption { @@ -2932,6 +2962,9 @@ { "loadvm", HAS_ARG, QEMU_OPTION_loadvm }, { "full-screen", 0, QEMU_OPTION_full_screen }, { "pidfile", HAS_ARG, QEMU_OPTION_pidfile }, +#ifdef TARGET_I386 + { "on-quit", HAS_ARG, QEMU_OPTION_on_quit }, +#endif /* temporary options */ { "pci", 0, QEMU_OPTION_pci }, @@ -3383,6 +3416,19 @@ case QEMU_OPTION_pidfile: create_pidfile(optarg); break; +#ifdef TARGET_I386 + case QEMU_OPTION_on_quit: + if(!strcmp(optarg, "ignore-unless-halted")) { + fprintf(stderr, "%s enabled\n", optarg); + on_quit = 1; + } + else if(!strcmp(optarg, "suspend-unless-halted")) { + fprintf(stderr, "%s enabled\n", optarg); + on_quit = 2; + } + else on_quit = 0; + break; +#endif #ifdef USE_KQEMU case QEMU_OPTION_no_kqemu: kqemu_allowed = 0; @@ -3696,6 +3742,23 @@ } } main_loop(); + +#ifdef TARGET_I386 + if( on_quit == 2 ) { + char *f = "suspended.qemu"; + if( ishalted() ) { + + fprintf(stderr, "VM is halted: removing suspend file %s\n",f); + unlink(f); + /* qemu_savevm(f); */ + } + else { + fprintf(stderr, "Autosaving VM to file %s\n",f); + qemu_savevm(f); + } + } +#endif + quit_timers(); return 0; }