diff options
-rw-r--r-- | target-i386/cpu.h | 15 | ||||
-rw-r--r-- | target-i386/helper.c | 9 | ||||
-rw-r--r-- | target-i386/seg_helper.c | 3 |
3 files changed, 21 insertions, 6 deletions
diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 6682022d81..1e850a7538 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -1014,9 +1014,20 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, #define cpu_handle_mmu_fault cpu_x86_handle_mmu_fault void cpu_x86_set_a20(CPUX86State *env, int a20_state); -static inline int hw_breakpoint_enabled(unsigned long dr7, int index) +static inline bool hw_local_breakpoint_enabled(unsigned long dr7, int index) { - return (dr7 >> (index * 2)) & 3; + return (dr7 >> (index * 2)) & 1; +} + +static inline bool hw_global_breakpoint_enabled(unsigned long dr7, int index) +{ + return (dr7 >> (index * 2)) & 2; + +} +static inline bool hw_breakpoint_enabled(unsigned long dr7, int index) +{ + return hw_global_breakpoint_enabled(dr7, index) || + hw_local_breakpoint_enabled(dr7, index); } static inline int hw_breakpoint_type(unsigned long dr7, int index) diff --git a/target-i386/helper.c b/target-i386/helper.c index 1fceb91d34..ebdd6a563a 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -970,9 +970,10 @@ void hw_breakpoint_insert(CPUX86State *env, int index) switch (hw_breakpoint_type(env->dr[7], index)) { case DR7_TYPE_BP_INST: - if (hw_breakpoint_enabled(env->dr[7], index)) + if (hw_breakpoint_enabled(env->dr[7], index)) { err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU, &env->cpu_breakpoint[index]); + } break; case DR7_TYPE_DATA_WR: type = BP_CPU | BP_MEM_WRITE; @@ -998,8 +999,9 @@ void hw_breakpoint_remove(CPUX86State *env, int index) return; switch (hw_breakpoint_type(env->dr[7], index)) { case DR7_TYPE_BP_INST: - if (hw_breakpoint_enabled(env->dr[7], index)) + if (hw_breakpoint_enabled(env->dr[7], index)) { cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]); + } break; case DR7_TYPE_DATA_WR: case DR7_TYPE_DATA_RW: @@ -1024,8 +1026,9 @@ int check_hw_breakpoints(CPUX86State *env, int force_dr6_update) ((type & 1) && env->cpu_watchpoint[reg] && (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) { dr6 |= 1 << reg; - if (hw_breakpoint_enabled(env->dr[7], reg)) + if (hw_breakpoint_enabled(env->dr[7], reg)) { hit_enabled = 1; + } } } if (hit_enabled || force_dr6_update) diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c index c40bd964c0..3247deeb60 100644 --- a/target-i386/seg_helper.c +++ b/target-i386/seg_helper.c @@ -467,7 +467,8 @@ static void switch_tss(CPUX86State *env, int tss_selector, /* reset local breakpoints */ if (env->dr[7] & DR7_LOCAL_BP_MASK) { for (i = 0; i < DR7_MAX_BP; i++) { - if (hw_breakpoint_enabled(env->dr[7], i) == 0x1) { + if (hw_local_breakpoint_enabled(env->dr[7], i) && + !hw_global_breakpoint_enabled(env->dr[7], i)) { hw_breakpoint_remove(env, i); } } |