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