Fixed CALL/JMP far through call gate 64
Decode SWAPGS and RDTSCP instructions Indent changes in fetchdecode
This commit is contained in:
parent
912b07fde8
commit
f347ab97bf
@ -4,6 +4,7 @@ Changes after 2.2.6 release:
|
||||
- Recognize #XF exception (19) when SSE is enabled
|
||||
- Fixed bug in SYSRET instruction legacy mode
|
||||
- Fixed bug in PSRAW/PSRAD MMX and SSE instructions
|
||||
- Fixed bug in CALL/JMP far through call gate 64 in x86-64 mode
|
||||
- Fixed bug in ENTER instruction in x86-64 mode (Stanislav Shwartsman)
|
||||
- Fixes in Bochs debugger and disassembler
|
||||
- Save and restore RIP/RSP only for FAULT-type exceptions, not for traps
|
||||
|
@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// $Id: call_far.cc,v 1.9 2006-03-06 22:02:51 sshwarts Exp $
|
||||
// $Id: call_far.cc,v 1.10 2006-03-22 20:47:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -127,7 +127,7 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
|
||||
exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
else {
|
||||
call_gate64(&gate_descriptor);
|
||||
call_gate64(&gate_selector);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -458,18 +458,21 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
void BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::call_gate64(bx_descriptor_t *gate_descriptor)
|
||||
void BX_CPP_AttrRegparmN(3)
|
||||
BX_CPU_C::call_gate64(bx_selector_t *gate_selector)
|
||||
{
|
||||
bx_selector_t cs_selector;
|
||||
Bit32u dword1, dword2, dword3;
|
||||
bx_descriptor_t cs_descriptor;
|
||||
bx_descriptor_t gate_descriptor;
|
||||
|
||||
// examine code segment selector in call gate descriptor
|
||||
BX_DEBUG(("call_gate64: CALL 64bit call gate"));
|
||||
|
||||
Bit16u dest_selector = gate_descriptor->u.gate386.dest_selector;
|
||||
fetch_raw_descriptor64(gate_selector, &dword1, &dword2, &dword3, BX_GP_EXCEPTION);
|
||||
parse_descriptor(dword1, dword2, &gate_descriptor);
|
||||
|
||||
Bit16u dest_selector = gate_descriptor.u.gate386.dest_selector;
|
||||
// selector must not be null else #GP(0)
|
||||
if ( (dest_selector & 0xfffc) == 0 ) {
|
||||
BX_ERROR(("call_gate64: selector in gate null"));
|
||||
@ -479,10 +482,11 @@ BX_CPU_C::call_gate64(bx_descriptor_t *gate_descriptor)
|
||||
parse_selector(dest_selector, &cs_selector);
|
||||
// selector must be within its descriptor table limits,
|
||||
// else #GP(code segment selector)
|
||||
fetch_raw_descriptor64(&cs_selector, &dword1, &dword2, &dword3, BX_GP_EXCEPTION);
|
||||
fetch_raw_descriptor(&cs_selector, &dword1, &dword2, BX_GP_EXCEPTION);
|
||||
parse_descriptor(dword1, dword2, &cs_descriptor);
|
||||
|
||||
Bit64u new_RIP = gate_descriptor->u.gate386.dest_offset;
|
||||
// find the RIP in the gate_descriptor
|
||||
Bit64u new_RIP = gate_descriptor.u.gate386.dest_offset;
|
||||
new_RIP |= ((Bit64u)dword3 << 32);
|
||||
|
||||
// AR byte of selected descriptor must indicate code segment,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.270 2006-03-16 20:24:09 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.271 2006-03-22 20:47:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -2759,11 +2759,11 @@ public: // for now...
|
||||
BX_SMF void jmp_call_gate16(bx_descriptor_t *gate_descriptor) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void jmp_call_gate32(bx_descriptor_t *gate_descriptor) BX_CPP_AttrRegparmN(1);
|
||||
#if BX_SUPPORT_X86_64
|
||||
BX_SMF void jmp_call_gate64(bx_descriptor_t *gate_descriptor) BX_CPP_AttrRegparmN(1);
|
||||
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);
|
||||
#if BX_SUPPORT_X86_64
|
||||
BX_SMF void call_gate64(bx_descriptor_t *gate_descriptor) BX_CPP_AttrRegparmN(1);
|
||||
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 iret_protected(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
@ -2809,13 +2809,13 @@ public: // for now...
|
||||
BX_SMF void check_cs(bx_descriptor_t *descriptor, Bit16u cs_raw, Bit8u check_rpl, Bit8u check_cpl);
|
||||
BX_SMF void load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cpl) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF void load_ss(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cpl) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF void fetch_raw_descriptor(bx_selector_t *selector,
|
||||
BX_SMF void fetch_raw_descriptor(const bx_selector_t *selector,
|
||||
Bit32u *dword1, Bit32u *dword2, unsigned exception) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF bx_bool fetch_raw_descriptor2(bx_selector_t *selector,
|
||||
BX_SMF bx_bool fetch_raw_descriptor2(const bx_selector_t *selector,
|
||||
Bit32u *dword1, Bit32u *dword2) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF void load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value) BX_CPP_AttrRegparmN(2);
|
||||
#if BX_SUPPORT_X86_64
|
||||
BX_SMF void fetch_raw_descriptor64(bx_selector_t *selector,
|
||||
BX_SMF void fetch_raw_descriptor64(const bx_selector_t *selector,
|
||||
Bit32u *dword1, Bit32u *dword2, Bit32u *dword3, unsigned exception_no);
|
||||
BX_SMF void loadSRegLMNominal(unsigned seg, unsigned selector,
|
||||
bx_address base, unsigned dpl);
|
||||
@ -3295,6 +3295,7 @@ IMPLEMENT_EFLAG_ACCESSOR (TF, 8)
|
||||
#define BxPrefixSSE 0x0020 // Group encoding: 010
|
||||
#define BxSplitMod11b 0x0030 // Group encoding: 011
|
||||
#define BxFPGroup 0x0040 // Group encoding: 100
|
||||
#define BxRMGroup 0x0050 // Group encoding: 101
|
||||
|
||||
#define BxPrefix 0x0080 // bit 7
|
||||
#define BxAnother 0x0100 // bit 8
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: ctrl_xfer64.cc,v 1.44 2006-03-16 20:24:09 sshwarts Exp $
|
||||
// $Id: ctrl_xfer64.cc,v 1.45 2006-03-22 20:47:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -42,7 +42,6 @@ void BX_CPU_C::RETnear64_Iw(bxInstruction_c *i)
|
||||
BX_CPU_THIS_PTR show_flag |= Flag_ret;
|
||||
#endif
|
||||
|
||||
Bit64u temp_RSP = RSP;
|
||||
Bit16u imm16 = i->Iw();
|
||||
|
||||
pop_64(&return_RIP);
|
||||
@ -66,8 +65,6 @@ void BX_CPU_C::RETnear64(bxInstruction_c *i)
|
||||
BX_CPU_THIS_PTR show_flag |= Flag_ret;
|
||||
#endif
|
||||
|
||||
Bit64u temp_RSP = RSP;
|
||||
|
||||
pop_64(&return_RIP);
|
||||
|
||||
if (! IsCanonical(return_RIP)) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode.cc,v 1.88 2006-03-06 22:02:53 sshwarts Exp $
|
||||
// $Id: fetchdecode.cc,v 1.89 2006-03-22 20:47:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -1495,8 +1495,7 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
|
||||
};
|
||||
|
||||
unsigned
|
||||
BX_CPU_C::fetchDecode(Bit8u *iptr, bxInstruction_c *instruction,
|
||||
unsigned remain)
|
||||
BX_CPU_C::fetchDecode(Bit8u *iptr, bxInstruction_c *instruction, unsigned remain)
|
||||
{
|
||||
// remain must be at least 1
|
||||
|
||||
@ -1795,6 +1794,9 @@ modrm_done:
|
||||
case BxGroupN:
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[nnn]);
|
||||
break;
|
||||
case BxRMGroup:
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[rm]);
|
||||
break;
|
||||
case BxPrefixSSE:
|
||||
{
|
||||
/* For SSE opcodes, look into another 4 entries table
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode.h,v 1.20 2006-02-17 13:34:30 sshwarts Exp $
|
||||
// $Id: fetchdecode.h,v 1.21 2006-03-22 20:47:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2003 Stanislav Shwartsman
|
||||
@ -59,53 +59,53 @@ BX_CPP_INLINE Bit64u FetchQWORD(Bit8u *iptr)
|
||||
//
|
||||
|
||||
static BxOpcodeInfo_t opcodesADD_EwIw[2] = {
|
||||
{ BxLockable, &BX_CPU_C::ADD_EEwIw },
|
||||
{ 0, &BX_CPU_C::ADD_EGwIw }
|
||||
/* M */ { BxLockable, &BX_CPU_C::ADD_EEwIw },
|
||||
/* R */ { 0, &BX_CPU_C::ADD_EGwIw }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesADD_EdId[2] = {
|
||||
{ BxLockable, &BX_CPU_C::ADD_EEdId },
|
||||
{ 0, &BX_CPU_C::ADD_EGdId }
|
||||
/* M */ { BxLockable, &BX_CPU_C::ADD_EEdId },
|
||||
/* R */ { 0, &BX_CPU_C::ADD_EGdId }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesADD_GwEw[2] = {
|
||||
{ 0, &BX_CPU_C::ADD_GwEEw },
|
||||
{ 0, &BX_CPU_C::ADD_GwEGw }
|
||||
/* M */ { 0, &BX_CPU_C::ADD_GwEEw },
|
||||
/* R */ { 0, &BX_CPU_C::ADD_GwEGw }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesADD_GdEd[2] = {
|
||||
{ 0, &BX_CPU_C::ADD_GdEEd },
|
||||
{ 0, &BX_CPU_C::ADD_GdEGd }
|
||||
/* M */ { 0, &BX_CPU_C::ADD_GdEEd },
|
||||
/* R */ { 0, &BX_CPU_C::ADD_GdEGd }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_GbEb[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_GbEEb },
|
||||
{ 0, &BX_CPU_C::MOV_GbEGb }
|
||||
/* M */ { 0, &BX_CPU_C::MOV_GbEEb },
|
||||
/* R */ { 0, &BX_CPU_C::MOV_GbEGb }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_GwEw[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_GwEEw },
|
||||
{ 0, &BX_CPU_C::MOV_GwEGw }
|
||||
/* M */ { 0, &BX_CPU_C::MOV_GwEEw },
|
||||
/* R */ { 0, &BX_CPU_C::MOV_GwEGw }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_GdEd[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_GdEEd },
|
||||
{ 0, &BX_CPU_C::MOV_GdEGd }
|
||||
/* M */ { 0, &BX_CPU_C::MOV_GdEEd },
|
||||
/* R */ { 0, &BX_CPU_C::MOV_GdEGd }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_EbGb[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_EEbGb },
|
||||
{ 0, &BX_CPU_C::MOV_EGbGb }
|
||||
/* M */ { 0, &BX_CPU_C::MOV_EEbGb },
|
||||
/* R */ { 0, &BX_CPU_C::MOV_EGbGb }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_EwGw[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_EEwGw },
|
||||
{ 0, &BX_CPU_C::MOV_EGwGw }
|
||||
/* M */ { 0, &BX_CPU_C::MOV_EEwGw },
|
||||
/* R */ { 0, &BX_CPU_C::MOV_EGwGw }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_EdGd[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_EEdGd },
|
||||
{ 0, &BX_CPU_C::MOV_EGdGd }
|
||||
/* M */ { 0, &BX_CPU_C::MOV_EEdGd },
|
||||
/* R */ { 0, &BX_CPU_C::MOV_EGdGd }
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode64.cc,v 1.88 2006-03-06 22:02:56 sshwarts Exp $
|
||||
// $Id: fetchdecode64.cc,v 1.89 2006-03-22 20:47:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -403,6 +403,30 @@ static BxOpcodeInfo_t BxOpcodeInfo64G6[8] = {
|
||||
/* 7 */ { 0, &BX_CPU_C::BxError }
|
||||
};
|
||||
|
||||
// ----------------------------------------------------
|
||||
// MOD REG RM | non 64 bit mode | 64 bit mode
|
||||
// ----------------------------------------------------
|
||||
// MOD <> 11 7 --- | INVLPG | INVLPG
|
||||
// MOD == 11 7 0 | #UD | SWAPGS
|
||||
// MOD == 11 7 1 | #UD | RDTSCP
|
||||
// MOD == 11 7 2-7 | #UD | #UD
|
||||
|
||||
static BxOpcodeInfo_t opcodesGroupRmINVLPG[8] = {
|
||||
/* 0 */ { 0, &BX_CPU_C::SWAPGS },
|
||||
/* 1 */ { 0, &BX_CPU_C::RDTSCP },
|
||||
/* 2 */ { 0, &BX_CPU_C::BxError },
|
||||
/* 3 */ { 0, &BX_CPU_C::BxError },
|
||||
/* 4 */ { 0, &BX_CPU_C::BxError },
|
||||
/* 5 */ { 0, &BX_CPU_C::BxError },
|
||||
/* 6 */ { 0, &BX_CPU_C::BxError },
|
||||
/* 7 */ { 0, &BX_CPU_C::BxError }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesGroupModINVLPG[2] = {
|
||||
/* M */ { 0, &BX_CPU_C::INVLPG },
|
||||
/* R */ { BxRMGroup, NULL, opcodesGroupRmINVLPG }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t BxOpcodeInfo64G7[8] = {
|
||||
/* 0 */ { 0, &BX_CPU_C::SGDT_Ms },
|
||||
/* 1 */ { 0, &BX_CPU_C::SIDT_Ms },
|
||||
@ -411,7 +435,7 @@ static BxOpcodeInfo_t BxOpcodeInfo64G7[8] = {
|
||||
/* 4 */ { 0, &BX_CPU_C::SMSW_Ew },
|
||||
/* 5 */ { 0, &BX_CPU_C::BxError },
|
||||
/* 6 */ { 0, &BX_CPU_C::LMSW_Ew },
|
||||
/* 7 */ { 0, &BX_CPU_C::INVLPG }
|
||||
/* 7 */ { BxSplitMod11b, NULL, opcodesGroupModINVLPG }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t BxOpcodeInfo64G8EwIb[8] = {
|
||||
@ -2095,8 +2119,7 @@ static BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
|
||||
|
||||
|
||||
unsigned
|
||||
BX_CPU_C::fetchDecode64(Bit8u *iptr, bxInstruction_c *instruction,
|
||||
unsigned remain)
|
||||
BX_CPU_C::fetchDecode64(Bit8u *iptr, bxInstruction_c *instruction, unsigned remain)
|
||||
{
|
||||
// remain must be at least 1
|
||||
|
||||
@ -2470,6 +2493,9 @@ modrm_done:
|
||||
case BxGroupN:
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[nnn]);
|
||||
break;
|
||||
case BxRMGroup:
|
||||
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[rm]);
|
||||
break;
|
||||
case BxPrefixSSE:
|
||||
{
|
||||
/* For SSE opcodes, look into another 4 entries table
|
||||
|
@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// $Id: jmp_far.cc,v 1.4 2006-03-06 22:03:00 sshwarts Exp $
|
||||
// $Id: jmp_far.cc,v 1.5 2006-03-22 20:47:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -90,7 +90,7 @@ BX_CPU_C::jump_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
|
||||
exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
else {
|
||||
jmp_call_gate64(&descriptor);
|
||||
jmp_call_gate64(&selector);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -254,43 +254,55 @@ BX_CPU_C::jmp_call_gate32(bx_descriptor_t *gate_descriptor)
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
void BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::jmp_call_gate64(bx_descriptor_t *gate_descriptor)
|
||||
BX_CPU_C::jmp_call_gate64(bx_selector_t *gate_selector)
|
||||
{
|
||||
bx_selector_t gate_cs_selector;
|
||||
bx_descriptor_t gate_cs_descriptor;
|
||||
bx_selector_t cs_selector;
|
||||
Bit32u dword1, dword2, dword3;
|
||||
Bit64u temp_RIP;
|
||||
bx_descriptor_t cs_descriptor;
|
||||
bx_descriptor_t gate_descriptor;
|
||||
|
||||
BX_DEBUG(("jump_protected: jump to CALL GATE 64"));
|
||||
|
||||
// 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.gate386.dest_selector;
|
||||
fetch_raw_descriptor64(gate_selector, &dword1, &dword2, &dword3, BX_GP_EXCEPTION);
|
||||
parse_descriptor(dword1, dword2, &gate_descriptor);
|
||||
|
||||
if ((gate_cs_raw & 0xfffc) == 0) {
|
||||
BX_ERROR(("jump_protected: CS selector null"));
|
||||
Bit16u dest_selector = gate_descriptor.u.gate386.dest_selector;
|
||||
// selector must not be null else #GP(0)
|
||||
if ( (dest_selector & 0xfffc) == 0 ) {
|
||||
BX_ERROR(("call_gate64: selector in gate null"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
parse_selector(gate_cs_raw, &gate_cs_selector);
|
||||
// selector must be within its descriptor table limits else #GP(CS selector)
|
||||
fetch_raw_descriptor64(&gate_cs_selector, &dword1, &dword2, &dword3, BX_GP_EXCEPTION);
|
||||
parse_descriptor(dword1, dword2, &gate_cs_descriptor);
|
||||
parse_selector(dest_selector, &cs_selector);
|
||||
// selector must be within its descriptor table limits,
|
||||
// else #GP(code segment selector)
|
||||
fetch_raw_descriptor(&cs_selector, &dword1, &dword2, BX_GP_EXCEPTION);
|
||||
parse_descriptor(dword1, dword2, &cs_descriptor);
|
||||
|
||||
// find the RIP in the gate_descriptor
|
||||
Bit64u new_RIP = gate_descriptor.u.gate386.dest_offset;
|
||||
new_RIP |= ((Bit64u)dword3 << 32);
|
||||
|
||||
// AR byte of selected descriptor must indicate code segment,
|
||||
// else #GP(code segment selector)
|
||||
if (cs_descriptor.valid==0 || cs_descriptor.segment==0 ||
|
||||
cs_descriptor.u.segment.executable==0)
|
||||
{
|
||||
BX_ERROR(("jump_protected: not code segment in call gate 64"));
|
||||
exception(BX_GP_EXCEPTION, dest_selector & 0xfffc, 0);
|
||||
}
|
||||
|
||||
// In long mode, only 64-bit call gates are allowed, and they must point
|
||||
// to 64-bit code segments, else #GP(selector)
|
||||
if (! IS_LONG64_SEGMENT(gate_cs_descriptor) || gate_cs_descriptor.u.segment.d_b)
|
||||
if (! IS_LONG64_SEGMENT(cs_descriptor) || cs_descriptor.u.segment.d_b)
|
||||
{
|
||||
BX_ERROR(("jump_protected: not 64-bit code segment in call gate 64"));
|
||||
exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
|
||||
exception(BX_GP_EXCEPTION, dest_selector & 0xfffc, 0);
|
||||
}
|
||||
|
||||
// check code-segment descriptor
|
||||
check_cs(&gate_cs_descriptor, gate_cs_raw, 0, CPL);
|
||||
|
||||
temp_RIP = gate_descriptor->u.gate386.dest_offset;
|
||||
temp_RIP |= ((Bit64u)dword3 << 32);
|
||||
|
||||
branch_far64(&gate_cs_selector, &gate_cs_descriptor, temp_RIP, CPL);
|
||||
check_cs(&cs_descriptor, dest_selector, 0, CPL);
|
||||
// and transfer the control
|
||||
branch_far64(&cs_selector, &cs_descriptor, new_RIP, CPL);
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: paging.cc,v 1.67 2006-03-06 22:03:01 sshwarts Exp $
|
||||
// $Id: paging.cc,v 1.68 2006-03-22 20:47:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -572,41 +572,7 @@ void BX_CPU_C::INVLPG(bxInstruction_c* i)
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
invalidate_prefetch_q();
|
||||
|
||||
// Operand must not be a register
|
||||
if (i->modC0()) {
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
|
||||
//
|
||||
// Opcode 0F 01:
|
||||
//
|
||||
|
||||
// ----------------------------------------------------
|
||||
// MOD REG RM | non 64 bit mode | 64 bit mode
|
||||
// ----------------------------------------------------
|
||||
// MOD <> 11 7 --- | INVLPG | INVLPG
|
||||
// MOD == 11 7 0 | #UD | SWAPGS
|
||||
// MOD == 11 7 1 | #UD | RDTSCP
|
||||
// MOD == 11 7 2-7 | #UD | #UD
|
||||
|
||||
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
|
||||
if (i->nnn() == 7) {
|
||||
switch(i->rm()) {
|
||||
case 0:
|
||||
BX_CPU_THIS_PTR SWAPGS(i);
|
||||
return;
|
||||
case 1:
|
||||
BX_CPU_THIS_PTR RDTSCP(i);
|
||||
return;
|
||||
default:
|
||||
BX_INFO(("INVLPG: 0F 01 /7 RM=%d opcode is undefined !", i->rm()));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
BX_INFO(("INVLPG: op is a register"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: proc_ctrl.cc,v 1.141 2006-03-15 17:57:11 sshwarts Exp $
|
||||
// $Id: proc_ctrl.cc,v 1.142 2006-03-22 20:47:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -737,7 +737,7 @@ void BX_CPU_C::MOV_CqRq(bxInstruction_c *i)
|
||||
BX_CPU_THIS_PTR cr2 = val_64;
|
||||
break;
|
||||
case 3: // CR3
|
||||
BX_INFO(("MOV_CqRq: write to CR3 of %08x:%08x",
|
||||
BX_DEBUG(("MOV_CqRq: write to CR3 of %08x:%08x",
|
||||
(Bit32u)(val_64 >> 32), (Bit32u)(val_64 & 0xFFFFFFFF)));
|
||||
// Reserved bits take on value of MOV instruction
|
||||
CR3_change(val_64);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: segment_ctrl_pro.cc,v 1.54 2006-03-06 22:03:02 sshwarts Exp $
|
||||
// $Id: segment_ctrl_pro.cc,v 1.55 2006-03-22 20:47:11 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -474,7 +474,7 @@ BX_CPU_C::load_ss(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp
|
||||
|
||||
#if BX_CPU_LEVEL >= 2
|
||||
void BX_CPP_AttrRegparmN(3)
|
||||
BX_CPU_C::fetch_raw_descriptor(bx_selector_t *selector,
|
||||
BX_CPU_C::fetch_raw_descriptor(const bx_selector_t *selector,
|
||||
Bit32u *dword1, Bit32u *dword2, unsigned exception_no)
|
||||
{
|
||||
if (selector->ti == 0) { /* GDT */
|
||||
@ -484,10 +484,8 @@ BX_CPU_C::fetch_raw_descriptor(bx_selector_t *selector,
|
||||
BX_CPU_THIS_PTR gdtr.limit));
|
||||
exception(exception_no, selector->value & 0xfffc, 0);
|
||||
}
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8, 4, 0,
|
||||
BX_READ, dword1);
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8 + 4, 4, 0,
|
||||
BX_READ, dword2);
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8, 4, 0, BX_READ, dword1);
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8+4, 4, 0, BX_READ, dword2);
|
||||
}
|
||||
else { /* LDT */
|
||||
if (BX_CPU_THIS_PTR ldtr.cache.valid==0) {
|
||||
@ -500,23 +498,19 @@ BX_CPU_C::fetch_raw_descriptor(bx_selector_t *selector,
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit));
|
||||
exception(exception_no, selector->value & 0xfffc, 0);
|
||||
}
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8, 4, 0,
|
||||
BX_READ, dword1);
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8 + 4, 4, 0,
|
||||
BX_READ, dword2);
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8, 4, 0, BX_READ, dword1);
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8+4, 4, 0, BX_READ, dword2);
|
||||
}
|
||||
}
|
||||
|
||||
bx_bool BX_CPP_AttrRegparmN(3)
|
||||
BX_CPU_C::fetch_raw_descriptor2(bx_selector_t *selector, Bit32u *dword1, Bit32u *dword2)
|
||||
BX_CPU_C::fetch_raw_descriptor2(const bx_selector_t *selector, Bit32u *dword1, Bit32u *dword2)
|
||||
{
|
||||
if (selector->ti == 0) { /* GDT */
|
||||
if ((selector->index*8 + 7) > BX_CPU_THIS_PTR gdtr.limit)
|
||||
return(0);
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8, 4, 0,
|
||||
BX_READ, dword1);
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8 + 4, 4, 0,
|
||||
BX_READ, dword2);
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8, 4, 0, BX_READ, dword1);
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8+4, 4, 0, BX_READ, dword2);
|
||||
return(1);
|
||||
}
|
||||
else { /* LDT */
|
||||
@ -526,18 +520,18 @@ BX_CPU_C::fetch_raw_descriptor2(bx_selector_t *selector, Bit32u *dword1, Bit32u
|
||||
}
|
||||
if ((selector->index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit)
|
||||
return(0);
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8, 4, 0,
|
||||
BX_READ, dword1);
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8 + 4, 4, 0,
|
||||
BX_READ, dword2);
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8, 4, 0, BX_READ, dword1);
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8+4, 4, 0, BX_READ, dword2);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
void BX_CPU_C::fetch_raw_descriptor64(bx_selector_t *selector,
|
||||
void BX_CPU_C::fetch_raw_descriptor64(const bx_selector_t *selector,
|
||||
Bit32u *dword1, Bit32u *dword2, Bit32u *dword3, unsigned exception_no)
|
||||
{
|
||||
Bit32u dword4;
|
||||
|
||||
if (selector->ti == 0) { /* GDT */
|
||||
if ((selector->index*8 + 15) > BX_CPU_THIS_PTR gdtr.limit) {
|
||||
BX_ERROR(("fetch_raw_descriptor64: GDT: index (%x)%x > limit (%x)",
|
||||
@ -545,12 +539,11 @@ void BX_CPU_C::fetch_raw_descriptor64(bx_selector_t *selector,
|
||||
BX_CPU_THIS_PTR gdtr.limit));
|
||||
exception(exception_no, selector->value & 0xfffc, 0);
|
||||
}
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8, 4, 0,
|
||||
BX_READ, dword1);
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8 + 4, 4, 0,
|
||||
BX_READ, dword2);
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8 + 8, 4, 0,
|
||||
BX_READ, dword3);
|
||||
bx_address base = BX_CPU_THIS_PTR gdtr.base;
|
||||
access_linear(base + selector->index*8, 4, 0, BX_READ, dword1);
|
||||
access_linear(base + selector->index*8 + 4, 4, 0, BX_READ, dword2);
|
||||
access_linear(base + selector->index*8 + 8, 4, 0, BX_READ, dword3);
|
||||
access_linear(base + selector->index*8 + 12, 4, 0, BX_READ, &dword4);
|
||||
}
|
||||
else { /* LDT */
|
||||
if (BX_CPU_THIS_PTR ldtr.cache.valid==0) {
|
||||
@ -563,12 +556,16 @@ void BX_CPU_C::fetch_raw_descriptor64(bx_selector_t *selector,
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit));
|
||||
exception(exception_no, selector->value & 0xfffc, 0);
|
||||
}
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8, 4, 0,
|
||||
BX_READ, dword1);
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8 + 4, 4, 0,
|
||||
BX_READ, dword2);
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8 + 8, 4, 0,
|
||||
BX_READ, dword3);
|
||||
bx_address base = BX_CPU_THIS_PTR ldtr.cache.u.ldt.base;
|
||||
access_linear(base + selector->index*8, 4, 0, BX_READ, dword1);
|
||||
access_linear(base + selector->index*8 + 4, 4, 0, BX_READ, dword2);
|
||||
access_linear(base + selector->index*8 + 8, 4, 0, BX_READ, dword3);
|
||||
access_linear(base + selector->index*8 + 12, 4, 0, BX_READ, &dword4);
|
||||
}
|
||||
|
||||
if (dword4 != 0) {
|
||||
BX_ERROR(("fetch_raw_descriptor64: extended attributes DWORD4 != 0"));
|
||||
exception(BX_GP_EXCEPTION, selector->value & 0xfffc, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user