target/cortex_m: allow setting the type of a breakpoint

Cortex-M target used 'auto_bp_type' mode. The requested type
of breakpoint was ignored and hard (FPB) breakpoints were set in
'code memory area' 0x00000000-0x1fffffff, soft breakpoints were set above
0x20000000.

The code memory area of Cortex-M does not mean the memory is flash and
vice versa. External flash (parallel or QSPI) is usually mapped above
code memory area. Cortex-M7 ITCM RAM is mapped at 0. Kinetis
has a RAM block under 0x20000000 boundary.

Remove 'auto_bp_type' mode, set breakpoints to requested type.

Change 'cortex_m maskisr auto' handling to use a hard temporary
breakpoint everywhere: it can also workaround not working soft breakpoints
on Cortex-M7 with ICache enabled.

Change-Id: I7a9f9464c5e10bfd7f17cba1037ed07a064fa2e8
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: http://openocd.zylin.com/4429
Tested-by: jenkins
Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
This commit is contained in:
Tomas Vanek
2018-02-23 00:12:50 +01:00
committed by Matthias Welwarsky
parent 09076d10dd
commit 81d0b769a6
3 changed files with 5 additions and 32 deletions

View File

@@ -51,11 +51,6 @@
* any longer.
*/
/**
* Returns the type of a break point required by address location
*/
#define BKPT_TYPE_BY_ADDR(addr) ((addr) < 0x20000000 ? BKPT_HARD : BKPT_SOFT)
/* forward declarations */
static int cortex_m_store_core_reg_u32(struct target *target,
uint32_t num, uint32_t value);
@@ -868,7 +863,7 @@ static int cortex_m_step(struct target *target, int current,
if (breakpoint)
retval = cortex_m_set_breakpoint(target, breakpoint);
else
retval = breakpoint_add(target, pc_value, 2, BKPT_TYPE_BY_ADDR(pc_value));
retval = breakpoint_add(target, pc_value, 2, BKPT_HARD);
bool tmp_bp_set = (retval == ERROR_OK);
/* No more breakpoints left, just do a step */
@@ -1131,9 +1126,6 @@ int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint
return ERROR_OK;
}
if (cortex_m->auto_bp_type)
breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address);
if (breakpoint->type == BKPT_HARD) {
uint32_t fpcr_value;
while (comparator_list[fp_num].used && (fp_num < cortex_m->fp_num_code))
@@ -1253,21 +1245,6 @@ int cortex_m_add_breakpoint(struct target *target, struct breakpoint *breakpoint
{
struct cortex_m_common *cortex_m = target_to_cm(target);
if (cortex_m->auto_bp_type)
breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address);
if (breakpoint->type != BKPT_TYPE_BY_ADDR(breakpoint->address)) {
if (breakpoint->type == BKPT_HARD) {
LOG_INFO("flash patch comparator requested outside code memory region");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
if (breakpoint->type == BKPT_SOFT) {
LOG_INFO("soft breakpoint requested in code (flash) memory region");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
}
if ((breakpoint->type == BKPT_HARD) && (cortex_m->fp_code_available < 1)) {
LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
@@ -1299,9 +1276,6 @@ int cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpo
return ERROR_TARGET_NOT_HALTED;
}
if (cortex_m->auto_bp_type)
breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address);
if (breakpoint->set)
cortex_m_unset_breakpoint(target, breakpoint);
@@ -2111,7 +2085,6 @@ int cortex_m_examine(struct target *target)
/* Setup FPB */
target_read_u32(target, FP_CTRL, &fpcr);
cortex_m->auto_bp_type = 1;
/* bits [14:12] and [7:4] */
cortex_m->fp_num_code = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xF);
cortex_m->fp_num_lit = (fpcr >> 8) & 0xF;

View File

@@ -175,7 +175,6 @@ struct cortex_m_common {
int fp_code_available;
int fp_rev;
int fpb_enabled;
int auto_bp_type;
struct cortex_m_fp_comparator *fp_comparator_list;
/* Data Watchpoint and Trace (DWT) */