Some EIP setting cleanups.

OK, currently I see big mess with setting of CS/EIP and SS/ESP everywhere, I have to unify it and make it easier !
This commit is contained in:
Stanislav Shwartsman 2007-10-18 21:27:56 +00:00
parent f8317d2dcd
commit 8065ada31f
7 changed files with 62 additions and 39 deletions

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////
// $Id: call_far.cc,v 1.15 2007-02-03 21:36:40 sshwarts Exp $
// $Id: call_far.cc,v 1.16 2007-10-18 21:27:56 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -366,7 +366,8 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
}
}
// Help for OS/2
// The follwoing push instructions might have a page fault which cannot
// be detected at this stage
BX_CPU_THIS_PTR except_chk = 1;
BX_CPU_THIS_PTR except_cs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS];
BX_CPU_THIS_PTR except_ss = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS];
@ -540,12 +541,17 @@ BX_CPU_C::call_gate64(bx_selector_t *gate_selector)
parse_selector(0, &ss_selector);
parse_descriptor(0, 0, &ss_descriptor);
// The following push instructions might have a page fault which cannot
// be detected at this stage
BX_CPU_THIS_PTR except_chk = 1;
BX_CPU_THIS_PTR except_cs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS];
BX_CPU_THIS_PTR except_ss = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS];
// load CS:RIP (guaranteed to be in 64 bit mode)
branch_far64(&cs_selector, &cs_descriptor, new_RIP, cs_descriptor.dpl);
// set up null SS descriptor
load_ss(&ss_selector, &ss_descriptor, cs_descriptor.dpl);
RSP = RSP_for_cpl_x;
// push old stack long pointer onto new stack
@ -554,6 +560,8 @@ BX_CPU_C::call_gate64(bx_selector_t *gate_selector)
// push long pointer to return address onto new stack
push_64(old_CS);
push_64(old_RIP);
BX_CPU_THIS_PTR except_chk = 0;
}
else
{
@ -566,12 +574,20 @@ BX_CPU_C::call_gate64(bx_selector_t *gate_selector)
exception(BX_GP_EXCEPTION, 0, 0);
}
// The following push instructions might have a page fault which cannot
// be detected at this stage
BX_CPU_THIS_PTR except_chk = 1;
BX_CPU_THIS_PTR except_cs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS];
BX_CPU_THIS_PTR except_ss = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS];
// load CS:RIP (guaranteed to be in 64 bit mode)
branch_far64(&cs_selector, &cs_descriptor, new_RIP, CPL);
// push return address onto stack
push_64(old_CS);
push_64(old_RIP);
BX_CPU_THIS_PTR except_chk = 0;
}
}
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer16.cc,v 1.37 2007-07-09 15:16:11 sshwarts Exp $
// $Id: ctrl_xfer16.cc,v 1.38 2007-10-18 21:27:56 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -103,8 +103,8 @@ void BX_CPU_C::RETfar16_Iw(bxInstruction_c *i)
pop_16(&ip);
pop_16(&cs_raw);
EIP = (Bit32u) ip;
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = (Bit32u) ip;
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
ESP += imm16;
@ -135,8 +135,9 @@ void BX_CPU_C::RETfar16(bxInstruction_c *i)
pop_16(&ip);
pop_16(&cs_raw);
EIP = (Bit32u) ip;
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = (Bit32u) ip;
done:
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET,
@ -154,13 +155,11 @@ void BX_CPU_C::CALL_Aw(bxInstruction_c *i)
new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0x0000ffff;
#if BX_CPU_LEVEL >= 2
if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
{
BX_ERROR(("CALL_Aw: new_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].limit"));
exception(BX_GP_EXCEPTION, 0, 0);
}
#endif
/* push 16 bit EA of next instruction */
push_16(IP);
@ -192,8 +191,9 @@ void BX_CPU_C::CALL16_Ap(bxInstruction_c *i)
push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
push_16((Bit16u) EIP);
EIP = (Bit32u) disp16;
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = (Bit32u) disp16;
done:
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL,
@ -248,7 +248,7 @@ void BX_CPU_C::CALL16_Ep(bxInstruction_c *i)
read_virtual_word(i->seg(), RMAddr(i), &op1_16);
read_virtual_word(i->seg(), RMAddr(i)+2, &cs_raw);
if ( protected_mode() ) {
if (protected_mode()) {
BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_16);
goto done;
}
@ -256,8 +256,8 @@ void BX_CPU_C::CALL16_Ep(bxInstruction_c *i)
push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
push_16(IP);
EIP = op1_16;
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = op1_16;
done:
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL,
@ -382,8 +382,8 @@ void BX_CPU_C::JMP16_Ep(bxInstruction_c *i)
}
#endif
EIP = op1_16;
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = op1_16;
done:
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP,
@ -408,12 +408,10 @@ void BX_CPU_C::IRET16(bxInstruction_c *i)
goto done;
}
#if BX_CPU_LEVEL >= 2
if (BX_CPU_THIS_PTR cr0.get_PE()) {
if (protected_mode()) {
iret_protected(i);
goto done;
}
#endif
if (! can_pop(6)) {
BX_ERROR(("IRET: top 6 bytes of stack not within stack limits"));

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer32.cc,v 1.49 2006-06-09 22:29:06 sshwarts Exp $
// $Id: ctrl_xfer32.cc,v 1.50 2007-10-18 21:27:56 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -85,8 +85,9 @@ void BX_CPU_C::RETfar32_Iw(bxInstruction_c *i)
pop_32(&eip);
pop_32(&ecs_raw);
EIP = eip;
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
EIP = eip;
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
ESP += imm16;
@ -115,8 +116,9 @@ void BX_CPU_C::RETfar32(bxInstruction_c *i)
pop_32(&eip);
pop_32(&ecs_raw); /* 32bit pop, MSW discarded */
EIP = eip;
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
EIP = eip;
done:
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET,
@ -164,8 +166,9 @@ void BX_CPU_C::CALL32_Ap(bxInstruction_c *i)
push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
push_32(EIP);
EIP = disp32;
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = disp32;
done:
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL,
@ -326,13 +329,12 @@ void BX_CPU_C::JMP_Ap(bxInstruction_c *i)
if (protected_mode()) {
BX_CPU_THIS_PTR jump_protected(i, cs_raw, disp32);
goto done;
}
else {
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = disp32;
}
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = disp32;
done:
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}
@ -374,15 +376,14 @@ void BX_CPU_C::JMP32_Ep(bxInstruction_c *i)
read_virtual_dword(i->seg(), RMAddr(i), &op1_32);
read_virtual_word(i->seg(), RMAddr(i)+4, &cs_raw);
if ( protected_mode() ) {
if (protected_mode()) {
BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_32);
goto done;
}
else {
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = op1_32;
}
EIP = op1_32;
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
done:
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer64.cc,v 1.48 2007-09-25 16:11:32 sshwarts Exp $
// $Id: ctrl_xfer64.cc,v 1.49 2007-10-18 21:27:56 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -183,8 +183,6 @@ void BX_CPU_C::CALL64_Ep(bxInstruction_c *i)
BX_ASSERT(protected_mode());
BX_INFO(("CallFar64 instruction executed ..."));
BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_32);
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL,
@ -274,8 +272,6 @@ void BX_CPU_C::JMP64_Ep(bxInstruction_c *i)
read_virtual_dword(i->seg(), RMAddr(i), &op1_32);
read_virtual_word(i->seg(), RMAddr(i)+4, &cs_raw);
BX_INFO(("JmpFar64 instruction executed ..."));
BX_ASSERT(protected_mode());
BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_32);

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer_pro.cc,v 1.58 2007-09-25 16:11:32 sshwarts Exp $
// $Id: ctrl_xfer_pro.cc,v 1.59 2007-10-18 21:27:56 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -98,7 +98,7 @@ BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp
/* caller may request different CPL then in selector */
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = cpl;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1;
// Added cpl to the selector value.
// Add cpl to the selector value.
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value =
(0xfffc & BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value) | cpl;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: exception.cc,v 1.90 2007-09-27 16:22:14 sshwarts Exp $
// $Id: exception.cc,v 1.91 2007-10-18 21:27:56 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -197,6 +197,12 @@ void BX_CPU_C::long_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code
parse_selector(0, &ss_selector);
parse_descriptor(0, 0, &ss_descriptor);
// The follwoing push instructions might have a page fault which cannot
// be detected at this stage
BX_CPU_THIS_PTR except_chk = 1;
BX_CPU_THIS_PTR except_cs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS];
BX_CPU_THIS_PTR except_ss = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS];
// load CS:RIP (guaranteed to be in 64 bit mode)
branch_far64(&cs_selector, &cs_descriptor, gate_dest_offset, cs_descriptor.dpl);
@ -217,6 +223,8 @@ void BX_CPU_C::long_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code
if (is_error_code)
push_64(error_code);
BX_CPU_THIS_PTR except_chk = 0;
// if INTERRUPT GATE set IF to 0
if (!(gate_descriptor.type & 1)) // even is int-gate
BX_CPU_THIS_PTR clear_IF();

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: segment_ctrl_pro.cc,v 1.71 2007-09-25 16:11:32 sshwarts Exp $
// $Id: segment_ctrl_pro.cc,v 1.72 2007-10-18 21:27:56 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -643,6 +643,10 @@ BX_CPU_C::load_ss(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache = *descriptor;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = cpl;
// Add cpl to the selector value.
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value =
(0xfffc & BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value) | cpl;
#if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
loadSRegLMNominal(BX_SEG_REG_SS, selector->value, cpl);