From 2a5a5c2de5049ce8489c139139c420e134f87a61 Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Sat, 12 Mar 2005 16:40:14 +0000 Subject: [PATCH] Fixed compilation error for 486 CPU small fixes for IRET instructionm --- bochs/cpu/cpu.h | 5 +--- bochs/cpu/ctrl_xfer16.cc | 40 +++++++++++++------------- bochs/cpu/ctrl_xfer32.cc | 39 +++++++++++++++++-------- bochs/cpu/ctrl_xfer_pro.cc | 58 +++----------------------------------- 4 files changed, 53 insertions(+), 89 deletions(-) diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index c5af03de5..9ea55a2d8 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.h,v 1.202 2005-03-09 22:01:12 sshwarts Exp $ +// $Id: cpu.h,v 1.203 2005-03-12 16:40:12 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -2662,9 +2662,6 @@ public: // for now... BX_SMF void call_protected(bxInstruction_c *, Bit16u cs, bx_address disp) BX_CPP_AttrRegparmN(3); BX_SMF void return_protected(bxInstruction_c *, Bit16u pop_bytes) BX_CPP_AttrRegparmN(2); BX_SMF void iret_protected(bxInstruction_c *) BX_CPP_AttrRegparmN(1); -#if BX_CPU_LEVEL >= 5 - BX_SMF bx_bool iret32_real(bxInstruction_c *) BX_CPP_AttrRegparmN(1); -#endif BX_SMF void validate_seg_regs(void); BX_SMF void stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector, Bit32u flags32); diff --git a/bochs/cpu/ctrl_xfer16.cc b/bochs/cpu/ctrl_xfer16.cc index 6715d4771..1edaf5297 100644 --- a/bochs/cpu/ctrl_xfer16.cc +++ b/bochs/cpu/ctrl_xfer16.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer16.cc,v 1.27 2005-02-16 21:26:50 sshwarts Exp $ +// $Id: ctrl_xfer16.cc,v 1.28 2005-03-12 16:40:14 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -83,7 +83,6 @@ void BX_CPU_C::RETnear16(bxInstruction_c *i) void BX_CPU_C::RETfar16_Iw(bxInstruction_c *i) { -BailBigRSP("RETfar16_Iw"); Bit16s imm16; Bit16u ip, cs_raw; @@ -189,7 +188,7 @@ void BX_CPU_C::CALL16_Ap(bxInstruction_c *i) 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); @@ -212,10 +211,10 @@ void BX_CPU_C::CALL_Ew(bxInstruction_c *i) if (i->modC0()) { op1_16 = BX_READ_16BIT_REG(i->rm()); - } + } else { 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) @@ -245,7 +244,7 @@ void BX_CPU_C::CALL16_Ep(bxInstruction_c *i) if (i->modC0()) { BX_INFO(("CALL_Ep: op1 is a register")); exception(BX_UD_EXCEPTION, 0, 0); - } + } read_virtual_word(i->seg(), RMAddr(i), &op1_16); read_virtual_word(i->seg(), RMAddr(i)+2, &cs_raw); @@ -253,7 +252,7 @@ void BX_CPU_C::CALL16_Ep(bxInstruction_c *i) if ( protected_mode() ) { BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_16); goto done; - } + } push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value); push_16(IP); @@ -301,7 +300,7 @@ void BX_CPU_C::JCC_Jw(bxInstruction_c *i) default: condition = 0; // For compiler...all targets should set condition. break; - } + } if (condition) { Bit32u new_EIP = EIP + (Bit32s) i->Id(); @@ -312,7 +311,7 @@ void BX_CPU_C::JCC_Jw(bxInstruction_c *i) #if BX_INSTRUMENTATION else { BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID); - } + } #endif } @@ -327,7 +326,7 @@ void BX_CPU_C::JZ_Jw(bxInstruction_c *i) #if BX_INSTRUMENTATION else { BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID); - } + } #endif } @@ -342,7 +341,7 @@ void BX_CPU_C::JNZ_Jw(bxInstruction_c *i) #if BX_INSTRUMENTATION else { BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID); - } + } #endif } @@ -352,10 +351,10 @@ void BX_CPU_C::JMP_Ew(bxInstruction_c *i) if (i->modC0()) { op1_16 = BX_READ_16BIT_REG(i->rm()); - } + } else { read_virtual_word(i->seg(), RMAddr(i), &op1_16); - } + } Bit32u new_EIP = op1_16; branch_near32(new_EIP); @@ -366,7 +365,6 @@ void BX_CPU_C::JMP_Ew(bxInstruction_c *i) void BX_CPU_C::JMP16_Ep(bxInstruction_c *i) { -BailBigRSP("JMP16_Ep"); Bit16u cs_raw; Bit16u op1_16; @@ -376,7 +374,7 @@ BailBigRSP("JMP16_Ep"); /* far indirect must specify a memory address */ BX_INFO(("JMP_Ep(): op1 is a register")); exception(BX_UD_EXCEPTION, 0, 0); - } + } read_virtual_word(i->seg(), RMAddr(i), &op1_16); read_virtual_word(i->seg(), RMAddr(i)+2, &cs_raw); @@ -385,7 +383,7 @@ BailBigRSP("JMP16_Ep"); if ( protected_mode() ) { BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_16); goto done; - } + } #endif EIP = op1_16; @@ -398,7 +396,6 @@ done: void BX_CPU_C::IRET16(bxInstruction_c *i) { -BailBigRSP("IRET16"); Bit16u ip, cs_raw, flags; invalidate_prefetch_q(); @@ -412,15 +409,20 @@ BailBigRSP("IRET16"); // IOPL check in stack_return_from_v86() stack_return_from_v86(i); goto done; - } + } #if BX_CPU_LEVEL >= 2 if (BX_CPU_THIS_PTR cr0.pe) { iret_protected(i); goto done; - } + } #endif + if (! can_pop(6)) { + BX_PANIC(("IRET: top 6 bytes of stack not within stack limits")); + exception(BX_SS_EXCEPTION, 0, 0); + } + pop_16(&ip); pop_16(&cs_raw); pop_16(&flags); diff --git a/bochs/cpu/ctrl_xfer32.cc b/bochs/cpu/ctrl_xfer32.cc index 6d9fae787..f9390be09 100644 --- a/bochs/cpu/ctrl_xfer32.cc +++ b/bochs/cpu/ctrl_xfer32.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer32.cc,v 1.38 2005-02-16 21:26:50 sshwarts Exp $ +// $Id: ctrl_xfer32.cc,v 1.39 2005-03-12 16:40:14 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -67,7 +67,6 @@ void BX_CPU_C::RETnear32(bxInstruction_c *i) void BX_CPU_C::RETfar32_Iw(bxInstruction_c *i) { -BailBigRSP("RETfar32_Iw"); Bit32u eip, ecs_raw; Bit16s imm16; @@ -101,7 +100,6 @@ done: void BX_CPU_C::RETfar32(bxInstruction_c *i) { -BailBigRSP("RETfar32"); Bit32u eip, ecs_raw; invalidate_prefetch_q(); @@ -149,7 +147,6 @@ BailBigRSP("CALL_Ad"); void BX_CPU_C::CALL32_Ap(bxInstruction_c *i) { -BailBigRSP("CALL32_Ap"); Bit16u cs_raw; Bit32u disp32; @@ -206,7 +203,6 @@ void BX_CPU_C::CALL_Ed(bxInstruction_c *i) void BX_CPU_C::CALL32_Ep(bxInstruction_c *i) { -BailBigRSP("CALL32_Ep"); Bit16u cs_raw; Bit32u op1_32; @@ -286,7 +282,7 @@ void BX_CPU_C::JCC_Jd(bxInstruction_c *i) #if BX_INSTRUMENTATION else { BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID); - } + } #endif } @@ -320,7 +316,6 @@ void BX_CPU_C::JNZ_Jd(bxInstruction_c *i) void BX_CPU_C::JMP_Ap(bxInstruction_c *i) { -BailBigRSP("JMP_Ap"); Bit32u disp32; Bit16u cs_raw; @@ -369,7 +364,6 @@ void BX_CPU_C::JMP_Ed(bxInstruction_c *i) void BX_CPU_C::JMP32_Ep(bxInstruction_c *i) { -BailBigRSP("JMP32_Ep"); Bit16u cs_raw; Bit32u op1_32; @@ -401,8 +395,6 @@ done: void BX_CPU_C::IRET32(bxInstruction_c *i) { -BailBigRSP("IRET32"); - invalidate_prefetch_q(); #if BX_DEBUGGER @@ -421,8 +413,31 @@ BailBigRSP("IRET32"); goto done; } - if (iret32_real(i)) - goto done; + Bit32u eip, ecs, eflags; + + if (! can_pop(12)) { + BX_PANIC(("IRETD: to 12 bytes of stack not within stack limits")); + exception(BX_SS_EXCEPTION, 0, 0); + } + + access_linear(BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_SS) + ESP, + 4, CPL == 3, BX_READ, &eip); + + // still need to be validated ! + if (eip > 0xffff) { + BX_PANIC(("IRETD: instruction pointer not within code segment limits")); + exception(BX_GP_EXCEPTION, 0, 0); + } + + pop_32(&eip); + pop_32(&ecs); + pop_32(&eflags); + ecs &= 0xffff; + eflags = (eflags & 0x257fd5) | (read_eflags() & 0x1a0000); + + load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u)ecs); + EIP = eip; + writeEFlags(eflags, 0xffffffff); done: BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET, diff --git a/bochs/cpu/ctrl_xfer_pro.cc b/bochs/cpu/ctrl_xfer_pro.cc index c68a8959e..91846492d 100644 --- a/bochs/cpu/ctrl_xfer_pro.cc +++ b/bochs/cpu/ctrl_xfer_pro.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer_pro.cc,v 1.33 2005-03-04 21:03:22 sshwarts Exp $ +// $Id: ctrl_xfer_pro.cc,v 1.34 2005-03-12 16:40:14 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -36,7 +36,6 @@ #endif -#if BX_CPU_LEVEL >= 2 void BX_CPP_AttrRegparmN(3) BX_CPU_C::jump_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) { @@ -423,10 +422,7 @@ BX_CPU_C::jump_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) } } } -#endif /* if BX_CPU_LEVEL >= 2 */ - -#if BX_CPU_LEVEL >= 2 void BX_CPP_AttrRegparmN(3) BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) { @@ -1002,10 +998,7 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) BX_PANIC(("call_protected: shouldn't get here!")); } -#endif /* 286+ */ - -#if BX_CPU_LEVEL >= 2 void BX_CPP_AttrRegparmN(2) BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes) { @@ -1027,7 +1020,6 @@ BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes) /* + 2: CS | + 4: CS */ /* + 0: IP | + 0: EIP */ -#if BX_CPU_LEVEL >= 3 if ( i->os32L() ) { /* operand size=32: third word on stack must be within stack limits, * else #SS(0); */ @@ -1039,9 +1031,7 @@ BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes) stack_cs_offset = 4; stack_param_offset = 8; } - else -#endif - { + else { /* operand size=16: second word on stack must be within stack limits, * else #SS(0); */ if ( !can_pop(4) ) { @@ -1130,14 +1120,11 @@ BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes) return; } -#if BX_CPU_LEVEL >= 3 if (i->os32L()) { access_linear(BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_SS) + temp_ESP + 0, 4, CPL==3, BX_READ, &return_EIP); - } - else -#endif - { + } + else { access_linear(BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_SS) + temp_ESP + 0, 2, CPL==3, BX_READ, &return_IP); return_EIP = return_IP; @@ -1340,41 +1327,7 @@ BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes) validate_seg_regs(); } } -#endif -#if BX_CPU_LEVEL >= 5 - bx_bool BX_CPP_AttrRegparmN(1) -BX_CPU_C::iret32_real(bxInstruction_c *i) -{ Bit32u eip, ecs, efl; - - if (ESP + 12 > 0xffff) - { - BX_PANIC(("iretd: to 12 bytes of stack not within stack limits")); - exception(BX_SS_EXCEPTION, 0, 0); - return 0; - } - access_linear(BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_SS) + ESP, - 4, CPL == 3, BX_READ, &eip); - if (eip > 0xffff) - { - BX_PANIC(("iretd: instruction pointer not within code segment limits")); - exception(BX_GP_EXCEPTION, 0, 0); - return 0; - } - pop_32(&eip); - pop_32(&ecs); - pop_32(&efl); - ecs &= 0xffff; - efl = (efl & 0x257fd5) | ( read_eflags() & 0x1a0000); - - load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u)ecs); - EIP = eip; - writeEFlags(efl, 0xffffffff); - return 1; -} -#endif - -#if BX_CPU_LEVEL >= 2 void BX_CPP_AttrRegparmN(1) BX_CPU_C::iret_protected(bxInstruction_c *i) { @@ -1988,9 +1941,7 @@ BX_CPU_C::iret_protected(bxInstruction_c *i) BX_PANIC(("IRET: shouldn't get here!")); } -#endif -#if BX_CPU_LEVEL >= 2 void BX_CPP_AttrRegparmN(1) BX_CPU_C::branch_near32(Bit32u new_EIP) { // check always, not only in protected mode @@ -2028,4 +1979,3 @@ void BX_CPU_C::validate_seg_regs(void) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = 0; } } -#endif