From 3d3dba780412becc2f37da11e3a77d1ae5d8234a Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Mon, 2 Jun 2008 19:50:40 +0000 Subject: [PATCH] - Implemented GD bit in DR7 register --- bochs/cpu/exception.cc | 6 ++++- bochs/cpu/proc_ctrl.cc | 54 +++++++++++++++++++++++++++++------------- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/bochs/cpu/exception.cc b/bochs/cpu/exception.cc index 42293ea4f..0378bc5ad 100644 --- a/bochs/cpu/exception.cc +++ b/bochs/cpu/exception.cc @@ -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; diff --git a/bochs/cpu/proc_ctrl.cc b/bochs/cpu/proc_ctrl.cc index 6119fbf01..77a383258 100644 --- a/bochs/cpu/proc_ctrl.cc +++ b/bochs/cpu/proc_ctrl.cc @@ -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); }