Fixed priority between #NP and #GP
This commit is contained in:
parent
8e1f883156
commit
e0833381d5
@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// $Id: call_far.cc,v 1.45 2009-03-15 16:52:54 sshwarts Exp $
|
||||
// $Id: call_far.cc,v 1.46 2009-04-14 09:23:36 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2005 Stanislav Shwartsman
|
||||
@ -162,31 +162,6 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
|
||||
BX_ERROR(("call_protected: gate type %u unsupported in long mode", (unsigned) gate_descriptor.type));
|
||||
exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
switch (gate_descriptor.type) {
|
||||
case BX_SYS_SEGMENT_AVAIL_286_TSS:
|
||||
case BX_SYS_SEGMENT_AVAIL_386_TSS:
|
||||
case BX_TASK_GATE:
|
||||
case BX_286_CALL_GATE:
|
||||
case BX_386_CALL_GATE:
|
||||
break;
|
||||
default:
|
||||
BX_ERROR(("call_protected(): gate.type(%u) unsupported", (unsigned) gate_descriptor.type));
|
||||
exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// gate descriptor must be present else #NP(gate selector)
|
||||
if (! IS_PRESENT(gate_descriptor)) {
|
||||
BX_ERROR(("call_protected: gate not present"));
|
||||
exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (long_mode()) {
|
||||
call_gate64(&gate_selector);
|
||||
return;
|
||||
}
|
||||
@ -195,7 +170,6 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
|
||||
switch (gate_descriptor.type) {
|
||||
case BX_SYS_SEGMENT_AVAIL_286_TSS:
|
||||
case BX_SYS_SEGMENT_AVAIL_386_TSS:
|
||||
|
||||
if (gate_descriptor.type==BX_SYS_SEGMENT_AVAIL_286_TSS)
|
||||
BX_DEBUG(("call_protected: 16bit available TSS"));
|
||||
else
|
||||
@ -213,6 +187,12 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
|
||||
return;
|
||||
|
||||
case BX_TASK_GATE:
|
||||
// gate descriptor must be present else #NP(gate selector)
|
||||
if (! IS_PRESENT(gate_descriptor)) {
|
||||
BX_ERROR(("call_protected: gate not present"));
|
||||
exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
|
||||
// examine selector to TSS, given in Task Gate descriptor
|
||||
// must specify global in the local/global bit else #TS(TSS selector)
|
||||
raw_tss_selector = gate_descriptor.u.taskgate.tss_selector;
|
||||
@ -268,6 +248,13 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
|
||||
case BX_386_CALL_GATE:
|
||||
// examine code segment selector in call gate descriptor
|
||||
BX_DEBUG(("call_protected: call gate"));
|
||||
|
||||
// gate descriptor must be present else #NP(gate selector)
|
||||
if (! IS_PRESENT(gate_descriptor)) {
|
||||
BX_ERROR(("call_protected: gate not present"));
|
||||
exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
|
||||
dest_selector = gate_descriptor.u.gate.dest_selector;
|
||||
new_EIP = gate_descriptor.u.gate.dest_offset;
|
||||
|
||||
@ -510,7 +497,7 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
|
||||
return;
|
||||
|
||||
default: // can't get here
|
||||
BX_PANIC(("call_protected: gate type %u unsupported", (unsigned) cs_descriptor.type));
|
||||
BX_ERROR(("call_protected(): gate.type(%u) unsupported", (unsigned) gate_descriptor.type));
|
||||
exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
}
|
||||
@ -530,6 +517,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::call_gate64(bx_selector_t *gate_selector)
|
||||
fetch_raw_descriptor_64(gate_selector, &dword1, &dword2, &dword3, BX_GP_EXCEPTION);
|
||||
parse_descriptor(dword1, dword2, &gate_descriptor);
|
||||
|
||||
// gate descriptor must be present else #NP(gate selector)
|
||||
if (! IS_PRESENT(gate_descriptor)) {
|
||||
BX_ERROR(("call_gate64: call gate not present"));
|
||||
exception(BX_NP_EXCEPTION, gate_selector->value & 0xfffc, 0);
|
||||
}
|
||||
|
||||
Bit16u dest_selector = gate_descriptor.u.gate.dest_selector;
|
||||
// selector must not be null else #GP(0)
|
||||
if ((dest_selector & 0xfffc) == 0) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.591 2009-04-07 16:12:19 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.592 2009-04-14 09:23:36 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -3009,23 +3009,23 @@ public: // for now...
|
||||
bx_descriptor_t *descriptor, bx_address rip, Bit8u cpl);
|
||||
|
||||
#if BX_SupportRepeatSpeedups
|
||||
BX_SMF Bit32u FastRepMOVSB(bxInstruction_c *, unsigned srcSeg, bx_address srcOff,
|
||||
BX_SMF Bit32u FastRepMOVSB(bxInstruction_c *i, unsigned srcSeg, bx_address srcOff,
|
||||
unsigned dstSeg, bx_address dstOff, Bit32u byteCount);
|
||||
BX_SMF Bit32u FastRepMOVSW(bxInstruction_c *, unsigned srcSeg, bx_address srcOff,
|
||||
BX_SMF Bit32u FastRepMOVSW(bxInstruction_c *i, unsigned srcSeg, bx_address srcOff,
|
||||
unsigned dstSeg, bx_address dstOff, Bit32u wordCount);
|
||||
BX_SMF Bit32u FastRepMOVSD(bxInstruction_c *, unsigned srcSeg, bx_address srcOff,
|
||||
BX_SMF Bit32u FastRepMOVSD(bxInstruction_c *i, unsigned srcSeg, bx_address srcOff,
|
||||
unsigned dstSeg, bx_address dstOff, Bit32u dwordCount);
|
||||
|
||||
BX_SMF Bit32u FastRepSTOSB(bxInstruction_c *, unsigned dstSeg, bx_address dstOff,
|
||||
BX_SMF Bit32u FastRepSTOSB(bxInstruction_c *i, unsigned dstSeg, bx_address dstOff,
|
||||
Bit8u val, Bit32u byteCount);
|
||||
BX_SMF Bit32u FastRepSTOSW(bxInstruction_c *, unsigned dstSeg, bx_address dstOff,
|
||||
BX_SMF Bit32u FastRepSTOSW(bxInstruction_c *i, unsigned dstSeg, bx_address dstOff,
|
||||
Bit16u val, Bit32u wordCount);
|
||||
BX_SMF Bit32u FastRepSTOSD(bxInstruction_c *, unsigned dstSeg, bx_address dstOff,
|
||||
BX_SMF Bit32u FastRepSTOSD(bxInstruction_c *i, unsigned dstSeg, bx_address dstOff,
|
||||
Bit32u val, Bit32u dwordCount);
|
||||
|
||||
BX_SMF Bit32u FastRepINSW(bxInstruction_c *, bx_address dstOff,
|
||||
BX_SMF Bit32u FastRepINSW(bxInstruction_c *i, bx_address dstOff,
|
||||
Bit16u port, Bit32u wordCount);
|
||||
BX_SMF Bit32u FastRepOUTSW(bxInstruction_c *, unsigned srcSeg, bx_address srcOff,
|
||||
BX_SMF Bit32u FastRepOUTSW(bxInstruction_c *i, unsigned srcSeg, bx_address srcOff,
|
||||
Bit16u port, Bit32u wordCount);
|
||||
#endif
|
||||
|
||||
@ -3101,17 +3101,17 @@ public: // for now...
|
||||
BX_SMF bx_bool relocate_apic(Bit64u val_64);
|
||||
#endif
|
||||
|
||||
BX_SMF void jump_protected(bxInstruction_c *, Bit16u cs, bx_address disp) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF void jmp_task_gate(bxInstruction_c *, bx_descriptor_t *gate_descriptor) BX_CPP_AttrRegparmN(2);
|
||||
BX_SMF void jmp_call_gate(bx_descriptor_t *gate_descriptor) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void jump_protected(bxInstruction_c *i, Bit16u cs, bx_address disp) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF void jmp_task_gate(bxInstruction_c *i, bx_selector_t *selector, bx_descriptor_t *gate_descriptor) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF void jmp_call_gate(bx_selector_t *selector, bx_descriptor_t *gate_descriptor) BX_CPP_AttrRegparmN(2);
|
||||
#if BX_SUPPORT_X86_64
|
||||
BX_SMF void jmp_call_gate64(bx_selector_t *selector) BX_CPP_AttrRegparmN(1);
|
||||
#endif
|
||||
BX_SMF void call_protected(bxInstruction_c *, Bit16u cs, bx_address disp) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF void call_protected(bxInstruction_c *i, Bit16u cs, bx_address disp) BX_CPP_AttrRegparmN(3);
|
||||
#if BX_SUPPORT_X86_64
|
||||
BX_SMF void call_gate64(bx_selector_t *selector) BX_CPP_AttrRegparmN(1);
|
||||
#endif
|
||||
BX_SMF void return_protected(bxInstruction_c *, Bit16u pop_bytes) BX_CPP_AttrRegparmN(2);
|
||||
BX_SMF void return_protected(bxInstruction_c *i, Bit16u pop_bytes) BX_CPP_AttrRegparmN(2);
|
||||
BX_SMF void iret_protected(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
#if BX_SUPPORT_X86_64
|
||||
BX_SMF void long_iret(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// $Id: jmp_far.cc,v 1.18 2009-01-31 10:43:23 sshwarts Exp $
|
||||
// $Id: jmp_far.cc,v 1.19 2009-04-14 09:23:36 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2005 Stanislav Shwartsman
|
||||
@ -77,31 +77,6 @@ BX_CPU_C::jump_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
|
||||
BX_ERROR(("jump_protected: gate type %u unsupported in long mode", (unsigned) descriptor.type));
|
||||
exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
switch (descriptor.type) {
|
||||
case BX_SYS_SEGMENT_AVAIL_286_TSS:
|
||||
case BX_SYS_SEGMENT_AVAIL_386_TSS:
|
||||
case BX_286_CALL_GATE:
|
||||
case BX_386_CALL_GATE:
|
||||
case BX_TASK_GATE:
|
||||
break;
|
||||
default:
|
||||
BX_ERROR(("jump_protected: gate type %u unsupported", (unsigned) descriptor.type));
|
||||
exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// task gate must be present else #NP(gate selector)
|
||||
if (! IS_PRESENT(descriptor)) {
|
||||
BX_ERROR(("jump_protected: call gate.p == 0"));
|
||||
exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (long_mode()) {
|
||||
jmp_call_gate64(&selector);
|
||||
return;
|
||||
}
|
||||
@ -127,23 +102,23 @@ BX_CPU_C::jump_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
|
||||
return;
|
||||
|
||||
case BX_TASK_GATE:
|
||||
jmp_task_gate(i, &descriptor);
|
||||
jmp_task_gate(i, &selector, &descriptor);
|
||||
return;
|
||||
|
||||
case BX_286_CALL_GATE:
|
||||
case BX_386_CALL_GATE:
|
||||
jmp_call_gate(&descriptor);
|
||||
jmp_call_gate(&selector, &descriptor);
|
||||
return;
|
||||
|
||||
default: // can't get here
|
||||
BX_PANIC(("jump_protected: gate type %u unsupported", (unsigned) descriptor.type));
|
||||
default:
|
||||
BX_ERROR(("jump_protected: gate type %u unsupported", (unsigned) descriptor.type));
|
||||
exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(2)
|
||||
BX_CPU_C::jmp_task_gate(bxInstruction_c *i, bx_descriptor_t *gate_descriptor)
|
||||
void BX_CPP_AttrRegparmN(3)
|
||||
BX_CPU_C::jmp_task_gate(bxInstruction_c *i, bx_selector_t *selector, bx_descriptor_t *gate_descriptor)
|
||||
{
|
||||
Bit16u raw_tss_selector;
|
||||
bx_selector_t tss_selector;
|
||||
@ -151,6 +126,12 @@ BX_CPU_C::jmp_task_gate(bxInstruction_c *i, bx_descriptor_t *gate_descriptor)
|
||||
Bit32u dword1, dword2;
|
||||
Bit32u temp_eIP;
|
||||
|
||||
// task gate must be present else #NP(gate selector)
|
||||
if (! gate_descriptor->p) {
|
||||
BX_ERROR(("jmp_task_gate: task gate not present"));
|
||||
exception(BX_NP_EXCEPTION, selector->value & 0xfffc, 0);
|
||||
}
|
||||
|
||||
// examine selector to TSS, given in Task Gate descriptor
|
||||
// must specify global in the local/global bit else #GP(TSS selector)
|
||||
raw_tss_selector = gate_descriptor->u.taskgate.tss_selector;
|
||||
@ -200,8 +181,8 @@ BX_CPU_C::jmp_task_gate(bxInstruction_c *i, bx_descriptor_t *gate_descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::jmp_call_gate(bx_descriptor_t *gate_descriptor)
|
||||
void BX_CPP_AttrRegparmN(2)
|
||||
BX_CPU_C::jmp_call_gate(bx_selector_t *selector, bx_descriptor_t *gate_descriptor)
|
||||
{
|
||||
bx_selector_t gate_cs_selector;
|
||||
bx_descriptor_t gate_cs_descriptor;
|
||||
@ -212,6 +193,12 @@ BX_CPU_C::jmp_call_gate(bx_descriptor_t *gate_descriptor)
|
||||
else
|
||||
BX_DEBUG(("jmp_call_gate: jump to 386 CALL GATE"));
|
||||
|
||||
// task gate must be present else #NP(gate selector)
|
||||
if (! gate_descriptor->p) {
|
||||
BX_ERROR(("jmp_call_gate: call gate not present!"));
|
||||
exception(BX_NP_EXCEPTION, selector->value & 0xfffc, 0);
|
||||
}
|
||||
|
||||
// examine selector to code segment given in call gate descriptor
|
||||
// selector must not be null, else #GP(0)
|
||||
Bit16u gate_cs_raw = gate_descriptor->u.gate.dest_selector;
|
||||
@ -247,6 +234,12 @@ BX_CPU_C::jmp_call_gate64(bx_selector_t *gate_selector)
|
||||
fetch_raw_descriptor_64(gate_selector, &dword1, &dword2, &dword3, BX_GP_EXCEPTION);
|
||||
parse_descriptor(dword1, dword2, &gate_descriptor);
|
||||
|
||||
// gate must be present else #NP(gate selector)
|
||||
if (! IS_PRESENT(gate_descriptor)) {
|
||||
BX_ERROR(("jmp_call_gate64: call gate.p == 0"));
|
||||
exception(BX_NP_EXCEPTION, gate_selector->value & 0xfffc, 0);
|
||||
}
|
||||
|
||||
Bit16u dest_selector = gate_descriptor.u.gate.dest_selector;
|
||||
// selector must not be null else #GP(0)
|
||||
if ((dest_selector & 0xfffc) == 0) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: tasking.cc,v 1.69 2009-04-05 19:09:44 sshwarts Exp $
|
||||
// $Id: tasking.cc,v 1.70 2009-04-14 09:23:36 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -146,6 +146,11 @@ void BX_CPU_C::task_switch(bxInstruction_c *i, bx_selector_t *tss_selector,
|
||||
// 2) TSS DPL must be >= TSS selector RPL
|
||||
// 3) TSS descriptor is not busy.
|
||||
|
||||
if (tss_descriptor->valid==0 || tss_selector->ti) {
|
||||
BX_ERROR(("task_switch: bad TSS selector !"));
|
||||
exception(BX_GP_EXCEPTION, tss_selector->value & 0xfffc, 0);
|
||||
}
|
||||
|
||||
// TSS must be present, else #NP(TSS selector)
|
||||
if (tss_descriptor->p==0) {
|
||||
BX_ERROR(("task_switch: TSS descriptor is not present !"));
|
||||
@ -167,10 +172,7 @@ void BX_CPU_C::task_switch(bxInstruction_c *i, bx_selector_t *tss_selector,
|
||||
nbase32 = (Bit32u) tss_descriptor->u.segment.base; // new TSS.base
|
||||
new_TSS_limit = tss_descriptor->u.segment.limit_scaled;
|
||||
|
||||
// TSS must have valid limit, else #TS(TSS selector)
|
||||
if (tss_selector->ti || tss_descriptor->valid==0 ||
|
||||
new_TSS_limit < new_TSS_max)
|
||||
{
|
||||
if (new_TSS_limit < new_TSS_max) {
|
||||
BX_ERROR(("task_switch(): new TSS limit < %d", new_TSS_max));
|
||||
exception(BX_TS_EXCEPTION, tss_selector->value & 0xfffc, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user