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:
parent
09076d10dd
commit
81d0b769a6
|
@ -8630,9 +8630,10 @@ the next instruction where the core was halted. After the step interrupts
|
||||||
are enabled again. If the interrupt handlers don't complete within 500ms,
|
are enabled again. If the interrupt handlers don't complete within 500ms,
|
||||||
the step command leaves with the core running.
|
the step command leaves with the core running.
|
||||||
|
|
||||||
Note that a free breakpoint is required for the @option{auto} option. If no
|
Note that a free hardware (FPB) breakpoint is required for the @option{auto}
|
||||||
breakpoint is available at the time of the step, then the step is taken
|
option. If no breakpoint is available at the time of the step, then the step
|
||||||
with interrupts enabled, i.e. the same way the @option{off} option does.
|
is taken with interrupts enabled, i.e. the same way the @option{off} option
|
||||||
|
does.
|
||||||
|
|
||||||
Default is @option{auto}.
|
Default is @option{auto}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
|
@ -51,11 +51,6 @@
|
||||||
* any longer.
|
* 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 */
|
/* forward declarations */
|
||||||
static int cortex_m_store_core_reg_u32(struct target *target,
|
static int cortex_m_store_core_reg_u32(struct target *target,
|
||||||
uint32_t num, uint32_t value);
|
uint32_t num, uint32_t value);
|
||||||
|
@ -868,7 +863,7 @@ static int cortex_m_step(struct target *target, int current,
|
||||||
if (breakpoint)
|
if (breakpoint)
|
||||||
retval = cortex_m_set_breakpoint(target, breakpoint);
|
retval = cortex_m_set_breakpoint(target, breakpoint);
|
||||||
else
|
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);
|
bool tmp_bp_set = (retval == ERROR_OK);
|
||||||
|
|
||||||
/* No more breakpoints left, just do a step */
|
/* 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;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cortex_m->auto_bp_type)
|
|
||||||
breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address);
|
|
||||||
|
|
||||||
if (breakpoint->type == BKPT_HARD) {
|
if (breakpoint->type == BKPT_HARD) {
|
||||||
uint32_t fpcr_value;
|
uint32_t fpcr_value;
|
||||||
while (comparator_list[fp_num].used && (fp_num < cortex_m->fp_num_code))
|
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);
|
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)) {
|
if ((breakpoint->type == BKPT_HARD) && (cortex_m->fp_code_available < 1)) {
|
||||||
LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
|
LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
|
||||||
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
|
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;
|
return ERROR_TARGET_NOT_HALTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cortex_m->auto_bp_type)
|
|
||||||
breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address);
|
|
||||||
|
|
||||||
if (breakpoint->set)
|
if (breakpoint->set)
|
||||||
cortex_m_unset_breakpoint(target, breakpoint);
|
cortex_m_unset_breakpoint(target, breakpoint);
|
||||||
|
|
||||||
|
@ -2111,7 +2085,6 @@ int cortex_m_examine(struct target *target)
|
||||||
|
|
||||||
/* Setup FPB */
|
/* Setup FPB */
|
||||||
target_read_u32(target, FP_CTRL, &fpcr);
|
target_read_u32(target, FP_CTRL, &fpcr);
|
||||||
cortex_m->auto_bp_type = 1;
|
|
||||||
/* bits [14:12] and [7:4] */
|
/* bits [14:12] and [7:4] */
|
||||||
cortex_m->fp_num_code = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xF);
|
cortex_m->fp_num_code = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xF);
|
||||||
cortex_m->fp_num_lit = (fpcr >> 8) & 0xF;
|
cortex_m->fp_num_lit = (fpcr >> 8) & 0xF;
|
||||||
|
|
|
@ -175,7 +175,6 @@ struct cortex_m_common {
|
||||||
int fp_code_available;
|
int fp_code_available;
|
||||||
int fp_rev;
|
int fp_rev;
|
||||||
int fpb_enabled;
|
int fpb_enabled;
|
||||||
int auto_bp_type;
|
|
||||||
struct cortex_m_fp_comparator *fp_comparator_list;
|
struct cortex_m_fp_comparator *fp_comparator_list;
|
||||||
|
|
||||||
/* Data Watchpoint and Trace (DWT) */
|
/* Data Watchpoint and Trace (DWT) */
|
||||||
|
|
Loading…
Reference in New Issue