Fixed LAR/LSL in 64-bit mode, compilation error fixes

This commit is contained in:
Stanislav Shwartsman 2008-05-25 15:53:29 +00:00
parent a85dfc7617
commit 77fbc2c187
5 changed files with 93 additions and 27 deletions

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////
// $Id: call_far.cc,v 1.36 2008-05-12 06:12:12 sshwarts Exp $
// $Id: call_far.cc,v 1.37 2008-05-25 15:53:29 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005 Stanislav Shwartsman
@ -481,7 +481,7 @@ BX_CPU_C::call_gate64(bx_selector_t *gate_selector)
// examine code segment selector in call gate descriptor
BX_DEBUG(("call_gate64: CALL 64bit call gate"));
fetch_raw_descriptor64(gate_selector, &dword1, &dword2, &dword3, BX_GP_EXCEPTION);
fetch_raw_descriptor_64(gate_selector, &dword1, &dword2, &dword3, BX_GP_EXCEPTION);
parse_descriptor(dword1, dword2, &gate_descriptor);
Bit16u dest_selector = gate_descriptor.u.gate.dest_selector;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.480 2008-05-23 17:49:46 sshwarts Exp $
// $Id: cpu.h,v 1.481 2008-05-25 15:53:29 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -3030,8 +3030,10 @@ public: // for now...
BX_SMF void load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value) BX_CPP_AttrRegparmN(2);
BX_SMF void load_null_selector(bx_segment_reg_t *seg) BX_CPP_AttrRegparmN(1);
#if BX_SUPPORT_X86_64
BX_SMF void fetch_raw_descriptor64(const bx_selector_t *selector,
BX_SMF void fetch_raw_descriptor_64(const bx_selector_t *selector,
Bit32u *dword1, Bit32u *dword2, Bit32u *dword3, unsigned exception_no);
BX_SMF bx_bool fetch_raw_descriptor2_64(const bx_selector_t *selector,
Bit32u *dword1, Bit32u *dword2, Bit32u *dword3);
BX_SMF void loadSRegLMNominal(unsigned seg, unsigned selector, unsigned dpl);
#endif
BX_SMF void push_16(Bit16u value16) BX_CPP_AttrRegparmN(1);

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////
// $Id: jmp_far.cc,v 1.15 2008-05-09 18:09:04 sshwarts Exp $
// $Id: jmp_far.cc,v 1.16 2008-05-25 15:53:29 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005 Stanislav Shwartsman
@ -244,7 +244,7 @@ BX_CPU_C::jmp_call_gate64(bx_selector_t *gate_selector)
BX_DEBUG(("jmp_call_gate64: jump to CALL GATE 64"));
fetch_raw_descriptor64(gate_selector, &dword1, &dword2, &dword3, BX_GP_EXCEPTION);
fetch_raw_descriptor_64(gate_selector, &dword1, &dword2, &dword3, BX_GP_EXCEPTION);
parse_descriptor(dword1, dword2, &gate_descriptor);
Bit16u dest_selector = gate_descriptor.u.gate.dest_selector;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: protect_ctrl.cc,v 1.84 2008-05-10 18:10:53 sshwarts Exp $
// $Id: protect_ctrl.cc,v 1.85 2008-05-25 15:53:29 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -74,6 +74,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LAR_GvEw(bxInstruction_c *i)
bx_descriptor_t descriptor;
bx_selector_t selector;
Bit32u dword1, dword2;
#if BX_SUPPORT_X86_64
Bit32u dword3;
#endif
if (real_mode() || v8086_mode()) {
BX_ERROR(("LAR: not recognized in real or virtual-8086 mode"));
@ -97,10 +100,20 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LAR_GvEw(bxInstruction_c *i)
parse_selector(raw_selector, &selector);
if (!fetch_raw_descriptor2(&selector, &dword1, &dword2)) {
/* not within descriptor table */
clear_ZF();
return;
#if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
if (!fetch_raw_descriptor2_64(&selector, &dword1, &dword2, &dword3)) {
clear_ZF();
return;
}
}
else
#endif
{
if (!fetch_raw_descriptor2(&selector, &dword1, &dword2)) {
clear_ZF();
return;
}
}
parse_descriptor(dword1, dword2, &descriptor);
@ -181,7 +194,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LSL_GvEw(bxInstruction_c *i)
Bit32u limit32;
bx_selector_t selector;
Bit32u dword1, dword2;
Bit32u descriptor_dpl;
#if BX_SUPPORT_X86_64
Bit32u dword3;
#endif
if (real_mode() || v8086_mode()) {
BX_ERROR(("LSL: not recognized in real or virtual-8086 mode"));
@ -205,13 +220,23 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LSL_GvEw(bxInstruction_c *i)
parse_selector(raw_selector, &selector);
if (!fetch_raw_descriptor2(&selector, &dword1, &dword2)) {
/* not within descriptor table */
clear_ZF();
return;
#if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
if (!fetch_raw_descriptor2_64(&selector, &dword1, &dword2, &dword3)) {
clear_ZF();
return;
}
}
else
#endif
{
if (!fetch_raw_descriptor2(&selector, &dword1, &dword2)) {
clear_ZF();
return;
}
}
descriptor_dpl = (dword2 >> 13) & 0x03;
Bit32u descriptor_dpl = (dword2 >> 13) & 0x03;
if ((dword2 & 0x00001000) == 0) { // system segment
Bit32u type = (dword2 >> 8) & 0x0000000f;
@ -361,10 +386,11 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LLDT_Ew(bxInstruction_c *i)
/* fetch descriptor; call handles out of limits checks */
#if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
fetch_raw_descriptor64(&selector, &dword1, &dword2, &dword3, BX_GP_EXCEPTION);
fetch_raw_descriptor_64(&selector, &dword1, &dword2, &dword3, BX_GP_EXCEPTION);
}
else
#endif
else {
{
fetch_raw_descriptor(&selector, &dword1, &dword2, BX_GP_EXCEPTION);
}
@ -447,10 +473,11 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LTR_Ew(bxInstruction_c *i)
/* fetch descriptor; call handles out of limits checks */
#if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
fetch_raw_descriptor64(&selector, &dword1, &dword2, &dword3, BX_GP_EXCEPTION);
fetch_raw_descriptor_64(&selector, &dword1, &dword2, &dword3, BX_GP_EXCEPTION);
}
else
#endif
else {
{
fetch_raw_descriptor(&selector, &dword1, &dword2, BX_GP_EXCEPTION);
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: segment_ctrl_pro.cc,v 1.93 2008-05-12 19:19:03 sshwarts Exp $
// $Id: segment_ctrl_pro.cc,v 1.94 2008-05-25 15:53:29 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -722,7 +722,7 @@ BX_CPU_C::fetch_raw_descriptor2(const bx_selector_t *selector, Bit32u *dword1, B
}
#if BX_SUPPORT_X86_64
void BX_CPU_C::fetch_raw_descriptor64(const bx_selector_t *selector,
void BX_CPU_C::fetch_raw_descriptor_64(const bx_selector_t *selector,
Bit32u *dword1, Bit32u *dword2, Bit32u *dword3, unsigned exception_no)
{
Bit32u index = selector->index;
@ -731,7 +731,7 @@ void BX_CPU_C::fetch_raw_descriptor64(const bx_selector_t *selector,
if (selector->ti == 0) { /* GDT */
if ((index*8 + 15) > BX_CPU_THIS_PTR gdtr.limit) {
BX_ERROR(("fetch_raw_descriptor64: GDT: index (%x)%x > limit (%x)",
BX_ERROR(("fetch_raw_descriptor_64: GDT: index (%x)%x > limit (%x)",
index*8 + 15, index, BX_CPU_THIS_PTR gdtr.limit));
exception(exception_no, selector->value & 0xfffc, 0);
}
@ -739,11 +739,11 @@ void BX_CPU_C::fetch_raw_descriptor64(const bx_selector_t *selector,
}
else { /* LDT */
if (BX_CPU_THIS_PTR ldtr.cache.valid==0) {
BX_ERROR(("fetch_raw_descriptor64: LDTR.valid=0"));
BX_ERROR(("fetch_raw_descriptor_64: LDTR.valid=0"));
exception(exception_no, selector->value & 0xfffc, 0);
}
if ((index*8 + 15) > BX_CPU_THIS_PTR ldtr.cache.u.system.limit_scaled) {
BX_ERROR(("fetch_raw_descriptor64: LDT: index (%x)%x > limit (%x)",
BX_ERROR(("fetch_raw_descriptor_64: LDT: index (%x)%x > limit (%x)",
index*8 + 15, index, BX_CPU_THIS_PTR ldtr.cache.u.system.limit_scaled));
exception(exception_no, selector->value & 0xfffc, 0);
}
@ -754,7 +754,7 @@ void BX_CPU_C::fetch_raw_descriptor64(const bx_selector_t *selector,
access_read_linear(offset + 8, 8, 0, BX_READ, &raw_descriptor2);
if (raw_descriptor2 & BX_CONST64(0x00001f0000000000)) {
BX_ERROR(("fetch_raw_descriptor64: extended attributes DWORD4 TYPE != 0"));
BX_ERROR(("fetch_raw_descriptor_64: extended attributes DWORD4 TYPE != 0"));
exception(BX_GP_EXCEPTION, selector->value & 0xfffc, 0);
}
@ -762,6 +762,43 @@ void BX_CPU_C::fetch_raw_descriptor64(const bx_selector_t *selector,
*dword2 = GET32H(raw_descriptor1);
*dword3 = GET32L(raw_descriptor2);
}
bx_bool BX_CPU_C::fetch_raw_descriptor2_64(const bx_selector_t *selector,
Bit32u *dword1, Bit32u *dword2, Bit32u *dword3)
{
Bit32u index = selector->index;
bx_address offset;
Bit64u raw_descriptor1, raw_descriptor2;
if (selector->ti == 0) { /* GDT */
if ((index*8 + 15) > BX_CPU_THIS_PTR gdtr.limit) {
return 0;
}
offset = BX_CPU_THIS_PTR gdtr.base + index*8;
}
else { /* LDT */
if (BX_CPU_THIS_PTR ldtr.cache.valid==0) {
BX_ERROR(("fetch_raw_descriptor2_64: LDTR.valid=0"));
return 0;
}
if ((index*8 + 15) > BX_CPU_THIS_PTR ldtr.cache.u.system.limit_scaled)
return 0;
offset = BX_CPU_THIS_PTR ldtr.cache.u.system.base + index*8;
}
access_read_linear(offset, 8, 0, BX_READ, &raw_descriptor1);
access_read_linear(offset + 8, 8, 0, BX_READ, &raw_descriptor2);
if (raw_descriptor2 & BX_CONST64(0x00001f0000000000))
return 0;
*dword1 = GET32L(raw_descriptor1);
*dword2 = GET32H(raw_descriptor1);
*dword3 = GET32L(raw_descriptor2);
return 1;
}
#endif
#endif