bug fix
This commit is contained in:
parent
63a984bf71
commit
8e94474e03
@ -1,5 +1,5 @@
|
|||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// $Id: call_far.cc,v 1.56 2010-04-02 18:24:27 sshwarts Exp $
|
// $Id: call_far.cc,v 1.57 2010-06-21 05:35:45 sshwarts Exp $
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (c) 2005-2009 Stanislav Shwartsman
|
// Copyright (c) 2005-2009 Stanislav Shwartsman
|
||||||
@ -530,22 +530,13 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::call_gate64(bx_selector_t *gate_selector)
|
|||||||
// if non-conforming code segment and DPL < CPL then
|
// if non-conforming code segment and DPL < CPL then
|
||||||
if (IS_CODE_SEGMENT_NON_CONFORMING(cs_descriptor.type) && (cs_descriptor.dpl < CPL))
|
if (IS_CODE_SEGMENT_NON_CONFORMING(cs_descriptor.type) && (cs_descriptor.dpl < CPL))
|
||||||
{
|
{
|
||||||
Bit64u RSP_for_cpl_x;
|
|
||||||
|
|
||||||
BX_DEBUG(("CALL GATE TO MORE PRIVILEGE LEVEL"));
|
BX_DEBUG(("CALL GATE TO MORE PRIVILEGE LEVEL"));
|
||||||
|
|
||||||
// get new RSP for new privilege level from TSS
|
// get new RSP for new privilege level from TSS
|
||||||
RSP_for_cpl_x = get_RSP_from_TSS(cs_descriptor.dpl);
|
Bit64u RSP_for_cpl_x = get_RSP_from_TSS(cs_descriptor.dpl);
|
||||||
Bit64u old_SS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
|
Bit64u old_SS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
|
||||||
Bit64u old_RSP = RSP;
|
Bit64u old_RSP = RSP;
|
||||||
|
|
||||||
if (! IsCanonical(RSP_for_cpl_x)) {
|
|
||||||
// #SS(selector) when changing priviledge level
|
|
||||||
BX_ERROR(("call_gate64: canonical address failure %08x%08x",
|
|
||||||
GET32H(RSP_for_cpl_x), GET32L(RSP_for_cpl_x)));
|
|
||||||
exception(BX_SS_EXCEPTION, old_SS & 0xfffc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// push old stack long pointer onto new stack
|
// push old stack long pointer onto new stack
|
||||||
write_new_stack_qword_64(RSP_for_cpl_x - 8, cs_descriptor.dpl, old_SS);
|
write_new_stack_qword_64(RSP_for_cpl_x - 8, cs_descriptor.dpl, old_SS);
|
||||||
write_new_stack_qword_64(RSP_for_cpl_x - 16, cs_descriptor.dpl, old_RSP);
|
write_new_stack_qword_64(RSP_for_cpl_x - 16, cs_descriptor.dpl, old_RSP);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// $Id: exception.cc,v 1.157 2010-04-14 17:33:19 sshwarts Exp $
|
// $Id: exception.cc,v 1.158 2010-06-21 05:35:45 sshwarts Exp $
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2010 The Bochs Project
|
// Copyright (C) 2001-2010 The Bochs Project
|
||||||
@ -41,7 +41,7 @@ void BX_CPU_C::long_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_error
|
|||||||
bx_selector_t cs_selector;
|
bx_selector_t cs_selector;
|
||||||
|
|
||||||
// interrupt vector must be within IDT table limits,
|
// interrupt vector must be within IDT table limits,
|
||||||
// else #GP(vector number*8 + 2 + EXT)
|
// else #GP(vector*8 + 2 + EXT)
|
||||||
if ((vector*16 + 15) > BX_CPU_THIS_PTR idtr.limit) {
|
if ((vector*16 + 15) > BX_CPU_THIS_PTR idtr.limit) {
|
||||||
BX_ERROR(("interrupt(long mode): vector must be within IDT table limits, IDT.limit = 0x%x", BX_CPU_THIS_PTR idtr.limit));
|
BX_ERROR(("interrupt(long mode): vector must be within IDT table limits, IDT.limit = 0x%x", BX_CPU_THIS_PTR idtr.limit));
|
||||||
exception(BX_GP_EXCEPTION, vector*8 + 2);
|
exception(BX_GP_EXCEPTION, vector*8 + 2);
|
||||||
@ -52,7 +52,7 @@ void BX_CPU_C::long_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_error
|
|||||||
|
|
||||||
if (desctmp2 & BX_CONST64(0x00001F0000000000)) {
|
if (desctmp2 & BX_CONST64(0x00001F0000000000)) {
|
||||||
BX_ERROR(("interrupt(long mode): IDT entry extended attributes DWORD4 TYPE != 0"));
|
BX_ERROR(("interrupt(long mode): IDT entry extended attributes DWORD4 TYPE != 0"));
|
||||||
exception(BX_GP_EXCEPTION, vector*8+ 2);
|
exception(BX_GP_EXCEPTION, vector*8 + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bit32u dword1 = GET32L(desctmp1);
|
Bit32u dword1 = GET32L(desctmp1);
|
||||||
@ -68,7 +68,7 @@ void BX_CPU_C::long_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// descriptor AR byte must indicate interrupt gate, trap gate,
|
// descriptor AR byte must indicate interrupt gate, trap gate,
|
||||||
// or task gate, else #GP(vector*16 + 2 + EXT)
|
// or task gate, else #GP(vector*8 + 2 + EXT)
|
||||||
if (gate_descriptor.type != BX_386_INTERRUPT_GATE &&
|
if (gate_descriptor.type != BX_386_INTERRUPT_GATE &&
|
||||||
gate_descriptor.type != BX_386_TRAP_GATE)
|
gate_descriptor.type != BX_386_TRAP_GATE)
|
||||||
{
|
{
|
||||||
@ -78,14 +78,14 @@ void BX_CPU_C::long_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if software interrupt, then gate descripor DPL must be >= CPL,
|
// if software interrupt, then gate descripor DPL must be >= CPL,
|
||||||
// else #GP(vector * 16 + 2 + EXT)
|
// else #GP(vector * 8 + 2 + EXT)
|
||||||
if (soft_int && gate_descriptor.dpl < CPL)
|
if (soft_int && gate_descriptor.dpl < CPL)
|
||||||
{
|
{
|
||||||
BX_ERROR(("interrupt(long mode): soft_int && gate.dpl < CPL"));
|
BX_ERROR(("interrupt(long mode): soft_int && gate.dpl < CPL"));
|
||||||
exception(BX_GP_EXCEPTION, vector*8 + 2);
|
exception(BX_GP_EXCEPTION, vector*8 + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gate must be present, else #NP(vector * 16 + 2 + EXT)
|
// Gate must be present, else #NP(vector * 8 + 2 + EXT)
|
||||||
if (! IS_PRESENT(gate_descriptor)) {
|
if (! IS_PRESENT(gate_descriptor)) {
|
||||||
BX_ERROR(("interrupt(long mode): gate.p == 0"));
|
BX_ERROR(("interrupt(long mode): gate.p == 0"));
|
||||||
exception(BX_NP_EXCEPTION, vector*8 + 2);
|
exception(BX_NP_EXCEPTION, vector*8 + 2);
|
||||||
@ -115,7 +115,7 @@ void BX_CPU_C::long_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_error
|
|||||||
// and code segment descriptor DPL<=CPL, else #GP(selector+EXT)
|
// and code segment descriptor DPL<=CPL, else #GP(selector+EXT)
|
||||||
if (cs_descriptor.valid==0 || cs_descriptor.segment==0 ||
|
if (cs_descriptor.valid==0 || cs_descriptor.segment==0 ||
|
||||||
IS_DATA_SEGMENT(cs_descriptor.type) ||
|
IS_DATA_SEGMENT(cs_descriptor.type) ||
|
||||||
cs_descriptor.dpl>CPL)
|
cs_descriptor.dpl > CPL)
|
||||||
{
|
{
|
||||||
BX_ERROR(("interrupt(long mode): not accessible or not code segment"));
|
BX_ERROR(("interrupt(long mode): not accessible or not code segment"));
|
||||||
exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc);
|
exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc);
|
||||||
@ -134,16 +134,21 @@ void BX_CPU_C::long_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_error
|
|||||||
exception(BX_NP_EXCEPTION, cs_selector.value & 0xfffc);
|
exception(BX_NP_EXCEPTION, cs_selector.value & 0xfffc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bit64u RSP_for_cpl_x;
|
||||||
|
|
||||||
|
Bit64u old_CS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
|
||||||
|
Bit64u old_RIP = RIP;
|
||||||
|
Bit64u old_SS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
|
||||||
|
Bit64u old_RSP = RSP;
|
||||||
|
|
||||||
// if code segment is non-conforming and DPL < CPL then
|
// if code segment is non-conforming and DPL < CPL then
|
||||||
// INTERRUPT TO INNER PRIVILEGE:
|
// INTERRUPT TO INNER PRIVILEGE:
|
||||||
if (IS_CODE_SEGMENT_NON_CONFORMING(cs_descriptor.type) && cs_descriptor.dpl<CPL)
|
if (IS_CODE_SEGMENT_NON_CONFORMING(cs_descriptor.type) && cs_descriptor.dpl < CPL)
|
||||||
{
|
{
|
||||||
Bit64u RSP_for_cpl_x;
|
|
||||||
|
|
||||||
BX_DEBUG(("interrupt(long mode): INTERRUPT TO INNER PRIVILEGE"));
|
BX_DEBUG(("interrupt(long mode): INTERRUPT TO INNER PRIVILEGE"));
|
||||||
|
|
||||||
// check selector and descriptor for new stack in current TSS
|
// check selector and descriptor for new stack in current TSS
|
||||||
if (ist != 0) {
|
if (ist > 0) {
|
||||||
BX_DEBUG(("interrupt(long mode): trap to IST, vector = %d", ist));
|
BX_DEBUG(("interrupt(long mode): trap to IST, vector = %d", ist));
|
||||||
RSP_for_cpl_x = get_RSP_from_TSS(ist+3);
|
RSP_for_cpl_x = get_RSP_from_TSS(ist+3);
|
||||||
}
|
}
|
||||||
@ -151,20 +156,9 @@ void BX_CPU_C::long_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_error
|
|||||||
RSP_for_cpl_x = get_RSP_from_TSS(cs_descriptor.dpl);
|
RSP_for_cpl_x = get_RSP_from_TSS(cs_descriptor.dpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// align stack
|
||||||
RSP_for_cpl_x &= BX_CONST64(0xfffffffffffffff0);
|
RSP_for_cpl_x &= BX_CONST64(0xfffffffffffffff0);
|
||||||
|
|
||||||
Bit64u old_CS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
|
|
||||||
Bit64u old_RIP = RIP;
|
|
||||||
Bit64u old_SS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
|
|
||||||
Bit64u old_RSP = RSP;
|
|
||||||
|
|
||||||
if (! IsCanonical(RSP_for_cpl_x)) {
|
|
||||||
// #SS(selector) when changing priviledge level
|
|
||||||
BX_ERROR(("interrupt(long mode): canonical address failure %08x%08x",
|
|
||||||
GET32H(RSP_for_cpl_x), GET32L(RSP_for_cpl_x)));
|
|
||||||
exception(BX_SS_EXCEPTION, old_SS & 0xfffc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// push old stack long pointer onto new stack
|
// push old stack long pointer onto new stack
|
||||||
write_new_stack_qword_64(RSP_for_cpl_x - 8, cs_descriptor.dpl, old_SS);
|
write_new_stack_qword_64(RSP_for_cpl_x - 8, cs_descriptor.dpl, old_SS);
|
||||||
write_new_stack_qword_64(RSP_for_cpl_x - 16, cs_descriptor.dpl, old_RSP);
|
write_new_stack_qword_64(RSP_for_cpl_x - 16, cs_descriptor.dpl, old_RSP);
|
||||||
@ -184,72 +178,60 @@ void BX_CPU_C::long_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_error
|
|||||||
|
|
||||||
// set up null SS descriptor
|
// set up null SS descriptor
|
||||||
load_null_selector(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], cs_descriptor.dpl);
|
load_null_selector(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], cs_descriptor.dpl);
|
||||||
RSP = RSP_for_cpl_x;
|
|
||||||
|
|
||||||
// if INTERRUPT GATE set IF to 0
|
|
||||||
if (!(gate_descriptor.type & 1)) // even is int-gate
|
|
||||||
BX_CPU_THIS_PTR clear_IF();
|
|
||||||
BX_CPU_THIS_PTR clear_TF();
|
|
||||||
BX_CPU_THIS_PTR clear_VM();
|
|
||||||
BX_CPU_THIS_PTR clear_RF();
|
|
||||||
BX_CPU_THIS_PTR clear_NT();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else if(IS_CODE_SEGMENT_CONFORMING(cs_descriptor.type) || cs_descriptor.dpl==CPL)
|
||||||
// if code segment is conforming OR code segment DPL = CPL then
|
|
||||||
// INTERRUPT TO SAME PRIVILEGE LEVEL:
|
|
||||||
if (IS_CODE_SEGMENT_CONFORMING(cs_descriptor.type) || cs_descriptor.dpl==CPL)
|
|
||||||
{
|
{
|
||||||
BX_DEBUG(("interrupt(long mode): INTERRUPT TO SAME PRIVILEGE"));
|
// if code segment is conforming OR code segment DPL = CPL then
|
||||||
|
// INTERRUPT TO SAME PRIVILEGE LEVEL:
|
||||||
|
|
||||||
Bit64u old_RSP = RSP, temp_RSP = RSP;
|
BX_DEBUG(("interrupt(long mode): INTERRUPT TO SAME PRIVILEGE"));
|
||||||
|
|
||||||
// check selector and descriptor for new stack in current TSS
|
// check selector and descriptor for new stack in current TSS
|
||||||
if (ist > 0) {
|
if (ist > 0) {
|
||||||
BX_DEBUG(("interrupt(long mode): trap to IST, vector = %d", ist));
|
BX_DEBUG(("interrupt(long mode): trap to IST, vector = %d", ist));
|
||||||
temp_RSP = get_RSP_from_TSS(ist+3);
|
RSP_for_cpl_x = get_RSP_from_TSS(ist+3);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
RSP_for_cpl_x = RSP;
|
||||||
}
|
}
|
||||||
|
|
||||||
// align stack
|
// align stack
|
||||||
temp_RSP &= BX_CONST64(0xfffffffffffffff0);
|
RSP_for_cpl_x &= BX_CONST64(0xfffffffffffffff0);
|
||||||
|
|
||||||
// push flags onto stack
|
// push flags onto stack
|
||||||
// push current CS selector onto stack
|
// push current CS selector onto stack
|
||||||
// push return offset onto stack
|
// push return offset onto stack
|
||||||
write_new_stack_qword_64(temp_RSP - 8, cs_descriptor.dpl,
|
write_new_stack_qword_64(RSP_for_cpl_x - 8, cs_descriptor.dpl, old_SS);
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
|
write_new_stack_qword_64(RSP_for_cpl_x - 16, cs_descriptor.dpl, old_RSP);
|
||||||
write_new_stack_qword_64(temp_RSP - 16, cs_descriptor.dpl, old_RSP);
|
write_new_stack_qword_64(RSP_for_cpl_x - 24, cs_descriptor.dpl, read_eflags());
|
||||||
write_new_stack_qword_64(temp_RSP - 24, cs_descriptor.dpl, read_eflags());
|
// push long pointer to return address onto new stack
|
||||||
write_new_stack_qword_64(temp_RSP - 32, cs_descriptor.dpl,
|
write_new_stack_qword_64(RSP_for_cpl_x - 32, cs_descriptor.dpl, old_CS);
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
|
write_new_stack_qword_64(RSP_for_cpl_x - 40, cs_descriptor.dpl, old_RIP);
|
||||||
write_new_stack_qword_64(temp_RSP - 40, cs_descriptor.dpl, RIP);
|
RSP_for_cpl_x -= 40;
|
||||||
temp_RSP -= 40;
|
|
||||||
|
|
||||||
if (push_error) {
|
if (push_error) {
|
||||||
temp_RSP -= 8;
|
RSP_for_cpl_x -= 8;
|
||||||
write_new_stack_qword_64(temp_RSP, cs_descriptor.dpl, error_code);
|
write_new_stack_qword_64(RSP_for_cpl_x, cs_descriptor.dpl, error_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the RPL field of CS to CPL
|
// set the RPL field of CS to CPL
|
||||||
branch_far64(&cs_selector, &cs_descriptor, gate_dest_offset, CPL);
|
branch_far64(&cs_selector, &cs_descriptor, gate_dest_offset, CPL);
|
||||||
|
}
|
||||||
RSP = temp_RSP;
|
else {
|
||||||
|
BX_ERROR(("interrupt(long mode): bad descriptor type %u (CS.DPL=%u CPL=%u)",
|
||||||
// if interrupt gate then set IF to 0
|
(unsigned) cs_descriptor.type, (unsigned) cs_descriptor.dpl, (unsigned) CPL));
|
||||||
if (!(gate_descriptor.type & 1)) // even is int-gate
|
exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc);
|
||||||
BX_CPU_THIS_PTR clear_IF();
|
|
||||||
BX_CPU_THIS_PTR clear_TF();
|
|
||||||
BX_CPU_THIS_PTR clear_VM();
|
|
||||||
BX_CPU_THIS_PTR clear_RF();
|
|
||||||
BX_CPU_THIS_PTR clear_NT();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// else #GP(CS selector + ext)
|
RSP = RSP_for_cpl_x;
|
||||||
BX_ERROR(("interrupt(long mode): bad descriptor type=%u, descriptor.dpl=%u, CPL=%u",
|
|
||||||
(unsigned) cs_descriptor.type, (unsigned) cs_descriptor.dpl, (unsigned) CPL));
|
// if interrupt gate then set IF to 0
|
||||||
BX_ERROR(("cs.segment = %u", (unsigned) cs_descriptor.segment));
|
if (!(gate_descriptor.type & 1)) // even is int-gate
|
||||||
exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc);
|
BX_CPU_THIS_PTR clear_IF();
|
||||||
|
BX_CPU_THIS_PTR clear_TF();
|
||||||
|
//BX_CPU_THIS_PTR clear_VM(); // VM is clear in long mode
|
||||||
|
BX_CPU_THIS_PTR clear_RF();
|
||||||
|
BX_CPU_THIS_PTR clear_NT();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -266,7 +248,7 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_
|
|||||||
Bit32u gate_dest_offset;
|
Bit32u gate_dest_offset;
|
||||||
|
|
||||||
// interrupt vector must be within IDT table limits,
|
// interrupt vector must be within IDT table limits,
|
||||||
// else #GP(vector number*8 + 2 + EXT)
|
// else #GP(vector*8 + 2 + EXT)
|
||||||
if ((vector*8 + 7) > BX_CPU_THIS_PTR idtr.limit) {
|
if ((vector*8 + 7) > BX_CPU_THIS_PTR idtr.limit) {
|
||||||
BX_ERROR(("interrupt(): vector must be within IDT table limits, IDT.limit = 0x%x", BX_CPU_THIS_PTR idtr.limit));
|
BX_ERROR(("interrupt(): vector must be within IDT table limits, IDT.limit = 0x%x", BX_CPU_THIS_PTR idtr.limit));
|
||||||
exception(BX_GP_EXCEPTION, vector*8 + 2);
|
exception(BX_GP_EXCEPTION, vector*8 + 2);
|
||||||
@ -402,7 +384,7 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_
|
|||||||
// and code segment descriptor DPL<=CPL, else #GP(selector+EXT)
|
// and code segment descriptor DPL<=CPL, else #GP(selector+EXT)
|
||||||
if (cs_descriptor.valid==0 || cs_descriptor.segment==0 ||
|
if (cs_descriptor.valid==0 || cs_descriptor.segment==0 ||
|
||||||
IS_DATA_SEGMENT(cs_descriptor.type) ||
|
IS_DATA_SEGMENT(cs_descriptor.type) ||
|
||||||
cs_descriptor.dpl>CPL)
|
cs_descriptor.dpl > CPL)
|
||||||
{
|
{
|
||||||
BX_ERROR(("interrupt(): not accessible or not code segment cs=0x%04x", cs_selector.value));
|
BX_ERROR(("interrupt(): not accessible or not code segment cs=0x%04x", cs_selector.value));
|
||||||
exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc);
|
exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc);
|
||||||
@ -414,14 +396,9 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_
|
|||||||
exception(BX_NP_EXCEPTION, cs_selector.value & 0xfffc);
|
exception(BX_NP_EXCEPTION, cs_selector.value & 0xfffc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cs_descriptor.dpl > CPL) {
|
|
||||||
BX_ERROR(("interrupt(): code segment DPL(%d) > CPL", cs_descriptor.dpl));
|
|
||||||
exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if code segment is non-conforming and DPL < CPL then
|
// if code segment is non-conforming and DPL < CPL then
|
||||||
// INTERRUPT TO INNER PRIVILEGE
|
// INTERRUPT TO INNER PRIVILEGE
|
||||||
if(IS_CODE_SEGMENT_NON_CONFORMING(cs_descriptor.type) && (cs_descriptor.dpl < CPL))
|
if(IS_CODE_SEGMENT_NON_CONFORMING(cs_descriptor.type) && cs_descriptor.dpl < CPL)
|
||||||
{
|
{
|
||||||
Bit16u old_SS, old_CS, SS_for_cpl_x;
|
Bit16u old_SS, old_CS, SS_for_cpl_x;
|
||||||
Bit32u ESP_for_cpl_x, old_EIP, old_ESP;
|
Bit32u ESP_for_cpl_x, old_EIP, old_ESP;
|
||||||
@ -633,16 +610,6 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_
|
|||||||
// load new SS:eSP values from TSS
|
// load new SS:eSP values from TSS
|
||||||
load_ss(&ss_selector, &ss_descriptor, cs_descriptor.dpl);
|
load_ss(&ss_selector, &ss_descriptor, cs_descriptor.dpl);
|
||||||
|
|
||||||
EIP = gate_dest_offset;
|
|
||||||
|
|
||||||
// if INTERRUPT GATE set IF to 0
|
|
||||||
if (!(gate_descriptor.type & 1)) // even is int-gate
|
|
||||||
BX_CPU_THIS_PTR clear_IF();
|
|
||||||
BX_CPU_THIS_PTR clear_TF();
|
|
||||||
BX_CPU_THIS_PTR clear_VM();
|
|
||||||
BX_CPU_THIS_PTR clear_RF();
|
|
||||||
BX_CPU_THIS_PTR clear_NT();
|
|
||||||
|
|
||||||
if (is_v8086_mode)
|
if (is_v8086_mode)
|
||||||
{
|
{
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid = 0;
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid = 0;
|
||||||
@ -654,8 +621,6 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_
|
|||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = 0;
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = 0;
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = 0;
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -695,18 +660,19 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_
|
|||||||
// load CS descriptor
|
// load CS descriptor
|
||||||
// set the RPL field of CS to CPL
|
// set the RPL field of CS to CPL
|
||||||
load_cs(&cs_selector, &cs_descriptor, CPL);
|
load_cs(&cs_selector, &cs_descriptor, CPL);
|
||||||
EIP = gate_dest_offset;
|
|
||||||
|
|
||||||
// if interrupt gate then set IF to 0
|
|
||||||
if (!(gate_descriptor.type & 1)) // even is int-gate
|
|
||||||
BX_CPU_THIS_PTR clear_IF();
|
|
||||||
BX_CPU_THIS_PTR clear_TF();
|
|
||||||
BX_CPU_THIS_PTR clear_NT();
|
|
||||||
BX_CPU_THIS_PTR clear_VM();
|
|
||||||
BX_CPU_THIS_PTR clear_RF();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EIP = gate_dest_offset;
|
||||||
|
|
||||||
|
// if interrupt gate then set IF to 0
|
||||||
|
if (!(gate_descriptor.type & 1)) // even is int-gate
|
||||||
|
BX_CPU_THIS_PTR clear_IF();
|
||||||
|
BX_CPU_THIS_PTR clear_TF();
|
||||||
|
BX_CPU_THIS_PTR clear_NT();
|
||||||
|
BX_CPU_THIS_PTR clear_VM();
|
||||||
|
BX_CPU_THIS_PTR clear_RF();
|
||||||
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BX_PANIC(("bad descriptor type in interrupt()!"));
|
BX_PANIC(("bad descriptor type in interrupt()!"));
|
||||||
break;
|
break;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// $Id: tasking.cc,v 1.95 2010-06-18 14:24:45 sshwarts Exp $
|
// $Id: tasking.cc,v 1.96 2010-06-21 05:35:45 sshwarts Exp $
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2010 The Bochs Project
|
// Copyright (C) 2001-2010 The Bochs Project
|
||||||
@ -784,6 +784,12 @@ Bit64u BX_CPU_C::get_RSP_from_TSS(unsigned pl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Bit64u rsp = system_read_qword(BX_CPU_THIS_PTR tr.cache.u.segment.base + TSSstackaddr);
|
Bit64u rsp = system_read_qword(BX_CPU_THIS_PTR tr.cache.u.segment.base + TSSstackaddr);
|
||||||
|
|
||||||
|
if (! IsCanonical(rsp)) {
|
||||||
|
BX_ERROR(("get_RSP_from_TSS: canonical address failure 0x%08x%08x", GET32H(rsp), GET32L(rsp)));
|
||||||
|
exception(BX_SS_EXCEPTION, BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value & 0xfffc);
|
||||||
|
}
|
||||||
|
|
||||||
return rsp;
|
return rsp;
|
||||||
}
|
}
|
||||||
#endif // #if BX_SUPPORT_X86_64
|
#endif // #if BX_SUPPORT_X86_64
|
||||||
|
Loading…
Reference in New Issue
Block a user