Fix code duplication for check_cs descriptor
The function will execute - segment is executable code segment - conforming/non-conforming segment priviledge checks - segment is present
This commit is contained in:
parent
2c6393dd8b
commit
f096a80716
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: access.cc,v 1.58 2005-06-14 20:55:55 sshwarts Exp $
|
||||
// $Id: access.cc,v 1.59 2005-08-01 21:40:10 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -24,7 +24,6 @@
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
#define NEED_CPU_REG_SHORTCUTS 1
|
||||
#include "bochs.h"
|
||||
#define LOG_THIS BX_CPU_THIS_PTR
|
||||
@ -275,7 +274,7 @@ BX_CPU_C::write_virtual_byte(unsigned s, bx_address offset, Bit8u *data)
|
||||
|
||||
seg = &BX_CPU_THIS_PTR sregs[s];
|
||||
if (seg->cache.valid & SegAccessWOK) {
|
||||
if ((IsLongMode() && IsCanonical(offset))
|
||||
if (((BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) && IsCanonical(offset))
|
||||
|| (offset <= seg->cache.u.segment.limit_scaled)) {
|
||||
unsigned pl;
|
||||
accessOK:
|
||||
@ -323,7 +322,7 @@ BX_CPU_C::write_virtual_word(unsigned s, bx_address offset, Bit16u *data)
|
||||
|
||||
seg = &BX_CPU_THIS_PTR sregs[s];
|
||||
if (seg->cache.valid & SegAccessWOK) {
|
||||
if ((IsLongMode() && IsCanonical(offset))
|
||||
if (((BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) && IsCanonical(offset))
|
||||
|| (offset < seg->cache.u.segment.limit_scaled)) {
|
||||
unsigned pl;
|
||||
accessOK:
|
||||
@ -373,7 +372,7 @@ BX_CPU_C::write_virtual_dword(unsigned s, bx_address offset, Bit32u *data)
|
||||
|
||||
seg = &BX_CPU_THIS_PTR sregs[s];
|
||||
if (seg->cache.valid & SegAccessWOK) {
|
||||
if ((IsLongMode() && IsCanonical(offset))
|
||||
if (((BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) && IsCanonical(offset))
|
||||
|| (offset < (seg->cache.u.segment.limit_scaled-2))) {
|
||||
unsigned pl;
|
||||
accessOK:
|
||||
@ -423,7 +422,7 @@ BX_CPU_C::write_virtual_qword(unsigned s, bx_address offset, Bit64u *data)
|
||||
|
||||
seg = &BX_CPU_THIS_PTR sregs[s];
|
||||
if (seg->cache.valid & SegAccessWOK) {
|
||||
if ((IsLongMode() && IsCanonical(offset))
|
||||
if (((BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) && IsCanonical(offset))
|
||||
|| (offset <= (seg->cache.u.segment.limit_scaled-7))) {
|
||||
unsigned pl;
|
||||
accessOK:
|
||||
@ -473,7 +472,7 @@ BX_CPU_C::read_virtual_byte(unsigned s, bx_address offset, Bit8u *data)
|
||||
|
||||
seg = &BX_CPU_THIS_PTR sregs[s];
|
||||
if (seg->cache.valid & SegAccessROK) {
|
||||
if ((IsLongMode() && IsCanonical(offset))
|
||||
if (((BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) && IsCanonical(offset))
|
||||
|| (offset <= seg->cache.u.segment.limit_scaled)) {
|
||||
unsigned pl;
|
||||
accessOK:
|
||||
@ -515,7 +514,7 @@ BX_CPU_C::read_virtual_word(unsigned s, bx_address offset, Bit16u *data)
|
||||
|
||||
seg = &BX_CPU_THIS_PTR sregs[s];
|
||||
if (seg->cache.valid & SegAccessROK) {
|
||||
if ((IsLongMode() && IsCanonical(offset))
|
||||
if (((BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) && IsCanonical(offset))
|
||||
|| (offset < seg->cache.u.segment.limit_scaled)) {
|
||||
unsigned pl;
|
||||
accessOK:
|
||||
@ -559,7 +558,7 @@ BX_CPU_C::read_virtual_dword(unsigned s, bx_address offset, Bit32u *data)
|
||||
|
||||
seg = &BX_CPU_THIS_PTR sregs[s];
|
||||
if (seg->cache.valid & SegAccessROK) {
|
||||
if ((IsLongMode() && IsCanonical(offset))
|
||||
if (((BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) && IsCanonical(offset))
|
||||
|| (offset < (seg->cache.u.segment.limit_scaled-2))) {
|
||||
unsigned pl;
|
||||
accessOK:
|
||||
@ -603,7 +602,7 @@ BX_CPU_C::read_virtual_qword(unsigned s, bx_address offset, Bit64u *data)
|
||||
|
||||
seg = &BX_CPU_THIS_PTR sregs[s];
|
||||
if (seg->cache.valid & SegAccessROK) {
|
||||
if ((IsLongMode() && IsCanonical(offset))
|
||||
if (((BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) && IsCanonical(offset))
|
||||
|| (offset <= (seg->cache.u.segment.limit_scaled-7))) {
|
||||
unsigned pl;
|
||||
accessOK:
|
||||
@ -652,7 +651,7 @@ BX_CPU_C::read_RMW_virtual_byte(unsigned s, bx_address offset, Bit8u *data)
|
||||
|
||||
seg = &BX_CPU_THIS_PTR sregs[s];
|
||||
if (seg->cache.valid & SegAccessWOK) {
|
||||
if ((IsLongMode() && IsCanonical(offset))
|
||||
if (((BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) && IsCanonical(offset))
|
||||
|| (offset <= seg->cache.u.segment.limit_scaled)) {
|
||||
unsigned pl;
|
||||
accessOK:
|
||||
@ -703,7 +702,7 @@ BX_CPU_C::read_RMW_virtual_word(unsigned s, bx_address offset, Bit16u *data)
|
||||
|
||||
seg = &BX_CPU_THIS_PTR sregs[s];
|
||||
if (seg->cache.valid & SegAccessWOK) {
|
||||
if ((IsLongMode() && IsCanonical(offset))
|
||||
if (((BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) && IsCanonical(offset))
|
||||
|| (offset < seg->cache.u.segment.limit_scaled)) {
|
||||
unsigned pl;
|
||||
accessOK:
|
||||
@ -754,7 +753,7 @@ BX_CPU_C::read_RMW_virtual_dword(unsigned s, bx_address offset, Bit32u *data)
|
||||
|
||||
seg = &BX_CPU_THIS_PTR sregs[s];
|
||||
if (seg->cache.valid & SegAccessWOK) {
|
||||
if ((IsLongMode() && IsCanonical(offset))
|
||||
if (((BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) && IsCanonical(offset))
|
||||
|| (offset < (seg->cache.u.segment.limit_scaled-2))) {
|
||||
unsigned pl;
|
||||
accessOK:
|
||||
@ -805,7 +804,7 @@ BX_CPU_C::read_RMW_virtual_qword(unsigned s, bx_address offset, Bit64u *data)
|
||||
|
||||
seg = &BX_CPU_THIS_PTR sregs[s];
|
||||
if (seg->cache.valid & SegAccessWOK) {
|
||||
if ((IsLongMode() && IsCanonical(offset))
|
||||
if (((BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) && IsCanonical(offset))
|
||||
|| (offset <= (seg->cache.u.segment.limit_scaled-7))) {
|
||||
unsigned pl;
|
||||
accessOK:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.228 2005-07-31 17:57:25 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.229 2005-08-01 21:40:10 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -331,8 +331,8 @@
|
||||
#define BX_MODE_IA32_REAL 0x0 // CR0.PE=0 |
|
||||
#define BX_MODE_IA32_V8086 0x1 // CR0.PE=1, EFLAGS.VM=1 | EFER.LMA=0
|
||||
#define BX_MODE_IA32_PROTECTED 0x2 // CR0.PE=1, EFLAGS.VM=0 |
|
||||
#define BX_MODE_LONG_COMPAT 0x3 // EFER.LMA = EFER.LME = 1, CR0.PE=1, CS.L=0
|
||||
#define BX_MODE_LONG_64 0x4 // EFER.LMA = EFER.LME = 1, CR0.PE=1, CS.L=1
|
||||
#define BX_MODE_LONG_COMPAT 0x3 // EFER.LMA = 1, CR0.PE=1, CS.L=0
|
||||
#define BX_MODE_LONG_64 0x4 // EFER.LMA = 1, CR0.PE=1, CS.L=1
|
||||
|
||||
#define BX_CANONICAL_BITS (48)
|
||||
|
||||
@ -343,8 +343,8 @@
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
#define IsLongMode() (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64)
|
||||
#define StackAddrSize64() (IsLongMode())
|
||||
#define IsLongMode() (BX_CPU_THIS_PTR msr.lma)
|
||||
#define StackAddrSize64() (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64)
|
||||
#else
|
||||
#define IsLongMode() (0)
|
||||
#define StackAddrSize64() (0)
|
||||
@ -2779,6 +2779,7 @@ public: // for now...
|
||||
BX_SMF void parse_selector(Bit16u raw_selector, bx_selector_t *selector) BX_CPP_AttrRegparmN(2);
|
||||
BX_SMF void parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF void load_ldtr(bx_selector_t *selector, bx_descriptor_t *descriptor);
|
||||
BX_SMF void check_cs(bx_descriptor_t *descriptor, Bit16u cs_raw, Bit8u check_rpl) BX_CPP_AttrRegparmN(3);
|
||||
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,
|
||||
@ -2982,8 +2983,11 @@ BX_CPP_INLINE Bit32u BX_CPU_C::get_EIP(void)
|
||||
BX_CPP_INLINE bx_address BX_CPU_C::get_segment_base(unsigned seg)
|
||||
{
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (IsLongMode() && seg != BX_SEG_REG_FS && seg != BX_SEG_REG_GS)
|
||||
return 0;
|
||||
if ((BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) &&
|
||||
(seg != BX_SEG_REG_FS) && (seg != BX_SEG_REG_GS))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return (BX_CPU_THIS_PTR sregs[seg].cache.u.segment.base);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: descriptor.h,v 1.8 2005-07-10 20:32:31 sshwarts Exp $
|
||||
// $Id: descriptor.h,v 1.9 2005-08-01 21:40:14 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -39,6 +39,7 @@ typedef struct { /* bx_selector_t */
|
||||
#endif
|
||||
} bx_selector_t;
|
||||
|
||||
#define BX_SELECTOR_RPL(selector) ((selector) & 0x03)
|
||||
#define BX_SELECTOR_RPL_MASK (0xfffc)
|
||||
|
||||
typedef struct
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode64.cc,v 1.80 2005-07-31 17:57:26 sshwarts Exp $
|
||||
// $Id: fetchdecode64.cc,v 1.81 2005-08-01 21:40:14 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -357,10 +357,10 @@ static BxOpcodeInfo_t BxOpcodeInfo64G5w[8] = {
|
||||
// attributes defined in main area
|
||||
/* 0 */ { BxLockable, &BX_CPU_C::INC_Ew },
|
||||
/* 1 */ { BxLockable, &BX_CPU_C::DEC_Ew },
|
||||
/* 2 */ { 0, &BX_CPU_C::CALL_Ew }, // invalid??
|
||||
/* 3 */ { 0, &BX_CPU_C::CALL16_Ep }, // invalid??
|
||||
/* 4 */ { 0, &BX_CPU_C::JMP_Eq }, // invalid??
|
||||
/* 5 */ { 0, &BX_CPU_C::JMP16_Ep }, // invalid??
|
||||
/* 2 */ { 0, &BX_CPU_C::CALL_Ew },
|
||||
/* 3 */ { 0, &BX_CPU_C::CALL16_Ep },
|
||||
/* 4 */ { 0, &BX_CPU_C::JMP_Eq },
|
||||
/* 5 */ { 0, &BX_CPU_C::JMP16_Ep },
|
||||
/* 6 */ { 0, &BX_CPU_C::PUSH_Ew },
|
||||
/* 7 */ { 0, &BX_CPU_C::BxError }
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: io.cc,v 1.27 2005-05-20 20:06:50 sshwarts Exp $
|
||||
// $Id: io.cc,v 1.28 2005-08-01 21:40:17 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -234,7 +234,7 @@ void BX_CPU_C::INSW_YvDX(bxInstruction_c *i)
|
||||
if ( !(dstSegPtr->cache.valid & SegAccessWOK) ) {
|
||||
goto noAcceleration;
|
||||
}
|
||||
if ( !IsLongMode() ) {
|
||||
if (BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64) {
|
||||
// Now make sure transfer will fit within the constraints of the
|
||||
// segment boundaries, 0..limit for non expand-down. We know
|
||||
// wordCount >= 1 here.
|
||||
@ -538,7 +538,7 @@ void BX_CPU_C::OUTSW_DXXv(bxInstruction_c *i)
|
||||
if ( !(srcSegPtr->cache.valid & SegAccessROK) ) {
|
||||
goto noAcceleration;
|
||||
}
|
||||
if ( !IsLongMode() ) {
|
||||
if (BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64) {
|
||||
// Now make sure transfer will fit within the constraints of the
|
||||
// segment boundaries, 0..limit for non expand-down. We know
|
||||
// wordCount >= 1 here.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: segment_ctrl_pro.cc,v 1.42 2005-07-31 17:57:27 sshwarts Exp $
|
||||
// $Id: segment_ctrl_pro.cc,v 1.43 2005-08-01 21:40:17 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -87,7 +87,6 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
#endif
|
||||
BX_ERROR(("load_seg_reg: SS: new_value == 0"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
bx_descriptor_t descriptor;
|
||||
@ -104,7 +103,6 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
BX_ERROR(("load_seg_reg: GDT: %s: index(%04x*8+7) > limit(%06x)",
|
||||
BX_CPU_THIS_PTR strseg(seg), (unsigned) index, (unsigned) BX_CPU_THIS_PTR gdtr.limit));
|
||||
exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
|
||||
return;
|
||||
}
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + index*8, 4, 0,
|
||||
BX_READ, &dword1);
|
||||
@ -115,12 +113,10 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
if (BX_CPU_THIS_PTR ldtr.cache.valid==0) { /* ??? */
|
||||
BX_ERROR(("load_seg_reg: LDT invalid"));
|
||||
exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
|
||||
return;
|
||||
}
|
||||
if ((index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit) {
|
||||
BX_ERROR(("load_seg_reg ss: LDT: index > limit"));
|
||||
exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
|
||||
return;
|
||||
}
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8, 4, 0,
|
||||
BX_READ, &dword1);
|
||||
@ -132,7 +128,6 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
if (rpl != CPL) {
|
||||
BX_ERROR(("load_seg_reg(): rpl != CPL"));
|
||||
exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
parse_descriptor(dword1, dword2, &descriptor);
|
||||
@ -140,7 +135,6 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
if (descriptor.valid==0) {
|
||||
BX_ERROR(("load_seg_reg(): valid bit cleared"));
|
||||
exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* AR byte must indicate a writable data segment else #GP(selector) */
|
||||
@ -219,7 +213,6 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
BX_ERROR(("load_seg_reg: GDT: %s: index(%04x) > limit(%06x)",
|
||||
BX_CPU_THIS_PTR strseg(seg), (unsigned) index, (unsigned) BX_CPU_THIS_PTR gdtr.limit));
|
||||
exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
|
||||
return;
|
||||
}
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + index*8, 4, 0,
|
||||
BX_READ, &dword1);
|
||||
@ -230,12 +223,10 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
if (BX_CPU_THIS_PTR ldtr.cache.valid==0) {
|
||||
BX_ERROR(("load_seg_reg: LDT invalid"));
|
||||
exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
|
||||
return;
|
||||
}
|
||||
if ((index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit) {
|
||||
BX_ERROR(("load_seg_reg ds,es: LDT: index > limit"));
|
||||
exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
|
||||
return;
|
||||
}
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8, 4, 0,
|
||||
BX_READ, &dword1);
|
||||
@ -248,7 +239,6 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
if (descriptor.valid==0) {
|
||||
BX_ERROR(("load_seg_reg(): valid bit cleared"));
|
||||
exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* AR byte must indicate data or readable code segment else #GP(selector) */
|
||||
@ -258,7 +248,6 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
{
|
||||
BX_ERROR(("load_seg_reg(): not data or readable code"));
|
||||
exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If data or non-conforming code, then both the RPL and the CPL
|
||||
@ -269,7 +258,6 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
if ((rpl > descriptor.dpl) || (CPL > descriptor.dpl)) {
|
||||
BX_ERROR(("load_seg_reg: RPL & CPL must be <= DPL"));
|
||||
exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -277,7 +265,6 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
if (! IS_PRESENT(descriptor)) {
|
||||
BX_ERROR(("load_seg_reg: segment not present"));
|
||||
exception(BX_NP_EXCEPTION, new_value & 0xfffc, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* load segment register with selector */
|
||||
@ -539,9 +526,63 @@ BX_CPU_C::load_ldtr(bx_selector_t *selector, bx_descriptor_t *descriptor)
|
||||
BX_CPU_THIS_PTR ldtr.cache.valid = 1;
|
||||
}
|
||||
|
||||
/* pass zero in check_rpl if no needed selector RPL checking for
|
||||
non-conforming segments */
|
||||
void BX_CPP_AttrRegparmN(3)
|
||||
BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor,
|
||||
Bit8u cpl)
|
||||
BX_CPU_C::check_cs(bx_descriptor_t *descriptor, Bit16u cs_raw, Bit8u check_rpl)
|
||||
{
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (descriptor->u.segment.l)
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR msr.lma) {
|
||||
BX_PANIC(("check_cs: attempt to jump to long mode without enabling EFER.LMA !"));
|
||||
}
|
||||
|
||||
if (descriptor->u.segment.d_b) {
|
||||
BX_ERROR(("check_cs: Both L and D bits enabled for segment descriptor !"));
|
||||
exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// descriptor AR byte must indicate code segment else #GP(selector)
|
||||
if ((descriptor->valid==0) || (descriptor->segment==0) ||
|
||||
(descriptor->u.segment.executable==0))
|
||||
{
|
||||
BX_ERROR(("check_cs: not a valid code segment !"));
|
||||
exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
|
||||
// if non-conforming, code segment descriptor DPL must = CPL else #GP(selector)
|
||||
if (descriptor->u.segment.c_ed==0) {
|
||||
if (descriptor->dpl != CPL) {
|
||||
BX_ERROR(("check_cs: non-conforming code seg descriptor DPL != CPL"));
|
||||
exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
|
||||
/* RPL of destination selector must be <= CPL else #GP(selector) */
|
||||
if (check_rpl > CPL) {
|
||||
BX_ERROR(("check_cs: non-conforming code seg selector rpl > CPL"));
|
||||
exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
}
|
||||
// if conforming, then code segment descriptor DPL must <= CPL else #GP(selector)
|
||||
else {
|
||||
if (descriptor->dpl > CPL) {
|
||||
BX_ERROR(("check_cs: conforming code seg descriptor DPL > CPL"));
|
||||
exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// code segment must be present else #NP(selector)
|
||||
if (! descriptor->p) {
|
||||
BX_ERROR(("check_cs: code segment not present !"));
|
||||
exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(3)
|
||||
BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cpl)
|
||||
{
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector = *selector;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache = *descriptor;
|
||||
@ -626,7 +667,6 @@ BX_CPU_C::fetch_raw_descriptor(bx_selector_t *selector,
|
||||
(selector->index*8 + 7), selector->index,
|
||||
BX_CPU_THIS_PTR gdtr.limit));
|
||||
exception(exception_no, selector->value & 0xfffc, 0);
|
||||
return;
|
||||
}
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8, 4, 0,
|
||||
BX_READ, dword1);
|
||||
@ -643,7 +683,6 @@ BX_CPU_C::fetch_raw_descriptor(bx_selector_t *selector,
|
||||
(selector->index*8 + 7), selector->index,
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit));
|
||||
exception(exception_no, selector->value & 0xfffc, 0);
|
||||
return;
|
||||
}
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8, 4, 0,
|
||||
BX_READ, dword1);
|
||||
@ -654,7 +693,6 @@ BX_CPU_C::fetch_raw_descriptor(bx_selector_t *selector,
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
bx_bool BX_CPP_AttrRegparmN(3)
|
||||
BX_CPU_C::fetch_raw_descriptor2(bx_selector_t *selector,
|
||||
Bit32u *dword1, Bit32u *dword2)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: string.cc,v 1.30 2005-07-04 17:44:08 sshwarts Exp $
|
||||
// $Id: string.cc,v 1.31 2005-08-01 21:40:17 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -124,7 +124,7 @@ Bit32u BX_CPU_C::FastRepMOVSB(bxInstruction_c *i, unsigned srcSeg, bx_address sr
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !IsLongMode() )
|
||||
if (BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64)
|
||||
{
|
||||
Bit32u srcSegLimit = srcSegPtr->cache.u.segment.limit_scaled;
|
||||
Bit32u dstSegLimit = dstSegPtr->cache.u.segment.limit_scaled;
|
||||
@ -261,7 +261,7 @@ Bit32u BX_CPU_C::FastRepMOVSW(bxInstruction_c *i, unsigned srcSeg, bx_address sr
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !IsLongMode() )
|
||||
if (BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64)
|
||||
{
|
||||
Bit32u srcSegLimit = srcSegPtr->cache.u.segment.limit_scaled;
|
||||
Bit32u dstSegLimit = dstSegPtr->cache.u.segment.limit_scaled;
|
||||
@ -399,7 +399,7 @@ Bit32u BX_CPU_C::FastRepMOVSD(bxInstruction_c *i, unsigned srcSeg, bx_address sr
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !IsLongMode() )
|
||||
if (BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64)
|
||||
{
|
||||
Bit32u srcSegLimit = srcSegPtr->cache.u.segment.limit_scaled;
|
||||
Bit32u dstSegLimit = dstSegPtr->cache.u.segment.limit_scaled;
|
||||
@ -503,7 +503,7 @@ Bit32u BX_CPU_C::FastRepSTOSB(bxInstruction_c *i, unsigned dstSeg, bx_address ds
|
||||
// are non expand-down (thus we can make a simple limit check).
|
||||
if ( !(dstSegPtr->cache.valid & SegAccessWOK) ) return 0;
|
||||
|
||||
if ( !IsLongMode() )
|
||||
if (BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64)
|
||||
{
|
||||
Bit32u dstSegLimit = dstSegPtr->cache.u.segment.limit_scaled;
|
||||
|
||||
@ -599,7 +599,7 @@ Bit32u BX_CPU_C::FastRepSTOSW(bxInstruction_c *i, unsigned dstSeg, bx_address ds
|
||||
// are non expand-down (thus we can make a simple limit check).
|
||||
if ( !(dstSegPtr->cache.valid & SegAccessWOK) ) return 0;
|
||||
|
||||
if ( !IsLongMode() )
|
||||
if (BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64)
|
||||
{
|
||||
Bit32u dstSegLimit = dstSegPtr->cache.u.segment.limit_scaled;
|
||||
|
||||
@ -696,7 +696,7 @@ Bit32u BX_CPU_C::FastRepSTOSD(bxInstruction_c *i, unsigned dstSeg, bx_address ds
|
||||
// are non expand-down (thus we can make a simple limit check).
|
||||
if ( !(dstSegPtr->cache.valid & SegAccessWOK) ) return 0;
|
||||
|
||||
if ( !IsLongMode() )
|
||||
if (BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64)
|
||||
{
|
||||
Bit32u dstSegLimit = dstSegPtr->cache.u.segment.limit_scaled;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user