mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
x86: Debug register emulation (Jan Kiszka)
Built on top of previously enhanced breakpoint/watchpoint support, this patch adds full debug register emulation for the x86 architecture. Many corner cases were considered, and the result was successfully tested inside a Linux guest with gdb, but I won't be surprised if one or two scenarios still behave differently in reality. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5747 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
2dc9f4117c
commit
01df040b52
5 changed files with 217 additions and 42 deletions
|
@ -496,6 +496,17 @@ static void switch_tss(int tss_selector,
|
|||
/* XXX: different exception if CALL ? */
|
||||
raise_exception_err(EXCP0D_GPF, 0);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
/* reset local breakpoints */
|
||||
if (env->dr[7] & 0x55) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (hw_breakpoint_enabled(env->dr[7], i) == 0x1)
|
||||
hw_breakpoint_remove(env, i);
|
||||
}
|
||||
env->dr[7] &= ~0x55;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* check if Port I/O is allowed in TSS */
|
||||
|
@ -1879,8 +1890,11 @@ void helper_cmpxchg16b(target_ulong a0)
|
|||
|
||||
void helper_single_step(void)
|
||||
{
|
||||
env->dr[6] |= 0x4000;
|
||||
raise_exception(EXCP01_SSTP);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
check_hw_breakpoints(env, 1);
|
||||
env->dr[6] |= DR6_BS;
|
||||
#endif
|
||||
raise_exception(EXCP01_DB);
|
||||
}
|
||||
|
||||
void helper_cpuid(void)
|
||||
|
@ -2868,6 +2882,10 @@ target_ulong helper_read_crN(int reg)
|
|||
void helper_write_crN(int reg, target_ulong t0)
|
||||
{
|
||||
}
|
||||
|
||||
void helper_movl_drN_T0(int reg, target_ulong t0)
|
||||
{
|
||||
}
|
||||
#else
|
||||
target_ulong helper_read_crN(int reg)
|
||||
{
|
||||
|
@ -2913,6 +2931,24 @@ void helper_write_crN(int reg, target_ulong t0)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void helper_movl_drN_T0(int reg, target_ulong t0)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (reg < 4) {
|
||||
hw_breakpoint_remove(env, reg);
|
||||
env->dr[reg] = t0;
|
||||
hw_breakpoint_insert(env, reg);
|
||||
} else if (reg == 7) {
|
||||
for (i = 0; i < 4; i++)
|
||||
hw_breakpoint_remove(env, i);
|
||||
env->dr[7] = t0;
|
||||
for (i = 0; i < 4; i++)
|
||||
hw_breakpoint_insert(env, i);
|
||||
} else
|
||||
env->dr[reg] = t0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void helper_lmsw(target_ulong t0)
|
||||
|
@ -2929,12 +2965,6 @@ void helper_clts(void)
|
|||
env->hflags &= ~HF_TS_MASK;
|
||||
}
|
||||
|
||||
/* XXX: do more */
|
||||
void helper_movl_drN_T0(int reg, target_ulong t0)
|
||||
{
|
||||
env->dr[reg] = t0;
|
||||
}
|
||||
|
||||
void helper_invlpg(target_ulong addr)
|
||||
{
|
||||
helper_svm_check_intercept_param(SVM_EXIT_INVLPG, 0);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue