modify set cr0 functionality
This commit is contained in:
parent
4369152c70
commit
836e9649d8
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user