improved x86 hw code bp handling

This commit is contained in:
Stanislav Shwartsman 2011-06-24 13:38:34 +00:00
parent 7e57d95364
commit beafa7c88b
7 changed files with 67 additions and 29 deletions

View File

@ -598,8 +598,6 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
DEV_dma_raise_hlda();
}
BX_CPU_THIS_PTR clear_RF();
if (BX_CPU_THIS_PTR get_TF())
{
// TF is set before execution of next instruction. Schedule
@ -640,12 +638,8 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
|| BX_CPU_THIS_PTR vmx_interrupt_window || BX_CPU_THIS_PTR inhibit_mask
#endif
#if BX_X86_DEBUGGER
// any debug code breakpoint is set
|| (BX_CPU_THIS_PTR dr7.get_bp_enabled() &&
(BX_CPU_THIS_PTR dr7.get_R_W0() == 0 ||
BX_CPU_THIS_PTR dr7.get_R_W1() == 0 ||
BX_CPU_THIS_PTR dr7.get_R_W2() == 0 ||
BX_CPU_THIS_PTR dr7.get_R_W3() == 0))
// a debug code breakpoint is set in current page
|| BX_CPU_THIS_PTR codebp
#endif
))
BX_CPU_THIS_PTR async_event = 0;
@ -704,6 +698,24 @@ void BX_CPU_C::prefetch(void)
}
}
#if BX_X86_DEBUGGER
if (hwbreakpoint_check(laddr, BX_HWDebugInstruction, BX_HWDebugInstruction)) {
BX_CPU_THIS_PTR async_event = 1;
BX_CPU_THIS_PTR codebp = 1;
if (! (BX_CPU_THIS_PTR inhibit_mask & BX_INHIBIT_DEBUG_SHADOW)) {
// The next instruction could already hit a code breakpoint but
// async_event won't take effect immediatelly.
// Check if the next executing instruction hits code breakpoint
if (code_breakpoint_match(laddr)) exception(BX_DB_EXCEPTION, 0);
}
}
else {
BX_CPU_THIS_PTR codebp = 0;
}
#endif
BX_CPU_THIS_PTR clear_RF();
bx_address lpf = LPFOf(laddr);
unsigned TLB_index = BX_TLB_INDEX_OF(lpf, 0);
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[TLB_index];

View File

@ -500,8 +500,8 @@ BOCHSAPI extern BX_CPU_C bx_cpu;
} \
}
// assert async_event when RF, IF or TF is set
#define IMPLEMENT_EFLAG_SET_ACCESSOR_IF_RF_TF(name,bitnum) \
// assert async_event when IF or TF is set
#define IMPLEMENT_EFLAG_SET_ACCESSOR_IF_TF(name,bitnum) \
BX_CPP_INLINE void BX_CPU_C::assert_##name() { \
BX_CPU_THIS_PTR async_event = 1; \
BX_CPU_THIS_PTR eflags |= (1<<bitnum); \
@ -515,6 +515,21 @@ BOCHSAPI extern BX_CPU_C bx_cpu;
(BX_CPU_THIS_PTR eflags&~(1<<bitnum))|((val)<<bitnum); \
}
// invalidate prefetch queue and call prefetch() when RF is set
#define IMPLEMENT_EFLAG_SET_ACCESSOR_RF(name,bitnum) \
BX_CPP_INLINE void BX_CPU_C::assert_##name() { \
invalidate_prefetch_q(); \
BX_CPU_THIS_PTR eflags |= (1<<bitnum); \
} \
BX_CPP_INLINE void BX_CPU_C::clear_##name() { \
BX_CPU_THIS_PTR eflags &= ~(1<<bitnum); \
} \
BX_CPP_INLINE void BX_CPU_C::set_##name(bx_bool val) { \
if (val) invalidate_prefetch_q(); \
BX_CPU_THIS_PTR eflags = \
(BX_CPU_THIS_PTR eflags&~(1<<bitnum))|((val)<<bitnum); \
}
#define DECLARE_EFLAG_ACCESSOR_IOPL(bitnum) \
BX_SMF BX_CPP_INLINE void set_IOPL(Bit32u val); \
BX_SMF BX_CPP_INLINE Bit32u get_IOPL(void);
@ -991,6 +1006,7 @@ public: // for now...
#if BX_X86_DEBUGGER
bx_bool in_repeat;
bx_bool codebp;
#endif
bx_bool in_smm;
unsigned cpu_mode;
@ -4045,20 +4061,20 @@ IMPLEMENT_EFLAG_ACCESSOR (DF, 10)
IMPLEMENT_EFLAG_ACCESSOR (IF, 9)
IMPLEMENT_EFLAG_ACCESSOR (TF, 8)
IMPLEMENT_EFLAG_SET_ACCESSOR (ID, 21)
IMPLEMENT_EFLAG_SET_ACCESSOR (VIP, 20)
IMPLEMENT_EFLAG_SET_ACCESSOR (VIF, 19)
IMPLEMENT_EFLAG_SET_ACCESSOR (ID, 21)
IMPLEMENT_EFLAG_SET_ACCESSOR (VIP, 20)
IMPLEMENT_EFLAG_SET_ACCESSOR (VIF, 19)
#if BX_SUPPORT_ALIGNMENT_CHECK && BX_CPU_LEVEL >= 4
IMPLEMENT_EFLAG_SET_ACCESSOR_AC ( 18)
IMPLEMENT_EFLAG_SET_ACCESSOR_AC ( 18)
#else
IMPLEMENT_EFLAG_SET_ACCESSOR (AC, 18)
IMPLEMENT_EFLAG_SET_ACCESSOR (AC, 18)
#endif
IMPLEMENT_EFLAG_SET_ACCESSOR_VM ( 17)
IMPLEMENT_EFLAG_SET_ACCESSOR_IF_RF_TF(RF, 16)
IMPLEMENT_EFLAG_SET_ACCESSOR (NT, 14)
IMPLEMENT_EFLAG_SET_ACCESSOR (DF, 10)
IMPLEMENT_EFLAG_SET_ACCESSOR_IF_RF_TF(IF, 9)
IMPLEMENT_EFLAG_SET_ACCESSOR_IF_RF_TF(TF, 8)
IMPLEMENT_EFLAG_SET_ACCESSOR_VM ( 17)
IMPLEMENT_EFLAG_SET_ACCESSOR_RF (RF, 16)
IMPLEMENT_EFLAG_SET_ACCESSOR (NT, 14)
IMPLEMENT_EFLAG_SET_ACCESSOR (DF, 10)
IMPLEMENT_EFLAG_SET_ACCESSOR_IF_TF(IF, 9)
IMPLEMENT_EFLAG_SET_ACCESSOR_IF_TF(TF, 8)
#define BX_TASK_FROM_CALL 0
#define BX_TASK_FROM_IRET 1

View File

@ -320,7 +320,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo32[512*2] = {
/* 9A /w */ { BxImmediate_Iw | BxImmediate_Iw2 | BxTraceEnd, BX_IA_CALL16_Ap },
/* 9B /w */ { 0, BX_IA_FWAIT },
/* 9C /w */ { 0, BX_IA_PUSHF_Fw },
/* 9D /w */ { 0, BX_IA_POPF_Fw },
/* 9D /w */ { BxTraceEnd, BX_IA_POPF_Fw },
/* 9E /w */ { 0, BX_IA_SAHF },
/* 9F /w */ { 0, BX_IA_LAHF },
/* A0 /w */ { BxImmediate_O, BX_IA_MOV_ALOd },
@ -865,7 +865,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo32[512*2] = {
/* 9A /d */ { BxImmediate_Id | BxImmediate_Iw2 | BxTraceEnd, BX_IA_CALL32_Ap },
/* 9B /d */ { 0, BX_IA_FWAIT },
/* 9C /d */ { 0, BX_IA_PUSHF_Fd },
/* 9D /d */ { 0, BX_IA_POPF_Fd },
/* 9D /d */ { BxTraceEnd, BX_IA_POPF_Fd },
/* 9E /d */ { 0, BX_IA_SAHF },
/* 9F /d */ { 0, BX_IA_LAHF },
/* A0 /d */ { BxImmediate_O, BX_IA_MOV_ALOd },

View File

@ -296,7 +296,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
/* 9A /w */ { 0, BX_IA_ERROR },
/* 9B /w */ { 0, BX_IA_FWAIT },
/* 9C /w */ { 0, BX_IA_PUSHF_Fw },
/* 9D /w */ { 0, BX_IA_POPF_Fw },
/* 9D /w */ { BxTraceEnd, BX_IA_POPF_Fw },
/* 9E /w */ { 0, BX_IA_SAHF },
/* 9F /w */ { 0, BX_IA_LAHF },
/* A0 /w */ { BxImmediate_O, BX_IA_MOV_ALOq },
@ -811,7 +811,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
/* 9A /d */ { 0, BX_IA_ERROR },
/* 9B /d */ { 0, BX_IA_FWAIT },
/* 9C /d */ { 0, BX_IA_PUSHF_Fq },
/* 9D /d */ { 0, BX_IA_POPF_Fq },
/* 9D /d */ { BxTraceEnd, BX_IA_POPF_Fq },
/* 9E /d */ { 0, BX_IA_SAHF },
/* 9F /d */ { 0, BX_IA_LAHF },
/* A0 /d */ { BxImmediate_O, BX_IA_MOV_ALOq },
@ -1326,7 +1326,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
/* 9A /q */ { 0, BX_IA_ERROR },
/* 9B /q */ { 0, BX_IA_FWAIT },
/* 9C /q */ { 0, BX_IA_PUSHF_Fq },
/* 9D /q */ { 0, BX_IA_POPF_Fq },
/* 9D /q */ { BxTraceEnd, BX_IA_POPF_Fq },
/* 9E /q */ { 0, BX_IA_SAHF },
/* 9F /q */ { 0, BX_IA_LAHF },
/* A0 /q */ { BxImmediate_O, BX_IA_MOV_ALOq },

View File

@ -35,7 +35,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::setEFlags(Bit32u val)
}
#endif
if (val & (EFlagsTFMask|EFlagsRFMask)) {
if (val & EFlagsRFMask) invalidate_prefetch_q();
if (val & EFlagsTFMask) {
BX_CPU_THIS_PTR async_event = 1; // TF == 1 || RF == 1
}

View File

@ -565,6 +565,8 @@ void BX_CPU_C::register_state(void)
#if BX_X86_DEBUGGER
BXRS_PARAM_BOOL(cpu, in_repeat, in_repeat);
// for debug only (no need for save/restore), calculated in prefetch()
BXRS_PARAM_BOOL(cpu, codebp, codebp);
#endif
BXRS_PARAM_BOOL(cpu, in_smm, in_smm);
@ -876,6 +878,7 @@ void BX_CPU_C::reset(unsigned source)
#if BX_X86_DEBUGGER
BX_CPU_THIS_PTR in_repeat = 0;
BX_CPU_THIS_PTR codebp = 0;
#endif
BX_CPU_THIS_PTR in_smm = 0;
BX_CPU_THIS_PTR disable_SMI = 0;

View File

@ -1537,7 +1537,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
//
BX_CPU_THIS_PTR async_event = 0;
if (guest.rflags & (EFlagsTFMask|EFlagsRFMask))
if (guest.rflags & EFlagsTFMask)
BX_CPU_THIS_PTR async_event = 1;
if (vm->vmentry_ctrls & VMX_VMENTRY_CTRL1_SMM_ENTER)
@ -1566,8 +1566,13 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
if (BX_CPU_THIS_PTR inhibit_mask)
BX_CPU_THIS_PTR async_event = 1;
if (guest.interruptibility_state & BX_VMX_INTERRUPTS_BLOCKED_NMI_BLOCKED)
if (guest.interruptibility_state & BX_VMX_INTERRUPTS_BLOCKED_NMI_BLOCKED) {
BX_CPU_THIS_PTR disable_NMI = 1;
}
else {
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_NMI_WINDOW_VMEXIT)
BX_CPU_THIS_PTR async_event = 1;
}
if (vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_INTERRUPT_WINDOW_VMEXIT) {
BX_CPU_THIS_PTR async_event = 1;