From 77fbc2c187a0c3e4c83df66261f57d25c68dd211 Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Sun, 25 May 2008 15:53:29 +0000 Subject: [PATCH] Fixed LAR/LSL in 64-bit mode, compilation error fixes --- bochs/cpu/call_far.cc | 4 +-- bochs/cpu/cpu.h | 6 ++-- bochs/cpu/jmp_far.cc | 4 +-- bochs/cpu/protect_ctrl.cc | 57 ++++++++++++++++++++++++++--------- bochs/cpu/segment_ctrl_pro.cc | 49 ++++++++++++++++++++++++++---- 5 files changed, 93 insertions(+), 27 deletions(-) diff --git a/bochs/cpu/call_far.cc b/bochs/cpu/call_far.cc index b5d758eea..48d9657e7 100755 --- a/bochs/cpu/call_far.cc +++ b/bochs/cpu/call_far.cc @@ -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; diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 37825d1b8..568c6fac6 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -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); diff --git a/bochs/cpu/jmp_far.cc b/bochs/cpu/jmp_far.cc index 51afe49e7..0218721cf 100755 --- a/bochs/cpu/jmp_far.cc +++ b/bochs/cpu/jmp_far.cc @@ -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; diff --git a/bochs/cpu/protect_ctrl.cc b/bochs/cpu/protect_ctrl.cc index 1e1162df4..d555f0fca 100644 --- a/bochs/cpu/protect_ctrl.cc +++ b/bochs/cpu/protect_ctrl.cc @@ -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); } diff --git a/bochs/cpu/segment_ctrl_pro.cc b/bochs/cpu/segment_ctrl_pro.cc index 688f095ec..d3c6619bf 100644 --- a/bochs/cpu/segment_ctrl_pro.cc +++ b/bochs/cpu/segment_ctrl_pro.cc @@ -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