]> git.proxmox.com Git - qemu.git/commitdiff
SMM fix for x86_64
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 27 Sep 2006 19:54:02 +0000 (19:54 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 27 Sep 2006 19:54:02 +0000 (19:54 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2183 c046a42c-6fe2-441c-8c8c-71466251a162

target-i386/cpu.h
target-i386/helper.c

index 55e7a98c5494f7e555972d975974067399606142..30507403e459e917dd2f7ff7c711cf4a061dd2ae 100644 (file)
 #define CPUID_MCA  (1 << 14)
 #define CPUID_CMOV (1 << 15)
 #define CPUID_PAT  (1 << 16)
+#define CPUID_PSE36   (1 << 17)
 #define CPUID_CLFLUSH (1 << 19)
 /* ... */
 #define CPUID_MMX  (1 << 23)
@@ -543,7 +544,8 @@ void cpu_set_ferr(CPUX86State *s);
    cache: it synchronizes the hflags with the segment cache values */
 static inline void cpu_x86_load_seg_cache(CPUX86State *env, 
                                           int seg_reg, unsigned int selector,
-                                          uint32_t base, unsigned int limit, 
+                                          target_ulong base,
+                                          unsigned int limit, 
                                           unsigned int flags)
 {
     SegmentCache *sc;
index d990c07ed11f8c2700b43f0643dfa342794eacf4..4017bee79c301aacd749ee89e66455d8babb2f1b 100644 (file)
@@ -1338,6 +1338,10 @@ void do_smm_enter(void)
 #endif
     /* init SMM cpu state */
 
+#ifdef TARGET_X86_64
+    env->efer = 0;
+    env->hflags &= ~HF_LMA_MASK;
+#endif
     load_eflags(0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
     env->eip = 0x00008000;
     cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
@@ -1352,9 +1356,6 @@ void do_smm_enter(void)
                        env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | CR0_PG_MASK));
     cpu_x86_update_cr4(env, 0);
     env->dr[7] = 0x00000400;
-#ifdef TARGET_X86_64
-    env->efer = 0;
-#endif
     CC_OP = CC_OP_EFLAGS;
 }
 
@@ -1366,6 +1367,12 @@ void helper_rsm(void)
 
     sm_state = env->smbase + 0x8000;
 #ifdef TARGET_X86_64
+    env->efer = ldq_phys(sm_state + 0x7ed0);
+    if (env->efer & MSR_EFER_LMA)
+        env->hflags |= HF_LMA_MASK;
+    else
+        env->hflags &= ~HF_LMA_MASK;
+
     for(i = 0; i < 6; i++) {
         offset = 0x7e00 + i * 16;
         cpu_x86_load_seg_cache(env, i, 
@@ -1391,8 +1398,6 @@ void helper_rsm(void)
     env->tr.limit = ldl_phys(sm_state + 0x7e94);
     env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8;
     
-    env->efer = ldq_phys(sm_state + 0x7ed0);
-
     EAX = ldq_phys(sm_state + 0x7ff8);
     ECX = ldq_phys(sm_state + 0x7ff0);
     EDX = ldq_phys(sm_state + 0x7fe8);