Make efer control MSR separate register

This commit is contained in:
Stanislav Shwartsman 2007-09-10 20:47:08 +00:00
parent 471e89dc84
commit 70f513b07b
8 changed files with 82 additions and 70 deletions

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.324 2007-09-10 16:00:14 sshwarts Exp $ // $Id: cpu.h,v 1.325 2007-09-10 20:47:08 sshwarts Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -537,13 +537,6 @@ typedef struct
#endif #endif
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
// x86-64 EFER bits
bx_bool sce; // system call extensions
bx_bool lme; // long mode enable
bx_bool lma; // long mode active
bx_bool nxe; // no-execute enable
bx_bool ffxsr; // fast FXSAVE/FXRSTOR
Bit64u star; Bit64u star;
Bit64u lstar; Bit64u lstar;
Bit64u cstar; Bit64u cstar;
@ -571,6 +564,17 @@ typedef struct
} bx_regs_msr_t; } bx_regs_msr_t;
#endif #endif
#if BX_SUPPORT_X86_64
typedef struct bx_efer_t {
// x86-64 EFER bits
bx_bool sce; // system call extensions
bx_bool lme; // long mode enable
bx_bool lma; // long mode active
bx_bool nxe; // no-execute enable
bx_bool ffxsr; // fast FXSAVE/FXRSTOR
} bx_efer_t;
#endif
#include "crregs.h" #include "crregs.h"
#include "descriptor.h" #include "descriptor.h"
@ -1037,6 +1041,10 @@ public: // for now...
#endif #endif
#endif #endif
#if BX_SUPPORT_X86_64
bx_efer_t efer;
#endif
/* SMM base register */ /* SMM base register */
Bit32u smbase; Bit32u smbase;
@ -3145,11 +3153,11 @@ BX_CPP_INLINE void BX_CPU_C::set_reg64(unsigned reg, Bit64u val)
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
BX_CPP_INLINE Bit32u BX_CPU_C::get_EFER(void) BX_CPP_INLINE Bit32u BX_CPU_C::get_EFER(void)
{ {
return (BX_CPU_THIS_PTR msr.sce << 0) | return (BX_CPU_THIS_PTR efer.sce << 0) |
(BX_CPU_THIS_PTR msr.lme << 8) | (BX_CPU_THIS_PTR efer.lme << 8) |
(BX_CPU_THIS_PTR msr.lma << 10) | (BX_CPU_THIS_PTR efer.lma << 10) |
(BX_CPU_THIS_PTR msr.nxe << 11) | (BX_CPU_THIS_PTR efer.nxe << 11) |
(BX_CPU_THIS_PTR msr.ffxsr << 14); (BX_CPU_THIS_PTR efer.ffxsr << 14);
} }
#endif #endif
@ -3176,7 +3184,7 @@ BX_CPP_INLINE bx_bool BX_CPU_C::protected_mode(void)
BX_CPP_INLINE unsigned BX_CPU_C::long_mode(void) BX_CPP_INLINE unsigned BX_CPU_C::long_mode(void)
{ {
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
return BX_CPU_THIS_PTR msr.lma; return BX_CPU_THIS_PTR efer.lma;
#else #else
return 0; return 0;
#endif #endif

View File

@ -1,5 +1,5 @@
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer_pro.cc,v 1.56 2007-03-14 21:15:15 sshwarts Exp $ // $Id: ctrl_xfer_pro.cc,v 1.57 2007-09-10 20:47:08 sshwarts Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -51,7 +51,7 @@ void BX_CPU_C::check_cs(bx_descriptor_t *descriptor, Bit16u cs_raw, Bit8u check_
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
if (descriptor->u.segment.l) if (descriptor->u.segment.l)
{ {
if (! BX_CPU_THIS_PTR msr.lma) { if (! BX_CPU_THIS_PTR efer.lma) {
BX_PANIC(("check_cs: attempt to jump to long mode without enabling EFER.LMA !")); BX_PANIC(("check_cs: attempt to jump to long mode without enabling EFER.LMA !"));
} }
@ -104,7 +104,7 @@ BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp
(0xfffc & BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value) | cpl; (0xfffc & BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value) | cpl;
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR msr.lma) { if (BX_CPU_THIS_PTR efer.lma) {
if (descriptor->u.segment.l) { if (descriptor->u.segment.l) {
BX_CPU_THIS_PTR cpu_mode = BX_MODE_LONG_64; BX_CPU_THIS_PTR cpu_mode = BX_MODE_LONG_64;
BX_DEBUG(("Long Mode Activated")); BX_DEBUG(("Long Mode Activated"));

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: init.cc,v 1.130 2007-07-31 20:25:52 sshwarts Exp $ // $Id: init.cc,v 1.131 2007-09-10 20:47:08 sshwarts Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -647,11 +647,11 @@ Bit64s BX_CPU_C::param_restore(bx_param_c *param, Bit64s val)
BX_CPU_THIS_PTR setEFlags((Bit32u)val); BX_CPU_THIS_PTR setEFlags((Bit32u)val);
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
} else if (!strcmp(pname, "EFER")) { } else if (!strcmp(pname, "EFER")) {
BX_CPU_THIS_PTR msr.sce = (val >> 0) & 1; BX_CPU_THIS_PTR efer.sce = (val >> 0) & 1;
BX_CPU_THIS_PTR msr.lme = (val >> 8) & 1; BX_CPU_THIS_PTR efer.lme = (val >> 8) & 1;
BX_CPU_THIS_PTR msr.lma = (val >> 10) & 1; BX_CPU_THIS_PTR efer.lma = (val >> 10) & 1;
BX_CPU_THIS_PTR msr.nxe = (val >> 11) & 1; BX_CPU_THIS_PTR efer.nxe = (val >> 11) & 1;
BX_CPU_THIS_PTR msr.ffxsr = (val >> 14) & 1; BX_CPU_THIS_PTR efer.ffxsr = (val >> 14) & 1;
#endif #endif
} else if (!strcmp(pname, "ar_byte") || !strcmp(pname, "selector")) { } else if (!strcmp(pname, "ar_byte") || !strcmp(pname, "selector")) {
segname = param->get_parent()->get_name(); segname = param->get_parent()->get_name();
@ -946,9 +946,10 @@ void BX_CPU_C::reset(unsigned source)
BX_CPU_THIS_PTR msr.apicbase |= 0x900; BX_CPU_THIS_PTR msr.apicbase |= 0x900;
#endif #endif
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
BX_CPU_THIS_PTR msr.lme = BX_CPU_THIS_PTR msr.lma = 0; BX_CPU_THIS_PTR efer.lme = BX_CPU_THIS_PTR efer.lma = 0;
BX_CPU_THIS_PTR msr.sce = BX_CPU_THIS_PTR msr.nxe = 0; BX_CPU_THIS_PTR efer.sce = BX_CPU_THIS_PTR efer.nxe = 0;
BX_CPU_THIS_PTR msr.ffxsr = 0; BX_CPU_THIS_PTR efer.ffxsr = 0;
BX_CPU_THIS_PTR msr.star = 0; BX_CPU_THIS_PTR msr.star = 0;
BX_CPU_THIS_PTR msr.lstar = 0; BX_CPU_THIS_PTR msr.lstar = 0;
BX_CPU_THIS_PTR msr.cstar = 0; BX_CPU_THIS_PTR msr.cstar = 0;
@ -1105,7 +1106,7 @@ void BX_CPU_C::assert_checks(void)
{ {
// check CPU mode consistency // check CPU mode consistency
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR msr.lma) { if (BX_CPU_THIS_PTR efer.lma) {
if (! BX_CPU_THIS_PTR cr0.get_PE()) { if (! BX_CPU_THIS_PTR cr0.get_PE()) {
BX_PANIC(("assert_checks: EFER.LMA is set when CR0.PE=0 !")); BX_PANIC(("assert_checks: EFER.LMA is set when CR0.PE=0 !"));
} }

View File

@ -1,5 +1,5 @@
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// $Id: iret.cc,v 1.18 2007-03-14 21:15:15 sshwarts Exp $ // $Id: iret.cc,v 1.19 2007-09-10 20:47:08 sshwarts Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -46,8 +46,7 @@ BX_CPU_C::iret_protected(bxInstruction_c *i)
bx_descriptor_t cs_descriptor, ss_descriptor; bx_descriptor_t cs_descriptor, ss_descriptor;
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR msr.lma) if (long_mode()) {
{
long_iret(i); long_iret(i);
return; return;
} }

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: paging.cc,v 1.84 2007-08-30 16:48:10 sshwarts Exp $ // $Id: paging.cc,v 1.85 2007-09-10 20:47:08 sshwarts Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -584,7 +584,7 @@ void BX_CPU_C::page_fault(unsigned fault, bx_address laddr, unsigned pl, unsigne
error_code |= (pl << 2) | (rw << 1); error_code |= (pl << 2) | (rw << 1);
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR msr.nxe && (access_type == CODE_ACCESS)) if (BX_CPU_THIS_PTR efer.nxe && (access_type == CODE_ACCESS))
error_code |= ERROR_CODE_ACCESS; // I/D = 1 error_code |= ERROR_CODE_ACCESS; // I/D = 1
#endif #endif
BX_CPU_THIS_PTR cr2 = laddr; BX_CPU_THIS_PTR cr2 = laddr;
@ -669,7 +669,7 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigne
page_fault(ERROR_NOT_PRESENT, laddr, pl, isWrite, access_type); // PML4 Entry NOT present page_fault(ERROR_NOT_PRESENT, laddr, pl, isWrite, access_type); // PML4 Entry NOT present
} }
if (pml4 & PAGE_DIRECTORY_NX_BIT) { if (pml4 & PAGE_DIRECTORY_NX_BIT) {
if (! BX_CPU_THIS_PTR msr.nxe) { if (! BX_CPU_THIS_PTR efer.nxe) {
BX_DEBUG(("PML4: NX bit set when EFER.NXE is disabled")); BX_DEBUG(("PML4: NX bit set when EFER.NXE is disabled"));
page_fault(ERROR_RESERVED | ERROR_PROTECTION, laddr, pl, isWrite, access_type); page_fault(ERROR_RESERVED | ERROR_PROTECTION, laddr, pl, isWrite, access_type);
} }
@ -704,10 +704,10 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigne
page_fault(ERROR_NOT_PRESENT, laddr, pl, isWrite, access_type); // PDP Entry NOT present page_fault(ERROR_NOT_PRESENT, laddr, pl, isWrite, access_type); // PDP Entry NOT present
} }
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR msr.lma) if (BX_CPU_THIS_PTR efer.lma)
{ {
if (pdp & PAGE_DIRECTORY_NX_BIT) { if (pdp & PAGE_DIRECTORY_NX_BIT) {
if (! BX_CPU_THIS_PTR msr.nxe) { if (! BX_CPU_THIS_PTR efer.nxe) {
BX_DEBUG(("PAE PDP: NX bit set when EFER.NXE is disabled")); BX_DEBUG(("PAE PDP: NX bit set when EFER.NXE is disabled"));
page_fault(ERROR_RESERVED | ERROR_PROTECTION, laddr, pl, isWrite, access_type); page_fault(ERROR_RESERVED | ERROR_PROTECTION, laddr, pl, isWrite, access_type);
} }
@ -738,7 +738,7 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigne
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
if (pde & PAGE_DIRECTORY_NX_BIT) { if (pde & PAGE_DIRECTORY_NX_BIT) {
if (! BX_CPU_THIS_PTR msr.nxe) { if (! BX_CPU_THIS_PTR efer.nxe) {
BX_DEBUG(("PAE PDE: NX bit set when EFER.NXE is disabled")); BX_DEBUG(("PAE PDE: NX bit set when EFER.NXE is disabled"));
page_fault(ERROR_RESERVED | ERROR_PROTECTION, laddr, pl, isWrite, access_type); page_fault(ERROR_RESERVED | ERROR_PROTECTION, laddr, pl, isWrite, access_type);
} }
@ -800,7 +800,7 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigne
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
if (pte & PAGE_DIRECTORY_NX_BIT) { if (pte & PAGE_DIRECTORY_NX_BIT) {
if (! BX_CPU_THIS_PTR msr.nxe) { if (! BX_CPU_THIS_PTR efer.nxe) {
BX_DEBUG(("PAE PTE: NX bit set when EFER.NXE is disabled")); BX_DEBUG(("PAE PTE: NX bit set when EFER.NXE is disabled"));
page_fault(ERROR_RESERVED | ERROR_PROTECTION, laddr, pl, isWrite, access_type); page_fault(ERROR_RESERVED | ERROR_PROTECTION, laddr, pl, isWrite, access_type);
} }
@ -854,7 +854,7 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigne
else else
#endif // #if BX_SUPPORT_PAE #endif // #if BX_SUPPORT_PAE
{ {
// CR4.PAE==0 (and MSR.LMA==0) // CR4.PAE==0 (and EFER.LMA==0)
Bit32u pde, pte; Bit32u pde, pte;
bx_phy_address pde_addr; bx_phy_address pde_addr;

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.167 2007-07-31 20:25:52 sshwarts Exp $ // $Id: proc_ctrl.cc,v 1.168 2007-09-10 20:47:08 sshwarts Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -1210,7 +1210,7 @@ void BX_CPU_C::LOADALL(bxInstruction_c *i)
void BX_CPU_C::handleCpuModeChange(void) void BX_CPU_C::handleCpuModeChange(void)
{ {
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR msr.lma) { if (BX_CPU_THIS_PTR efer.lma) {
if (! BX_CPU_THIS_PTR cr0.get_PE()) { if (! BX_CPU_THIS_PTR cr0.get_PE()) {
BX_PANIC(("change_cpu_mode: EFER.LMA is set when CR0.PE=0 !")); BX_PANIC(("change_cpu_mode: EFER.LMA is set when CR0.PE=0 !"));
} }
@ -1293,20 +1293,24 @@ void BX_CPU_C::SetCR0(Bit32u val_32)
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
if (prev_pg==0 && BX_CPU_THIS_PTR cr0.get_PG()) { if (prev_pg==0 && BX_CPU_THIS_PTR cr0.get_PG()) {
if (BX_CPU_THIS_PTR msr.lme) { if (BX_CPU_THIS_PTR efer.lme) {
if (!BX_CPU_THIS_PTR cr4.get_PAE()) { if (!BX_CPU_THIS_PTR cr4.get_PAE()) {
BX_ERROR(("SetCR0: attempt to enter x86-64 LONG mode without enabling CR4.PAE !")); BX_ERROR(("SetCR0: attempt to enter x86-64 long mode without enabling CR4.PAE !"));
exception(BX_GP_EXCEPTION, 0, 0); exception(BX_GP_EXCEPTION, 0, 0);
} }
BX_CPU_THIS_PTR msr.lma = 1; if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.l) {
BX_ERROR(("SetCR0: attempt to enter x86-64 long mode with CS.L !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
BX_CPU_THIS_PTR efer.lma = 1;
} }
} }
else if (prev_pg==1 && ! BX_CPU_THIS_PTR cr0.get_PG()) { else if (prev_pg==1 && ! BX_CPU_THIS_PTR cr0.get_PG()) {
if (BX_CPU_THIS_PTR msr.lma) { if (BX_CPU_THIS_PTR efer.lma) {
if (BX_CPU_THIS_PTR dword.rip_upper != 0) { if (BX_CPU_THIS_PTR dword.rip_upper != 0) {
BX_PANIC(("SetCR0: attempt to leave x86-64 LONG mode with RIP upper != 0 !!!")); BX_PANIC(("SetCR0: attempt to leave x86-64 LONG mode with RIP upper != 0 !!!"));
} }
BX_CPU_THIS_PTR msr.lma = 0; BX_CPU_THIS_PTR efer.lma = 0;
} }
} }
#endif // #if BX_SUPPORT_X86_64 #endif // #if BX_SUPPORT_X86_64
@ -1376,11 +1380,11 @@ bx_bool BX_CPU_C::SetCR4(Bit32u val_32)
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
// need to GP(0) if LMA=1 and PAE=1->0 // need to GP(0) if LMA=1 and PAE=1->0
if ((BX_CPU_THIS_PTR msr.lma) if ((BX_CPU_THIS_PTR efer.lma)
&& (!(val_32 >> 5) & 1) && (!(val_32 >> 5) & 1)
&& (BX_CPU_THIS_PTR cr4.get_PAE())) && (BX_CPU_THIS_PTR cr4.get_PAE()))
{ {
BX_ERROR(("SetCR4: attempt to change PAE when LMA=1")); BX_ERROR(("SetCR4: attempt to change PAE when EFER.LMA=1"));
return 0; return 0;
} }
#endif #endif
@ -1711,16 +1715,16 @@ void BX_CPU_C::WRMSR(bxInstruction_c *i)
case BX_MSR_EFER: case BX_MSR_EFER:
// GPF #0 if lme 0->1 and cr0.pg = 1 // GPF #0 if lme 0->1 and cr0.pg = 1
// GPF #0 if lme 1->0 and cr0.pg = 1 // GPF #0 if lme 1->0 and cr0.pg = 1
if ((BX_CPU_THIS_PTR msr.lme != ((EAX >> 8) & 1)) && if ((BX_CPU_THIS_PTR efer.lme != ((EAX >> 8) & 1)) &&
BX_CPU_THIS_PTR cr0.get_PG()) BX_CPU_THIS_PTR cr0.get_PG())
{ {
BX_ERROR(("WRMSR: attempt to change LME when CR0.PG=1")); BX_ERROR(("WRMSR: attempt to change LME when CR0.PG=1"));
exception(BX_GP_EXCEPTION, 0, 0); exception(BX_GP_EXCEPTION, 0, 0);
} }
BX_CPU_THIS_PTR msr.sce = (EAX >> 0) & 1; BX_CPU_THIS_PTR efer.sce = (EAX >> 0) & 1;
BX_CPU_THIS_PTR msr.lme = (EAX >> 8) & 1; BX_CPU_THIS_PTR efer.lme = (EAX >> 8) & 1;
BX_CPU_THIS_PTR msr.nxe = (EAX >> 11) & 1; BX_CPU_THIS_PTR efer.nxe = (EAX >> 11) & 1;
BX_CPU_THIS_PTR msr.ffxsr = (EAX >> 14) & 1; BX_CPU_THIS_PTR efer.ffxsr = (EAX >> 14) & 1;
return; return;
case BX_MSR_STAR: case BX_MSR_STAR:
@ -1966,13 +1970,13 @@ SYSCALL_LEGACY_MODE:
BX_DEBUG(("Execute SYSCALL instruction")); BX_DEBUG(("Execute SYSCALL instruction"));
if (!BX_CPU_THIS_PTR msr.sce) { if (!BX_CPU_THIS_PTR efer.sce) {
exception(BX_UD_EXCEPTION, 0, 0); exception(BX_UD_EXCEPTION, 0, 0);
} }
invalidate_prefetch_q(); invalidate_prefetch_q();
if (BX_CPU_THIS_PTR msr.lma) if (BX_CPU_THIS_PTR efer.lma)
{ {
RCX = RIP; RCX = RIP;
R11 = read_eflags() & ~(EFlagsRFMask); R11 = read_eflags() & ~(EFlagsRFMask);
@ -2137,7 +2141,7 @@ SYSRET_NON_64BIT_MODE:
BX_DEBUG(("Execute SYSRET instruction")); BX_DEBUG(("Execute SYSRET instruction"));
if (!BX_CPU_THIS_PTR msr.sce) { if (!BX_CPU_THIS_PTR efer.sce) {
exception(BX_UD_EXCEPTION, 0, 0); exception(BX_UD_EXCEPTION, 0, 0);
} }

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: segment_ctrl_pro.cc,v 1.69 2007-03-14 21:15:15 sshwarts Exp $ // $Id: segment_ctrl_pro.cc,v 1.70 2007-09-10 20:47:08 sshwarts Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2001 MandrakeSoft S.A. // Copyright (C) 2001 MandrakeSoft S.A.
@ -41,7 +41,7 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
if ((new_value & 0xfffc) == 0) { /* null selector */ if ((new_value & 0xfffc) == 0) { /* null selector */
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
// allow SS = 0 in 64 bit mode with cpl != 3 // allow SS = 0 in 64 bit mode with cpl != 3
if (BX_CPU_THIS_PTR msr.lma && CPL != 3) { if (BX_CPU_THIS_PTR efer.lma && CPL != 3) {
seg->selector.index = 0; seg->selector.index = 0;
seg->selector.ti = 0; seg->selector.ti = 0;
seg->selector.rpl = 0; seg->selector.rpl = 0;

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// $Id: smm.cc,v 1.25 2007-07-09 15:16:13 sshwarts Exp $ // $Id: smm.cc,v 1.26 2007-09-10 20:47:08 sshwarts Exp $
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2006 Stanislav Shwartsman // Copyright (c) 2006 Stanislav Shwartsman
@ -142,10 +142,10 @@ void BX_CPU_C::enter_system_management_mode(void)
BX_CPU_THIS_PTR cr4.setRegister(0); BX_CPU_THIS_PTR cr4.setRegister(0);
#endif #endif
// EFER.LME = 0, EFER.LME = 1 // EFER.LME = 0, EFER.LME = 0
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
BX_CPU_THIS_PTR msr.lme = 0; BX_CPU_THIS_PTR efer.lme = 0;
BX_CPU_THIS_PTR msr.lma = 0; BX_CPU_THIS_PTR efer.lma = 0;
#endif #endif
parse_selector(BX_CPU_THIS_PTR smbase >> 4, parse_selector(BX_CPU_THIS_PTR smbase >> 4,
@ -359,26 +359,26 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
return 0; return 0;
} }
BX_CPU_THIS_PTR msr.sce = (temp_efer >> 0) & 1; BX_CPU_THIS_PTR efer.sce = (temp_efer >> 0) & 1;
BX_CPU_THIS_PTR msr.lme = (temp_efer >> 8) & 1; BX_CPU_THIS_PTR efer.lme = (temp_efer >> 8) & 1;
BX_CPU_THIS_PTR msr.lma = (temp_efer >> 10) & 1; BX_CPU_THIS_PTR efer.lma = (temp_efer >> 10) & 1;
BX_CPU_THIS_PTR msr.nxe = (temp_efer >> 11) & 1; BX_CPU_THIS_PTR efer.nxe = (temp_efer >> 11) & 1;
BX_CPU_THIS_PTR msr.ffxsr = (temp_efer >> 14) & 1; BX_CPU_THIS_PTR efer.ffxsr = (temp_efer >> 14) & 1;
if (BX_CPU_THIS_PTR msr.lma) { if (BX_CPU_THIS_PTR efer.lma) {
if (temp_eflags & EFlagsVMMask) { if (temp_eflags & EFlagsVMMask) {
BX_PANIC(("SMM restore: If EFER.LMA = 1 => RFLAGS.VM=0 !")); BX_PANIC(("SMM restore: If EFER.LMA = 1 => RFLAGS.VM=0 !"));
return 0; return 0;
} }
if (!BX_CPU_THIS_PTR cr4.get_PAE() || !pg || !pe || !BX_CPU_THIS_PTR msr.lme) { if (!BX_CPU_THIS_PTR cr4.get_PAE() || !pg || !pe || !BX_CPU_THIS_PTR efer.lme) {
BX_PANIC(("SMM restore: If EFER.LMA = 1 <=> CR4.PAE, CR0.PG, CR0.PE, EFER.LME=1 !")); BX_PANIC(("SMM restore: If EFER.LMA = 1 <=> CR4.PAE, CR0.PG, CR0.PE, EFER.LME=1 !"));
return 0; return 0;
} }
} }
if (BX_CPU_THIS_PTR cr4.get_PAE() && pg && pe && BX_CPU_THIS_PTR msr.lme) { if (BX_CPU_THIS_PTR cr4.get_PAE() && pg && pe && BX_CPU_THIS_PTR efer.lme) {
if (! BX_CPU_THIS_PTR msr.lma) { if (! BX_CPU_THIS_PTR efer.lma) {
BX_PANIC(("SMM restore: If EFER.LMA = 1 <=> CR4.PAE, CR0.PG, CR0.PE, EFER.LME=1 !")); BX_PANIC(("SMM restore: If EFER.LMA = 1 <=> CR4.PAE, CR0.PG, CR0.PE, EFER.LME=1 !"));
return 0; return 0;
} }