modify set cr0 functionality

This commit is contained in:
Stanislav Shwartsman 2009-01-10 10:07:57 +00:00
parent 4369152c70
commit 836e9649d8
6 changed files with 40 additions and 22 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.548 2009-01-08 18:07:43 sshwarts Exp $
// $Id: cpu.h,v 1.549 2009-01-10 10:07:57 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -2420,6 +2420,9 @@ public: // for now...
BX_SMF void POPCNT_GwEwR(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void POPCNT_GdEdR(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
#if BX_SUPPORT_X86_64
BX_SMF void POPCNT_GqEqR(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
#endif
#if BX_SUPPORT_X86_64
// 64 bit extensions
@ -2717,7 +2720,6 @@ public: // for now...
BX_SMF void MOVQ_PqEq(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void MOVQ_VdqEq(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void MOVNTI_MqGq(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void POPCNT_GqEqR(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
#endif // #if BX_SUPPORT_X86_64
BX_SMF void INVLPG(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
@ -3085,7 +3087,7 @@ public: // for now...
BX_SMF void smram_save_state(Bit32u *smm_saved_state);
BX_SMF bx_bool smram_restore_state(const Bit32u *smm_saved_state);
BX_SMF int int_number(unsigned s);
BX_SMF void SetCR0(Bit32u val_32) BX_CPP_AttrRegparmN(1);
BX_SMF bx_bool SetCR0(Bit32u val_32) BX_CPP_AttrRegparmN(1);
BX_SMF void SetCR3(bx_address value) BX_CPP_AttrRegparmN(1);
#if BX_CPU_LEVEL >= 4
BX_SMF bx_bool SetCR4(bx_address val) BX_CPP_AttrRegparmN(1);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: descriptor.h,v 1.25 2008-09-08 20:47:33 sshwarts Exp $
// $Id: descriptor.h,v 1.26 2009-01-10 10:07:57 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007 Stanislav Shwartsman
@ -55,6 +55,7 @@ typedef struct { /* bx_selector_t */
typedef struct
{
// do not go above 4 bits !
#define SegValidCache (0x01)
#define SegAccessROK (0x02)
#define SegAccessWOK (0x04)

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: init.cc,v 1.188 2009-01-08 18:07:44 sshwarts Exp $
// $Id: init.cc,v 1.189 2009-01-10 10:07:57 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -670,7 +670,8 @@ void BX_CPU_C::after_restore_state(void)
{
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_IA32_V8086) CPL = 3;
SetCR0(cr0.val32);
if (!SetCR0(cr0.val32))
BX_PANIC(("Incorrect CR0 state !"));
SetCR3(cr3);
TLB_flush();
assert_checks();

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.268 2009-01-10 09:36:44 sshwarts Exp $
// $Id: proc_ctrl.cc,v 1.269 2009-01-10 10:07:57 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -554,7 +554,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_CdRd(bxInstruction_c *i)
switch (i->nnn()) {
case 0: // CR0 (MSW)
SetCR0(val_32);
if (! SetCR0(val_32))
exception(BX_GP_EXCEPTION, 0, 0);
break;
case 2: /* CR2 */
BX_DEBUG(("MOV_CdRd:CR2 = %08x", val_32));
@ -655,7 +656,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_CqRq(bxInstruction_c *i)
switch (i->nnn()) {
case 0: // CR0 (MSW)
SetCR0((Bit32u) val_64);
if (! SetCR0((Bit32u) val_64))
exception(BX_GP_EXCEPTION, 0, 0);
break;
case 2: /* CR2 */
BX_DEBUG(("MOV_CqRq: write to CR2 of %08x:%08x", GET32H(val_64), GET32L(val_64)));
@ -783,7 +785,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LMSW_Ew(bxInstruction_c *i)
msw &= 0xf; // LMSW only affects last 4 flags
Bit32u cr0 = (BX_CPU_THIS_PTR cr0.get32() & 0xfffffff0) | msw;
SetCR0(cr0);
if (! SetCR0(cr0))
exception(BX_GP_EXCEPTION, 0, 0);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::SMSW_EwR(bxInstruction_c *i)
@ -1159,7 +1162,7 @@ void BX_CPU_C::handleAlignmentCheck(void)
}
#endif
void BX_CPP_AttrRegparmN(1) BX_CPU_C::SetCR0(Bit32u val_32)
bx_bool BX_CPP_AttrRegparmN(1) BX_CPU_C::SetCR0(Bit32u val_32)
{
bx_bool pe = val_32 & 0x01;
bx_bool nw = (val_32 >> 29) & 0x01;
@ -1168,12 +1171,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SetCR0(Bit32u val_32)
if (pg && !pe) {
BX_ERROR(("SetCR0: GP(0) when attempt to set CR0.PG with CR0.PE cleared !"));
exception(BX_GP_EXCEPTION, 0, 0);
return 0;
}
if (nw && !cd) {
BX_ERROR(("SetCR0: GP(0) when attempt to set CR0.NW with CR0.CD cleared !"));
exception(BX_GP_EXCEPTION, 0, 0);
return 0;
}
if (pe && BX_CPU_THIS_PTR get_VM()) BX_PANIC(("EFLAGS.VM=1, enter_PM"));
@ -1189,15 +1192,15 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SetCR0(Bit32u val_32)
if (BX_CPU_THIS_PTR efer.get_LME()) {
if (!BX_CPU_THIS_PTR cr4.get_PAE()) {
BX_ERROR(("SetCR0: attempt to enter x86-64 long mode without enabling CR4.PAE !"));
exception(BX_GP_EXCEPTION, 0, 0);
return 0;
}
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);
return 0;
}
if (BX_CPU_THIS_PTR tr.cache.type <= 3) {
BX_ERROR(("SetCR0: attempt to enter x86-64 long mode with TSS286 in TR !"));
exception(BX_GP_EXCEPTION, 0, 0);
return 0;
}
BX_CPU_THIS_PTR efer.set_LMA(1);
}
@ -1205,7 +1208,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SetCR0(Bit32u val_32)
else if (prev_pg==1 && ! pg) {
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
BX_ERROR(("SetCR0: attempt to leave 64 bit mode directly to legacy mode !"));
exception(BX_GP_EXCEPTION, 0, 0);
return 0;
}
if (BX_CPU_THIS_PTR efer.get_LMA()) {
if (BX_CPU_THIS_PTR gen_reg[BX_64BIT_REG_RIP].dword.hrx != 0) {
@ -1239,6 +1242,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SetCR0(Bit32u val_32)
// Give the paging unit a chance to look for changes in bits
// it cares about, like {PG,PE}, so it can flush cache entries etc.
pagingCR0Changed(oldCR0, val_32);
return 1;
}
#if BX_CPU_LEVEL >= 4

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: smm.cc,v 1.49 2008-12-06 18:52:02 sshwarts Exp $
// $Id: smm.cc,v 1.50 2009-01-10 10:07:57 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006 Stanislav Shwartsman
@ -388,7 +388,10 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
// hack CR0 to be able to back to long mode correctly
BX_CPU_THIS_PTR cr0.set_PE(0); // real mode (bit 0)
BX_CPU_THIS_PTR cr0.set_PG(0); // paging disabled (bit 31)
SetCR0(temp_cr0);
if (! SetCR0(temp_cr0)) {
BX_PANIC(("SMM restore: failed to restore CR0 !"));
return 0;
}
setEFlags(temp_eflags);
bx_phy_address temp_cr3 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR3);
@ -662,7 +665,10 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
return 0;
}
SetCR0(temp_cr0);
if (!SetCR0(temp_cr0)) {
BX_PANIC(("SMM restore: failed to restore CR0 !"));
return 0;
}
SetCR3(temp_cr3);
setEFlags(temp_eflags);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: load32bitOShack.cc,v 1.30 2008-05-01 20:08:36 sshwarts Exp $
// $Id: load32bitOShack.cc,v 1.31 2009-01-10 10:07:56 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -213,7 +213,10 @@ void bx_load_linux_hack(void)
// BX_CPU(0)->cr0.pe = 1;
// BX_CPU(0)->cr0.val32 |= 0x01;
BX_CPU(0)->SetCR0(BX_CPU(0)->cr0.val32 | 0x01);
if (! BX_CPU(0)->SetCR0(BX_CPU(0)->cr0.val32 | 0x01)) {
BX_INFO(("bx_load_linux_hack: can't enable protected mode in CR0"));
BX_EXIT(1);
}
// load esi with real_mode
BX_CPU(0)->gen_reg[BX_32BIT_REG_ESI].dword.erx = 0x90000;