Commit 8988ae8945f93049a0e416600d928a7b4ce8446f

Authored by bellard
1 parent 69c3bcb4

SMM fix for x86_64


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2183 c046a42c-6fe2-441c-8c8c-71466251a162
target-i386/cpu.h
@@ -260,6 +260,7 @@ @@ -260,6 +260,7 @@
260 #define CPUID_MCA (1 << 14) 260 #define CPUID_MCA (1 << 14)
261 #define CPUID_CMOV (1 << 15) 261 #define CPUID_CMOV (1 << 15)
262 #define CPUID_PAT (1 << 16) 262 #define CPUID_PAT (1 << 16)
  263 +#define CPUID_PSE36 (1 << 17)
263 #define CPUID_CLFLUSH (1 << 19) 264 #define CPUID_CLFLUSH (1 << 19)
264 /* ... */ 265 /* ... */
265 #define CPUID_MMX (1 << 23) 266 #define CPUID_MMX (1 << 23)
@@ -543,7 +544,8 @@ void cpu_set_ferr(CPUX86State *s); @@ -543,7 +544,8 @@ void cpu_set_ferr(CPUX86State *s);
543 cache: it synchronizes the hflags with the segment cache values */ 544 cache: it synchronizes the hflags with the segment cache values */
544 static inline void cpu_x86_load_seg_cache(CPUX86State *env, 545 static inline void cpu_x86_load_seg_cache(CPUX86State *env,
545 int seg_reg, unsigned int selector, 546 int seg_reg, unsigned int selector,
546 - uint32_t base, unsigned int limit, 547 + target_ulong base,
  548 + unsigned int limit,
547 unsigned int flags) 549 unsigned int flags)
548 { 550 {
549 SegmentCache *sc; 551 SegmentCache *sc;
target-i386/helper.c
@@ -1338,6 +1338,10 @@ void do_smm_enter(void) @@ -1338,6 +1338,10 @@ void do_smm_enter(void)
1338 #endif 1338 #endif
1339 /* init SMM cpu state */ 1339 /* init SMM cpu state */
1340 1340
  1341 +#ifdef TARGET_X86_64
  1342 + env->efer = 0;
  1343 + env->hflags &= ~HF_LMA_MASK;
  1344 +#endif
1341 load_eflags(0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); 1345 load_eflags(0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
1342 env->eip = 0x00008000; 1346 env->eip = 0x00008000;
1343 cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase, 1347 cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
@@ -1352,9 +1356,6 @@ void do_smm_enter(void) @@ -1352,9 +1356,6 @@ void do_smm_enter(void)
1352 env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | CR0_PG_MASK)); 1356 env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | CR0_PG_MASK));
1353 cpu_x86_update_cr4(env, 0); 1357 cpu_x86_update_cr4(env, 0);
1354 env->dr[7] = 0x00000400; 1358 env->dr[7] = 0x00000400;
1355 -#ifdef TARGET_X86_64  
1356 - env->efer = 0;  
1357 -#endif  
1358 CC_OP = CC_OP_EFLAGS; 1359 CC_OP = CC_OP_EFLAGS;
1359 } 1360 }
1360 1361
@@ -1366,6 +1367,12 @@ void helper_rsm(void) @@ -1366,6 +1367,12 @@ void helper_rsm(void)
1366 1367
1367 sm_state = env->smbase + 0x8000; 1368 sm_state = env->smbase + 0x8000;
1368 #ifdef TARGET_X86_64 1369 #ifdef TARGET_X86_64
  1370 + env->efer = ldq_phys(sm_state + 0x7ed0);
  1371 + if (env->efer & MSR_EFER_LMA)
  1372 + env->hflags |= HF_LMA_MASK;
  1373 + else
  1374 + env->hflags &= ~HF_LMA_MASK;
  1375 +
1369 for(i = 0; i < 6; i++) { 1376 for(i = 0; i < 6; i++) {
1370 offset = 0x7e00 + i * 16; 1377 offset = 0x7e00 + i * 16;
1371 cpu_x86_load_seg_cache(env, i, 1378 cpu_x86_load_seg_cache(env, i,
@@ -1391,8 +1398,6 @@ void helper_rsm(void) @@ -1391,8 +1398,6 @@ void helper_rsm(void)
1391 env->tr.limit = ldl_phys(sm_state + 0x7e94); 1398 env->tr.limit = ldl_phys(sm_state + 0x7e94);
1392 env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8; 1399 env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8;
1393 1400
1394 - env->efer = ldq_phys(sm_state + 0x7ed0);  
1395 -  
1396 EAX = ldq_phys(sm_state + 0x7ff8); 1401 EAX = ldq_phys(sm_state + 0x7ff8);
1397 ECX = ldq_phys(sm_state + 0x7ff0); 1402 ECX = ldq_phys(sm_state + 0x7ff0);
1398 EDX = ldq_phys(sm_state + 0x7fe8); 1403 EDX = ldq_phys(sm_state + 0x7fe8);