ide PCI ident fix, aka FreeBSD/amd64 bug fix (Jung-uk Kim)
[qemu] / target-i386 / helper2.c
index 9ecf05d..6033590 100644 (file)
@@ -98,22 +98,48 @@ CPUX86State *cpu_x86_init(void)
 #else
         /* pentium pro */
         family = 6;
-        model = 1;
+        model = 3;
         stepping = 3;
 #endif
 #endif
+        env->cpuid_level = 2;
         env->cpuid_version = (family << 8) | (model << 4) | stepping;
         env->cpuid_features = (CPUID_FP87 | CPUID_DE | CPUID_PSE |
                                CPUID_TSC | CPUID_MSR | CPUID_MCE |
-                               CPUID_CX8 | CPUID_PGE | CPUID_CMOV);
+                               CPUID_CX8 | CPUID_PGE | CPUID_CMOV |
+                               CPUID_PAT);
+        env->pat = 0x0007040600070406ULL;
+        env->cpuid_ext_features = 0;
+        env->cpuid_features |= CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_PAE | CPUID_SEP;
+        env->cpuid_xlevel = 0;
+        {
+            const char *model_id = "QEMU Virtual CPU version " QEMU_VERSION;
+            int c, len, i;
+            len = strlen(model_id);
+            for(i = 0; i < 48; i++) {
+                if (i >= len)
+                    c = '\0';
+                else
+                    c = model_id[i];
+                env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
+            }
+        }
 #ifdef TARGET_X86_64
         /* currently not enabled for std i386 because not fully tested */
-        env->cpuid_features |= CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2;
-        env->cpuid_features |= CPUID_APIC | CPUID_PAE;
+        env->cpuid_features |= CPUID_APIC;
+        env->cpuid_ext2_features = (env->cpuid_features & 0x0183F3FF);
+        env->cpuid_ext2_features |= CPUID_EXT2_LM | CPUID_EXT2_SYSCALL;
+        env->cpuid_xlevel = 0x80000008;
+
+        /* these features are needed for Win64 and aren't fully implemented */
+        env->cpuid_features |= CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA;
 #endif
     }
     cpu_single_env = env;
     cpu_reset(env);
+#ifdef USE_KQEMU
+    kqemu_init(env);
+#endif
     return env;
 }
 
@@ -229,7 +255,7 @@ void cpu_dump_state(CPUState *env, FILE *f,
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                     int flags)
 {
-    int eflags, i;
+    int eflags, i, nb;
     char cc_op_name[32];
     static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
 
@@ -377,16 +403,54 @@ void cpu_dump_state(CPUState *env, FILE *f,
         }
     }
     if (flags & X86_DUMP_FPU) {
-        cpu_fprintf(f, "ST0=%f ST1=%f ST2=%f ST3=%f\n", 
-                (double)env->fpregs[0].d, 
-                (double)env->fpregs[1].d, 
-                (double)env->fpregs[2].d, 
-                (double)env->fpregs[3].d);
-        cpu_fprintf(f, "ST4=%f ST5=%f ST6=%f ST7=%f\n", 
-                (double)env->fpregs[4].d, 
-                (double)env->fpregs[5].d, 
-                (double)env->fpregs[7].d, 
-                (double)env->fpregs[8].d);
+        int fptag;
+        fptag = 0;
+        for(i = 0; i < 8; i++) {
+            fptag |= ((!env->fptags[i]) << i);
+        }
+        cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
+                    env->fpuc,
+                    (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
+                    env->fpstt,
+                    fptag,
+                    env->mxcsr);
+        for(i=0;i<8;i++) {
+#if defined(USE_X86LDOUBLE)
+            union {
+                long double d;
+                struct {
+                    uint64_t lower;
+                    uint16_t upper;
+                } l;
+            } tmp;
+            tmp.d = env->fpregs[i].d;
+            cpu_fprintf(f, "FPR%d=%016llx %04x",
+                        i, tmp.l.lower, tmp.l.upper);
+#else
+            cpu_fprintf(f, "FPR%d=%016llx",
+                        i, env->fpregs[i].mmx.q);
+#endif
+            if ((i & 1) == 1)
+                cpu_fprintf(f, "\n");
+            else
+                cpu_fprintf(f, " ");
+        }
+        if (env->hflags & HF_CS64_MASK) 
+            nb = 16;
+        else
+            nb = 8;
+        for(i=0;i<nb;i++) {
+            cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
+                        i, 
+                        env->xmm_regs[i].XMM_L(3),
+                        env->xmm_regs[i].XMM_L(2),
+                        env->xmm_regs[i].XMM_L(1),
+                        env->xmm_regs[i].XMM_L(0));
+            if ((i & 1) == 1)
+                cpu_fprintf(f, "\n");
+            else
+                cpu_fprintf(f, " ");
+        }
     }
 }
 
@@ -453,6 +517,8 @@ void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
         ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
 }
 
+/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
+   the PDPT */
 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
 {
     env->cr[3] = new_cr3;
@@ -485,7 +551,7 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
 }
 
 /* XXX: also flush 4MB pages */
-void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr)
+void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr)
 {
     tlb_flush_page(env, addr);
 }