Commit patch

[ 950905 ] Do not PANIC on rare, bad input from user-mode
by h.johansson
with little changes and fixes
This commit is contained in:
Stanislav Shwartsman 2004-05-10 21:05:51 +00:00
parent 7cd2f11e79
commit 3274e0dd12
18 changed files with 220 additions and 217 deletions

View File

@ -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

View File

@ -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 *);

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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)
{

View File

@ -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())) {

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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
}

View File

@ -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
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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 },

View File

@ -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;