physmem: make watchpoint checking code TCG-only
cpu_check_watchpoint, watchpoint_address_matches are TCG-only. Signed-off-by: Claudio Fontana <cfontana@suse.de> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20210204163931.7358-13-cfontana@suse.de> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
8535dd702d
commit
79fc8d4511
@ -840,6 +840,7 @@ void cpu_watchpoint_remove_all(CPUState *cpu, int mask)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TCG
|
||||
/* Return true if this watchpoint address matches the specified
|
||||
* access (ie the address range covered by the watchpoint overlaps
|
||||
* partially or completely with the address range covered by the
|
||||
@ -873,6 +874,77 @@ int cpu_watchpoint_address_matches(CPUState *cpu, vaddr addr, vaddr len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Generate a debug exception if a watchpoint has been hit. */
|
||||
void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
|
||||
MemTxAttrs attrs, int flags, uintptr_t ra)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
CPUWatchpoint *wp;
|
||||
|
||||
assert(tcg_enabled());
|
||||
if (cpu->watchpoint_hit) {
|
||||
/*
|
||||
* We re-entered the check after replacing the TB.
|
||||
* Now raise the debug interrupt so that it will
|
||||
* trigger after the current instruction.
|
||||
*/
|
||||
qemu_mutex_lock_iothread();
|
||||
cpu_interrupt(cpu, CPU_INTERRUPT_DEBUG);
|
||||
qemu_mutex_unlock_iothread();
|
||||
return;
|
||||
}
|
||||
|
||||
addr = cc->adjust_watchpoint_address(cpu, addr, len);
|
||||
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
|
||||
if (watchpoint_address_matches(wp, addr, len)
|
||||
&& (wp->flags & flags)) {
|
||||
if (replay_running_debug()) {
|
||||
/*
|
||||
* Don't process the watchpoints when we are
|
||||
* in a reverse debugging operation.
|
||||
*/
|
||||
replay_breakpoint();
|
||||
return;
|
||||
}
|
||||
if (flags == BP_MEM_READ) {
|
||||
wp->flags |= BP_WATCHPOINT_HIT_READ;
|
||||
} else {
|
||||
wp->flags |= BP_WATCHPOINT_HIT_WRITE;
|
||||
}
|
||||
wp->hitaddr = MAX(addr, wp->vaddr);
|
||||
wp->hitattrs = attrs;
|
||||
if (!cpu->watchpoint_hit) {
|
||||
if (wp->flags & BP_CPU &&
|
||||
!cc->debug_check_watchpoint(cpu, wp)) {
|
||||
wp->flags &= ~BP_WATCHPOINT_HIT;
|
||||
continue;
|
||||
}
|
||||
cpu->watchpoint_hit = wp;
|
||||
|
||||
mmap_lock();
|
||||
tb_check_watchpoint(cpu, ra);
|
||||
if (wp->flags & BP_STOP_BEFORE_ACCESS) {
|
||||
cpu->exception_index = EXCP_DEBUG;
|
||||
mmap_unlock();
|
||||
cpu_loop_exit_restore(cpu, ra);
|
||||
} else {
|
||||
/* Force execution of one insn next time. */
|
||||
cpu->cflags_next_tb = 1 | curr_cflags();
|
||||
mmap_unlock();
|
||||
if (ra) {
|
||||
cpu_restore_state(cpu, ra, true);
|
||||
}
|
||||
cpu_loop_exit_noexc(cpu);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wp->flags &= ~BP_WATCHPOINT_HIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TCG */
|
||||
|
||||
/* Called from RCU critical section */
|
||||
static RAMBlock *qemu_get_ram_block(ram_addr_t addr)
|
||||
{
|
||||
@ -2359,75 +2431,6 @@ ram_addr_t qemu_ram_addr_from_host(void *ptr)
|
||||
return block->offset + offset;
|
||||
}
|
||||
|
||||
/* Generate a debug exception if a watchpoint has been hit. */
|
||||
void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
|
||||
MemTxAttrs attrs, int flags, uintptr_t ra)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
CPUWatchpoint *wp;
|
||||
|
||||
assert(tcg_enabled());
|
||||
if (cpu->watchpoint_hit) {
|
||||
/*
|
||||
* We re-entered the check after replacing the TB.
|
||||
* Now raise the debug interrupt so that it will
|
||||
* trigger after the current instruction.
|
||||
*/
|
||||
qemu_mutex_lock_iothread();
|
||||
cpu_interrupt(cpu, CPU_INTERRUPT_DEBUG);
|
||||
qemu_mutex_unlock_iothread();
|
||||
return;
|
||||
}
|
||||
|
||||
addr = cc->adjust_watchpoint_address(cpu, addr, len);
|
||||
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
|
||||
if (watchpoint_address_matches(wp, addr, len)
|
||||
&& (wp->flags & flags)) {
|
||||
if (replay_running_debug()) {
|
||||
/*
|
||||
* Don't process the watchpoints when we are
|
||||
* in a reverse debugging operation.
|
||||
*/
|
||||
replay_breakpoint();
|
||||
return;
|
||||
}
|
||||
if (flags == BP_MEM_READ) {
|
||||
wp->flags |= BP_WATCHPOINT_HIT_READ;
|
||||
} else {
|
||||
wp->flags |= BP_WATCHPOINT_HIT_WRITE;
|
||||
}
|
||||
wp->hitaddr = MAX(addr, wp->vaddr);
|
||||
wp->hitattrs = attrs;
|
||||
if (!cpu->watchpoint_hit) {
|
||||
if (wp->flags & BP_CPU &&
|
||||
!cc->debug_check_watchpoint(cpu, wp)) {
|
||||
wp->flags &= ~BP_WATCHPOINT_HIT;
|
||||
continue;
|
||||
}
|
||||
cpu->watchpoint_hit = wp;
|
||||
|
||||
mmap_lock();
|
||||
tb_check_watchpoint(cpu, ra);
|
||||
if (wp->flags & BP_STOP_BEFORE_ACCESS) {
|
||||
cpu->exception_index = EXCP_DEBUG;
|
||||
mmap_unlock();
|
||||
cpu_loop_exit_restore(cpu, ra);
|
||||
} else {
|
||||
/* Force execution of one insn next time. */
|
||||
cpu->cflags_next_tb = 1 | curr_cflags();
|
||||
mmap_unlock();
|
||||
if (ra) {
|
||||
cpu_restore_state(cpu, ra, true);
|
||||
}
|
||||
cpu_loop_exit_noexc(cpu);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wp->flags &= ~BP_WATCHPOINT_HIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
|
||||
MemTxAttrs attrs, void *buf, hwaddr len);
|
||||
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
|
||||
|
Loading…
Reference in New Issue
Block a user