diff --git a/bochs/bx_debug/dbg_main.cc b/bochs/bx_debug/dbg_main.cc index 12cf0f1be..ca47a48db 100644 --- a/bochs/bx_debug/dbg_main.cc +++ b/bochs/bx_debug/dbg_main.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: dbg_main.cc,v 1.105 2007-11-01 20:53:20 sshwarts Exp $ +// $Id: dbg_main.cc,v 1.106 2007-11-24 14:22:32 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -207,9 +207,9 @@ int bx_dbg_main(void) // in the disassembly code to decide what instruction to print. for (int i=0; iguard_found.cs = BX_CPU(i)->sregs[BX_SEG_REG_CS].selector.value; - BX_CPU(i)->guard_found.eip = BX_CPU(i)->prev_eip; + BX_CPU(i)->guard_found.eip = BX_CPU(i)->prev_rip; BX_CPU(i)->guard_found.laddr = - (BX_CPU(i)->get_segment_base(BX_SEG_REG_CS) + BX_CPU(i)->prev_eip); + (BX_CPU(i)->get_segment_base(BX_SEG_REG_CS) + BX_CPU(i)->prev_rip); BX_CPU(i)->guard_found.is_32bit_code = (BX_CPU(i)->sregs[BX_SEG_REG_CS].cache.u.segment.d_b); BX_CPU(i)->guard_found.is_64bit_code = diff --git a/bochs/cpu/cpu.cc b/bochs/cpu/cpu.cc index d8c410ab6..751d0e204 100644 --- a/bochs/cpu/cpu.cc +++ b/bochs/cpu/cpu.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.cc,v 1.182 2007-11-17 23:28:30 sshwarts Exp $ +// $Id: cpu.cc,v 1.183 2007-11-24 14:22:32 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -220,8 +220,8 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count) // back from an exception() call. In either case, commit the // new EIP/ESP, and set up other environmental fields. This code // mirrors similar code below, after the interrupt() call. - BX_CPU_THIS_PTR prev_eip = RIP; // commit new EIP - BX_CPU_THIS_PTR prev_esp = RSP; // commit new ESP + BX_CPU_THIS_PTR prev_rip = RIP; // commit new EIP + BX_CPU_THIS_PTR speculative_rsp = 0; BX_CPU_THIS_PTR EXT = 0; BX_CPU_THIS_PTR errorno = 0; @@ -263,7 +263,7 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count) #if BX_DEBUGGER bx_dbg_disassemble_current(BX_CPU_ID, 1); // only one cpu, print time stamp #else - debug_disasm_instruction(BX_CPU_THIS_PTR prev_eip); + debug_disasm_instruction(BX_CPU_THIS_PTR prev_rip); #endif } #endif @@ -272,8 +272,7 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count) BX_INSTR_BEFORE_EXECUTION(BX_CPU_ID, i); RIP += i->ilen(); BX_CPU_CALL_METHOD(i->execute, (i)); // might iterate repeat instruction - BX_CPU_THIS_PTR prev_eip = RIP; // commit new RIP - BX_CPU_THIS_PTR prev_esp = RSP; // commit new RSP + BX_CPU_THIS_PTR prev_rip = RIP; // commit new RIP BX_INSTR_AFTER_EXECUTION(BX_CPU_ID, i); BX_TICK1_IF_SINGLE_PROCESSOR(); @@ -353,7 +352,7 @@ void BX_CPU_C::repeat(bxInstruction_c *i, BxExecutePtr_t execute) } } - RIP = BX_CPU_THIS_PTR prev_eip; // repeat loop not done, restore RIP + RIP = BX_CPU_THIS_PTR prev_rip; // repeat loop not done, restore RIP } void BX_CPU_C::repeat_ZFL(bxInstruction_c *i, BxExecutePtr_t execute) @@ -428,7 +427,7 @@ void BX_CPU_C::repeat_ZFL(bxInstruction_c *i, BxExecutePtr_t execute) } } - RIP = BX_CPU_THIS_PTR prev_eip; // repeat loop not done, restore RIP + RIP = BX_CPU_THIS_PTR prev_rip; // repeat loop not done, restore RIP } unsigned BX_CPU_C::handleAsyncEvent(void) @@ -575,8 +574,8 @@ unsigned BX_CPU_C::handleAsyncEvent(void) // the new EIP/ESP values. But here, we call interrupt() much like // it was a sofware interrupt instruction, and need to effect the // commit here. This code mirrors similar code above. - BX_CPU_THIS_PTR prev_eip = RIP; // commit new RIP - BX_CPU_THIS_PTR prev_esp = RSP; // commit new RSP + BX_CPU_THIS_PTR prev_rip = RIP; // commit new RIP + BX_CPU_THIS_PTR speculative_rsp = 0; BX_CPU_THIS_PTR EXT = 0; BX_CPU_THIS_PTR errorno = 0; } @@ -627,7 +626,7 @@ unsigned BX_CPU_C::handleAsyncEvent(void) else { // only bother comparing if any breakpoints enabled if (BX_CPU_THIS_PTR dr7 & 0x000000ff) { - bx_address iaddr = BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_CS) + BX_CPU_THIS_PTR prev_eip; + bx_address iaddr = BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_CS) + BX_CPU_THIS_PTR prev_rip; Bit32u dr6_bits = hwdebug_compare(iaddr, 1, BX_HWDebugInstruction, BX_HWDebugInstruction); if (dr6_bits) { @@ -785,7 +784,7 @@ void BX_CPU_C::boundaryFetch(Bit8u *fetchPtr, unsigned remainingInPage, bxInstru } // Restore EIP since we fudged it to start at the 2nd page boundary. - RIP = BX_CPU_THIS_PTR prev_eip; + RIP = BX_CPU_THIS_PTR prev_rip; // Since we cross an instruction boundary, note that we need a prefetch() // again on the next instruction. Perhaps we can optimize this to diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 02bfcd7d6..c8245d379 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.h,v 1.374 2007-11-23 22:49:54 sshwarts Exp $ +// $Id: cpu.h,v 1.375 2007-11-24 14:22:32 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -440,23 +440,29 @@ typedef struct { (BX_CPU_THIS_PTR eflags.val32&~(1<= 4 #define DECLARE_EFLAG_ACCESSOR_AC(bitnum) \ - BX_CPP_INLINE void clear_AC (); \ + BX_CPP_INLINE void clear_AC(); \ BX_CPP_INLINE Bit32u get_AC(); \ BX_CPP_INLINE bx_bool getB_AC(); \ + BX_CPP_INLINE void set_AC(bx_bool val); \ #define IMPLEMENT_EFLAG_ACCESSOR_AC(bitnum) \ BX_CPP_INLINE void BX_CPU_C::clear_AC () { \ BX_CPU_THIS_PTR eflags.val32 &= ~(1<> bitnum); \ + } \ + BX_CPP_INLINE void BX_CPU_C::set_AC(bx_bool val) { \ + BX_CPU_THIS_PTR eflags.val32 = \ + (BX_CPU_THIS_PTR eflags.val32&~(1<= 4 DECLARE_EFLAG_ACCESSOR_AC( 18) #else DECLARE_EFLAG_ACCESSOR (AC, 18) diff --git a/bochs/cpu/ctrl_xfer16.cc b/bochs/cpu/ctrl_xfer16.cc index 274e67878..21e7303d4 100644 --- a/bochs/cpu/ctrl_xfer16.cc +++ b/bochs/cpu/ctrl_xfer16.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer16.cc,v 1.42 2007-11-18 18:24:45 sshwarts Exp $ +// $Id: ctrl_xfer16.cc,v 1.43 2007-11-24 14:22:33 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -31,6 +31,11 @@ #include "cpu.h" #define LOG_THIS BX_CPU_THIS_PTR +// Make code more tidy with a few macros. +#if BX_SUPPORT_X86_64==0 +#define RSP ESP +#endif + void BX_CPU_C::RETnear16_Iw(bxInstruction_c *i) { @@ -40,6 +45,9 @@ void BX_CPU_C::RETnear16_Iw(bxInstruction_c *i) BX_CPU_THIS_PTR show_flag |= Flag_ret; #endif + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_16(&return_IP); if (return_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) @@ -55,7 +63,9 @@ void BX_CPU_C::RETnear16_Iw(bxInstruction_c *i) if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */ ESP += imm16; else - SP += imm16; + SP += imm16; + + BX_CPU_THIS_PTR speculative_rsp = 0; BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, EIP); } @@ -68,6 +78,9 @@ void BX_CPU_C::RETnear16(bxInstruction_c *i) BX_CPU_THIS_PTR show_flag |= Flag_ret; #endif + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_16(&return_IP); if (return_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) @@ -78,6 +91,8 @@ void BX_CPU_C::RETnear16(bxInstruction_c *i) EIP = return_IP; + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, EIP); } @@ -94,12 +109,13 @@ void BX_CPU_C::RETfar16_Iw(bxInstruction_c *i) imm16 = i->Iw(); -#if BX_CPU_LEVEL >= 2 + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + if (protected_mode()) { BX_CPU_THIS_PTR return_protected(i, imm16); goto done; } -#endif pop_16(&ip); pop_16(&cs_raw); @@ -110,9 +126,12 @@ void BX_CPU_C::RETfar16_Iw(bxInstruction_c *i) if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) ESP += imm16; else - SP += imm16; + SP += imm16; done: + + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } @@ -127,12 +146,13 @@ void BX_CPU_C::RETfar16(bxInstruction_c *i) BX_CPU_THIS_PTR show_flag |= Flag_ret; #endif -#if BX_CPU_LEVEL >= 2 - if ( protected_mode() ) { + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + + if (protected_mode()) { BX_CPU_THIS_PTR return_protected(i, 0); goto done; } -#endif pop_16(&ip); pop_16(&cs_raw); @@ -141,6 +161,9 @@ void BX_CPU_C::RETfar16(bxInstruction_c *i) EIP = (Bit32u) ip; done: + + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } @@ -183,12 +206,13 @@ void BX_CPU_C::CALL16_Ap(bxInstruction_c *i) disp16 = i->Iw(); cs_raw = i->Iw2(); -#if BX_CPU_LEVEL >= 2 + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + if (protected_mode()) { BX_CPU_THIS_PTR call_protected(i, cs_raw, disp16); goto done; } -#endif push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value); push_16((Bit16u) EIP); @@ -197,6 +221,9 @@ void BX_CPU_C::CALL16_Ap(bxInstruction_c *i) EIP = (Bit32u) disp16; done: + + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } @@ -216,13 +243,11 @@ void BX_CPU_C::CALL_Ew(bxInstruction_c *i) read_virtual_word(i->seg(), RMAddr(i), &op1_16); } -#if BX_CPU_LEVEL >= 2 if (op1_16 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) { BX_ERROR(("CALL_Ew: IP out of CS limits!")); exception(BX_GP_EXCEPTION, 0, 0); } -#endif push_16(IP); EIP = op1_16; @@ -244,6 +269,9 @@ void BX_CPU_C::CALL16_Ep(bxInstruction_c *i) read_virtual_word(i->seg(), RMAddr(i), &op1_16); read_virtual_word(i->seg(), RMAddr(i)+2, &cs_raw); + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + if (protected_mode()) { BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_16); goto done; @@ -256,6 +284,9 @@ void BX_CPU_C::CALL16_Ep(bxInstruction_c *i) EIP = op1_16; done: + + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } @@ -535,17 +566,20 @@ void BX_CPU_C::JMP16_Ep(bxInstruction_c *i) read_virtual_word(i->seg(), RMAddr(i), &op1_16); read_virtual_word(i->seg(), RMAddr(i)+2, &cs_raw); -#if BX_CPU_LEVEL >= 2 - if ( protected_mode() ) { + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + + if (protected_mode()) { BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_16); goto done; } -#endif load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw); EIP = op1_16; done: + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } @@ -562,6 +596,9 @@ void BX_CPU_C::IRET16(bxInstruction_c *i) BX_CPU_THIS_PTR nmi_disable = 0; + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + if (v8086_mode()) { // IOPL check in stack_return_from_v86() iret16_stack_return_from_v86(i); @@ -587,6 +624,8 @@ void BX_CPU_C::IRET16(bxInstruction_c *i) write_flags(flags, /* change IOPL? */ 1, /* change IF? */ 1); done: + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } diff --git a/bochs/cpu/ctrl_xfer32.cc b/bochs/cpu/ctrl_xfer32.cc index 43b5bb73e..3d84ddd41 100644 --- a/bochs/cpu/ctrl_xfer32.cc +++ b/bochs/cpu/ctrl_xfer32.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer32.cc,v 1.54 2007-11-17 18:08:46 sshwarts Exp $ +// $Id: ctrl_xfer32.cc,v 1.55 2007-11-24 14:22:33 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -31,6 +31,10 @@ #include "cpu.h" #define LOG_THIS BX_CPU_THIS_PTR +// Make code more tidy with a few macros. +#if BX_SUPPORT_X86_64==0 +#define RSP ESP +#endif #if BX_CPU_LEVEL >= 3 @@ -42,13 +46,18 @@ void BX_CPU_C::RETnear32_Iw(bxInstruction_c *i) BX_CPU_THIS_PTR show_flag |= Flag_ret; #endif + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + Bit16u imm16 = i->Iw(); pop_32(&return_EIP); branch_near32(return_EIP); if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) ESP += imm16; else - SP += imm16; + SP += imm16; + + BX_CPU_THIS_PTR speculative_rsp = 0; BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, EIP); } @@ -61,9 +70,14 @@ void BX_CPU_C::RETnear32(bxInstruction_c *i) BX_CPU_THIS_PTR show_flag |= Flag_ret; #endif + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_32(&return_EIP); branch_near32(return_EIP); + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, EIP); } @@ -79,6 +93,9 @@ void BX_CPU_C::RETfar32_Iw(bxInstruction_c *i) Bit16u imm16 = i->Iw(); + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + if (protected_mode()) { BX_CPU_THIS_PTR return_protected(i, imm16); goto done; @@ -93,9 +110,11 @@ void BX_CPU_C::RETfar32_Iw(bxInstruction_c *i) if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) ESP += imm16; else - SP += imm16; + SP += imm16; done: + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } @@ -110,7 +129,10 @@ void BX_CPU_C::RETfar32(bxInstruction_c *i) BX_CPU_THIS_PTR show_flag |= Flag_ret; #endif - if ( protected_mode() ) { + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + + if (protected_mode()) { BX_CPU_THIS_PTR return_protected(i, 0); goto done; } @@ -122,6 +144,8 @@ void BX_CPU_C::RETfar32(bxInstruction_c *i) EIP = eip; done: + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } @@ -160,6 +184,9 @@ void BX_CPU_C::CALL32_Ap(bxInstruction_c *i) disp32 = i->Id(); cs_raw = i->Iw2(); + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + if (protected_mode()) { BX_CPU_THIS_PTR call_protected(i, cs_raw, disp32); goto done; @@ -172,6 +199,8 @@ void BX_CPU_C::CALL32_Ap(bxInstruction_c *i) EIP = disp32; done: + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } @@ -218,7 +247,10 @@ void BX_CPU_C::CALL32_Ep(bxInstruction_c *i) read_virtual_dword(i->seg(), RMAddr(i), &op1_32); read_virtual_word(i->seg(), RMAddr(i)+4, &cs_raw); - if ( protected_mode() ) { + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + + if (protected_mode()) { BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_32); goto done; } @@ -230,6 +262,8 @@ void BX_CPU_C::CALL32_Ep(bxInstruction_c *i) load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw); done: + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } @@ -480,6 +514,9 @@ void BX_CPU_C::JMP_Ap(bxInstruction_c *i) } cs_raw = i->Iw2(); + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + if (protected_mode()) { BX_CPU_THIS_PTR jump_protected(i, cs_raw, disp32); } @@ -488,6 +525,8 @@ void BX_CPU_C::JMP_Ap(bxInstruction_c *i) EIP = disp32; } + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } @@ -522,6 +561,9 @@ void BX_CPU_C::JMP32_Ep(bxInstruction_c *i) read_virtual_dword(i->seg(), RMAddr(i), &op1_32); read_virtual_word(i->seg(), RMAddr(i)+4, &cs_raw); + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + if (protected_mode()) { BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_32); } @@ -530,6 +572,8 @@ void BX_CPU_C::JMP32_Ep(bxInstruction_c *i) EIP = op1_32; } + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } @@ -544,6 +588,9 @@ void BX_CPU_C::IRET32(bxInstruction_c *i) BX_CPU_THIS_PTR nmi_disable = 0; + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + if (v8086_mode()) { // IOPL check in stack_return_from_v86() iret32_stack_return_from_v86(i); @@ -579,6 +626,8 @@ void BX_CPU_C::IRET32(bxInstruction_c *i) writeEFlags(eflags, 0x00257fd5); // VIF, VIP, VM unchanged done: + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } diff --git a/bochs/cpu/ctrl_xfer64.cc b/bochs/cpu/ctrl_xfer64.cc index 84d20961e..f4c67c08d 100644 --- a/bochs/cpu/ctrl_xfer64.cc +++ b/bochs/cpu/ctrl_xfer64.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer64.cc,v 1.53 2007-11-17 12:44:09 sshwarts Exp $ +// $Id: ctrl_xfer64.cc,v 1.54 2007-11-24 14:22:33 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -44,6 +44,9 @@ void BX_CPU_C::RETnear64_Iw(bxInstruction_c *i) Bit16u imm16 = i->Iw(); + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_64(&return_RIP); if (! IsCanonical(return_RIP)) { @@ -54,6 +57,8 @@ void BX_CPU_C::RETnear64_Iw(bxInstruction_c *i) RIP = return_RIP; RSP += imm16; + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, RIP); } @@ -65,6 +70,9 @@ void BX_CPU_C::RETnear64(bxInstruction_c *i) BX_CPU_THIS_PTR show_flag |= Flag_ret; #endif + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_64(&return_RIP); if (! IsCanonical(return_RIP)) { @@ -74,6 +82,8 @@ void BX_CPU_C::RETnear64(bxInstruction_c *i) RIP = return_RIP; + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, RIP); } @@ -87,10 +97,14 @@ void BX_CPU_C::RETfar64_Iw(bxInstruction_c *i) BX_ASSERT(protected_mode()); - BX_INFO(("RETfar64_Iw instruction executed ...")); + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + // return_protected is not RSP safe return_protected(i, i->Iw()); + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP); } @@ -105,10 +119,14 @@ void BX_CPU_C::RETfar64(bxInstruction_c *i) BX_ASSERT(protected_mode()); - BX_INFO(("RETfar64 instruction executed ...")); + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + // return_protected is not RSP safe return_protected(i, 0); + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP); } @@ -177,7 +195,13 @@ void BX_CPU_C::CALL64_Ep(bxInstruction_c *i) BX_ASSERT(protected_mode()); - BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_32); + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + + // call_protected is not RSP safe + call_protected(i, cs_raw, op1_32); + + BX_CPU_THIS_PTR speculative_rsp = 0; BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP); @@ -430,7 +454,14 @@ void BX_CPU_C::JMP64_Ep(bxInstruction_c *i) read_virtual_word(i->seg(), RMAddr(i)+4, &cs_raw); BX_ASSERT(protected_mode()); - BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_32); + + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + + // jump_protected is nto RSP safe + jump_protected(i, cs_raw, op1_32); + + BX_CPU_THIS_PTR speculative_rsp = 0; BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP); @@ -447,7 +478,14 @@ void BX_CPU_C::IRET64(bxInstruction_c *i) BX_CPU_THIS_PTR nmi_disable = 0; BX_ASSERT(protected_mode()); - iret_protected(i); + + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + + // long_iret is not RSP safe + long_iret(i); + + BX_CPU_THIS_PTR speculative_rsp = 0; BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP); diff --git a/bochs/cpu/debugstuff.cc b/bochs/cpu/debugstuff.cc index 5b5b3424a..3f86dc7ee 100644 --- a/bochs/cpu/debugstuff.cc +++ b/bochs/cpu/debugstuff.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: debugstuff.cc,v 1.85 2007-11-08 18:21:37 sshwarts Exp $ +// $Id: debugstuff.cc,v 1.86 2007-11-24 14:22:33 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -238,8 +238,8 @@ void BX_CPU_C::debug(bx_address offset) #if BX_SUPPORT_X86_64 BX_INFO(("| RIP=%08x%08x (%08x%08x)", (unsigned) BX_CPU_THIS_PTR eip_reg.dword.rip_upper, (unsigned) EIP, - (unsigned) (BX_CPU_THIS_PTR prev_eip >> 32), - (unsigned) (BX_CPU_THIS_PTR prev_eip & 0xffffffff))); + (unsigned) (BX_CPU_THIS_PTR prev_rip >> 32), + (unsigned) (BX_CPU_THIS_PTR prev_rip & 0xffffffff))); BX_INFO(("| CR0=0x%08x CR1=0x%x CR2=0x%08x%08x", (unsigned) (BX_CPU_THIS_PTR cr0.val32), 0, (unsigned) (BX_CPU_THIS_PTR cr2 >> 32), @@ -248,7 +248,7 @@ void BX_CPU_C::debug(bx_address offset) (unsigned) BX_CPU_THIS_PTR cr3, BX_CPU_THIS_PTR cr4.getRegister())); #else BX_INFO(("| EIP=%08x (%08x)", (unsigned) EIP, - (unsigned) BX_CPU_THIS_PTR prev_eip)); + (unsigned) BX_CPU_THIS_PTR prev_rip)); #if BX_CPU_LEVEL >= 2 && BX_CPU_LEVEL < 4 BX_INFO(("| CR0=0x%08x CR1=%x CR2=0x%08x CR3=0x%08x", @@ -440,5 +440,5 @@ void BX_CPU_C::dbg_get_idtr(bx_dbg_global_sreg_t *sreg) void BX_CPU_C::atexit(void) { - debug(BX_CPU_THIS_PTR prev_eip); + debug(BX_CPU_THIS_PTR prev_rip); } diff --git a/bochs/cpu/exception.cc b/bochs/cpu/exception.cc index 1d062faf7..35996c1ae 100644 --- a/bochs/cpu/exception.cc +++ b/bochs/cpu/exception.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: exception.cc,v 1.95 2007-11-06 19:17:42 sshwarts Exp $ +// $Id: exception.cc,v 1.96 2007-11-24 14:22:33 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -851,7 +851,7 @@ void BX_CPU_C::exception(unsigned vector, Bit16u error_code, bx_bool is_INT) // if 1st was a double fault (software INT?), then shutdown (BX_CPU_THIS_PTR errorno == 2 && BX_CPU_THIS_PTR curr_exception[0]==BX_ET_DOUBLE_FAULT)) { - debug(BX_CPU_THIS_PTR prev_eip); // print debug information to the log + debug(BX_CPU_THIS_PTR prev_rip); // print debug information to the log #if BX_DEBUGGER // trap into debugger (similar as done when PANIC occured) bx_debug_break(); @@ -998,8 +998,9 @@ void BX_CPU_C::exception(unsigned vector, Bit16u error_code, bx_bool is_INT) if (exception_class == BX_EXCEPTION_CLASS_FAULT) { // restore RIP/RSP to value before error occurred - RIP = BX_CPU_THIS_PTR prev_eip; - RSP = BX_CPU_THIS_PTR prev_esp; + RIP = BX_CPU_THIS_PTR prev_rip; + if (BX_CPU_THIS_PTR speculative_rsp) + RSP = BX_CPU_THIS_PTR prev_rsp; if (vector != BX_DB_EXCEPTION) BX_CPU_THIS_PTR assert_RF(); } diff --git a/bochs/cpu/fetchdecode64.cc b/bochs/cpu/fetchdecode64.cc index 9271016e7..19f1eb3b5 100644 --- a/bochs/cpu/fetchdecode64.cc +++ b/bochs/cpu/fetchdecode64.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: fetchdecode64.cc,v 1.147 2007-11-23 16:37:06 sshwarts Exp $ +// $Id: fetchdecode64.cc,v 1.148 2007-11-24 14:22:33 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -909,7 +909,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64R[512*3] = { /* CC /dr */ { 0, &BX_CPU_C::INT3 }, /* CD /dr */ { BxImmediate_Ib, &BX_CPU_C::INT_Ib }, /* CE /dr */ { 0, &BX_CPU_C::BxError }, - /* CF /dr */ { 0, &BX_CPU_C::IRET32 }, + /* CF /dr */ { 0, &BX_CPU_C::IRET64 }, /* D0 /dr */ { BxGroup2, NULL, BxOpcodeInfoG2Eb }, /* D1 /dr */ { BxGroup2, NULL, BxOpcodeInfoG2Ed }, /* D2 /dr */ { BxGroup2, NULL, BxOpcodeInfoG2Eb }, @@ -1973,7 +1973,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64M[512*3] = { /* CC /wm */ { 0, &BX_CPU_C::INT3 }, /* CD /wm */ { BxImmediate_Ib, &BX_CPU_C::INT_Ib }, /* CE /wm */ { 0, &BX_CPU_C::BxError }, - /* CF /wm */ { 0, &BX_CPU_C::IRET16 }, + /* CF /wm */ { 0, &BX_CPU_C::IRET64 }, /* D0 /wm */ { BxGroup2, NULL, BxOpcodeInfoG2Eb }, /* D1 /wm */ { BxGroup2, NULL, BxOpcodeInfoG2Ew }, /* D2 /wm */ { BxGroup2, NULL, BxOpcodeInfoG2Eb }, @@ -2502,7 +2502,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64M[512*3] = { /* CC /dm */ { 0, &BX_CPU_C::INT3 }, /* CD /dm */ { BxImmediate_Ib, &BX_CPU_C::INT_Ib }, /* CE /dm */ { 0, &BX_CPU_C::BxError }, - /* CF /dm */ { 0, &BX_CPU_C::IRET32 }, + /* CF /dm */ { 0, &BX_CPU_C::IRET64 }, /* D0 /dm */ { BxGroup2, NULL, BxOpcodeInfoG2Eb }, /* D1 /dm */ { BxGroup2, NULL, BxOpcodeInfoG2Ed }, /* D2 /dm */ { BxGroup2, NULL, BxOpcodeInfoG2Eb }, diff --git a/bochs/cpu/flag_ctrl.cc b/bochs/cpu/flag_ctrl.cc index 9d9790fe4..63882535c 100644 --- a/bochs/cpu/flag_ctrl.cc +++ b/bochs/cpu/flag_ctrl.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: flag_ctrl.cc,v 1.31 2007-11-22 21:52:55 sshwarts Exp $ +// $Id: flag_ctrl.cc,v 1.32 2007-11-24 14:22:34 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2002 MandrakeSoft S.A. @@ -31,6 +31,11 @@ #include "cpu.h" #define LOG_THIS BX_CPU_THIS_PTR +// Make code more tidy with a few macros. +#if BX_SUPPORT_X86_64==0 +#define RSP ESP +#endif + void BX_CPU_C::SAHF(bxInstruction_c *i) { @@ -214,6 +219,9 @@ void BX_CPU_C::POPF_Fw(bxInstruction_c *i) BX_DEBUG(("POPFW: #GP(0) in v8086 (no VME) mode")); exception(BX_GP_EXCEPTION, 0, 0); } + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_16(&flags16); #if BX_SUPPORT_VME if (CR4_VME_ENABLED && BX_CPU_THIS_PTR get_IOPL() < 3) { @@ -233,6 +241,8 @@ void BX_CPU_C::POPF_Fw(bxInstruction_c *i) } #endif changeMask |= EFlagsIFMask; + + BX_CPU_THIS_PTR speculative_rsp = 0; } else { pop_16(&flags16); diff --git a/bochs/cpu/init.cc b/bochs/cpu/init.cc index bb4f2e9d8..a168c1101 100644 --- a/bochs/cpu/init.cc +++ b/bochs/cpu/init.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: init.cc,v 1.144 2007-11-18 21:07:40 sshwarts Exp $ +// $Id: init.cc,v 1.145 2007-11-24 14:22:34 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -718,9 +718,9 @@ void BX_CPU_C::reset(unsigned source) /* instruction pointer */ #if BX_CPU_LEVEL < 2 - BX_CPU_THIS_PTR prev_eip = EIP = 0x00000000; + BX_CPU_THIS_PTR prev_rip = EIP = 0x00000000; #else /* from 286 up */ - BX_CPU_THIS_PTR prev_eip = RIP = 0x0000FFF0; + BX_CPU_THIS_PTR prev_rip = RIP = 0x0000FFF0; #endif /* CS (Code Segment) and descriptor cache */ diff --git a/bochs/cpu/iret.cc b/bochs/cpu/iret.cc index 27675fc09..1a37f0368 100755 --- a/bochs/cpu/iret.cc +++ b/bochs/cpu/iret.cc @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////// -// $Id: iret.cc,v 1.22 2007-11-17 23:28:31 sshwarts Exp $ +// $Id: iret.cc,v 1.23 2007-11-24 14:22:34 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (c) 2005 Stanislav Shwartsman @@ -47,7 +47,7 @@ BX_CPU_C::iret_protected(bxInstruction_c *i) } #endif - if (BX_CPU_THIS_PTR get_NT ()) /* NT = 1: RETURN FROM NESTED TASK */ + if (BX_CPU_THIS_PTR get_NT()) /* NT = 1: RETURN FROM NESTED TASK */ { /* what's the deal with NT & VM ? */ Bit16u raw_link_selector; diff --git a/bochs/cpu/resolve64.cc b/bochs/cpu/resolve64.cc index 51b9738d4..66079a642 100644 --- a/bochs/cpu/resolve64.cc +++ b/bochs/cpu/resolve64.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: resolve64.cc,v 1.13 2007-11-18 19:46:14 sshwarts Exp $ +// $Id: resolve64.cc,v 1.14 2007-11-24 14:22:34 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -38,13 +38,13 @@ BX_CPU_C::BxResolve32Rip(bxInstruction_c *i) { // RIP hasn't been bumped yet when this is called. must choose the saved value. - RMAddr(i) = (Bit32u) (BX_CPU_THIS_PTR prev_eip + i->ilen() + (Bit32s) i->displ32u()); + RMAddr(i) = (Bit32u) (BX_CPU_THIS_PTR prev_rip + i->ilen() + (Bit32s) i->displ32u()); } void BX_CPP_AttrRegparmN(1) BX_CPU_C::BxResolve64Rip(bxInstruction_c *i) { // RIP hasn't been bumped yet when this is called. must choose the saved value. - RMAddr(i) = BX_CPU_THIS_PTR prev_eip + i->ilen() + (Bit32s) i->displ32u(); + RMAddr(i) = BX_CPU_THIS_PTR prev_rip + i->ilen() + (Bit32s) i->displ32u(); } void BX_CPP_AttrRegparmN(1) diff --git a/bochs/cpu/segment_ctrl_pro.cc b/bochs/cpu/segment_ctrl_pro.cc index c8c4337b0..71808df70 100644 --- a/bochs/cpu/segment_ctrl_pro.cc +++ b/bochs/cpu/segment_ctrl_pro.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: segment_ctrl_pro.cc,v 1.75 2007-11-20 21:22:03 sshwarts Exp $ +// $Id: segment_ctrl_pro.cc,v 1.76 2007-11-24 14:22:34 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -684,7 +684,7 @@ BX_CPU_C::fetch_raw_descriptor(const bx_selector_t *selector, else { /* LDT */ if (BX_CPU_THIS_PTR ldtr.cache.valid==0) { BX_PANIC(("fetch_raw_descriptor: LDTR.valid=0")); - debug(BX_CPU_THIS_PTR prev_eip); + debug(BX_CPU_THIS_PTR prev_rip); } if ((index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.system.limit_scaled) { BX_ERROR(("fetch_raw_descriptor: LDT: index (%x)%x > limit (%x)", @@ -746,7 +746,7 @@ void BX_CPU_C::fetch_raw_descriptor64(const bx_selector_t *selector, else { /* LDT */ if (BX_CPU_THIS_PTR ldtr.cache.valid==0) { BX_PANIC(("fetch_raw_descriptor: LDTR.valid=0")); - debug(BX_CPU_THIS_PTR prev_eip); + debug(BX_CPU_THIS_PTR prev_rip); } if ((index*8 + 15) > BX_CPU_THIS_PTR ldtr.cache.u.system.limit_scaled) { BX_ERROR(("fetch_raw_descriptor64: LDT: index (%x)%x > limit (%x)", diff --git a/bochs/cpu/smm.cc b/bochs/cpu/smm.cc index 1f602b079..95061eb7c 100755 --- a/bochs/cpu/smm.cc +++ b/bochs/cpu/smm.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: smm.cc,v 1.28 2007-11-20 21:22:03 sshwarts Exp $ +// $Id: smm.cc,v 1.29 2007-11-24 14:22:34 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (c) 2006 Stanislav Shwartsman @@ -106,7 +106,7 @@ void BX_CPU_C::enter_system_management_mode(void) BX_INFO(("Enter to System Management Mode")); - // debug(BX_CPU_THIS_PTR prev_eip); + // debug(BX_CPU_THIS_PTR prev_rip); BX_CPU_THIS_PTR in_smm = 1; @@ -124,7 +124,7 @@ void BX_CPU_C::enter_system_management_mode(void) } BX_CPU_THIS_PTR setEFlags(0x2); // Bit1 is always set - BX_CPU_THIS_PTR prev_eip = RIP = 0x00008000; + BX_CPU_THIS_PTR prev_rip = RIP = 0x00008000; BX_CPU_THIS_PTR dr7 = 0x00000400; // CR0 - PE, EM, TS, and PG flags set to 0; others unmodified diff --git a/bochs/cpu/soft_int.cc b/bochs/cpu/soft_int.cc index 7c0b6c65d..70d221306 100644 --- a/bochs/cpu/soft_int.cc +++ b/bochs/cpu/soft_int.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: soft_int.cc,v 1.34 2007-11-17 23:28:32 sshwarts Exp $ +// $Id: soft_int.cc,v 1.35 2007-11-24 14:22:34 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -34,6 +34,11 @@ #include "extdb.h" #endif +// Make code more tidy with a few macros. +#if BX_SUPPORT_X86_64==0 +#define RSP ESP +#endif + void BX_CPU_C::BOUND_GwMa(bxInstruction_c *i) { Bit16s bound_min, bound_max; @@ -75,7 +80,14 @@ void BX_CPU_C::INT1(bxInstruction_c *i) trap_debugger(0); #endif + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + + // interrupt is not RSP safe interrupt(1, 1, 0, 0); + + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); @@ -89,7 +101,14 @@ void BX_CPU_C::INT3(bxInstruction_c *i) BX_CPU_THIS_PTR show_flag |= Flag_softint; #endif + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + + // interrupt is not RSP safe interrupt(3, 1, 0, 0); + + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); @@ -104,6 +123,9 @@ void BX_CPU_C::INT_Ib(bxInstruction_c *i) Bit8u vector = i->Ib(); + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + if (v8086_mode()) { #if BX_SUPPORT_VME if (BX_CPU_THIS_PTR cr4.get_VME()) @@ -120,7 +142,7 @@ void BX_CPU_C::INT_Ib(bxInstruction_c *i) { // redirect interrupt through virtual-mode idt v86_redirect_interrupt(vector); - return; + goto done; } } #endif @@ -139,6 +161,11 @@ void BX_CPU_C::INT_Ib(bxInstruction_c *i) #endif interrupt(vector, 1, 0, 0); + +done: + + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); @@ -151,7 +178,14 @@ void BX_CPU_C::INTO(bxInstruction_c *i) #endif if (get_OF()) { + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + + // interrupt is not RSP safe interrupt(4, 1, 0, 0); + + BX_CPU_THIS_PTR speculative_rsp = 0; + BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); diff --git a/bochs/cpu/stack16.cc b/bochs/cpu/stack16.cc index 183f508fd..323053696 100644 --- a/bochs/cpu/stack16.cc +++ b/bochs/cpu/stack16.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: stack16.cc,v 1.26 2007-11-20 17:15:33 sshwarts Exp $ +// $Id: stack16.cc,v 1.27 2007-11-24 14:22:34 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -30,6 +30,10 @@ #include "cpu.h" #define LOG_THIS BX_CPU_THIS_PTR +// Make code more tidy with a few macros. +#if BX_SUPPORT_X86_64==0 +#define RSP ESP +#endif void BX_CPU_C::PUSH_RX(bxInstruction_c *i) { @@ -69,37 +73,68 @@ void BX_CPU_C::PUSH16_SS(bxInstruction_c *i) void BX_CPU_C::POP16_DS(bxInstruction_c *i) { Bit16u ds; + + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_16(&ds); load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], ds); + + BX_CPU_THIS_PTR speculative_rsp = 0; + } void BX_CPU_C::POP16_ES(bxInstruction_c *i) { Bit16u es; + + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_16(&es); load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], es); + + BX_CPU_THIS_PTR speculative_rsp = 0; } void BX_CPU_C::POP16_FS(bxInstruction_c *i) { Bit16u fs; + + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_16(&fs); load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], fs); + + BX_CPU_THIS_PTR speculative_rsp = 0; } void BX_CPU_C::POP16_GS(bxInstruction_c *i) { Bit16u gs; + + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_16(&gs); load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], gs); + + BX_CPU_THIS_PTR speculative_rsp = 0; } void BX_CPU_C::POP16_SS(bxInstruction_c *i) { Bit16u ss; + + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_16(&ss); load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], ss); + BX_CPU_THIS_PTR speculative_rsp = 0; + // POP SS inhibits interrupts, debug exceptions and single-step // trap exceptions until the execution boundary following the // next instruction is reached. @@ -120,6 +155,9 @@ void BX_CPU_C::POP_EwM(bxInstruction_c *i) { Bit16u val16; + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_16(&val16); // Note: there is one little weirdism here. It is possible to use @@ -129,6 +167,8 @@ void BX_CPU_C::POP_EwM(bxInstruction_c *i) BX_CPU_CALL_METHODR (i->ResolveModrm, (i)); } write_virtual_word(i->seg(), RMAddr(i), &val16); + + BX_CPU_THIS_PTR speculative_rsp = 0; } void BX_CPU_C::POP_EwR(bxInstruction_c *i) diff --git a/bochs/cpu/stack32.cc b/bochs/cpu/stack32.cc index 79f6f05e8..af11d323d 100644 --- a/bochs/cpu/stack32.cc +++ b/bochs/cpu/stack32.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: stack32.cc,v 1.40 2007-11-22 17:33:06 sshwarts Exp $ +// $Id: stack32.cc,v 1.41 2007-11-24 14:22:34 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -30,10 +30,18 @@ #include "cpu.h" #define LOG_THIS BX_CPU_THIS_PTR +// Make code more tidy with a few macros. +#if BX_SUPPORT_X86_64==0 +#define RSP ESP +#endif + void BX_CPU_C::POP_EdM(bxInstruction_c *i) { Bit32u val32; + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_32(&val32); // Note: there is one little weirdism here. It is possible to use @@ -44,6 +52,8 @@ void BX_CPU_C::POP_EdM(bxInstruction_c *i) BX_CPU_CALL_METHODR (i->ResolveModrm, (i)); } write_virtual_dword(i->seg(), RMAddr(i), &val32); + + BX_CPU_THIS_PTR speculative_rsp = 0; } void BX_CPU_C::POP_EdR(bxInstruction_c *i) @@ -79,6 +89,13 @@ void BX_CPU_C::PUSH32_DS(bxInstruction_c *i) decrementESPForPush(4, &eSP); write_virtual_word(BX_SEG_REG_SS, eSP, &BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value); + + if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { + ESP = eSP; + } + else { + SP = (Bit16u) eSP; + } } void BX_CPU_C::PUSH32_ES(bxInstruction_c *i) @@ -87,6 +104,13 @@ void BX_CPU_C::PUSH32_ES(bxInstruction_c *i) decrementESPForPush(4, &eSP); write_virtual_word(BX_SEG_REG_SS, eSP, &BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value); + + if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { + ESP = eSP; + } + else { + SP = (Bit16u) eSP; + } } void BX_CPU_C::PUSH32_FS(bxInstruction_c *i) @@ -95,6 +119,13 @@ void BX_CPU_C::PUSH32_FS(bxInstruction_c *i) decrementESPForPush(4, &eSP); write_virtual_word(BX_SEG_REG_SS, eSP, &BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value); + + if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { + ESP = eSP; + } + else { + SP = (Bit16u) eSP; + } } void BX_CPU_C::PUSH32_GS(bxInstruction_c *i) @@ -103,6 +134,13 @@ void BX_CPU_C::PUSH32_GS(bxInstruction_c *i) decrementESPForPush(4, &eSP); write_virtual_word(BX_SEG_REG_SS, eSP, &BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value); + + if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { + ESP = eSP; + } + else { + SP = (Bit16u) eSP; + } } void BX_CPU_C::PUSH32_SS(bxInstruction_c *i) @@ -111,42 +149,79 @@ void BX_CPU_C::PUSH32_SS(bxInstruction_c *i) decrementESPForPush(4, &eSP); write_virtual_word(BX_SEG_REG_SS, eSP, &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value); + + if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { + ESP = eSP; + } + else { + SP = (Bit16u) eSP; + } } void BX_CPU_C::POP32_DS(bxInstruction_c *i) { Bit32u ds; + + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_32(&ds); load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], (Bit16u) ds); + + BX_CPU_THIS_PTR speculative_rsp = 0; } void BX_CPU_C::POP32_ES(bxInstruction_c *i) { Bit32u es; + + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_32(&es); load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], (Bit16u) es); + + BX_CPU_THIS_PTR speculative_rsp = 0; } void BX_CPU_C::POP32_FS(bxInstruction_c *i) { Bit32u fs; + + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_32(&fs); load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], (Bit16u) fs); + + BX_CPU_THIS_PTR speculative_rsp = 0; } void BX_CPU_C::POP32_GS(bxInstruction_c *i) { Bit32u gs; + + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_32(&gs); load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], (Bit16u) gs); + + BX_CPU_THIS_PTR speculative_rsp = 0; } void BX_CPU_C::POP32_SS(bxInstruction_c *i) { Bit32u ss; + + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_32(&ss); load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], (Bit16u) ss); + BX_CPU_THIS_PTR speculative_rsp = 0; + // POP SS inhibits interrupts, debug exceptions and single-step // trap exceptions until the execution boundary following the // next instruction is reached. @@ -254,6 +329,9 @@ void BX_CPU_C::ENTER16_IwIb(bxInstruction_c *i) Bit8u level = i->Ib2(); level &= 0x1F; + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + Bit32u ebp; // Use temp copy in case of exception. push_16(BP); @@ -286,6 +364,8 @@ void BX_CPU_C::ENTER16_IwIb(bxInstruction_c *i) push_16((Bit16u)frame_ptr32); } + BX_CPU_THIS_PTR speculative_rsp = 0; + if (ss32) { EBP = frame_ptr32; ESP -= imm16; @@ -304,6 +384,9 @@ void BX_CPU_C::ENTER32_IwIb(bxInstruction_c *i) Bit8u level = i->Ib2(); level &= 0x1F; + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + Bit32u ebp; // Use temp copy in case of exception. push_32(EBP); @@ -336,6 +419,8 @@ void BX_CPU_C::ENTER32_IwIb(bxInstruction_c *i) push_32(frame_ptr32); } + BX_CPU_THIS_PTR speculative_rsp = 0; + if (ss32) { EBP = frame_ptr32; ESP -= imm16; @@ -372,13 +457,16 @@ void BX_CPU_C::LEAVE(bxInstruction_c *i) } } + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + // delete frame #if BX_CPU_LEVEL >= 3 if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) ESP = EBP; else #endif - SP = BP; + SP = BP; // restore frame pointer #if BX_CPU_LEVEL >= 3 @@ -394,5 +482,7 @@ void BX_CPU_C::LEAVE(bxInstruction_c *i) pop_16(&temp16); BP = temp16; } + + BX_CPU_THIS_PTR speculative_rsp = 0; } #endif diff --git a/bochs/cpu/stack64.cc b/bochs/cpu/stack64.cc index 0bf90c536..04c5b95e5 100644 --- a/bochs/cpu/stack64.cc +++ b/bochs/cpu/stack64.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: stack64.cc,v 1.28 2007-11-22 21:52:55 sshwarts Exp $ +// $Id: stack64.cc,v 1.29 2007-11-24 14:22:34 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -36,6 +36,9 @@ void BX_CPU_C::POP_EqM(bxInstruction_c *i) { Bit64u val64; + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_64(&val64); // Note: there is one little weirdism here. It is possible to use @@ -46,6 +49,8 @@ void BX_CPU_C::POP_EqM(bxInstruction_c *i) BX_CPU_CALL_METHODR (i->ResolveModrm, (i)); } write_virtual_qword(i->seg(), RMAddr(i), &val64); + + BX_CPU_THIS_PTR speculative_rsp = 0; } void BX_CPU_C::POP_EqR(bxInstruction_c *i) @@ -57,7 +62,7 @@ void BX_CPU_C::POP_EqR(bxInstruction_c *i) void BX_CPU_C::PUSH_RRX(bxInstruction_c *i) { - push_64(BX_CPU_THIS_PTR gen_reg[i->opcodeReg()].rrx); + push_64(BX_READ_64BIT_REG(i->opcodeReg())); } void BX_CPU_C::POP_RRX(bxInstruction_c *i) @@ -80,15 +85,27 @@ void BX_CPU_C::PUSH64_GS(bxInstruction_c *i) void BX_CPU_C::POP64_FS(bxInstruction_c *i) { Bit64u fs; + + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_64(&fs); load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], (Bit16u) fs); + + BX_CPU_THIS_PTR speculative_rsp = 0; } void BX_CPU_C::POP64_GS(bxInstruction_c *i) { Bit64u gs; + + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + pop_64(&gs); load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], (Bit16u) gs); + + BX_CPU_THIS_PTR speculative_rsp = 0; } void BX_CPU_C::PUSH64_Id(bxInstruction_c *i) @@ -118,6 +135,9 @@ void BX_CPU_C::ENTER64_IwIb(bxInstruction_c *i) level &= 0x1F; Bit64u bytes_to_push = 8 + level*8 + i->Iw(); + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + push_64(RBP); Bit64u frame_ptr64 = RSP; @@ -138,13 +158,17 @@ void BX_CPU_C::ENTER64_IwIb(bxInstruction_c *i) write_virtual_qword(BX_SEG_REG_SS, RSP, &frame_ptr64); } /* if (level > 0) ... */ - RBP = frame_ptr64; + BX_CPU_THIS_PTR speculative_rsp = 0; + RBP = frame_ptr64; RSP -= i->Iw(); } void BX_CPU_C::LEAVE64(bxInstruction_c *i) { + BX_CPU_THIS_PTR speculative_rsp = 1; + BX_CPU_THIS_PTR prev_rsp = RSP; + // delete frame RSP = RBP; @@ -152,6 +176,8 @@ void BX_CPU_C::LEAVE64(bxInstruction_c *i) Bit64u temp64; pop_64(&temp64); RBP = temp64; + + BX_CPU_THIS_PTR speculative_rsp = 0; } #endif /* if BX_SUPPORT_X86_64 */ diff --git a/bochs/cpu/stack_pro.cc b/bochs/cpu/stack_pro.cc index e3e45b6c7..1512254bf 100644 --- a/bochs/cpu/stack_pro.cc +++ b/bochs/cpu/stack_pro.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: stack_pro.cc,v 1.31 2007-11-17 23:28:33 sshwarts Exp $ +// $Id: stack_pro.cc,v 1.32 2007-11-24 14:22:34 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -353,11 +353,9 @@ void BX_CPU_C::decrementESPForPush(unsigned nBytes, Bit32u *eSP_ptr) // And finally, decrement eSP and return the new eSP value. eSP -= nBytes; if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { - ESP = eSP; *eSP_ptr = eSP; } else { - SP = (Bit16u) eSP; *eSP_ptr = SP; } } diff --git a/bochs/cpu/tasking.cc b/bochs/cpu/tasking.cc index 3b606b487..5edbcd6d6 100644 --- a/bochs/cpu/tasking.cc +++ b/bochs/cpu/tasking.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: tasking.cc,v 1.41 2007-11-20 21:22:03 sshwarts Exp $ +// $Id: tasking.cc,v 1.42 2007-11-24 14:22:34 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -429,7 +429,7 @@ void BX_CPU_C::task_switch(bx_selector_t *tss_selector, } } - BX_CPU_THIS_PTR prev_eip = EIP = newEIP; + BX_CPU_THIS_PTR prev_rip = EIP = newEIP; EAX = newEAX; ECX = newECX; diff --git a/bochs/fpu/fpu.cc b/bochs/fpu/fpu.cc index 03a2e4fd3..fed0f958b 100644 --- a/bochs/fpu/fpu.cc +++ b/bochs/fpu/fpu.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: fpu.cc,v 1.26 2007-10-30 18:52:25 sshwarts Exp $ +// $Id: fpu.cc,v 1.27 2007-11-24 14:22:34 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (c) 2003 Stanislav Shwartsman @@ -47,7 +47,7 @@ void BX_CPU_C::prepareFPU(bxInstruction_c *i, { BX_CPU_THIS_PTR the_i387.foo = ((Bit32u)(i->b1()) << 8) | (Bit32u)(i->modrm()) & 0x7ff; BX_CPU_THIS_PTR the_i387.fcs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value; - BX_CPU_THIS_PTR the_i387.fip = BX_CPU_THIS_PTR prev_eip; + BX_CPU_THIS_PTR the_i387.fip = BX_CPU_THIS_PTR prev_rip; if (! i->modC0()) { BX_CPU_THIS_PTR the_i387.fds = BX_CPU_THIS_PTR sregs[i->seg()].selector.value; diff --git a/bochs/load32bitOShack.cc b/bochs/load32bitOShack.cc index 9cd7b2309..2c4ef18e7 100644 --- a/bochs/load32bitOShack.cc +++ b/bochs/load32bitOShack.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: load32bitOShack.cc,v 1.23 2007-10-18 22:44:38 sshwarts Exp $ +// $Id: load32bitOShack.cc,v 1.24 2007-11-24 14:22:32 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -235,8 +235,7 @@ void bx_load_null_kernel_hack(void) bx_load_kernel_image(SIM->get_param_string(BXPN_LOAD32BITOS_PATH)->getptr(), 0x100000); // EIP deltas - BX_CPU(0)->prev_eip = - BX_CPU(0)->eip_reg.dword.eip = 0x00100000; + BX_CPU(0)->prev_rip = BX_CPU(0)->eip_reg.dword.eip = 0x00100000; // CS deltas BX_CPU(0)->sregs[BX_SEG_REG_CS].cache.u.segment.base = 0x00000000; diff --git a/bochs/plex86-interface.cc b/bochs/plex86-interface.cc index 878a3914c..0f34401e3 100644 --- a/bochs/plex86-interface.cc +++ b/bochs/plex86-interface.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -//// $Id: plex86-interface.cc,v 1.9 2007-10-18 22:44:38 sshwarts Exp $ +//// $Id: plex86-interface.cc,v 1.10 2007-11-24 14:22:32 sshwarts Exp $ /////////////////////////////////////////////////////////////////////////// //// //// Copyright (C) 2002 Kevin P. Lawton @@ -305,8 +305,7 @@ void copyPlex86StateToBochs(BX_CPU_C *cpu) cpu->eip_reg.dword.eip = plex86GuestCPU->eip; // Set fields used for exception processing. - cpu->prev_eip = plex86GuestCPU->eip; - cpu->prev_esp = plex86GuestCPU->esp; + cpu->prev_rip = plex86GuestCPU->eip; // ES/CS/SS/DS/FS/GS for (unsigned s=0; s<6; s++) {