ARM system emulation (Paul Brook)
[qemu] / kqemu.c
diff --git a/kqemu.c b/kqemu.c
index 9a0f05b..70cfe28 100644 (file)
--- a/kqemu.c
+++ b/kqemu.c
@@ -119,13 +119,19 @@ static void kqemu_update_cpuid(CPUState *env)
     critical_features_mask = 
         CPUID_CMOV | CPUID_CX8 | 
         CPUID_FXSR | CPUID_MMX | CPUID_SSE | 
-        CPUID_SSE2;
+        CPUID_SSE2 | CPUID_SEP;
     if (!is_cpuid_supported()) {
         features = 0;
     } else {
         cpuid(1, eax, ebx, ecx, edx);
         features = edx;
     }
+#ifdef __x86_64__
+    /* NOTE: on x86_64 CPUs, SYSENTER is not supported in
+       compatibility mode, so in order to have the best performances
+       it is better not to use it */
+    features &= ~CPUID_SEP;
+#endif
     env->cpuid_features = (env->cpuid_features & ~critical_features_mask) |
         (features & critical_features_mask);
     /* XXX: we could update more of the target CPUID state so that the
@@ -237,6 +243,9 @@ void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr)
         fprintf(logfile, "kqemu_set_notdirty: addr=%08lx\n", ram_addr);
     }
 #endif
+    /* we only track transitions to dirty state */
+    if (phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] != 0xff)
+        return;
     if (nb_ram_pages_to_update >= KQEMU_MAX_RAM_PAGES_TO_UPDATE)
         nb_ram_pages_to_update = KQEMU_RAM_PAGES_UPDATE_ALL;
     else
@@ -587,11 +596,14 @@ int kqemu_cpu_exec(CPUState *env)
     }
 
 #ifdef _WIN32
-    DeviceIoControl(kqemu_fd, KQEMU_EXEC,
-                   kenv, sizeof(struct kqemu_cpu_state),
-                   kenv, sizeof(struct kqemu_cpu_state),
-                   &temp, NULL);
-    ret = kenv->retval;
+    if (DeviceIoControl(kqemu_fd, KQEMU_EXEC,
+                        kenv, sizeof(struct kqemu_cpu_state),
+                        kenv, sizeof(struct kqemu_cpu_state),
+                        &temp, NULL)) {
+        ret = kenv->retval;
+    } else {
+        ret = -1;
+    }
 #else
 #if KQEMU_VERSION >= 0x010100
     ioctl(kqemu_fd, KQEMU_EXEC, kenv);
@@ -728,4 +740,13 @@ int kqemu_cpu_exec(CPUState *env)
     return 0;
 }
 
+void kqemu_cpu_interrupt(CPUState *env)
+{
+#if defined(_WIN32) && KQEMU_VERSION >= 0x010101
+    /* cancelling the I/O request causes KQEMU to finish executing the 
+       current block and successfully returning. */
+    CancelIo(kqemu_fd);
+#endif
+}
+
 #endif