aarch64: Add hardware breakpoint support
Enable the use of hardware breakpoint on AARCH64. Change-Id: I59caaa6d92ac60278af8938625b1790a1787372f Signed-off-by: pierre Kuo <vichy.kuo@gmail.com> Signed-off-by: David Ung <david.ung.42@gmail.com> Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com>gitignore-build
parent
d376f7f518
commit
236c9966dd
|
@ -1254,6 +1254,7 @@ static int aarch64_set_breakpoint(struct target *target,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (breakpoint->type == BKPT_HARD) {
|
if (breakpoint->type == BKPT_HARD) {
|
||||||
|
int64_t bpt_value;
|
||||||
while (brp_list[brp_i].used && (brp_i < aarch64->brp_num))
|
while (brp_list[brp_i].used && (brp_i < aarch64->brp_num))
|
||||||
brp_i++;
|
brp_i++;
|
||||||
if (brp_i >= aarch64->brp_num) {
|
if (brp_i >= aarch64->brp_num) {
|
||||||
|
@ -1264,38 +1265,46 @@ static int aarch64_set_breakpoint(struct target *target,
|
||||||
if (breakpoint->length == 2)
|
if (breakpoint->length == 2)
|
||||||
byte_addr_select = (3 << (breakpoint->address & 0x02));
|
byte_addr_select = (3 << (breakpoint->address & 0x02));
|
||||||
control = ((matchmode & 0x7) << 20)
|
control = ((matchmode & 0x7) << 20)
|
||||||
|
| (1 << 13)
|
||||||
| (byte_addr_select << 5)
|
| (byte_addr_select << 5)
|
||||||
| (3 << 1) | 1;
|
| (3 << 1) | 1;
|
||||||
brp_list[brp_i].used = 1;
|
brp_list[brp_i].used = 1;
|
||||||
brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC);
|
brp_list[brp_i].value = breakpoint->address & 0xFFFFFFFFFFFFFFFC;
|
||||||
brp_list[brp_i].control = control;
|
brp_list[brp_i].control = control;
|
||||||
|
bpt_value = brp_list[brp_i].value;
|
||||||
|
|
||||||
retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
|
retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
|
||||||
+ CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
|
+ CPUDBG_BVR_BASE + 16 * brp_list[brp_i].BRPn,
|
||||||
brp_list[brp_i].value);
|
(uint32_t)(bpt_value & 0xFFFFFFFF));
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
|
retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
|
||||||
+ CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
|
+ CPUDBG_BVR_BASE + 4 + 16 * brp_list[brp_i].BRPn,
|
||||||
|
(uint32_t)(bpt_value >> 32));
|
||||||
|
if (retval != ERROR_OK)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
|
||||||
|
+ CPUDBG_BCR_BASE + 16 * brp_list[brp_i].BRPn,
|
||||||
brp_list[brp_i].control);
|
brp_list[brp_i].control);
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%" TARGET_PRIxADDR, brp_i,
|
LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%" TARGET_PRIxADDR, brp_i,
|
||||||
brp_list[brp_i].control,
|
brp_list[brp_i].control,
|
||||||
brp_list[brp_i].value);
|
brp_list[brp_i].value);
|
||||||
|
|
||||||
} else if (breakpoint->type == BKPT_SOFT) {
|
} else if (breakpoint->type == BKPT_SOFT) {
|
||||||
uint8_t code[4];
|
uint8_t code[4];
|
||||||
if (breakpoint->length == 2)
|
buf_set_u32(code, 0, 32, 0xD4400000);
|
||||||
buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
|
|
||||||
else
|
|
||||||
buf_set_u32(code, 0, 32, ARMV5_BKPT(0x11));
|
|
||||||
retval = target_read_memory(target,
|
retval = target_read_memory(target,
|
||||||
breakpoint->address & 0xFFFFFFFE,
|
breakpoint->address & 0xFFFFFFFFFFFFFFFE,
|
||||||
breakpoint->length, 1,
|
breakpoint->length, 1,
|
||||||
breakpoint->orig_instr);
|
breakpoint->orig_instr);
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
retval = target_write_memory(target,
|
retval = target_write_memory(target,
|
||||||
breakpoint->address & 0xFFFFFFFE,
|
breakpoint->address & 0xFFFFFFFFFFFFFFFE,
|
||||||
breakpoint->length, 1, code);
|
breakpoint->length, 1, code);
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -1465,11 +1474,6 @@ static int aarch64_unset_breakpoint(struct target *target, struct breakpoint *br
|
||||||
brp_list[brp_i].control);
|
brp_list[brp_i].control);
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
|
|
||||||
+ CPUDBG_BVR_BASE + 16 * brp_list[brp_i].BRPn,
|
|
||||||
brp_list[brp_i].value);
|
|
||||||
if (retval != ERROR_OK)
|
|
||||||
return retval;
|
|
||||||
if ((brp_j < 0) || (brp_j >= aarch64->brp_num)) {
|
if ((brp_j < 0) || (brp_j >= aarch64->brp_num)) {
|
||||||
LOG_DEBUG("Invalid BRP number in breakpoint");
|
LOG_DEBUG("Invalid BRP number in breakpoint");
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
|
@ -1484,11 +1488,6 @@ static int aarch64_unset_breakpoint(struct target *target, struct breakpoint *br
|
||||||
brp_list[brp_j].control);
|
brp_list[brp_j].control);
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
|
|
||||||
+ CPUDBG_BVR_BASE + 16 * brp_list[brp_j].BRPn,
|
|
||||||
brp_list[brp_j].value);
|
|
||||||
if (retval != ERROR_OK)
|
|
||||||
return retval;
|
|
||||||
breakpoint->linked_BRP = 0;
|
breakpoint->linked_BRP = 0;
|
||||||
breakpoint->set = 0;
|
breakpoint->set = 0;
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
|
|
Loading…
Reference in New Issue