- Preliminary implementation of X86 IO breakpoints

This commit is contained in:
Stanislav Shwartsman 2008-08-30 08:14:46 +00:00
parent db8445abde
commit 79eb5efffa
3 changed files with 36 additions and 20 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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<<n);
BX_CPU_THIS_PTR async_event = 1;
}
}
}
}
#endif