mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 10:13:56 -06:00
hvf: add breakpoint handlers
Required for guest debugging. The code has been structured like the KVM counterpart. Signed-off-by: Francesco Cagnin <fcagnin@quarkslab.com> Message-id: 20230601153107.81955-4-fcagnin@quarkslab.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
ce799a04b2
commit
f41520402c
6 changed files with 236 additions and 0 deletions
|
@ -31,6 +31,8 @@
|
|||
#include "trace/trace-target_arm_hvf.h"
|
||||
#include "migration/vmstate.h"
|
||||
|
||||
#include "exec/gdbstub.h"
|
||||
|
||||
#define HVF_SYSREG(crn, crm, op0, op1, op2) \
|
||||
ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP, crn, crm, op0, op1, op2)
|
||||
#define PL1_WRITE_MASK 0x4
|
||||
|
@ -1711,3 +1713,64 @@ int hvf_arch_init(void)
|
|||
qemu_add_vm_change_state_handler(hvf_vm_state_change, &vtimer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const uint32_t brk_insn = 0xd4200000;
|
||||
|
||||
int hvf_arch_insert_sw_breakpoint(CPUState *cpu, struct hvf_sw_breakpoint *bp)
|
||||
{
|
||||
if (cpu_memory_rw_debug(cpu, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
|
||||
cpu_memory_rw_debug(cpu, bp->pc, (uint8_t *)&brk_insn, 4, 1)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hvf_arch_remove_sw_breakpoint(CPUState *cpu, struct hvf_sw_breakpoint *bp)
|
||||
{
|
||||
static uint32_t brk;
|
||||
|
||||
if (cpu_memory_rw_debug(cpu, bp->pc, (uint8_t *)&brk, 4, 0) ||
|
||||
brk != brk_insn ||
|
||||
cpu_memory_rw_debug(cpu, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hvf_arch_insert_hw_breakpoint(target_ulong addr, target_ulong len, int type)
|
||||
{
|
||||
switch (type) {
|
||||
case GDB_BREAKPOINT_HW:
|
||||
return insert_hw_breakpoint(addr);
|
||||
case GDB_WATCHPOINT_READ:
|
||||
case GDB_WATCHPOINT_WRITE:
|
||||
case GDB_WATCHPOINT_ACCESS:
|
||||
return insert_hw_watchpoint(addr, len, type);
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
}
|
||||
|
||||
int hvf_arch_remove_hw_breakpoint(target_ulong addr, target_ulong len, int type)
|
||||
{
|
||||
switch (type) {
|
||||
case GDB_BREAKPOINT_HW:
|
||||
return delete_hw_breakpoint(addr);
|
||||
case GDB_WATCHPOINT_READ:
|
||||
case GDB_WATCHPOINT_WRITE:
|
||||
case GDB_WATCHPOINT_ACCESS:
|
||||
return delete_hw_watchpoint(addr, len, type);
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
}
|
||||
|
||||
void hvf_arch_remove_all_hw_breakpoints(void)
|
||||
{
|
||||
if (cur_hw_wps > 0) {
|
||||
g_array_remove_range(hw_watchpoints, 0, cur_hw_wps);
|
||||
}
|
||||
if (cur_hw_bps > 0) {
|
||||
g_array_remove_range(hw_breakpoints, 0, cur_hw_bps);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue