mirror of https://github.com/xemu-project/xemu.git
SMM fix for x86_64
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2183 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
69c3bcb48f
commit
8988ae8945
|
@ -260,6 +260,7 @@
|
||||||
#define CPUID_MCA (1 << 14)
|
#define CPUID_MCA (1 << 14)
|
||||||
#define CPUID_CMOV (1 << 15)
|
#define CPUID_CMOV (1 << 15)
|
||||||
#define CPUID_PAT (1 << 16)
|
#define CPUID_PAT (1 << 16)
|
||||||
|
#define CPUID_PSE36 (1 << 17)
|
||||||
#define CPUID_CLFLUSH (1 << 19)
|
#define CPUID_CLFLUSH (1 << 19)
|
||||||
/* ... */
|
/* ... */
|
||||||
#define CPUID_MMX (1 << 23)
|
#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 */
|
cache: it synchronizes the hflags with the segment cache values */
|
||||||
static inline void cpu_x86_load_seg_cache(CPUX86State *env,
|
static inline void cpu_x86_load_seg_cache(CPUX86State *env,
|
||||||
int seg_reg, unsigned int selector,
|
int seg_reg, unsigned int selector,
|
||||||
uint32_t base, unsigned int limit,
|
target_ulong base,
|
||||||
|
unsigned int limit,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
SegmentCache *sc;
|
SegmentCache *sc;
|
||||||
|
|
|
@ -1338,6 +1338,10 @@ void do_smm_enter(void)
|
||||||
#endif
|
#endif
|
||||||
/* init SMM cpu state */
|
/* 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));
|
load_eflags(0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
|
||||||
env->eip = 0x00008000;
|
env->eip = 0x00008000;
|
||||||
cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
|
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));
|
env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | CR0_PG_MASK));
|
||||||
cpu_x86_update_cr4(env, 0);
|
cpu_x86_update_cr4(env, 0);
|
||||||
env->dr[7] = 0x00000400;
|
env->dr[7] = 0x00000400;
|
||||||
#ifdef TARGET_X86_64
|
|
||||||
env->efer = 0;
|
|
||||||
#endif
|
|
||||||
CC_OP = CC_OP_EFLAGS;
|
CC_OP = CC_OP_EFLAGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1366,6 +1367,12 @@ void helper_rsm(void)
|
||||||
|
|
||||||
sm_state = env->smbase + 0x8000;
|
sm_state = env->smbase + 0x8000;
|
||||||
#ifdef TARGET_X86_64
|
#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++) {
|
for(i = 0; i < 6; i++) {
|
||||||
offset = 0x7e00 + i * 16;
|
offset = 0x7e00 + i * 16;
|
||||||
cpu_x86_load_seg_cache(env, i,
|
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.limit = ldl_phys(sm_state + 0x7e94);
|
||||||
env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8;
|
env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8;
|
||||||
|
|
||||||
env->efer = ldq_phys(sm_state + 0x7ed0);
|
|
||||||
|
|
||||||
EAX = ldq_phys(sm_state + 0x7ff8);
|
EAX = ldq_phys(sm_state + 0x7ff8);
|
||||||
ECX = ldq_phys(sm_state + 0x7ff0);
|
ECX = ldq_phys(sm_state + 0x7ff0);
|
||||||
EDX = ldq_phys(sm_state + 0x7fe8);
|
EDX = ldq_phys(sm_state + 0x7fe8);
|
||||||
|
|
Loading…
Reference in New Issue