This is an automated email from Gerrit. Tomas Vanek (van...@fbl.cz) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/4429
-- gerrit commit 12803e419ee36e341c54588cbfabdc61cdd52c09 Author: Tomas Vanek <van...@fbl.cz> Date: Fri Feb 23 00:12:50 2018 +0100 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 Kx has RAM block under 0x20000000 boundary. Remove 'auto_bp_type' mode, set breakpoints to requested type. Introduce target_addr_in_flash() test to check if address is in a flash bank. Set temporary breakpoint in 'cortex_m maskisr auto' mode of hard type if address is in flash, soft type otherwise. Introduce 'cortex_m maskisr auto_hard_bp' mode to use hard temporary breakpoint everywhere: it can workaround not working soft breakpoints on Cortex-M7 with ICache enabled. Change-Id: I7a9f9464c5e10bfd7f17cba1037ed07a064fa2e8 Signed-off-by: Tomas Vanek <van...@fbl.cz> diff --git a/src/flash/nor/core.h b/src/flash/nor/core.h index 338363e..6abd6ea 100644 --- a/src/flash/nor/core.h +++ b/src/flash/nor/core.h @@ -174,6 +174,10 @@ int default_flash_read(struct flash_bank *bank, int default_flash_blank_check(struct flash_bank *bank); /** + * @return The first bank in the global list. + */ +struct flash_bank *flash_bank_list(void); +/** * Returns the flash bank specified by @a name, which matches the * driver name and a suffix (option) specify the driver-specific * bank number. The suffix consists of the '.' and the driver-specific diff --git a/src/flash/nor/imp.h b/src/flash/nor/imp.h index 87475a3..c317387 100644 --- a/src/flash/nor/imp.h +++ b/src/flash/nor/imp.h @@ -30,11 +30,6 @@ */ void flash_bank_add(struct flash_bank *bank); -/** - * @return The first bank in the global list. - */ -struct flash_bank *flash_bank_list(void); - int flash_driver_erase(struct flash_bank *bank, int first, int last); int flash_driver_protect(struct flash_bank *bank, int set, int first, int last); int flash_driver_write(struct flash_bank *bank, diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 79af632..3d51142 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -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); @@ -818,9 +813,10 @@ static int cortex_m_step(struct target *target, int current, * instruction - as such simulate a step */ if (bkpt_inst_found == false) { /* Automatic ISR masking mode off: Just step over the next instruction */ - if ((cortex_m->isrmasking_mode != CORTEX_M_ISRMASK_AUTO)) + if (cortex_m->isrmasking_mode == CORTEX_M_ISRMASK_ON + || cortex_m->isrmasking_mode == CORTEX_M_ISRMASK_OFF) { cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT); - else { + } else { /* Process interrupts during stepping in a way they don't interfere * debugging. * @@ -867,8 +863,13 @@ static int cortex_m_step(struct target *target, int current, /* Set a temporary break point */ if (breakpoint) retval = cortex_m_set_breakpoint(target, breakpoint); - else - retval = breakpoint_add(target, pc_value, 2, BKPT_TYPE_BY_ADDR(pc_value)); + else { + enum breakpoint_type type = + (cortex_m->isrmasking_mode == CORTEX_M_ISRMASK_AUTO + && !target_addr_in_flash(target, pc_value)) + ? BKPT_SOFT : BKPT_HARD; + retval = breakpoint_add(target, pc_value, 2, type); + } bool tmp_bp_set = (retval == ERROR_OK); /* No more breakpoints left, just do a step */ @@ -1131,9 +1132,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 +1251,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 +1282,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); @@ -2104,7 +2084,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; @@ -2392,6 +2371,7 @@ COMMAND_HANDLER(handle_cortex_m_mask_interrupts_command) { .name = "auto", .value = CORTEX_M_ISRMASK_AUTO }, { .name = "off", .value = CORTEX_M_ISRMASK_OFF }, { .name = "on", .value = CORTEX_M_ISRMASK_ON }, + { .name = "auto_hard_bp", .value = CORTEX_M_ISRMASK_AUTO_HARD_BP }, { .name = NULL, .value = -1 }, }; const Jim_Nvp *n; @@ -2468,7 +2448,7 @@ static const struct command_registration cortex_m_exec_command_handlers[] = { .handler = handle_cortex_m_mask_interrupts_command, .mode = COMMAND_EXEC, .help = "mask cortex_m interrupts", - .usage = "['auto'|'on'|'off']", + .usage = "['auto'|'on'|'off'|'auto_hard_bp']", }, { .name = "vector_catch", diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index 9500acc..8e78348 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -159,6 +159,7 @@ enum cortex_m_isrmasking_mode { CORTEX_M_ISRMASK_AUTO, CORTEX_M_ISRMASK_OFF, CORTEX_M_ISRMASK_ON, + CORTEX_M_ISRMASK_AUTO_HARD_BP, }; struct cortex_m_common { @@ -175,7 +176,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) */ diff --git a/src/target/target.c b/src/target/target.c index 58d6d82..d937230 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -1160,6 +1160,19 @@ int target_hit_watchpoint(struct target *target, return target->type->hit_watchpoint(target, hit_watchpoint); } +bool target_addr_in_flash(struct target *target, target_addr_t addr) +{ + struct flash_bank *bank; + bank = flash_bank_list(); + while (bank) { + if (bank->target == target) + if (addr >= bank->base && addr < bank->base + bank->size) + return true; + bank = bank->next; + } + return false; +} + int target_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class) diff --git a/src/target/target.h b/src/target/target.h index 6020400..a56a542 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -461,6 +461,11 @@ int target_hit_watchpoint(struct target *target, struct watchpoint **watchpoint); /** + * Check if @a addr is in a flash bank of @a target + */ +bool target_addr_in_flash(struct target *target, target_addr_t addr); + +/** * Obtain the registers for GDB. * * This routine is a wrapper for target->type->get_gdb_reg_list. -- ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ OpenOCD-devel mailing list OpenOCD-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openocd-devel