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)) {
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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.
|
||||
@ -59,7 +59,7 @@ BX_CPU_C::jump_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
|
||||
/* examine AR byte of destination selector for legal values: */
|
||||
parse_descriptor(dword1, dword2, &descriptor);
|
||||
|
||||
if ( descriptor.segment ) {
|
||||
if (descriptor.segment) {
|
||||
check_cs(&descriptor, cs_raw, BX_SELECTOR_RPL(cs_raw), CPL);
|
||||
branch_far64(&selector, &descriptor, disp, CPL);
|
||||
return;
|
||||
@ -90,17 +90,17 @@ 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;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
switch ( descriptor.type ) {
|
||||
switch (descriptor.type) {
|
||||
case BX_SYS_SEGMENT_AVAIL_286_TSS:
|
||||
case BX_SYS_SEGMENT_AVAIL_386_TSS:
|
||||
|
||||
if ( descriptor.type==BX_SYS_SEGMENT_AVAIL_286_TSS )
|
||||
if (descriptor.type==BX_SYS_SEGMENT_AVAIL_286_TSS)
|
||||
BX_DEBUG(("jump to 286 TSS"));
|
||||
else
|
||||
BX_DEBUG(("jump to 386 TSS"));
|
||||
@ -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