Fixed CALL/JMP far through call gate 64

Decode SWAPGS and RDTSCP instructions
Indent changes in fetchdecode
This commit is contained in:
Stanislav Shwartsman 2006-03-22 20:47:11 +00:00
parent 912b07fde8
commit f347ab97bf
11 changed files with 4646 additions and 4640 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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