From 3274e0dd1266abfcc483cea369f795f3c425b398 Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Mon, 10 May 2004 21:05:51 +0000 Subject: [PATCH] Commit patch [ 950905 ] Do not PANIC on rare, bad input from user-mode by h.johansson with little changes and fixes --- bochs/CHANGES | 8 +- bochs/cpu/cpu.h | 9 +-- bochs/cpu/ctrl_xfer16.cc | 8 +- bochs/cpu/ctrl_xfer32.cc | 8 +- bochs/cpu/ctrl_xfer64.cc | 8 +- bochs/cpu/ctrl_xfer_pro.cc | 142 +++++++++++++++++----------------- bochs/cpu/data_xfer16.cc | 45 +++++------ bochs/cpu/data_xfer32.cc | 18 ++--- bochs/cpu/data_xfer64.cc | 31 +++----- bochs/cpu/fetchdecode.cc | 6 +- bochs/cpu/proc_ctrl.cc | 66 ++++++++++++---- bochs/cpu/segment_ctrl_pro.cc | 8 +- bochs/cpu/stack16.cc | 22 ++---- bochs/cpu/stack32.cc | 37 +++------ bochs/cpu/stack64.cc | 9 ++- bochs/cpu/stack_pro.cc | 8 +- bochs/disasm/dis_tables.h | 2 +- bochs/fpu/wmFPUemu_glue.cc | 2 +- 18 files changed, 220 insertions(+), 217 deletions(-) diff --git a/bochs/CHANGES b/bochs/CHANGES index 410ee575d..b371cc2fa 100644 --- a/bochs/CHANGES +++ b/bochs/CHANGES @@ -15,10 +15,16 @@ Changes to next release: - speed optimizations in MMX and CPU core (sshwarts and psychosmur) - fix MSR_APICBASE always returning APIC ADDRESS 0 (Kangmo Kim) - fetchdecode fixes for AMD64 and 3DNow! + - change BX_PANIC messages to BX_INFO when behaviour exactly + matches Intel docs + - fixed using invalid segment register for MOV instruction (h.johansson) - FPU - fixed #NM exception on when FPU is disabled for FPU opcodes +- Disassembler + - fixed MOV opcode 0x88, has exchanged the operands (h.johansson) + - I/O devices - general - handle cpu reset through port 0x92 @@ -65,7 +71,7 @@ Changes to next release: [877510] amd64 fixes... [903465] SEGV in iodev/ne2k.cc line 1211 on Alpha architecture by Christian Lestrade [903332] copy the bximage result to clipboard, etc by Lukewarm - + [950905] Do not PANIC on rare, bad input from user-mode by h.johansson - these S.F. bugs were closed #923653 DAA instruction is broken diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index d9134db11..3c31f1252 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.h,v 1.162 2004-04-09 15:34:57 sshwarts Exp $ +// $Id: cpu.h,v 1.163 2004-05-10 21:05:47 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -2359,12 +2359,14 @@ union { BX_SMF void RETfar32_Iw(bxInstruction_c *); BX_SMF void RETfar16_Iw(bxInstruction_c *); +#if BX_CPU_LEVEL == 2 BX_SMF void LOADALL(bxInstruction_c *); +#endif + BX_SMF void CMOV_GdEd(bxInstruction_c *); BX_SMF void CMOV_GwEw(bxInstruction_c *); BX_SMF void ADD_EwGw(bxInstruction_c *); - BX_SMF void ADD_GwEEw(bxInstruction_c *); BX_SMF void ADD_GwEGw(bxInstruction_c *); @@ -2429,7 +2431,6 @@ union { BX_SMF void OR_GqEq(bxInstruction_c *); BX_SMF void OR_RAXId(bxInstruction_c *); - BX_SMF void ADC_EqGq(bxInstruction_c *); BX_SMF void ADC_GqEq(bxInstruction_c *); BX_SMF void ADC_RAXId(bxInstruction_c *); @@ -2496,9 +2497,7 @@ union { BX_SMF void JCC_Jq(bxInstruction_c *); BX_SMF void SHLD_EqGq(bxInstruction_c *); - BX_SMF void SHRD_EqGq(bxInstruction_c *); - BX_SMF void IMUL_GqEq(bxInstruction_c *); BX_SMF void MOVZX_GqEb(bxInstruction_c *); diff --git a/bochs/cpu/ctrl_xfer16.cc b/bochs/cpu/ctrl_xfer16.cc index e37d12222..faaa0de83 100644 --- a/bochs/cpu/ctrl_xfer16.cc +++ b/bochs/cpu/ctrl_xfer16.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer16.cc,v 1.20 2003-05-10 22:25:51 kevinlawton Exp $ +// $Id: ctrl_xfer16.cc,v 1.21 2004-05-10 21:05:47 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -269,7 +269,8 @@ BailBigRSP("CALL_16_Ep"); #endif if (i->modC0()) { - BX_PANIC(("CALL_Ep: op1 is a register")); + BX_INFO(("CALL_Ep: op1 is a register")); + exception(BX_UD_EXCEPTION, 0, 0); } read_virtual_word(i->seg(), RMAddr(i), &op1_16); @@ -477,7 +478,8 @@ BailBigRSP("JMP16_Ep"); if (i->modC0()) { /* far indirect must specify a memory address */ - BX_PANIC(("JMP_Ep(): op1 is a register")); + BX_INFO(("JMP_Ep(): op1 is a register")); + exception(BX_UD_EXCEPTION, 0, 0); } read_virtual_word(i->seg(), RMAddr(i), &op1_16); diff --git a/bochs/cpu/ctrl_xfer32.cc b/bochs/cpu/ctrl_xfer32.cc index 6e43d2625..354b53073 100644 --- a/bochs/cpu/ctrl_xfer32.cc +++ b/bochs/cpu/ctrl_xfer32.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer32.cc,v 1.28 2003-08-29 21:20:52 sshwarts Exp $ +// $Id: ctrl_xfer32.cc,v 1.29 2004-05-10 21:05:47 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -326,7 +326,8 @@ BailBigRSP("CALL32_Ep"); /* op1_32 is a register or memory reference */ if (i->modC0()) { - BX_PANIC(("CALL_Ep: op1 is a register")); + BX_INFO(("CALL_Ep: op1 is a register")); + exception(BX_UD_EXCEPTION, 0, 0); } /* pointer, segment address pair */ @@ -568,7 +569,8 @@ BailBigRSP("JMP32_Ep"); /* op1_32 is a register or memory reference */ if (i->modC0()) { /* far indirect must specify a memory address */ - BX_PANIC(("JMP_Ep(): op1 is a register")); + BX_INFO(("JMP_Ep(): op1 is a register")); + exception(BX_UD_EXCEPTION, 0, 0); } /* pointer, segment address pair */ diff --git a/bochs/cpu/ctrl_xfer64.cc b/bochs/cpu/ctrl_xfer64.cc index bd267d021..18573aedf 100644 --- a/bochs/cpu/ctrl_xfer64.cc +++ b/bochs/cpu/ctrl_xfer64.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer64.cc,v 1.23 2003-12-29 21:47:36 sshwarts Exp $ +// $Id: ctrl_xfer64.cc,v 1.24 2004-05-10 21:05:47 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -248,7 +248,8 @@ BX_CPU_C::CALL64_Ep(bxInstruction_c *i) /* op1_64 is a register or memory reference */ if (i->modC0()) { - BX_PANIC(("CALL_Ep: op1 is a register")); + BX_INFO(("CALL_Ep: op1 is a register")); + exception(BX_UD_EXCEPTION, 0, 0); } /* pointer, segment address pair */ @@ -357,7 +358,8 @@ BX_CPU_C::JMP64_Ep(bxInstruction_c *i) invalidate_prefetch_q(); if (i->modC0()) { - BX_PANIC(("JMP_Ep(): op1 is a register")); + BX_INFO(("JMP_Ep(): op1 is a register")); + exception(BX_UD_EXCEPTION, 0, 0); } read_virtual_dword(i->seg(), RMAddr(i), &op1_32); diff --git a/bochs/cpu/ctrl_xfer_pro.cc b/bochs/cpu/ctrl_xfer_pro.cc index 34d125a2b..509d028a3 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.24 2004-02-11 23:47:55 cbothamy Exp $ +// $Id: ctrl_xfer_pro.cc,v 1.25 2004-05-10 21:05:48 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -48,11 +48,9 @@ BX_CPU_C::jump_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) bx_selector_t selector; Bit32u dword1, dword2; - - /* destination selector is not null else #GP(0) */ if ((cs_raw & 0xfffc) == 0) { - BX_PANIC(("jump_protected: cs == 0")); + BX_ERROR(("jump_protected: cs == 0")); exception(BX_GP_EXCEPTION, 0, 0); return; } @@ -108,7 +106,7 @@ BX_CPU_C::jump_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) else { /* RPL of destination selector must be <= CPL else #GP(selector) */ if (selector.rpl > CPL) { - BX_PANIC(("jump_protected: rpl > CPL")); + BX_ERROR(("jump_protected: rpl > CPL")); exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0); return; } @@ -182,15 +180,14 @@ BX_CPU_C::jump_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) // checked in task_switch() // SWITCH_TASKS _without_ nesting to TSS - task_switch(&selector, &descriptor, - BX_TASK_FROM_JUMP, dword1, dword2); + task_switch(&selector, &descriptor, BX_TASK_FROM_JUMP, dword1, dword2); // IP must be in code seg limit, else #GP(0) if (EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) { BX_ERROR(("jump_protected: TSS.p == 0")); exception(BX_GP_EXCEPTION, 0, 0); return; - } + } return; break; @@ -221,15 +218,16 @@ BX_CPU_C::jump_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) BX_PANIC(("jump_protected: task gate.p == 0")); exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0); return; - } + } // examine selector to code segment given in call gate descriptor // selector must not be null, else #GP(0) gate_cs_raw = descriptor.u.gate286.dest_selector; - if ( (gate_cs_raw & 0xfffc) == 0) { - BX_PANIC(("jump_protected: CS selector null")); + if ((gate_cs_raw & 0xfffc) == 0) + { + BX_ERROR(("jump_protected: CS selector null")); exception(BX_GP_EXCEPTION, 0x0000, 0); - } + } parse_selector(gate_cs_raw, &gate_cs_selector); // selector must be within its descriptor table limits else #GP(CS selector) @@ -388,35 +386,35 @@ BX_CPU_C::jump_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) // examine selector to code segment given in call gate descriptor // selector must not be null, else #GP(0) gate_cs_raw = descriptor.u.gate386.dest_selector; - if ( (gate_cs_raw & 0xfffc) == 0) { - BX_PANIC(("jump_protected: CS selector null")); + if ((gate_cs_raw & 0xfffc) == 0) { + BX_ERROR(("jump_protected: CS selector null")); exception(BX_GP_EXCEPTION, 0x0000, 0); - } + } parse_selector(gate_cs_raw, &gate_cs_selector); // selector must be within its descriptor table limits else #GP(CS selector) - fetch_raw_descriptor(&gate_cs_selector, &dword1, &dword2, - BX_GP_EXCEPTION); + fetch_raw_descriptor(&gate_cs_selector, &dword1, &dword2, BX_GP_EXCEPTION); parse_descriptor(dword1, dword2, &gate_cs_descriptor); // descriptor AR byte must indicate code segment else #GP(CS selector) if ( (gate_cs_descriptor.valid==0) || (gate_cs_descriptor.segment==0) || - (gate_cs_descriptor.u.segment.executable==0) ) { + (gate_cs_descriptor.u.segment.executable==0) ) + { BX_PANIC(("jump_protected: AR byte: not code segment.")); exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0); - } + } // if non-conforming, code segment descriptor DPL must = CPL else #GP(CS selector) if (gate_cs_descriptor.u.segment.c_ed==0) { if (gate_cs_descriptor.dpl != CPL) { - BX_PANIC(("jump_protected: non-conform: code seg des DPL != CPL.")); + BX_ERROR(("jump_protected: non-conform: code seg des DPL != CPL.")); exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0); } } // if conforming, then code segment descriptor DPL must <= CPL else #GP(CS selector) else { if (gate_cs_descriptor.dpl > CPL) { - BX_PANIC(("jump_protected: conform: code seg des DPL > CPL.")); + BX_ERROR(("jump_protected: conform: code seg des DPL > CPL.")); exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0); } } @@ -429,10 +427,11 @@ BX_CPU_C::jump_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) // IP must be in code segment limit else #GP(0) if ( descriptor.u.gate386.dest_offset > - gate_cs_descriptor.u.segment.limit_scaled ) { + gate_cs_descriptor.u.segment.limit_scaled ) + { BX_PANIC(("jump_protected: IP > limit")); exception(BX_GP_EXCEPTION, 0x0000, 0); - } + } // load CS:IP from call gate // load CS cache with new code segment @@ -471,10 +470,10 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) */ /* new cs selector must not be null, else #GP(0) */ - if ( (cs_raw & 0xfffc) == 0) { - BX_PANIC(("call_protected: CS selector null")); + if ((cs_raw & 0xfffc) == 0) { + BX_ERROR(("call_protected: CS selector null")); exception(BX_GP_EXCEPTION, 0, 0); - } + } parse_selector(cs_raw, &cs_selector); @@ -487,7 +486,7 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) // examine AR byte of selected descriptor for various legal values if (cs_descriptor.valid==0) { - BX_PANIC(("call_protected: invalid CS descriptor")); + BX_ERROR(("call_protected: invalid CS descriptor")); exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0); } @@ -495,7 +494,7 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) Bit32u temp_ESP; if (cs_descriptor.u.segment.executable==0) { - BX_PANIC(("call_protected: non executable segment")); + BX_ERROR(("call_protected: non executable segment")); exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0); return; } @@ -513,7 +512,7 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) // DPL must be = CPL, else #GP(code seg selector) if ( (cs_selector.rpl > CPL) || (cs_descriptor.dpl != CPL) ) { - BX_PANIC(("call_protected: cs.rpl > CPL")); + BX_ERROR(("call_protected: cs.rpl > CPL")); exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0); } } @@ -545,7 +544,7 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) // push return address onto stack (CS padded to 32bits) push_32((Bit32u) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value); push_32(EIP); - } + } else { // 16bit opsize if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 4) ) { BX_PANIC(("call_protected: stack doesn't have room for ret addr")); @@ -612,7 +611,7 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) BX_PANIC(("call_protected: TSS.dpl < selector.rpl")); exception(BX_TS_EXCEPTION, cs_raw & 0xfffc, 0); return; - } + } // descriptor AR byte must specify available TSS, // else #TS(TSS selector) */ @@ -685,7 +684,6 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0); } - // task state segment must be present, else #NP(tss selector) if (tss_descriptor.p==0) { BX_PANIC(("call_protected: task descriptor.p == 0")); @@ -701,10 +699,11 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) temp_eIP = EIP; else temp_eIP = IP; - if (temp_eIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) { + if (temp_eIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) + { BX_PANIC(("call_protected: eIP > cs.limit")); exception(BX_TS_EXCEPTION, 0x0000, 0); - } + } return; break; @@ -719,16 +718,17 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) // call gate DPL must be >= CPL, else #GP(call gate selector) // call gate DPL must be >= RPL, else #GP(call gate selector) if ( (gate_descriptor.dpl < CPL) || - (gate_descriptor.dpl < gate_selector.rpl) ) { + (gate_descriptor.dpl < gate_selector.rpl) ) + { BX_PANIC(("call_protected: DPL < CPL or RPL")); exception(BX_GP_EXCEPTION, gate_selector.value & 0xfffc, 0); - } + } // call gate must be present, else #NP(call gate selector) if (gate_descriptor.p==0) { BX_PANIC(("call_protected: not present")); exception(BX_NP_EXCEPTION, gate_selector.value & 0xfffc, 0); - } + } // examine code segment selector in call gate descriptor @@ -933,11 +933,11 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) if (gate_descriptor.type==4) { push_16(return_SS); push_16((Bit16u) return_ESP); - } + } else { push_32(return_SS); push_32(return_ESP); - } + } /* get word count from call gate, mask to 5 bits */ /* copy parameters from old stack onto new stack */ @@ -1026,9 +1026,8 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) // set RPL of CS to CPL load_cs(&cs_selector, &cs_descriptor, CPL); EIP = new_EIP; - return; - } + } BX_PANIC(("call_protected: call gate: should not get here")); return; @@ -1039,10 +1038,9 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address dispBig) return; } BX_PANIC(("call_protected: gate segment unfinished")); - } + } BX_PANIC(("call_protected: shouldn't get here!")); - return; } #endif /* 286+ */ @@ -1074,8 +1072,8 @@ BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes) /* operand size=32: third word on stack must be within stack limits, * else #SS(0); */ if (!can_pop(6)) { - BX_PANIC(("return_protected: 3rd word not in stack limits")); - /* #SS(0) */ + BX_ERROR(("return_protected: 3rd word not in stack limits")); + exception(BX_SS_EXCEPTION, 0, 0); return; } stack_cs_offset = 4; @@ -1083,18 +1081,18 @@ BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes) } else #endif - { + { /* operand size=16: second word on stack must be within stack limits, * else #SS(0); */ if ( !can_pop(4) ) { BX_PANIC(("return_protected: 2nd word not in stack limits")); - /* #SS(0) */ + exception(BX_SS_EXCEPTION, 0, 0); return; - } + } stack_cs_offset = 2; stack_param_offset = 4; - } + } if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) temp_ESP = ESP; else temp_ESP = SP; @@ -1250,20 +1248,22 @@ BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes) /* descriptor AR byte must indicate code segment else #GP(selector) */ if (cs_descriptor.valid==0 || cs_descriptor.segment==0 || - cs_descriptor.u.segment.executable==0) { + cs_descriptor.u.segment.executable==0) + { BX_PANIC(("return_protected: AR byte not code")); /* #GP(selector) */ return; - } + } /* if non-conforming code then code seg DPL must equal return selector RPL * else #GP(selector) */ if (cs_descriptor.u.segment.c_ed==0 && - cs_descriptor.dpl!=cs_selector.rpl) { + cs_descriptor.dpl!=cs_selector.rpl) + { BX_PANIC(("return_protected: non-conforming seg DPL != selector.rpl")); /* #GP(selector) */ return; - } + } /* if conforming then code segment DPL must be <= return selector RPL * else #GP(selector) */ @@ -1473,7 +1473,6 @@ BX_CPU_C::iret_protected(bxInstruction_c *i) exception(BX_TS_EXCEPTION, raw_link_selector & 0xfffc, 0); } - // TSS must be present, else #NP(new TSS selector) if (tss_descriptor.p==0) { BX_INFO(("iret: task descriptor.p == 0")); @@ -1520,7 +1519,7 @@ BX_CPU_C::iret_protected(bxInstruction_c *i) /* CS on stack must be within stack limits, else #SS(0) */ if ( !can_pop(top_nbytes_same) ) { - BX_PANIC(("iret: CS not within stack limits")); + BX_ERROR(("iret: CS not within stack limits")); exception(BX_SS_EXCEPTION, 0, 0); return; } @@ -1545,7 +1544,7 @@ BX_CPU_C::iret_protected(bxInstruction_c *i) // return CS selector must be non-null, else #GP(0) if ( (raw_cs_selector & 0xfffc) == 0 ) { - BX_PANIC(("iret: return CS selector null")); + BX_ERROR(("iret: return CS selector null")); exception(BX_GP_EXCEPTION, 0, 0); return; } @@ -1560,19 +1559,20 @@ BX_CPU_C::iret_protected(bxInstruction_c *i) // AR byte must indicate code segment else #GP(return selector) if ( cs_descriptor.valid==0 || cs_descriptor.segment==0 || - cs_descriptor.u.segment.executable==0 ) { - BX_PANIC(("iret: AR byte indicated non code segment (%x) %x:%x", -raw_cs_selector, dword1, dword2)); + cs_descriptor.u.segment.executable==0 ) + { + BX_ERROR(("iret: AR byte indicated non code segment (%x) %x:%x", + raw_cs_selector, dword1, dword2)); exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0); return; - } + } // return CS selector RPL must be >= CPL, else #GP(return selector) if (cs_selector.rpl < CPL) { - BX_PANIC(("iret: return selector RPL < CPL")); + BX_ERROR(("iret: return selector RPL < CPL")); exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0); return; - } + } // if return code seg descriptor is conforming // and return code seg DPL > return code seg selector RPL @@ -1770,7 +1770,7 @@ raw_cs_selector, dword1, dword2)); /* CS on stack must be within stack limits, else #SS(0) */ if ( !can_pop(top_nbytes_same) ) { - BX_PANIC(("iret: CS not within stack limits")); + BX_ERROR(("iret: CS not within stack limits")); exception(BX_SS_EXCEPTION, 0, 0); return; } @@ -1808,7 +1808,7 @@ raw_cs_selector, dword1, dword2)); // return CS selector must be non-null, else #GP(0) if ( (raw_cs_selector & 0xfffc) == 0 ) { - BX_PANIC(("iret: return CS selector null")); + BX_ERROR(("iret: return CS selector null")); exception(BX_GP_EXCEPTION, 0, 0); return; } @@ -1823,18 +1823,19 @@ raw_cs_selector, dword1, dword2)); // AR byte must indicate code segment else #GP(return selector) if ( cs_descriptor.valid==0 || cs_descriptor.segment==0 || - cs_descriptor.u.segment.executable==0 ) { - BX_PANIC(("iret: AR byte indicated non code segment")); + cs_descriptor.u.segment.executable==0 ) + { + BX_ERROR(("iret: AR byte indicated non code segment")); exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0); return; - } + } // return CS selector RPL must be >= CPL, else #GP(return selector) if (cs_selector.rpl < CPL) { - BX_PANIC(("iret: return selector RPL < CPL")); + BX_ERROR(("iret: return selector RPL < CPL")); exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0); return; - } + } // if return code seg descriptor is conforming // and return code seg DPL > return code seg selector RPL @@ -1896,7 +1897,7 @@ raw_cs_selector, dword1, dword2)); /* load flags with third word on stack */ write_flags(new_flags, CPL==0, CPL<=BX_CPU_THIS_PTR get_IOPL ()); - } + } /* increment stack by 6/12 */ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) @@ -1976,7 +1977,6 @@ raw_cs_selector, dword1, dword2)); return; } - if (i->os32L()) { access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0, 4, 0, BX_READ, &new_eip); diff --git a/bochs/cpu/data_xfer16.cc b/bochs/cpu/data_xfer16.cc index 058e24a30..d19ec0476 100644 --- a/bochs/cpu/data_xfer16.cc +++ b/bochs/cpu/data_xfer16.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: data_xfer16.cc,v 1.28 2004-02-26 19:17:40 sshwarts Exp $ +// $Id: data_xfer16.cc,v 1.29 2004-05-10 21:05:48 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -26,9 +26,6 @@ - - - #define NEED_CPU_REG_SHORTCUTS 1 #include "bochs.h" #define LOG_THIS BX_CPU_THIS_PTR @@ -43,9 +40,7 @@ BX_CPU_C::MOV_RXIw(bxInstruction_c *i) void BX_CPU_C::XCHG_RXAX(bxInstruction_c *i) { - Bit16u temp16; - - temp16 = AX; + Bit16u temp16 = AX; AX = BX_CPU_THIS_PTR gen_reg[i->opcodeReg()].word.rx; BX_CPU_THIS_PTR gen_reg[i->opcodeReg()].word.rx = temp16; } @@ -59,10 +54,7 @@ BX_CPU_C::MOV_EEwGw(bxInstruction_c *i) void BX_CPU_C::MOV_EGwGw(bxInstruction_c *i) { - Bit16u op2_16; - - op2_16 = BX_READ_16BIT_REG(i->nnn()); - + Bit16u op2_16 = BX_READ_16BIT_REG(i->nnn()); BX_WRITE_16BIT_REG(i->rm(), op2_16); } @@ -87,13 +79,17 @@ BX_CPU_C::MOV_GwEEw(bxInstruction_c *i) void BX_CPU_C::MOV_EwSw(bxInstruction_c *i) { - Bit16u seg_reg; - #if BX_CPU_LEVEL < 3 BX_PANIC(("MOV_EwSw: incomplete for CPU < 3")); #endif - seg_reg = BX_CPU_THIS_PTR sregs[i->nnn()].selector.value; + /* Illegal to use nonexisting segments */ + if (i->nnn() >= 6) { + BX_INFO(("MOV_EwSw: using of nonexisting segment register")); + UndefinedOpcode(i); + } + + Bit16u seg_reg = BX_CPU_THIS_PTR sregs[i->nnn()].selector.value; if (i->modC0()) { if ( i->os32L() ) { @@ -113,14 +109,20 @@ BX_CPU_C::MOV_SwEw(bxInstruction_c *i) { Bit16u op2_16; +#if BX_CPU_LEVEL < 3 + BX_PANIC(("MOV_SwEw: incomplete for CPU < 3")); +#endif + /* If attempt is made to load the CS register ... */ if (i->nnn() == BX_SEG_REG_CS) { UndefinedOpcode(i); } -#if BX_CPU_LEVEL < 3 - BX_PANIC(("MOV_SwEw: incomplete for CPU < 3")); -#endif + /* Illegal to use nonexisting segments */ + if (i->nnn() >= 6) { + BX_INFO(("MOV_EwSw: using of nonexisting segment register")); + UndefinedOpcode(i); + } if (i->modC0()) { op2_16 = BX_READ_16BIT_REG(i->rm()); @@ -139,19 +141,18 @@ BX_CPU_C::MOV_SwEw(bxInstruction_c *i) BX_CPU_THIS_PTR inhibit_mask |= BX_INHIBIT_INTERRUPTS | BX_INHIBIT_DEBUG; BX_CPU_THIS_PTR async_event = 1; - } + } } void BX_CPU_C::LEA_GwM(bxInstruction_c *i) { if (i->modC0()) { - BX_INFO(("LEA_GvM: op2 is a register")); + BX_INFO(("LEA_GwM: op2 is a register")); UndefinedOpcode(i); - return; - } + } - BX_WRITE_16BIT_REG(i->nnn(), (Bit16u) RMAddr(i)); + BX_WRITE_16BIT_REG(i->nnn(), (Bit16u) RMAddr(i)); } void diff --git a/bochs/cpu/data_xfer32.cc b/bochs/cpu/data_xfer32.cc index dd0a2f5e2..67afc8139 100644 --- a/bochs/cpu/data_xfer32.cc +++ b/bochs/cpu/data_xfer32.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: data_xfer32.cc,v 1.26 2004-02-26 19:17:40 sshwarts Exp $ +// $Id: data_xfer32.cc,v 1.27 2004-05-10 21:05:48 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -23,10 +23,7 @@ // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - - - + #define NEED_CPU_REG_SHORTCUTS 1 @@ -95,13 +92,12 @@ BX_CPU_C::MOV_GdEEd(bxInstruction_c *i) BX_CPU_C::LEA_GdM(bxInstruction_c *i) { if (i->modC0()) { - BX_INFO(("LEA_GvM: op2 is a register")); + BX_INFO(("LEA_GdM: op2 is a register")); UndefinedOpcode(i); - return; - } + } - /* write effective address of op2 in op1 */ - BX_WRITE_32BIT_REGZ(i->nnn(), RMAddr(i)); + /* write effective address of op2 in op1 */ + BX_WRITE_32BIT_REGZ(i->nnn(), RMAddr(i)); } @@ -131,8 +127,6 @@ BX_CPU_C::MOV_OdEAX(bxInstruction_c *i) } } - - void BX_CPU_C::MOV_EdId(bxInstruction_c *i) { diff --git a/bochs/cpu/data_xfer64.cc b/bochs/cpu/data_xfer64.cc index 116091b9e..24ccf89a4 100644 --- a/bochs/cpu/data_xfer64.cc +++ b/bochs/cpu/data_xfer64.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: data_xfer64.cc,v 1.17 2004-04-07 19:23:06 sshwarts Exp $ +// $Id: data_xfer64.cc,v 1.18 2004-05-10 21:05:48 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -35,9 +35,7 @@ void BX_CPU_C::XCHG_RRXRAX(bxInstruction_c *i) { - Bit64u temp64; - - temp64 = RAX; + Bit64u temp64 = RAX; RAX = BX_CPU_THIS_PTR gen_reg[i->opcodeReg()].rrx; BX_CPU_THIS_PTR gen_reg[i->opcodeReg()].rrx = temp64; } @@ -51,10 +49,8 @@ BX_CPU_C::MOV_RRXIq(bxInstruction_c *i) void BX_CPU_C::MOV_EqGq(bxInstruction_c *i) { - Bit64u op2_64; - /* op2_64 is a register, op2_addr is an index of a register */ - op2_64 = BX_READ_64BIT_REG(i->nnn()); + Bit64u op2_64 = BX_READ_64BIT_REG(i->nnn()); /* op1_64 is a register or memory reference */ /* now write op2 to op1 */ @@ -86,13 +82,12 @@ BX_CPU_C::MOV_GqEq(bxInstruction_c *i) BX_CPU_C::LEA_GqM(bxInstruction_c *i) { if (i->modC0()) { - BX_INFO(("LEA_GvM: op2 is a register")); + BX_INFO(("LEA_GqM: op2 is a register")); UndefinedOpcode(i); - return; - } + } - /* write effective address of op2 in op1 */ - BX_WRITE_64BIT_REG(i->nnn(), RMAddr(i)); + /* write effective address of op2 in op1 */ + BX_WRITE_64BIT_REG(i->nnn(), RMAddr(i)); } void @@ -117,11 +112,10 @@ BX_CPU_C::MOV_ALOq(bxInstruction_c *i) void BX_CPU_C::MOV_OqAL(bxInstruction_c *i) { - Bit8u temp_8; bx_address addr = i->Iq(); /* read from register */ - temp_8 = AL; + Bit8u temp_8 = AL; /* write to memory address */ if (!BX_NULL_SEG_REG(i->seg())) { @@ -153,11 +147,10 @@ BX_CPU_C::MOV_AXOq(bxInstruction_c *i) void BX_CPU_C::MOV_OqAX(bxInstruction_c *i) { - Bit16u temp_16; bx_address addr = i->Iq(); /* read from register */ - temp_16 = AX; + Bit16u temp_16 = AX; /* write to memory address */ if (!BX_NULL_SEG_REG(i->seg())) { @@ -191,11 +184,10 @@ BX_CPU_C::MOV_EAXOq(bxInstruction_c *i) void BX_CPU_C::MOV_OqEAX(bxInstruction_c *i) { - Bit32u temp_32; bx_address addr = i->Iq(); /* read from register */ - temp_32 = EAX; + Bit32u temp_32 = EAX; /* write to memory address */ if (!BX_NULL_SEG_REG(i->seg())) { @@ -228,11 +220,10 @@ BX_CPU_C::MOV_RAXOq(bxInstruction_c *i) void BX_CPU_C::MOV_OqRAX(bxInstruction_c *i) { - Bit64u temp_64; bx_address addr = i->Iq(); /* read from register */ - temp_64 = RAX; + Bit64u temp_64 = RAX; /* write to memory address */ if (!BX_NULL_SEG_REG(i->seg())) { diff --git a/bochs/cpu/fetchdecode.cc b/bochs/cpu/fetchdecode.cc index 9ec9debe2..c864effe4 100644 --- a/bochs/cpu/fetchdecode.cc +++ b/bochs/cpu/fetchdecode.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: fetchdecode.cc,v 1.63 2004-05-03 17:58:35 sshwarts Exp $ +// $Id: fetchdecode.cc,v 1.64 2004-05-10 21:05:48 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -743,7 +743,7 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2] = { #if BX_SUPPORT_X86_64 /* 0F 05 */ { 0, &BX_CPU_C::SYSCALL }, #else - /* 0F 05 */ { 0, &BX_CPU_C::LOADALL }, + /* 0F 05 */ { 0, &BX_CPU_C::BxError }, #endif /* 0F 06 */ { 0, &BX_CPU_C::CLTS }, #if BX_SUPPORT_X86_64 @@ -1289,7 +1289,7 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2] = { #if BX_SUPPORT_X86_64 /* 0F 05 */ { 0, &BX_CPU_C::SYSCALL }, #else - /* 0F 05 */ { 0, &BX_CPU_C::LOADALL }, + /* 0F 05 */ { 0, &BX_CPU_C::BxError }, #endif /* 0F 06 */ { 0, &BX_CPU_C::CLTS }, #if BX_SUPPORT_X86_64 diff --git a/bochs/cpu/proc_ctrl.cc b/bochs/cpu/proc_ctrl.cc index f0a8a86c3..20b91e35d 100644 --- a/bochs/cpu/proc_ctrl.cc +++ b/bochs/cpu/proc_ctrl.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: proc_ctrl.cc,v 1.78 2003-11-13 21:57:13 sshwarts Exp $ +// $Id: proc_ctrl.cc,v 1.79 2004-05-10 21:05:50 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -949,11 +949,9 @@ void BX_CPU_C::MOV_RdTd(bxInstruction_c *i) #endif } +#if BX_CPU_LEVEL == 2 void BX_CPU_C::LOADALL(bxInstruction_c *i) { -#if BX_CPU_LEVEL < 2 - BX_PANIC(("Undocumented LOADALL instruction not supported on 8086")); -#else Bit16u msw, tr, flags, ip, ldtr; Bit16u ds_raw, ss_raw, cs_raw, es_raw; Bit16u di, si, bp, sp, bx, dx, cx, ax; @@ -962,13 +960,8 @@ void BX_CPU_C::LOADALL(bxInstruction_c *i) if (v8086_mode()) BX_PANIC(("proc_ctrl: LOADALL in v8086 mode unsupported")); -#if BX_CPU_LEVEL > 2 - BX_PANIC(("loadall: not implemented for 386")); - /* ??? need to set G and other bits, and compute .limit_scaled also */ - /* for all segments CS,DS,SS,... */ -#endif - - if (BX_CPU_THIS_PTR cr0.pe) { + if (BX_CPU_THIS_PTR cr0.pe) + { BX_PANIC(("LOADALL not yet supported for protected mode")); } @@ -1270,8 +1263,8 @@ void BX_CPU_C::LOADALL(bxInstruction_c *i) BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x85e, 2, &limit); BX_CPU_THIS_PTR idtr.base = (base_23_16 << 16) | base_15_0; BX_CPU_THIS_PTR idtr.limit = limit; -#endif } +#endif void BX_CPU_C::SetCR0(Bit32u val_32) { @@ -1428,16 +1421,54 @@ void BX_CPU_C::RSM(bxInstruction_c *i) #if BX_CPU_LEVEL >= 4 invalidate_prefetch_q(); - BX_PANIC(("RSM: System Management Mode not implemented yet")); -#else - UndefinedOpcode(i); + /* If we are not in System Management Mode, then + * #UD should be generated. + * + * Bochs has no SMM. + */ + + BX_INFO(("RSM: System Management Mode not implemented yet")); #endif + + UndefinedOpcode(i); } void BX_CPU_C::RDPMC(bxInstruction_c *i) { -#if BX_CPU_LEVEL >= 5 - BX_PANIC(("RDPMC: Performance Counters Support not implemented yet")); +/* We need to be Pentium with MMX or later */ +#if ((BX_CPU_LEVEL >= 6) || (BX_SUPPORT_MMX && BX_CPU_LEVEL == 5)) + bx_bool pce = BX_CPU_THIS_PTR cr4.get_PCE(); + + if ((pce==1) || (CPL==0) || real_mode()) + { + /* According to manual, Pentium 4 has 18 counters, + * previous versions have two. And the P4 also can do + * short read-out (EDX always 0). Otherwise it is + * limited to 40 bits. + */ + +#if (BX_CPU_LEVEL == 6 && BX_SUPPORT_SSE >= 2) // Pentium 4 processor (see cpuid.cc) + if ((ECX & 0x7fffffff) >= 18) + exception (BX_GP_EXCEPTION, 0, 0); +#else // + if ((ECX & 0xffffffff) >= 2) + exception (BX_GP_EXCEPTION, 0, 0); +#endif + // Most counters are for hardware specific details, which + // we anyhow do not emulate (like pipeline stalls etc) + + // Could be interesting to count number of memory reads, + // writes. Misaligned etc... But to monitor bochs, this + // is easier done from the host. + + EAX = 0; + EDX = 0; // if P4 and ECX & 0x10000000, then always 0 (short read 32 bits) + + BX_ERROR(("RDPMC: Performance Counters Support not reasonably implemented yet")); + } else { + // not allowed to use RDPMC! + exception (BX_GP_EXCEPTION, 0, 0); + } #else UndefinedOpcode(i); #endif @@ -1937,4 +1968,5 @@ Bit32u BX_CPU_C::hwdebug_compare(Bit32u laddr_0, unsigned size, } return(0); } + #endif diff --git a/bochs/cpu/segment_ctrl_pro.cc b/bochs/cpu/segment_ctrl_pro.cc index 184a47d13..890dd868d 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.26 2003-08-15 13:18:53 sshwarts Exp $ +// $Id: segment_ctrl_pro.cc,v 1.27 2004-05-10 21:05:50 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -86,7 +86,7 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value) Bit32u dword1, dword2; if ((new_value & 0xfffc) == 0) { /* null selector */ - BX_PANIC(("load_seg_reg: SS: new_value == 0")); + BX_ERROR(("load_seg_reg: SS: new_value == 0")); exception(BX_GP_EXCEPTION, 0, 0); return; } @@ -99,7 +99,7 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value) if (ti == 0) { /* GDT */ if ((index*8 + 7) > BX_CPU_THIS_PTR gdtr.limit) { - BX_PANIC(("load_seg_reg: GDT: %s: index(%04x*8+7) > limit(%06x)", + BX_ERROR(("load_seg_reg: GDT: %s: index(%04x*8+7) > limit(%06x)", BX_CPU_THIS_PTR strseg(seg), (unsigned) index, (unsigned) BX_CPU_THIS_PTR gdtr.limit)); exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0); return; @@ -610,7 +610,7 @@ BX_INFO(("-----------------------------------")); BX_PANIC(("fetch_raw_descriptor: LDTR.valid=0")); } if ((selector->index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit) { - BX_PANIC(("fetch_raw_descriptor: LDT: index (%x)%x > limit (%x)", + BX_ERROR(("fetch_raw_descriptor: LDT: index (%x)%x > limit (%x)", (selector->index*8 + 7), selector->index, BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit)); exception(exception_no, selector->value & 0xfffc, 0); diff --git a/bochs/cpu/stack16.cc b/bochs/cpu/stack16.cc index 5b570a201..25fb5b171 100644 --- a/bochs/cpu/stack16.cc +++ b/bochs/cpu/stack16.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: stack16.cc,v 1.14 2003-03-17 00:41:00 cbothamy Exp $ +// $Id: stack16.cc,v 1.15 2004-05-10 21:05:50 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -26,11 +26,6 @@ - - - - - #define NEED_CPU_REG_SHORTCUTS 1 #include "bochs.h" #define LOG_THIS BX_CPU_THIS_PTR @@ -87,11 +82,10 @@ BX_CPU_C::PUSHAD16(bxInstruction_c *i) else temp_ESP = SP; - #if BX_CPU_LEVEL >= 2 if (protected_mode()) { if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 16) ) { - BX_PANIC(("PUSHA(): stack doesn't have enough room!")); + BX_ERROR(("PUSHAD(): stack doesn't have enough room!")); exception(BX_SS_EXCEPTION, 0, 0); return; } @@ -100,7 +94,7 @@ BX_CPU_C::PUSHAD16(bxInstruction_c *i) #endif { if (temp_ESP < 16) - BX_PANIC(("pushad: eSP < 16")); + BX_PANIC(("PUSHAD: eSP < 16")); } sp = SP; @@ -128,7 +122,7 @@ BX_CPU_C::POPAD16(bxInstruction_c *i) if (protected_mode()) { if ( !can_pop(16) ) { - BX_PANIC(("pop_a: not enough bytes on stack")); + BX_ERROR(("POPAD: not enough bytes on stack")); exception(BX_SS_EXCEPTION, 0, 0); return; } @@ -160,12 +154,8 @@ BX_CPU_C::PUSH_Iw(bxInstruction_c *i) #if BX_CPU_LEVEL < 2 BX_PANIC(("PUSH_Iv: not supported on 8086!")); #else - - Bit16u imm16; - - imm16 = i->Iw(); - - push_16(imm16); + Bit16u imm16 = i->Iw(); + push_16(imm16); #endif } diff --git a/bochs/cpu/stack32.cc b/bochs/cpu/stack32.cc index ab0955f1c..f5914be13 100644 --- a/bochs/cpu/stack32.cc +++ b/bochs/cpu/stack32.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: stack32.cc,v 1.17 2003-03-17 00:41:01 cbothamy Exp $ +// $Id: stack32.cc,v 1.18 2004-05-10 21:05:50 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -25,9 +25,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - - #define NEED_CPU_REG_SHORTCUTS 1 #include "bochs.h" #define LOG_THIS BX_CPU_THIS_PTR @@ -77,12 +74,10 @@ BX_CPU_C::PUSH_ERX(bxInstruction_c *i) BX_CPU_C::POP_ERX(bxInstruction_c *i) { Bit32u erx; - pop_32(&erx); BX_CPU_THIS_PTR gen_reg[i->opcodeReg()].dword.erx = erx; } - void BX_CPU_C::PUSH_CS(bxInstruction_c *i) { @@ -110,7 +105,6 @@ BX_CPU_C::PUSH_ES(bxInstruction_c *i) void BX_CPU_C::PUSH_FS(bxInstruction_c *i) { -BailBigRSP("push_fs"); if (i->os32L()) push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value); else @@ -119,7 +113,6 @@ BailBigRSP("push_fs"); void BX_CPU_C::PUSH_GS(bxInstruction_c *i) { -BailBigRSP("push_gs"); if (i->os32L()) push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value); else @@ -134,7 +127,6 @@ BX_CPU_C::PUSH_SS(bxInstruction_c *i) push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value); } - void BX_CPU_C::POP_DS(bxInstruction_c *i) { @@ -166,7 +158,6 @@ BX_CPU_C::POP_ES(bxInstruction_c *i) void BX_CPU_C::POP_FS(bxInstruction_c *i) { -BailBigRSP("pop_fs"); if (i->os32L()) { Bit32u fs; pop_32(&fs); @@ -181,7 +172,6 @@ BailBigRSP("pop_fs"); void BX_CPU_C::POP_GS(bxInstruction_c *i) { -BailBigRSP("pop_gs"); if (i->os32L()) { Bit32u gs; pop_32(&gs); @@ -234,7 +224,7 @@ BX_CPU_C::PUSHAD32(bxInstruction_c *i) if (protected_mode()) { if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 32) ) { - BX_PANIC(("PUSHAD(): stack doesn't have enough room!")); + BX_ERROR(("PUSHAD(): stack doesn't have enough room!")); exception(BX_SS_EXCEPTION, 0, 0); return; } @@ -268,7 +258,7 @@ BX_CPU_C::POPAD32(bxInstruction_c *i) if (protected_mode()) { if ( !can_pop(32) ) { - BX_PANIC(("pop_ad: not enough bytes on stack")); + BX_ERROR(("POPAD: not enough bytes on stack")); exception(BX_SS_EXCEPTION, 0, 0); return; } @@ -300,12 +290,8 @@ BX_CPU_C::PUSH_Id(bxInstruction_c *i) #if BX_CPU_LEVEL < 2 BX_PANIC(("PUSH_Iv: not supported on 8086!")); #else - - Bit32u imm32; - - imm32 = i->Id(); - - push_32(imm32); + Bit32u imm32 = i->Id(); + push_32(imm32); #endif } @@ -326,7 +312,6 @@ BX_CPU_C::PUSH_Ed(bxInstruction_c *i) push_32(op1_32); } - void BX_CPU_C::ENTER_IwIb(bxInstruction_c *i) { @@ -372,8 +357,9 @@ BX_CPU_C::ENTER_IwIb(bxInstruction_c *i) temp_ESP = ESP; else temp_ESP = SP; + if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, bytes_to_push) ) { - BX_PANIC(("ENTER: not enough room on stack!")); + BX_ERROR(("ENTER: not enough room on stack!")); exception(BX_SS_EXCEPTION, 0, 0); } } @@ -473,7 +459,6 @@ BX_CPU_C::LEAVE(bxInstruction_c *i) #else Bit32u temp_EBP; - invalidate_prefetch_q(); #if BX_CPU_LEVEL >= 3 @@ -513,17 +498,15 @@ BX_CPU_C::LEAVE(bxInstruction_c *i) #if BX_CPU_LEVEL >= 3 if (i->os32L()) { Bit32u temp32; - pop_32(&temp32); RBP = temp32; - } + } else #endif - { + { Bit16u temp16; - pop_16(&temp16); BP = temp16; - } + } #endif } diff --git a/bochs/cpu/stack64.cc b/bochs/cpu/stack64.cc index 5fb018abf..a9bd31045 100644 --- a/bochs/cpu/stack64.cc +++ b/bochs/cpu/stack64.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: stack64.cc,v 1.11 2003-03-17 00:41:01 cbothamy Exp $ +// $Id: stack64.cc,v 1.12 2004-05-10 21:05:50 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -163,7 +163,7 @@ BX_CPU_C::PUSHAD64(bxInstruction_c *i) temp_RSP = RSP; if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_RSP, 64) ) { - BX_PANIC(("PUSHAD(): stack doesn't have enough room!")); + BX_ERROR(("PUSHAD(): stack doesn't have enough room!")); exception(BX_SS_EXCEPTION, 0, 0); return; } @@ -187,7 +187,7 @@ BX_CPU_C::POPAD64(bxInstruction_c *i) Bit64u rdi, rsi, rbp, rtmp, rbx, rdx, rcx, rax; if ( !can_pop(64) ) { - BX_PANIC(("pop_ad: not enough bytes on stack")); + BX_ERROR(("POPAD: not enough bytes on stack")); exception(BX_SS_EXCEPTION, 0, 0); return; } @@ -271,9 +271,10 @@ BX_CPU_C::ENTER64_IwIb(bxInstruction_c *i) else { /* level > 0 */ bytes_to_push = 8 + (level-1)*8 + 8 + i->Iw(); } + temp_RSP = RSP; if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_RSP, bytes_to_push) ) { - BX_PANIC(("ENTER: not enough room on stack!")); + BX_ERROR(("ENTER: not enough room on stack!")); exception(BX_SS_EXCEPTION, 0, 0); } } diff --git a/bochs/cpu/stack_pro.cc b/bochs/cpu/stack_pro.cc index 90c1dd67c..421d8dd8e 100644 --- a/bochs/cpu/stack_pro.cc +++ b/bochs/cpu/stack_pro.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: stack_pro.cc,v 1.15 2003-08-03 16:44:53 sshwarts Exp $ +// $Id: stack_pro.cc,v 1.16 2004-05-10 21:05:50 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -169,7 +169,7 @@ BailBigRSP("pop_16"); #if BX_CPU_LEVEL >= 2 if (protected_mode()) { if ( !can_pop(2) ) { - BX_INFO(("pop_16(): can't pop from stack")); + BX_ERROR(("pop_16(): can't pop from stack")); exception(BX_SS_EXCEPTION, 0, 0); return; } @@ -202,7 +202,7 @@ BailBigRSP("pop_32"); /* 16 bit stack mode: use SS:SP */ if (protected_mode()) { if ( !can_pop(4) ) { - BX_PANIC(("pop_32(): can't pop from stack")); + BX_ERROR(("pop_32(): can't pop from stack")); exception(BX_SS_EXCEPTION, 0, 0); return; } @@ -222,7 +222,7 @@ BailBigRSP("pop_32"); BX_CPU_C::pop_64(Bit64u *value64_ptr) { if ( !can_pop(8) ) { - BX_PANIC(("pop_64(): can't pop from stack")); + BX_ERROR(("pop_64(): can't pop from stack")); exception(BX_SS_EXCEPTION, 0, 0); return; } diff --git a/bochs/disasm/dis_tables.h b/bochs/disasm/dis_tables.h index fa9abd5b0..82813f0d5 100755 --- a/bochs/disasm/dis_tables.h +++ b/bochs/disasm/dis_tables.h @@ -2277,7 +2277,7 @@ static BxDisasmOpcodeInfo_t BxDisasmOpcodes[256*2] = { /* 85 */ { "test", 0, Ev, Gv, XX }, /* 86 */ { "xchg", 0, Eb, Gb, XX }, /* 87 */ { "xchg", 0, Ev, Gv, XX }, - /* 88 */ { "mov", 0, Gb, Eb, XX }, + /* 88 */ { "mov", 0, Eb, Gb, XX }, /* 89 */ { "mov", 0, Ev, Gv, XX }, /* 8A */ { "mov", 0, Gb, Eb, XX }, /* 8B */ { "mov", 0, Gv, Ev, XX }, diff --git a/bochs/fpu/wmFPUemu_glue.cc b/bochs/fpu/wmFPUemu_glue.cc index 9fe976815..e977fda90 100644 --- a/bochs/fpu/wmFPUemu_glue.cc +++ b/bochs/fpu/wmFPUemu_glue.cc @@ -267,7 +267,7 @@ math_abort(void *info, unsigned int signal) // execution does not reach here case SIGILL: - BX_PANIC (("math_abort: SIGILL not implemented yet.")); + BX_INFO (("math_abort: SIGILL not implemented yet.")); fpu_cpu_ptr->UndefinedOpcode(fpu_iptr); break;