diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index bd1cdeba5..61a798613 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.h,v 1.515 2008-08-29 19:23:00 sshwarts Exp $ +// $Id: cpu.h,v 1.516 2008-08-30 08:14:46 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -3154,6 +3154,7 @@ public: // for now... #if BX_X86_DEBUGGER // x86 hardware debug support BX_SMF bx_bool hwbreakpoint_check(bx_address laddr); + BX_SMF void iobreakpoint_match(unsigned port, unsigned len); BX_SMF void hwbreakpoint_match(bx_address laddr, unsigned len, unsigned rw); BX_SMF Bit32u hwdebug_compare(bx_address laddr, unsigned len, unsigned opa, unsigned opb); diff --git a/bochs/cpu/io_pro.cc b/bochs/cpu/io_pro.cc index 73a2be283..85ec80d73 100644 --- a/bochs/cpu/io_pro.cc +++ b/bochs/cpu/io_pro.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: io_pro.cc,v 1.36 2008-08-27 21:26:23 sshwarts Exp $ +// $Id: io_pro.cc,v 1.37 2008-08-30 08:14:46 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -143,5 +143,9 @@ bx_bool BX_CPU_C::allow_io(Bit16u port, unsigned len) return(0); } +#if BX_X86_DEBUGGER + iobreakpoint_match(port, len); +#endif + return(1); } diff --git a/bochs/cpu/proc_ctrl.cc b/bochs/cpu/proc_ctrl.cc index eb4fcc939..e9693ce9a 100644 --- a/bochs/cpu/proc_ctrl.cc +++ b/bochs/cpu/proc_ctrl.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: proc_ctrl.cc,v 1.256 2008-08-29 22:14:02 sshwarts Exp $ +// $Id: proc_ctrl.cc,v 1.257 2008-08-30 08:14:46 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -297,13 +297,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>>16) & 3)==2) || - (((val_32>>20) & 3)==2) || - (((val_32>>24) & 3)==2) || - (((val_32>>28) & 3)==2)) { - // IO breakpoints (10b) are not yet supported. - BX_PANIC(("MOV_DdRd: write of %08x contains IO breakpoint", val_32)); - } if (((((val_32>>16) & 3)==0) && (((val_32>>18) & 3)!=0)) || ((((val_32>>20) & 3)==0) && (((val_32>>22) & 3)!=0)) || ((((val_32>>24) & 3)==0) && (((val_32>>26) & 3)!=0)) || @@ -461,22 +454,13 @@ 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>>16) & 3)==2) || - (((val_64>>20) & 3)==2) || - (((val_64>>24) & 3)==2) || - (((val_64>>28) & 3)==2)) - { - // IO breakpoints (10b) are not yet supported. - BX_PANIC(("MOV_DqRq: write of %08x:%08x contains IO breakpoint", - (Bit32u)(val_64 >> 32), (Bit32u)(val_64 & 0xFFFFFFFF))); - } if (((((val_64>>16) & 3)==0) && (((val_64>>18) & 3)!=0)) || ((((val_64>>20) & 3)==0) && (((val_64>>22) & 3)!=0)) || ((((val_64>>24) & 3)==0) && (((val_64>>26) & 3)!=0)) || ((((val_64>>28) & 3)==0) && (((val_64>>30) & 3)!=0))) { // Instruction breakpoint with LENx not 00b (1-byte length) - BX_PANIC(("MOV_DqRq: write of %08x:%08x , R/W=00b LEN!=00b", + BX_PANIC(("MOV_DqRq: write of %08x:%08x, R/W=00b LEN!=00b", (Bit32u)(val_64 >> 32), (Bit32u)(val_64 & 0xFFFFFFFF))); } @@ -2601,4 +2585,31 @@ Bit32u BX_CPU_C::hwdebug_compare(bx_address laddr_0, unsigned size, return dr6_mask; } + +void BX_CPU_C::iobreakpoint_match(unsigned port, unsigned len) +{ + // Only compare debug registers if any breakpoints are enabled + if (BX_CPU_THIS_PTR cr4.get_DE() && (BX_CPU_THIS_PTR dr7 & 0x000000ff)) + { + Bit32u dr_op[4], dr_len[4]; + Bit32u dr7 = BX_CPU_THIS_PTR dr7; + + dr_len[0] = 1 + (dr7>>18) & 3; + dr_len[1] = 1 + (dr7>>22) & 3; + dr_len[2] = 1 + (dr7>>26) & 3; + dr_len[3] = 1 + (dr7>>30) & 3; + + dr_op[0] = (dr7>>16) & 3; + dr_op[1] = (dr7>>20) & 3; + dr_op[2] = (dr7>>24) & 3; + dr_op[3] = (dr7>>28) & 3; + + for (unsigned n=0;n<4;n++) { + if (dr_op[n] == 2 && dr_len[n] == len && BX_CPU_THIS_PTR dr[n] == port) { + BX_CPU_THIS_PTR debug_trap |= (1<