diff options
author | Richard Henderson <rth@twiddle.net> | 2015-09-15 11:45:13 -0700 |
---|---|---|
committer | Eduardo Habkost <ehabkost@redhat.com> | 2015-10-23 12:59:27 -0200 |
commit | d0052339236072bbf08c1d600c0906126b1ab258 (patch) | |
tree | ca1cc289d1122c1ded250868f7e5bbda747b25c2 /target-i386/bpt_helper.c | |
parent | 5223a9423c5fb9e32b0c3eaaa2c0bf8c5cfd6866 (diff) |
target-i386: Check CR4[DE] for processing DR4/DR5
Introduce helper_get_dr so that we don't have to put CR4[DE]
into the scarce HFLAGS resource. At the same time, rename
helper_movl_drN_T0 to helper_set_dr and set the helper flags.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Diffstat (limited to 'target-i386/bpt_helper.c')
-rw-r--r-- | target-i386/bpt_helper.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/target-i386/bpt_helper.c b/target-i386/bpt_helper.c index 117cea2564..144cfd43fc 100644 --- a/target-i386/bpt_helper.c +++ b/target-i386/bpt_helper.c @@ -242,10 +242,11 @@ void helper_single_step(CPUX86State *env) raise_exception(env, EXCP01_DB); } -void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0) +void helper_set_dr(CPUX86State *env, int reg, target_ulong t0) { #ifndef CONFIG_USER_ONLY - if (reg < 4) { + switch (reg) { + case 0: case 1: case 2: case 3: if (hw_breakpoint_enabled(env->dr[7], reg) && hw_breakpoint_type(env->dr[7], reg) != DR7_TYPE_IO_RW) { hw_breakpoint_remove(env, reg); @@ -254,14 +255,49 @@ void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0) } else { env->dr[reg] = t0; } - } else if (reg == 7) { + return; + case 4: + if (env->cr[4] & CR4_DE_MASK) { + break; + } + /* fallthru */ + case 6: + env->dr[6] = t0; + return; + case 5: + if (env->cr[4] & CR4_DE_MASK) { + break; + } + /* fallthru */ + case 7: cpu_x86_update_dr7(env, t0); - } else { - env->dr[reg] = t0; + return; } + raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); #endif } +target_ulong helper_get_dr(CPUX86State *env, int reg) +{ + switch (reg) { + case 0: case 1: case 2: case 3: case 6: case 7: + return env->dr[reg]; + case 4: + if (env->cr[4] & CR4_DE_MASK) { + break; + } else { + return env->dr[6]; + } + case 5: + if (env->cr[4] & CR4_DE_MASK) { + break; + } else { + return env->dr[7]; + } + } + raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); +} + /* Check if Port I/O is trapped by a breakpoint. */ void helper_bpt_io(CPUX86State *env, uint32_t port, uint32_t size, target_ulong next_eip) |