From 836e9649d8f65b4d6e39ad1bfb00c82fe3347035 Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Sat, 10 Jan 2009 10:07:57 +0000 Subject: [PATCH] modify set cr0 functionality --- bochs/cpu/cpu.h | 8 +++++--- bochs/cpu/descriptor.h | 3 ++- bochs/cpu/init.cc | 5 +++-- bochs/cpu/proc_ctrl.cc | 27 ++++++++++++++++----------- bochs/cpu/smm.cc | 12 +++++++++--- bochs/load32bitOShack.cc | 7 +++++-- 6 files changed, 40 insertions(+), 22 deletions(-) diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 5a7a93676..09b0c2291 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -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); diff --git a/bochs/cpu/descriptor.h b/bochs/cpu/descriptor.h index 2289a4b87..00ea32030 100755 --- a/bochs/cpu/descriptor.h +++ b/bochs/cpu/descriptor.h @@ -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) diff --git a/bochs/cpu/init.cc b/bochs/cpu/init.cc index e21fe1060..22de81761 100644 --- a/bochs/cpu/init.cc +++ b/bochs/cpu/init.cc @@ -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(); diff --git a/bochs/cpu/proc_ctrl.cc b/bochs/cpu/proc_ctrl.cc index 68b6ffdb4..9567b0386 100644 --- a/bochs/cpu/proc_ctrl.cc +++ b/bochs/cpu/proc_ctrl.cc @@ -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 diff --git a/bochs/cpu/smm.cc b/bochs/cpu/smm.cc index ead291596..b967bca24 100755 --- a/bochs/cpu/smm.cc +++ b/bochs/cpu/smm.cc @@ -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); diff --git a/bochs/load32bitOShack.cc b/bochs/load32bitOShack.cc index 6fc217708..070c875ab 100644 --- a/bochs/load32bitOShack.cc +++ b/bochs/load32bitOShack.cc @@ -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;