X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Fcortex_m.c;h=ea8a086027e42edb498a3f3bdc093b889197f5af;hb=c8492ee2d468bcee8e2b7bb0560e6329c12a86e2;hp=28824b8a36822ff7a5b7ae1f6a29cc86617935be;hpb=79fa75e199ae7cafe0be9d71d7246464da34015e;p=openocd.git diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 28824b8a36..ea8a086027 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -21,7 +21,7 @@ * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * * * * * Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) * @@ -61,7 +61,7 @@ /* forward declarations */ static int cortex_m3_store_core_reg_u32(struct target *target, - enum armv7m_regtype type, uint32_t num, uint32_t value); + uint32_t num, uint32_t value); static int cortexm3_dap_read_coreregister_u32(struct adiv5_dap *swjdp, uint32_t *value, int regnum) @@ -298,7 +298,7 @@ static int cortex_m3_endreset_event(struct target *target) if (retval != ERROR_OK) return retval; - register_cache_invalidate(cortex_m3->armv7m.core_cache); + register_cache_invalidate(armv7m->arm.core_cache); /* make sure we have latest dhcsr flags */ retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr); @@ -421,48 +421,36 @@ static int cortex_m3_debug_entry(struct target *target) return retval; /* Examine target state and mode - * First load register acessible through core debug port*/ - int num_regs = armv7m->core_cache->num_regs; + * First load register accessible through core debug port */ + int num_regs = arm->core_cache->num_regs; for (i = 0; i < num_regs; i++) { - if (!armv7m->core_cache->reg_list[i].valid) - armv7m->read_core_reg(target, i); + r = &armv7m->arm.core_cache->reg_list[i]; + if (!r->valid) + arm->read_core_reg(target, r, i, ARM_MODE_ANY); } - r = armv7m->core_cache->reg_list + ARMV7M_xPSR; + r = arm->cpsr; xPSR = buf_get_u32(r->value, 0, 32); -#ifdef ARMV7_GDB_HACKS - /* FIXME this breaks on scan chains with more than one Cortex-M3. - * Instead, each CM3 should have its own dummy value... - */ - /* copy real xpsr reg for gdb, setting thumb bit */ - buf_set_u32(armv7m_gdb_dummy_cpsr_value, 0, 32, xPSR); - buf_set_u32(armv7m_gdb_dummy_cpsr_value, 5, 1, 1); - armv7m_gdb_dummy_cpsr_reg.valid = r->valid; - armv7m_gdb_dummy_cpsr_reg.dirty = r->dirty; -#endif - /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */ if (xPSR & 0xf00) { r->dirty = r->valid; - cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR & ~0xff); + cortex_m3_store_core_reg_u32(target, 16, xPSR & ~0xff); } /* Are we in an exception handler */ if (xPSR & 0x1FF) { - armv7m->core_mode = ARMV7M_MODE_HANDLER; armv7m->exception_number = (xPSR & 0x1FF); arm->core_mode = ARM_MODE_HANDLER; arm->map = armv7m_msp_reg_map; } else { - unsigned control = buf_get_u32(armv7m->core_cache + unsigned control = buf_get_u32(arm->core_cache ->reg_list[ARMV7M_CONTROL].value, 0, 2); /* is this thread privileged? */ - armv7m->core_mode = control & 1; - arm->core_mode = armv7m->core_mode + arm->core_mode = control & 1 ? ARM_MODE_USER_THREAD : ARM_MODE_THREAD; @@ -479,7 +467,7 @@ static int cortex_m3_debug_entry(struct target *target) cortex_m3_examine_exception_reason(target); LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", target->state: %s", - armv7m_mode_strings[armv7m->core_mode], + arm_mode_name(arm->core_mode), *(uint32_t *)(arm->pc->value), target_state_name(target)); @@ -633,6 +621,12 @@ static int cortex_m3_soft_reset_halt(struct target *target) uint32_t dcb_dhcsr = 0; int retval, timeout = 0; + /* soft_reset_halt is deprecated on cortex_m as the same functionality + * can be obtained by using 'reset halt' and 'cortex_m reset_config vectreset' + * As this reset only used VC_CORERESET it would only ever reset the cortex_m + * core, not the peripherals */ + LOG_WARNING("soft_reset_halt is deprecated, please use 'reset halt' instead."); + /* Enter debug state on reset; restore DEMCR in endreset_event() */ retval = mem_ap_write_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET); @@ -647,7 +641,7 @@ static int cortex_m3_soft_reset_halt(struct target *target) target->state = TARGET_RESET; /* registers are now invalid */ - register_cache_invalidate(cortex_m3->armv7m.core_cache); + register_cache_invalidate(cortex_m3->armv7m.arm.core_cache); while (timeout < 100) { retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr); @@ -677,7 +671,7 @@ static int cortex_m3_soft_reset_halt(struct target *target) return ERROR_OK; } -static void cortex_m3_enable_breakpoints(struct target *target) +void cortex_m3_enable_breakpoints(struct target *target) { struct breakpoint *breakpoint = target->breakpoints; @@ -709,7 +703,7 @@ static int cortex_m3_resume(struct target *target, int current, } if (debug_execution) { - r = armv7m->core_cache->reg_list + ARMV7M_PRIMASK; + r = armv7m->arm.core_cache->reg_list + ARMV7M_PRIMASK; /* Disable interrupts */ /* We disable interrupts in the PRIMASK register instead of @@ -727,7 +721,7 @@ static int cortex_m3_resume(struct target *target, int current, r->valid = true; /* Make sure we are in Thumb mode */ - r = armv7m->core_cache->reg_list + ARMV7M_xPSR; + r = armv7m->arm.cpsr; buf_set_u32(r->value, 24, 1, 1); r->dirty = true; r->valid = true; @@ -773,7 +767,7 @@ static int cortex_m3_resume(struct target *target, int current, target->debug_reason = DBG_REASON_NOTHALTED; /* registers are now invalid */ - register_cache_invalidate(armv7m->core_cache); + register_cache_invalidate(armv7m->arm.core_cache); if (!debug_execution) { target->state = TARGET_RUNNING; @@ -879,7 +873,10 @@ static int cortex_m3_step(struct target *target, int current, else { /* Set a temporary break point */ - retval = breakpoint_add(target, pc_value, 2, BKPT_TYPE_BY_ADDR(pc_value)); + if (breakpoint) + retval = cortex_m3_set_breakpoint(target, breakpoint); + else + retval = breakpoint_add(target, pc_value, 2, BKPT_TYPE_BY_ADDR(pc_value)); bool tmp_bp_set = (retval == ERROR_OK); /* No more breakpoints left, just do a step */ @@ -903,8 +900,13 @@ static int cortex_m3_step(struct target *target, int current, isr_timed_out = ((timeval_ms() - t_start) > 500); } while (!((cortex_m3->dcb_dhcsr & S_HALT) || isr_timed_out)); - /* Remove the temporary breakpoint */ - breakpoint_remove(target, pc_value); + /* only remove breakpoint if we created it */ + if (breakpoint) + cortex_m3_unset_breakpoint(target, breakpoint); + else { + /* Remove the temporary breakpoint */ + breakpoint_remove(target, pc_value); + } if (isr_timed_out) { LOG_DEBUG("Interrupt handlers didn't complete within time, " @@ -928,7 +930,7 @@ static int cortex_m3_step(struct target *target, int current, return retval; /* registers are now invalid */ - register_cache_invalidate(cortex_m3->armv7m.core_cache); + register_cache_invalidate(armv7m->arm.core_cache); if (breakpoint) cortex_m3_set_breakpoint(target, breakpoint); @@ -971,7 +973,7 @@ static int cortex_m3_assert_reset(struct target *target) /* allow scripts to override the reset event */ target_handle_event(target, TARGET_EVENT_RESET_ASSERT); - register_cache_invalidate(cortex_m3->armv7m.core_cache); + register_cache_invalidate(cortex_m3->armv7m.arm.core_cache); target->state = TARGET_RESET; return ERROR_OK; @@ -982,7 +984,8 @@ static int cortex_m3_assert_reset(struct target *target) bool srst_asserted = false; - if (jtag_reset_config & RESET_SRST_NO_GATING) { + if ((jtag_reset_config & RESET_HAS_SRST) && + (jtag_reset_config & RESET_SRST_NO_GATING)) { adapter_assert_reset(); srst_asserted = true; } @@ -1053,11 +1056,11 @@ static int cortex_m3_assert_reset(struct target *target) if (retval != ERROR_OK) return retval; - LOG_DEBUG("Using Cortex-M3 %s", (reset_config == CORTEX_M3_RESET_SYSRESETREQ) + LOG_DEBUG("Using Cortex-M %s", (reset_config == CORTEX_M3_RESET_SYSRESETREQ) ? "SYSRESETREQ" : "VECTRESET"); if (reset_config == CORTEX_M3_RESET_VECTRESET) { - LOG_WARNING("Only resetting the Cortex-M3 core, use a reset-init event " + LOG_WARNING("Only resetting the Cortex-M core, use a reset-init event " "handler to reset any peripherals or configure hardware srst support."); } @@ -1076,7 +1079,7 @@ static int cortex_m3_assert_reset(struct target *target) target->state = TARGET_RESET; jtag_add_sleep(50000); - register_cache_invalidate(cortex_m3->armv7m.core_cache); + register_cache_invalidate(cortex_m3->armv7m.arm.core_cache); if (target->reset_halt) { retval = target_halt(target); @@ -1218,17 +1221,8 @@ int cortex_m3_add_breakpoint(struct target *target, struct breakpoint *breakpoin { struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - if (cortex_m3->auto_bp_type) { + if (cortex_m3->auto_bp_type) breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address); -#ifdef ARMV7_GDB_HACKS - if (breakpoint->length != 2) { - /* XXX Hack: Replace all breakpoints with length != 2 with - * a hardware breakpoint. */ - breakpoint->type = BKPT_HARD; - breakpoint->length = 2; - } -#endif - } if (breakpoint->type != BKPT_TYPE_BY_ADDR(breakpoint->address)) { if (breakpoint->type == BKPT_HARD) { @@ -1458,7 +1452,7 @@ void cortex_m3_enable_watchpoints(struct target *target) } static int cortex_m3_load_core_reg_u32(struct target *target, - enum armv7m_regtype type, uint32_t num, uint32_t *value) + uint32_t num, uint32_t *value) { int retval; struct armv7m_common *armv7m = target_to_armv7m(target); @@ -1519,25 +1513,13 @@ static int cortex_m3_load_core_reg_u32(struct target *target, } static int cortex_m3_store_core_reg_u32(struct target *target, - enum armv7m_regtype type, uint32_t num, uint32_t value) + uint32_t num, uint32_t value) { int retval; uint32_t reg; struct armv7m_common *armv7m = target_to_armv7m(target); struct adiv5_dap *swjdp = armv7m->arm.dap; -#ifdef ARMV7_GDB_HACKS - /* If the LR register is being modified, make sure it will put us - * in "thumb" mode, or an INVSTATE exception will occur. This is a - * hack to deal with the fact that gdb will sometimes "forge" - * return addresses, and doesn't set the LSB correctly (i.e., when - * printing expressions containing function calls, it sets LR = 0.) - * Valid exception return codes have bit 0 set too. - */ - if (num == ARMV7M_R14) - value |= 0x01; -#endif - /* NOTE: we "know" here that the register identifiers used * in the v7m header match the Cortex-M3 Debug Core Register * Selector values for R0..R15, xPSR, MSP, and PSP. @@ -1549,7 +1531,7 @@ static int cortex_m3_store_core_reg_u32(struct target *target, struct reg *r; LOG_ERROR("JTAG failure"); - r = armv7m->core_cache->reg_list + num; + r = armv7m->arm.core_cache->reg_list + num; r->dirty = r->valid; return ERROR_JTAG_DEVICE_ERROR; } @@ -1601,7 +1583,6 @@ static int cortex_m3_read_memory(struct target *target, uint32_t address, { struct armv7m_common *armv7m = target_to_armv7m(target); struct adiv5_dap *swjdp = armv7m->arm.dap; - int retval = ERROR_COMMAND_SYNTAX_ERROR; if (armv7m->arm.is_armv6m) { /* armv6m does not handle unaligned memory access */ @@ -1609,22 +1590,7 @@ static int cortex_m3_read_memory(struct target *target, uint32_t address, return ERROR_TARGET_UNALIGNED_ACCESS; } - /* cortex_m3 handles unaligned memory access */ - if (count && buffer) { - switch (size) { - case 4: - retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address); - break; - case 2: - retval = mem_ap_read_buf_u16(swjdp, buffer, 2 * count, address); - break; - case 1: - retval = mem_ap_read_buf_u8(swjdp, buffer, count, address); - break; - } - } - - return retval; + return mem_ap_read(swjdp, buffer, size, count, address, true); } static int cortex_m3_write_memory(struct target *target, uint32_t address, @@ -1632,7 +1598,6 @@ static int cortex_m3_write_memory(struct target *target, uint32_t address, { struct armv7m_common *armv7m = target_to_armv7m(target); struct adiv5_dap *swjdp = armv7m->arm.dap; - int retval = ERROR_COMMAND_SYNTAX_ERROR; if (armv7m->arm.is_armv6m) { /* armv6m does not handle unaligned memory access */ @@ -1640,27 +1605,7 @@ static int cortex_m3_write_memory(struct target *target, uint32_t address, return ERROR_TARGET_UNALIGNED_ACCESS; } - if (count && buffer) { - switch (size) { - case 4: - retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address); - break; - case 2: - retval = mem_ap_write_buf_u16(swjdp, buffer, 2 * count, address); - break; - case 1: - retval = mem_ap_write_buf_u8(swjdp, buffer, count, address); - break; - } - } - - return retval; -} - -static int cortex_m3_bulk_write_memory(struct target *target, uint32_t address, - uint32_t count, const uint8_t *buffer) -{ - return cortex_m3_write_memory(target, address, 4, count, buffer); + return mem_ap_write(swjdp, buffer, size, count, address, true); } static int cortex_m3_init_target(struct command_context *cmd_ctx, @@ -1795,6 +1740,9 @@ fail1: for (j = 0; j < 3; j++, reg++) cortex_m3_dwt_addreg(target, cache->reg_list + reg, dwt_comp + 3 * i + j); + + /* make sure we clear any watchpoints enabled on the target */ + target_write_u32(target, comparator->dwt_comparator_address + 8, 0); } *register_get_last_cache_p(&target->reg_cache) = cache; @@ -1886,6 +1834,9 @@ int cortex_m3_examine(struct target *target) cortex_m3->fp_comparator_list[i].type = (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL; cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i; + + /* make sure we clear any breakpoints enabled on the target */ + target_write_u32(target, cortex_m3->fp_comparator_list[i].fpcr_address, 0); } LOG_DEBUG("FPB fpcr 0x%" PRIx32 ", numcode %i, numlit %i", fpcr, @@ -1910,7 +1861,7 @@ static int cortex_m3_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t * uint16_t dcrdr; int retval; - mem_ap_read_buf_u16(swjdp, (uint8_t *)&dcrdr, 1, DCB_DCRDR); + mem_ap_read_buf_u16(swjdp, (uint8_t *)&dcrdr, 2, DCB_DCRDR); *ctrl = (uint8_t)dcrdr; *value = (uint8_t)(dcrdr >> 8); @@ -1920,7 +1871,7 @@ static int cortex_m3_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t * * signify we have read data */ if (dcrdr & (1 << 0)) { dcrdr = 0; - retval = mem_ap_write_buf_u16(swjdp, (uint8_t *)&dcrdr, 1, DCB_DCRDR); + retval = mem_ap_write_buf_u16(swjdp, (uint8_t *)&dcrdr, 2, DCB_DCRDR); if (retval != ERROR_OK) return retval; } @@ -2043,7 +1994,7 @@ static int cortex_m3_verify_pointer(struct command_context *cmd_ctx, struct cortex_m3_common *cm3) { if (cm3->common_magic != CORTEX_M3_COMMON_MAGIC) { - command_print(cmd_ctx, "target is not a Cortex-M3"); + command_print(cmd_ctx, "target is not a Cortex-M"); return ERROR_TARGET_INVALID; } return ERROR_OK; @@ -2178,7 +2129,7 @@ COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command) } n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_m3->isrmasking_mode); - command_print(CMD_CTX, "cortex_m3 interrupt mask %s", n->name); + command_print(CMD_CTX, "cortex_m interrupt mask %s", n->name); return ERROR_OK; } @@ -2215,7 +2166,7 @@ COMMAND_HANDLER(handle_cortex_m3_reset_config_command) break; } - command_print(CMD_CTX, "cortex_m3 reset_config %s", reset_config); + command_print(CMD_CTX, "cortex_m reset_config %s", reset_config); return ERROR_OK; } @@ -2225,7 +2176,7 @@ static const struct command_registration cortex_m3_exec_command_handlers[] = { .name = "maskisr", .handler = handle_cortex_m3_mask_interrupts_command, .mode = COMMAND_EXEC, - .help = "mask cortex_m3 interrupts", + .help = "mask cortex_m interrupts", .usage = "['auto'|'on'|'off']", }, { @@ -2249,9 +2200,9 @@ static const struct command_registration cortex_m3_command_handlers[] = { .chain = armv7m_command_handlers, }, { - .name = "cortex_m3", + .name = "cortex_m", .mode = COMMAND_EXEC, - .help = "Cortex-M3 command group", + .help = "Cortex-M command group", .usage = "", .chain = cortex_m3_exec_command_handlers, }, @@ -2259,7 +2210,8 @@ static const struct command_registration cortex_m3_command_handlers[] = { }; struct target_type cortexm3_target = { - .name = "cortex_m3", + .name = "cortex_m", + .deprecated_name = "cortex_m3", .poll = cortex_m3_poll, .arch_state = armv7m_arch_state, @@ -2278,7 +2230,6 @@ struct target_type cortexm3_target = { .read_memory = cortex_m3_read_memory, .write_memory = cortex_m3_write_memory, - .bulk_write_memory = cortex_m3_bulk_write_memory, .checksum_memory = armv7m_checksum_memory, .blank_check_memory = armv7m_blank_check_memory,