From 8988ae8945f93049a0e416600d928a7b4ce8446f Mon Sep 17 00:00:00 2001 From: bellard Date: Wed, 27 Sep 2006 19:54:02 +0000 Subject: [PATCH] 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 | 4 +++- target-i386/helper.c | 15 ++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 55e7a98c54..30507403e4 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -260,6 +260,7 @@ #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; diff --git a/target-i386/helper.c b/target-i386/helper.c index d990c07ed1..4017bee79c 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -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);