- Implemented GD bit in DR7 register

This commit is contained in:
Stanislav Shwartsman 2008-06-02 19:50:40 +00:00
parent b7480b3e6f
commit 3d3dba7804
2 changed files with 43 additions and 17 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: exception.cc,v 1.117 2008-05-21 21:38:59 sshwarts Exp $
// $Id: exception.cc,v 1.118 2008-06-02 19:50:40 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1009,6 +1009,10 @@ void BX_CPU_C::exception(unsigned vector, Bit16u error_code, bx_bool trap)
}
}
// clear GD flag in the DR7 prior entering debug exception handler
if (vector == BX_DB_EXCEPTION)
BX_CPU_THIS_PTR dr7 &= ~0x00002000;
if (exception_type != BX_ET_PAGE_FAULT) {
// Page faults have different format
error_code = (error_code & 0xfffe) | BX_CPU_THIS_PTR EXT;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.237 2008-06-02 18:41:08 sshwarts Exp $
// $Id: proc_ctrl.cc,v 1.238 2008-06-02 19:50:40 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -234,6 +234,14 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_DdRd(bxInstruction_c *i)
}
#endif
// Note: processor clears GD upon entering debug exception
// handler, to allow access to the debug registers
if (BX_CPU_THIS_PTR dr7 & 0x2000) { // GD bit set
BX_ERROR(("MOV_DdRd: DR7 GD bit is set"));
BX_CPU_THIS_PTR dr6 |= 0x2000;
exception(BX_DB_EXCEPTION, 0, 0);
}
if (!real_mode() && CPL!=0) {
BX_ERROR(("MOV_DdRd: CPL!=0 not in real mode"));
exception(BX_GP_EXCEPTION, 0, 0);
@ -288,11 +296,6 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_DdRd(bxInstruction_c *i)
// by setting the LE and/or GE flags.
// Some sanity checks...
if (val_32 & 0x00002000) {
BX_INFO(("MOV_DdRd: GD bit not supported yet"));
// Note: processor clears GD upon entering debug exception
// handler, to allow access to the debug registers
}
if ((((val_32>>16) & 3)==2) ||
(((val_32>>20) & 3)==2) ||
(((val_32>>24) & 3)==2) ||
@ -330,7 +333,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_DdRd(bxInstruction_c *i)
break;
default:
BX_ERROR(("MOV_DdRd: #UD - control register index out of range"));
BX_ERROR(("MOV_DdRd: #UD - register index out of range"));
UndefinedOpcode(i);
}
}
@ -348,6 +351,14 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RdDd(bxInstruction_c *i)
}
#endif
// Note: processor clears GD upon entering debug exception
// handler, to allow access to the debug registers
if (BX_CPU_THIS_PTR dr7 & 0x2000) { // GD bit set
BX_ERROR(("MOV_RdDd: DR7 GD bit is set"));
BX_CPU_THIS_PTR dr6 |= 0x2000;
exception(BX_DB_EXCEPTION, 0, 0);
}
if (!real_mode() && CPL!=0) {
BX_ERROR(("MOV_RdDd: CPL!=0 not in real mode"));
exception(BX_GP_EXCEPTION, 0, 0);
@ -382,7 +393,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RdDd(bxInstruction_c *i)
break;
default:
BX_ERROR(("MOV_RdDd: #UD - control register index out of range"));
BX_ERROR(("MOV_RdDd: #UD - register index out of range"));
UndefinedOpcode(i);
}
@ -405,6 +416,14 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_DqRq(bxInstruction_c *i)
}
}
// Note: processor clears GD upon entering debug exception
// handler, to allow access to the debug registers
if (BX_CPU_THIS_PTR dr7 & 0x2000) { // GD bit set
BX_ERROR(("MOV_DqRq: DR7 GD bit is set"));
BX_CPU_THIS_PTR dr6 |= 0x2000;
exception(BX_DB_EXCEPTION, 0, 0);
}
/* #GP(0) if CPL is not 0 */
if (CPL != 0) {
BX_ERROR(("MOV_DqRq: #GP(0) if CPL is not 0"));
@ -448,11 +467,6 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_DqRq(bxInstruction_c *i)
// by setting the LE and/or GE flags.
// Some sanity checks...
if (val_64 & 0x00002000) {
BX_PANIC(("MOV_DqRq: GD bit not supported yet"));
// Note: processor clears GD upon entering debug exception
// handler, to allow access to the debug registers
}
if ((((val_64>>16) & 3)==2) ||
(((val_64>>20) & 3)==2) ||
(((val_64>>24) & 3)==2) ||
@ -478,7 +492,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_DqRq(bxInstruction_c *i)
break;
default:
BX_ERROR(("MOV_DqRq: #UD - control register index out of range"));
BX_ERROR(("MOV_DqRq: #UD - register index out of range"));
UndefinedOpcode(i);
}
}
@ -489,11 +503,19 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RqDq(bxInstruction_c *i)
if (BX_CPU_THIS_PTR cr4.get_DE()) {
if ((i->nnn() & 0xE) == 4) {
BX_ERROR(("MOV_DqRq: access to DR4/DR5 causes #UD"));
BX_ERROR(("MOV_RqDq: access to DR4/DR5 causes #UD"));
UndefinedOpcode(i);
}
}
// Note: processor clears GD upon entering debug exception
// handler, to allow access to the debug registers
if (BX_CPU_THIS_PTR dr7 & 0x2000) { // GD bit set
BX_ERROR(("MOV_RqDq: DR7 GD bit is set"));
BX_CPU_THIS_PTR dr6 |= 0x2000;
exception(BX_DB_EXCEPTION, 0, 0);
}
/* #GP(0) if CPL is not 0 */
if (CPL != 0) {
BX_ERROR(("MOV_RqDq: #GP(0) if CPL is not 0"));
@ -529,7 +551,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RqDq(bxInstruction_c *i)
break;
default:
BX_ERROR(("MOV_DqRq: #UD - control register index out of range"));
BX_ERROR(("MOV_RqDq: #UD - register index out of range"));
UndefinedOpcode(i);
}