- Fixed x86 data breakpoint match when breakpoint length is 8 bytes
- FIxed x86 data breakpoint in paging disabled mode
This commit is contained in:
parent
40bbae9b84
commit
b7480b3e6f
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: paging.cc,v 1.139 2008-05-30 16:58:47 sshwarts Exp $
|
||||
// $Id: paging.cc,v 1.140 2008-06-02 18:41:08 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -1278,24 +1278,31 @@ void BX_CPU_C::access_write_linear(bx_address laddr, unsigned len, unsigned curr
|
||||
curr_pl, BX_WRITE, (Bit8u*) data);
|
||||
|
||||
#if BX_SupportGuest2HostTLB
|
||||
unsigned tlbIndex = BX_TLB_INDEX_OF(laddr, 0);
|
||||
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[tlbIndex];
|
||||
bx_address lpf = LPFOf(laddr);
|
||||
// do not replace to the TLB if there is a breakpoint defined
|
||||
// in the same page
|
||||
#if BX_X86_DEBUGGER
|
||||
if (! hwbreakpoint_check(laddr))
|
||||
#endif
|
||||
{
|
||||
unsigned tlbIndex = BX_TLB_INDEX_OF(laddr, 0);
|
||||
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[tlbIndex];
|
||||
bx_address lpf = LPFOf(laddr);
|
||||
|
||||
if (tlbEntry->lpf != lpf) {
|
||||
// We haven't seen this page, or it's been bumped before.
|
||||
|
||||
if (tlbEntry->lpf != lpf) {
|
||||
// We haven't seen this page, or it's been bumped before.
|
||||
// Request a direct write pointer so we can do either R or W.
|
||||
bx_hostpageaddr_t hostPageAddr = (bx_hostpageaddr_t)
|
||||
BX_MEM(0)->getHostMemAddr(BX_CPU_THIS, A20ADDR(lpf), BX_WRITE, DATA_ACCESS);
|
||||
|
||||
// Request a direct write pointer so we can do either R or W.
|
||||
bx_hostpageaddr_t hostPageAddr = (bx_hostpageaddr_t)
|
||||
BX_MEM(0)->getHostMemAddr(BX_CPU_THIS, A20ADDR(lpf), BX_WRITE, DATA_ACCESS);
|
||||
|
||||
if (hostPageAddr) {
|
||||
tlbEntry->lpf = lpf;
|
||||
tlbEntry->ppf = (bx_phy_address) lpf;
|
||||
tlbEntry->hostPageAddr = hostPageAddr;
|
||||
// Got direct write pointer OK. Mark for any operation to succeed.
|
||||
tlbEntry->accessBits = (TLB_ReadSysOK | TLB_ReadUserOK | TLB_WriteSysOK | TLB_WriteUserOK |
|
||||
if (hostPageAddr) {
|
||||
tlbEntry->lpf = lpf;
|
||||
tlbEntry->ppf = (bx_phy_address) lpf;
|
||||
tlbEntry->hostPageAddr = hostPageAddr;
|
||||
// Got direct write pointer OK. Mark for any operation to succeed.
|
||||
tlbEntry->accessBits = (TLB_ReadSysOK | TLB_ReadUserOK | TLB_WriteSysOK | TLB_WriteUserOK |
|
||||
TLB_ReadSysPtrOK | TLB_ReadUserPtrOK | TLB_WriteSysPtrOK | TLB_WriteUserPtrOK);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1442,36 +1449,43 @@ void BX_CPU_C::access_read_linear(bx_address laddr, unsigned len, unsigned curr_
|
||||
BX_INSTR_LIN_ACCESS(BX_CPU_ID, laddr, (bx_phy_address) laddr, len, xlate_rw);
|
||||
|
||||
#if BX_SupportGuest2HostTLB
|
||||
unsigned tlbIndex = BX_TLB_INDEX_OF(laddr, 0);
|
||||
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[tlbIndex];
|
||||
bx_address lpf = LPFOf(laddr);
|
||||
// do not replace to the TLB if there is a breakpoint defined
|
||||
// in the same page
|
||||
#if BX_X86_DEBUGGER
|
||||
if (! hwbreakpoint_check(laddr))
|
||||
#endif
|
||||
{
|
||||
unsigned tlbIndex = BX_TLB_INDEX_OF(laddr, 0);
|
||||
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[tlbIndex];
|
||||
bx_address lpf = LPFOf(laddr);
|
||||
|
||||
if (tlbEntry->lpf != lpf) {
|
||||
// We haven't seen this page, or it's been bumped before.
|
||||
if (tlbEntry->lpf != lpf) {
|
||||
// We haven't seen this page, or it's been bumped before.
|
||||
|
||||
// Request a direct write pointer so we can do either R or W.
|
||||
bx_hostpageaddr_t hostPageAddr = (bx_hostpageaddr_t)
|
||||
BX_MEM(0)->getHostMemAddr(BX_CPU_THIS, A20ADDR(lpf), BX_WRITE, DATA_ACCESS);
|
||||
|
||||
if (hostPageAddr) {
|
||||
tlbEntry->lpf = lpf;
|
||||
tlbEntry->ppf = (bx_phy_address) lpf;
|
||||
tlbEntry->hostPageAddr = hostPageAddr;
|
||||
// Got direct write pointer OK. Mark for any operation to succeed.
|
||||
tlbEntry->accessBits = (TLB_ReadSysOK | TLB_ReadUserOK | TLB_WriteSysOK | TLB_WriteUserOK |
|
||||
TLB_ReadSysPtrOK | TLB_ReadUserPtrOK | TLB_WriteSysPtrOK | TLB_WriteUserPtrOK);
|
||||
}
|
||||
else {
|
||||
// Direct write vetoed. Try requesting only direct reads.
|
||||
hostPageAddr = (bx_hostpageaddr_t) BX_MEM(0)->getHostMemAddr(BX_CPU_THIS,
|
||||
A20ADDR(lpf), BX_READ, DATA_ACCESS);
|
||||
// Request a direct write pointer so we can do either R or W.
|
||||
bx_hostpageaddr_t hostPageAddr = (bx_hostpageaddr_t)
|
||||
BX_MEM(0)->getHostMemAddr(BX_CPU_THIS, A20ADDR(lpf), BX_WRITE, DATA_ACCESS);
|
||||
|
||||
if (hostPageAddr) {
|
||||
tlbEntry->lpf = lpf;
|
||||
tlbEntry->ppf = (bx_phy_address) lpf;
|
||||
tlbEntry->hostPageAddr = hostPageAddr;
|
||||
// Got direct write pointer OK. Mark for any operation to succeed.
|
||||
tlbEntry->accessBits = (TLB_ReadSysOK | TLB_ReadUserOK | TLB_ReadSysPtrOK | TLB_ReadUserPtrOK);
|
||||
tlbEntry->accessBits = (TLB_ReadSysOK | TLB_ReadUserOK | TLB_WriteSysOK | TLB_WriteUserOK |
|
||||
TLB_ReadSysPtrOK | TLB_ReadUserPtrOK | TLB_WriteSysPtrOK | TLB_WriteUserPtrOK);
|
||||
}
|
||||
else {
|
||||
// Direct write vetoed. Try requesting only direct reads.
|
||||
hostPageAddr = (bx_hostpageaddr_t) BX_MEM(0)->getHostMemAddr(BX_CPU_THIS,
|
||||
A20ADDR(lpf), BX_READ, DATA_ACCESS);
|
||||
|
||||
if (hostPageAddr) {
|
||||
tlbEntry->lpf = lpf;
|
||||
tlbEntry->ppf = (bx_phy_address) lpf;
|
||||
tlbEntry->hostPageAddr = hostPageAddr;
|
||||
// Got direct write pointer OK. Mark for any operation to succeed.
|
||||
tlbEntry->accessBits = (TLB_ReadSysOK | TLB_ReadUserOK | TLB_ReadSysPtrOK | TLB_ReadUserPtrOK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: proc_ctrl.cc,v 1.236 2008-05-31 21:17:02 sshwarts Exp $
|
||||
// $Id: proc_ctrl.cc,v 1.237 2008-06-02 18:41:08 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -2524,88 +2524,56 @@ Bit32u BX_CPU_C::hwdebug_compare(bx_address laddr_0, unsigned size,
|
||||
// Support x86 hardware debug facilities (DR0..DR7)
|
||||
Bit32u dr7 = BX_CPU_THIS_PTR dr7;
|
||||
|
||||
bx_bool ibpoint_found = 0;
|
||||
bx_address laddr_n = laddr_0 + (size - 1);
|
||||
static bx_address alignment_mask[4] =
|
||||
// 00b=1 01b=2 10b=undef(8) 11b=4
|
||||
{ 0x0, 0x1, 0x7, 0x3 };
|
||||
|
||||
Bit32u len0 = (dr7>>18) & 3;
|
||||
Bit32u len1 = (dr7>>22) & 3;
|
||||
Bit32u len2 = (dr7>>26) & 3;
|
||||
Bit32u len3 = (dr7>>30) & 3;
|
||||
bx_address laddr_n = laddr_0 + (size - 1);
|
||||
bx_address dr[4], dr_n[4];
|
||||
Bit32u dr_op[4], len[4];
|
||||
bx_bool ibpoint_found_n[4], ibpoint_found = 0;
|
||||
|
||||
bx_address dr0 = (BX_CPU_THIS_PTR dr[0]) & ~(alignment_mask[len0]);
|
||||
bx_address dr1 = (BX_CPU_THIS_PTR dr[1]) & ~(alignment_mask[len1]);
|
||||
bx_address dr2 = (BX_CPU_THIS_PTR dr[2]) & ~(alignment_mask[len2]);
|
||||
bx_address dr3 = (BX_CPU_THIS_PTR dr[3]) & ~(alignment_mask[len3]);
|
||||
len[0] = (dr7>>18) & 3;
|
||||
len[1] = (dr7>>22) & 3;
|
||||
len[2] = (dr7>>26) & 3;
|
||||
len[3] = (dr7>>30) & 3;
|
||||
|
||||
bx_address dr0_n = dr0 + len0;
|
||||
bx_address dr1_n = dr1 + len1;
|
||||
bx_address dr2_n = dr2 + len2;
|
||||
bx_address dr3_n = dr3 + len3;
|
||||
dr_op[0] = (dr7>>16) & 3;
|
||||
dr_op[1] = (dr7>>20) & 3;
|
||||
dr_op[2] = (dr7>>24) & 3;
|
||||
dr_op[3] = (dr7>>28) & 3;
|
||||
|
||||
Bit32u dr0_op = (dr7>>16) & 3;
|
||||
Bit32u dr1_op = (dr7>>20) & 3;
|
||||
Bit32u dr2_op = (dr7>>24) & 3;
|
||||
Bit32u dr3_op = (dr7>>28) & 3;
|
||||
for (unsigned i=0;i<4;i++) {
|
||||
dr[i] = BX_CPU_THIS_PTR dr[i] & ~alignment_mask[len[i]];
|
||||
dr_n[i] = dr[i] + alignment_mask[len[i]];
|
||||
ibpoint_found_n[i] = 0;
|
||||
|
||||
// See if this instruction address matches any breakpoints
|
||||
if ((dr7 & 0x00000003)) {
|
||||
if ((dr0_op==opa || dr0_op==opb) &&
|
||||
(laddr_0 <= dr0_n) &&
|
||||
(laddr_n >= dr0))
|
||||
ibpoint_found = 1;
|
||||
}
|
||||
if ((dr7 & 0x0000000c)) {
|
||||
if ((dr1_op==opa || dr1_op==opb) &&
|
||||
(laddr_0 <= dr1_n) &&
|
||||
(laddr_n >= dr1))
|
||||
ibpoint_found = 1;
|
||||
}
|
||||
if ((dr7 & 0x00000030)) {
|
||||
if ((dr2_op==opa || dr2_op==opb) &&
|
||||
(laddr_0 <= dr2_n) &&
|
||||
(laddr_n >= dr2))
|
||||
ibpoint_found = 1;
|
||||
}
|
||||
if ((dr7 & 0x000000c0)) {
|
||||
if ((dr3_op==opa || dr3_op==opb) &&
|
||||
(laddr_0 <= dr3_n) &&
|
||||
(laddr_n >= dr3))
|
||||
ibpoint_found = 1;
|
||||
// See if this instruction address matches any breakpoints
|
||||
if (dr7 & (3 << i*2)) {
|
||||
if ((dr_op[i]==opa || dr_op[i]==opb) &&
|
||||
(laddr_0 <= dr_n[i]) &&
|
||||
(laddr_n >= dr[i])) {
|
||||
ibpoint_found_n[i] = 1;
|
||||
ibpoint_found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If *any* enabled breakpoints matched, then we need to
|
||||
// set status bits for *all* breakpoints, even disabled ones,
|
||||
// as long as they meet the other breakpoint criteria.
|
||||
// This code is similar to that above, only without the
|
||||
// breakpoint enabled check. Seems weird to duplicate effort,
|
||||
// but its more efficient to do it this way.
|
||||
// dr6_mask is the return value. These bits represent the bits
|
||||
// to be OR'd into DR6 as a result of the debug event.
|
||||
Bit32u dr6_mask = 0;
|
||||
|
||||
if (ibpoint_found) {
|
||||
// dr6_mask is the return value. These bits represent the bits to
|
||||
// be OR'd into DR6 as a result of the debug event.
|
||||
Bit32u dr6_mask=0;
|
||||
if ((dr0_op==opa || dr0_op==opb) &&
|
||||
(laddr_0 <= dr0_n) &&
|
||||
(laddr_n >= dr0))
|
||||
dr6_mask |= 0x01;
|
||||
if ((dr1_op==opa || dr1_op==opb) &&
|
||||
(laddr_0 <= dr1_n) &&
|
||||
(laddr_n >= dr1))
|
||||
dr6_mask |= 0x02;
|
||||
if ((dr2_op==opa || dr2_op==opb) &&
|
||||
(laddr_0 <= dr2_n) &&
|
||||
(laddr_n >= dr2))
|
||||
dr6_mask |= 0x04;
|
||||
if ((dr3_op==opa || dr3_op==opb) &&
|
||||
(laddr_0 <= dr3_n) &&
|
||||
(laddr_n >= dr3))
|
||||
dr6_mask |= 0x08;
|
||||
return(dr6_mask);
|
||||
if (ibpoint_found_n[0]) dr6_mask |= 0x1;
|
||||
if (ibpoint_found_n[1]) dr6_mask |= 0x2;
|
||||
if (ibpoint_found_n[2]) dr6_mask |= 0x4;
|
||||
if (ibpoint_found_n[3]) dr6_mask |= 0x8;
|
||||
}
|
||||
|
||||
return(0);
|
||||
return dr6_mask;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user