improved x86 hw code bp handling
This commit is contained in:
parent
7e57d95364
commit
beafa7c88b
@ -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];
|
||||
|
@ -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
|
||||
|
@ -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 },
|
||||
|
@ -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 },
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user